Skip to content

Commit

Permalink
Dear 130 add chart to display happiness by workkind during sprint (#19)
Browse files Browse the repository at this point in the history
* DEAR-130 dto, endpoint for all insights

* DEAR-130 dto, endpoint for all insights

* DEAR-130 checkstyle

* DEAR-130 sort dates

* DEAR-130 clean up

* DEAR-130 add tests

* DEAR-130 fix checkstyle
  • Loading branch information
smuefsmuef authored Jul 29, 2024
1 parent 0f7c08c commit f9d0861
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,16 @@ public class InsightsController {
@Autowired
private InsightsService insightsService;

// Line Chart: overall happiness team vs personal
// Overall
@GetMapping("/{userId}/team/{teamId}/sprint/{sprint}")
public ResponseEntity<InsightDTO> getInsightsByTeamAndSprint(@PathVariable Integer userId,
@PathVariable Integer teamId,
@PathVariable String sprint) {
InsightDTO insights = insightsService.getInsightsByTeamAndSprint(userId, teamId, sprint);
return ResponseEntity.ok(insights);
}

// happiness team vs personal
@GetMapping("/happiness/{userId}/team/{teamId}/sprint/{sprint}")
public ResponseEntity<List<HappinessInsightDTO>> getHappinessInsightsByTeam(
@PathVariable Integer userId, @PathVariable Integer teamId, @PathVariable String sprint) {
Expand All @@ -29,22 +38,4 @@ public ResponseEntity<List<HappinessInsightDTO>> getHappinessInsightsByTeam(
}
}

// Bar Chart: workkind team vs personal
@GetMapping("/workkind/{userId}/team/{teamId}/sprint/{sprint}")
public List<TeamWorkKindInsightDTO> getWorkKindHappinessByUserId(@PathVariable Integer userId, @PathVariable Integer teamId, @PathVariable String sprint) {
// return insightsService.getWorkKindHappinessByUserId(userId);
return List.of();
}

// Line Chart/Area Chart: velocity of the sprint vs happiness vs workkind
// no timestamp
// y: workkind, velocity
// x: days

// Radar Chart
// Top 10 Emotions Personal & Team

// Radar Chart
// Top 10 Workkinds Personal & Team

}
13 changes: 13 additions & 0 deletions src/main/java/ch/fhnw/deardevbackend/dto/InsightDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ch.fhnw.deardevbackend.dto;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.List;

@Data
@AllArgsConstructor
public class InsightDTO {
private List<HappinessInsightDTO> happinessInsights;
private List<WorkKindInsightDTO> workKindInsights;
}
47 changes: 19 additions & 28 deletions src/main/java/ch/fhnw/deardevbackend/services/InsightsService.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
import org.springframework.transaction.annotation.Transactional;


import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import java.time.format.DateTimeFormatter;

@Service
public class InsightsService {
Expand All @@ -38,28 +40,11 @@ public InsightsService(InsightsRepository insightsRepository,
}

@Transactional(readOnly = true)
public List<TeamHappinessInsightDTO> getDailyAveragesByUserId(@ValidateUserIdParam Integer userId) {
List<Integer> teamIds = teamMemberRepository.findTeamIdByUserId(userId);

return teamIds.stream().map(teamId -> {
List<Object[]> userAverages = happinessSurveyRepository.findDailyAveragesByUserId(userId);
List<Object[]> teamAverages = insightsRepository.findTeamDailyAveragesExcludingUser(teamId, userId);

List<HappinessInsightDTO> insights = userAverages.stream().map(userAvg -> {
String day = userAvg[0].toString();
double userAverage = ((Number) userAvg[1]).doubleValue();

double teamAverage = teamAverages.stream()
.filter(teamAvg -> teamAvg[0].toString().equals(day))
.map(teamAvg -> ((Number) teamAvg[1]).doubleValue())
.findFirst()
.orElse(0.0);
public InsightDTO getInsightsByTeamAndSprint(@ValidateUserIdParam Integer userId, Integer teamId, String sprint) {
List<HappinessInsightDTO> happinessInsights = getHappinessInsightsByTeam(userId, teamId, sprint);
List<WorkKindInsightDTO> workKindInsights = getWorkKindInsightsByUserId(userId);

return happinessInsightMapper.toDTO(day, userAverage, teamAverage);
}).collect(Collectors.toList());

return new TeamHappinessInsightDTO(teamId, insights);
}).collect(Collectors.toList());
return new InsightDTO(happinessInsights, workKindInsights);
}

@Transactional(readOnly = true)
Expand Down Expand Up @@ -109,27 +94,33 @@ public List<HappinessInsightDTO> getHappinessInsightsByTeam(@ValidateUserIdParam
double teamAverage = teamAveragesMap.getOrDefault(day, 0.0);
return happinessInsightMapper.toDTO(day, userAverage, teamAverage);
})
.sorted(Comparator.comparing(h -> LocalDate.parse(h.getDay(), DateTimeFormatter.ISO_DATE)))
.collect(Collectors.toList());

}

// todo later asap structure is defined
private WorkKindInsightDTO findMatchingWorkKindInsight(HappinessInsightDTO happinessInsightDTO, List<WorkKindInsightDTO> workKindInsights) {
return workKindInsights.stream()
// .filter(workKindInsightDTO -> workKindInsightDTO.getTeamId().equals(happinessInsightDTO.getTeamId()))
.findFirst()
.orElse(null);
}


// todo remove
@Transactional(readOnly = true)
public List<TeamWorkKindInsightDTO> getWorkKindHappinessByUserId(@ValidateUserIdParam Integer userId) {
public List<WorkKindInsightDTO> getWorkKindInsightsByUserId(@ValidateUserIdParam Integer userId) {
List<Object[]> results = insightsRepository.findWorkKindHappinessByUserId(userId);

Map<Integer, List<WorkKindInsightDTO>> groupedByTeam = results.stream()
return results.stream()
.map(row -> workKindInsightMapper.toDTO(
(Integer) row[0],
(Integer) row[1],
(String) row[2],
(Double) row[3],
(Long) row[4]
))
.collect(Collectors.groupingBy(WorkKindInsightDTO::getTeamId));

return groupedByTeam.entrySet().stream()
.map(entry -> new TeamWorkKindInsightDTO(entry.getKey(), entry.getValue()))
.collect(Collectors.toList());
}
}
129 changes: 44 additions & 85 deletions src/test/java/ch/fhnw/deardevbackend/services/InsightsServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@
import static org.mockito.Mockito.*;

import ch.fhnw.deardevbackend.dto.HappinessInsightDTO;
import ch.fhnw.deardevbackend.dto.TeamHappinessInsightDTO;
import ch.fhnw.deardevbackend.dto.TeamWorkKindInsightDTO;
import ch.fhnw.deardevbackend.dto.InsightDTO;
import ch.fhnw.deardevbackend.dto.WorkKindInsightDTO;
import ch.fhnw.deardevbackend.mapper.HappinessInsightMapper;
import ch.fhnw.deardevbackend.mapper.WorkKindInsightMapper;
import ch.fhnw.deardevbackend.repositories.InsightsRepository;
import ch.fhnw.deardevbackend.repositories.HappinessSurveyRepository;
import ch.fhnw.deardevbackend.repositories.TeamMemberRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand All @@ -35,9 +33,6 @@ public class InsightsServiceTest {
@Mock
private HappinessSurveyRepository happinessSurveyRepository;

@Mock
private TeamMemberRepository teamMemberRepository;

@Mock
private HappinessInsightMapper happinessInsightMapper;

Expand Down Expand Up @@ -83,106 +78,70 @@ void setUp() {
}

@Test
void getDailyAveragesByUserId_success() {
List<Integer> teamIds = List.of(1);

when(teamMemberRepository.findTeamIdByUserId(userId)).thenReturn(teamIds);
when(happinessSurveyRepository.findDailyAveragesByUserId(userId)).thenReturn(userAverages);
when(insightsRepository.findTeamDailyAveragesExcludingUser(1, userId)).thenReturn(teamAverages);
void getInsightsByTeamAndSprint_success() {
Integer teamId = 1;
String sprint = "current";

when(happinessSurveyRepository.findDailyAveragesByUserIdAndDateRange(eq(userId), any(), any())).thenReturn(userAverages);
when(insightsRepository.findTeamDailyAveragesExcludingUserAndDateRange(eq(teamId), eq(userId), any(), any())).thenReturn(teamAverages);
when(happinessInsightMapper.toDTO("2024-07-27", 5.0, 4.0)).thenReturn(new HappinessInsightDTO("2024-07-27", 5.0, 4.0));
when(happinessInsightMapper.toDTO("2024-07-28", 5.0, 2.0)).thenReturn(new HappinessInsightDTO("2024-07-28", 5.0, 2.0));
when(happinessInsightMapper.toDTO("2024-07-29", 6.0, 3.0)).thenReturn(new HappinessInsightDTO("2024-07-29", 6.0, 3.0));

List<TeamHappinessInsightDTO> result = insightsService.getDailyAveragesByUserId(userId);
when(insightsRepository.findWorkKindHappinessByUserId(userId)).thenReturn(workKindHappinessData);
when(workKindInsightMapper.toDTO(1, 1, "Development", 4.5, 10L)).thenReturn(workKindInsightDTO1);
when(workKindInsightMapper.toDTO(1, 2, "Testing", 3.5, 5L)).thenReturn(workKindInsightDTO2);
when(workKindInsightMapper.toDTO(2, 1, "Development", 4.0, 8L)).thenReturn(workKindInsightDTO3);
when(workKindInsightMapper.toDTO(2, 2, "Testing", 3.0, 6L)).thenReturn(workKindInsightDTO4);

InsightDTO result = insightsService.getInsightsByTeamAndSprint(userId, teamId, sprint);

assertNotNull(result);
assertEquals(1, result.size());
assertEquals(1, result.getFirst().getTeamId());
assertEquals(3, result.getFirst().getInsights().size());
assertEquals("2024-07-27", result.getFirst().getInsights().getFirst().getDay());
assertEquals(5.0, result.getFirst().getInsights().getFirst().getUserAverage());
assertEquals(4.0, result.getFirst().getInsights().getFirst().getTeamAverage());
assertEquals("2024-07-28", result.getFirst().getInsights().get(1).getDay());
assertEquals(5.0, result.getFirst().getInsights().get(1).getUserAverage());
assertEquals(2.0, result.getFirst().getInsights().get(1).getTeamAverage());
assertEquals("2024-07-29", result.getFirst().getInsights().get(2).getDay());
assertEquals(6.0, result.getFirst().getInsights().get(2).getUserAverage());
assertEquals(3.0, result.getFirst().getInsights().get(2).getTeamAverage());

verify(teamMemberRepository, times(1)).findTeamIdByUserId(userId);
verify(happinessSurveyRepository, times(1)).findDailyAveragesByUserId(userId);
verify(insightsRepository, times(1)).findTeamDailyAveragesExcludingUser(1, userId);
assertNotNull(result.getHappinessInsights());
assertNotNull(result.getWorkKindInsights());
assertEquals(3, result.getHappinessInsights().size());
assertEquals(4, result.getWorkKindInsights().size());

verify(happinessSurveyRepository, times(1)).findDailyAveragesByUserIdAndDateRange(eq(userId), any(), any());
verify(insightsRepository, times(1)).findTeamDailyAveragesExcludingUserAndDateRange(eq(teamId), eq(userId), any(), any());
verify(happinessInsightMapper, times(3)).toDTO(anyString(), anyDouble(), anyDouble());

verify(insightsRepository, times(1)).findWorkKindHappinessByUserId(userId);
verify(workKindInsightMapper, times(4)).toDTO(anyInt(), anyInt(), anyString(), anyDouble(), anyLong());
}

@Test
void getDailyAveragesByUserId_multipleTeams_success() {
List<Integer> teamIds = Arrays.asList(1, 2);

when(teamMemberRepository.findTeamIdByUserId(userId)).thenReturn(teamIds);
when(happinessSurveyRepository.findDailyAveragesByUserId(userId)).thenReturn(userAverages);
when(insightsRepository.findTeamDailyAveragesExcludingUser(1, userId)).thenReturn(teamAverages);
when(insightsRepository.findTeamDailyAveragesExcludingUser(2, userId)).thenReturn(teamAverages);
void getHappinessInsightsByTeam_success() {
Integer teamId = 1;
String sprint = "current";

when(happinessSurveyRepository.findDailyAveragesByUserIdAndDateRange(eq(userId), any(), any())).thenReturn(userAverages);
when(insightsRepository.findTeamDailyAveragesExcludingUserAndDateRange(eq(teamId), eq(userId), any(), any())).thenReturn(teamAverages);
when(happinessInsightMapper.toDTO("2024-07-27", 5.0, 4.0)).thenReturn(new HappinessInsightDTO("2024-07-27", 5.0, 4.0));
when(happinessInsightMapper.toDTO("2024-07-28", 5.0, 2.0)).thenReturn(new HappinessInsightDTO("2024-07-28", 5.0, 2.0));
when(happinessInsightMapper.toDTO("2024-07-29", 6.0, 3.0)).thenReturn(new HappinessInsightDTO("2024-07-29", 6.0, 3.0));

List<TeamHappinessInsightDTO> result = insightsService.getDailyAveragesByUserId(userId);
List<HappinessInsightDTO> result = insightsService.getHappinessInsightsByTeam(userId, teamId, sprint);

assertNotNull(result);
assertEquals(2, result.size());

// Team 1 Assertions
assertEquals(1, result.getFirst().getTeamId());
assertEquals(3, result.getFirst().getInsights().size());
assertEquals("2024-07-27", result.getFirst().getInsights().getFirst().getDay());
assertEquals(5.0, result.getFirst().getInsights().getFirst().getUserAverage());
assertEquals(4.0, result.getFirst().getInsights().getFirst().getTeamAverage());
assertEquals("2024-07-28", result.getFirst().getInsights().get(1).getDay());
assertEquals(5.0, result.getFirst().getInsights().get(1).getUserAverage());
assertEquals(2.0, result.getFirst().getInsights().get(1).getTeamAverage());
assertEquals("2024-07-29", result.getFirst().getInsights().get(2).getDay());
assertEquals(6.0, result.getFirst().getInsights().get(2).getUserAverage());
assertEquals(3.0, result.getFirst().getInsights().get(2).getTeamAverage());

// Team 2 Assertions
assertEquals(2, result.get(1).getTeamId());
assertEquals(3, result.get(1).getInsights().size());
assertEquals("2024-07-27", result.get(1).getInsights().getFirst().getDay());
assertEquals(5.0, result.get(1).getInsights().getFirst().getUserAverage());
assertEquals(4.0, result.get(1).getInsights().getFirst().getTeamAverage());
assertEquals("2024-07-28", result.get(1).getInsights().get(1).getDay());
assertEquals(5.0, result.get(1).getInsights().get(1).getUserAverage());
assertEquals(2.0, result.get(1).getInsights().get(1).getTeamAverage());
assertEquals("2024-07-29", result.get(1).getInsights().get(2).getDay());
assertEquals(6.0, result.get(1).getInsights().get(2).getUserAverage());
assertEquals(3.0, result.get(1).getInsights().get(2).getTeamAverage());

verify(teamMemberRepository, times(1)).findTeamIdByUserId(userId);
verify(happinessSurveyRepository, times(2)).findDailyAveragesByUserId(userId);
verify(insightsRepository, times(1)).findTeamDailyAveragesExcludingUser(1, userId);
verify(insightsRepository, times(1)).findTeamDailyAveragesExcludingUser(2, userId);
verify(happinessInsightMapper, times(6)).toDTO(anyString(), anyDouble(), anyDouble());
}
assertEquals(3, result.size());

@Test
void getWorkKindHappinessByUserId_success() {
when(insightsRepository.findWorkKindHappinessByUserId(userId)).thenReturn(workKindHappinessData);
when(workKindInsightMapper.toDTO(1, 1, "Development", 4.5, 10L)).thenReturn(workKindInsightDTO1);
when(workKindInsightMapper.toDTO(1, 2, "Testing", 3.5, 5L)).thenReturn(workKindInsightDTO2);
when(workKindInsightMapper.toDTO(2, 1, "Development", 4.0, 8L)).thenReturn(workKindInsightDTO3);
when(workKindInsightMapper.toDTO(2, 2, "Testing", 3.0, 6L)).thenReturn(workKindInsightDTO4);

List<TeamWorkKindInsightDTO> result = insightsService.getWorkKindHappinessByUserId(userId);
assertEquals("2024-07-27", result.getFirst().getDay());
assertEquals(5.0, result.getFirst().getUserAverage());
assertEquals(4.0, result.getFirst().getTeamAverage());

assertEquals(2, result.size());
assertEquals("2024-07-28", result.get(1).getDay());
assertEquals(5.0, result.get(1).getUserAverage());
assertEquals(2.0, result.get(1).getTeamAverage());

List<WorkKindInsightDTO> team1Insights = Arrays.asList(workKindInsightDTO1, workKindInsightDTO2);
List<WorkKindInsightDTO> team2Insights = Arrays.asList(workKindInsightDTO3, workKindInsightDTO4);
assertEquals("2024-07-29", result.get(2).getDay());
assertEquals(6.0, result.get(2).getUserAverage());
assertEquals(3.0, result.get(2).getTeamAverage());

assertEquals(new TeamWorkKindInsightDTO(1, team1Insights), result.getFirst());
assertEquals(new TeamWorkKindInsightDTO(2, team2Insights), result.get(1));
verify(happinessSurveyRepository, times(1)).findDailyAveragesByUserIdAndDateRange(eq(userId), any(), any());
verify(insightsRepository, times(1)).findTeamDailyAveragesExcludingUserAndDateRange(eq(teamId), eq(userId), any(), any());
verify(happinessInsightMapper, times(3)).toDTO(anyString(), anyDouble(), anyDouble());
}


}

0 comments on commit f9d0861

Please sign in to comment.