ProjectService.java

1
package com.edtech.service;
2
3
import com.edtech.dto.ProjectMemberRequestDto;
4
import com.edtech.dto.ProjectRequestDto;
5
import com.edtech.dto.ProjectResponseDto;
6
import com.edtech.model.AuditAction;
7
import com.edtech.model.Project;
8
import com.edtech.model.ProjectMember;
9
import com.edtech.model.ProjectRole;
10
import com.edtech.model.User;
11
import com.edtech.repository.ProjectMemberRepository;
12
import com.edtech.repository.ProjectRepository;
13
import com.edtech.repository.UserRepository;
14
import java.util.UUID;
15
import org.springframework.cache.annotation.CacheEvict;
16
import org.springframework.cache.annotation.Cacheable;
17
import org.springframework.stereotype.Service;
18
import org.springframework.transaction.annotation.Transactional;
19
20
/** Documentação para ProjectService. */
21
@Service
22
public class ProjectService {
23
24
  private final ProjectRepository projectRepository;
25
  private final ProjectMemberRepository projectMemberRepository;
26
  private final UserRepository userRepository;
27
  private final AuditLogService auditLogService;
28
29
  /** Documentação. */
30
  public ProjectService(
31
      ProjectRepository projectRepository,
32
      ProjectMemberRepository projectMemberRepository,
33
      UserRepository userRepository,
34
      AuditLogService auditLogService) {
35
    this.projectRepository = projectRepository;
36
    this.projectMemberRepository = projectMemberRepository;
37
    this.userRepository = userRepository;
38
    this.auditLogService = auditLogService;
39
  }
40
41
  /** Documentação. */
42
  @Transactional
43
  @CacheEvict(value = "projects", key = "#advisorId")
44
  public ProjectResponseDto createProject(ProjectRequestDto request, UUID advisorId) {
45
    User advisor =
46
        userRepository
47
            .findById(advisorId)
48 1 1. lambda$createProject$0 : replaced return value with null for com/edtech/service/ProjectService::lambda$createProject$0 → KILLED
            .orElseThrow(() -> new RuntimeException("User not found"));
49
50
    Project project = new Project();
51 1 1. createProject : removed call to com/edtech/model/Project::setTitle → SURVIVED
    project.setTitle(request.getTitle());
52 1 1. createProject : removed call to com/edtech/model/Project::setDescription → SURVIVED
    project.setDescription(request.getDescription());
53 1 1. createProject : removed call to com/edtech/model/Project::setAdvisor → SURVIVED
    project.setAdvisor(advisor);
54
55
    project = projectRepository.save(project);
56
57
    ProjectMember member = new ProjectMember();
58 1 1. createProject : removed call to com/edtech/model/ProjectMember::setProject → SURVIVED
    member.setProject(project);
59 1 1. createProject : removed call to com/edtech/model/ProjectMember::setUser → KILLED
    member.setUser(advisor);
60 1 1. createProject : removed call to com/edtech/model/ProjectMember::setRole → KILLED
    member.setRole(ProjectRole.ADVISOR);
61
    projectMemberRepository.save(member);
62
63 1 1. createProject : replaced return value with null for com/edtech/service/ProjectService::createProject → KILLED
    return mapToDto(project);
64
  }
65
66
  /** Documentação para o método listProjectsByUser. */
67
  @Cacheable(
68
      value = "projects",
69
      key = "#userId + '-' + #pageable.pageNumber + '-' + #pageable.pageSize")
70
  public org.springframework.data.domain.Page<ProjectResponseDto> listProjectsByUser(
71
      UUID userId, org.springframework.data.domain.Pageable pageable) {
72
    User user = userRepository.findById(userId).orElse(null);
73 1 1. listProjectsByUser : negated conditional → KILLED
    if (user == null) {
74 1 1. listProjectsByUser : replaced return value with null for com/edtech/service/ProjectService::listProjectsByUser → KILLED
      return projectRepository
75
          .findProjectsByUserId(userId, pageable)
76 1 1. lambda$listProjectsByUser$1 : replaced return value with null for com/edtech/service/ProjectService::lambda$listProjectsByUser$1 → KILLED
          .map(project -> mapToDto(project, userId));
77
    }
78 1 1. listProjectsByUser : negated conditional → NO_COVERAGE
    if (user.getRole() == com.edtech.model.UserRole.ADVISOR) {
79 1 1. listProjectsByUser : replaced return value with null for com/edtech/service/ProjectService::listProjectsByUser → NO_COVERAGE
      return projectRepository
80
          .findProjectsByUserId(userId, pageable)
81 1 1. lambda$listProjectsByUser$2 : replaced return value with null for com/edtech/service/ProjectService::lambda$listProjectsByUser$2 → NO_COVERAGE
          .map(project -> mapToDto(project, userId));
82
    }
83 1 1. listProjectsByUser : replaced return value with null for com/edtech/service/ProjectService::listProjectsByUser → NO_COVERAGE
    return projectRepository
84
        .findProjectsByInstitutionId(user.getInstitutionId(), pageable)
85 1 1. lambda$listProjectsByUser$3 : replaced return value with null for com/edtech/service/ProjectService::lambda$listProjectsByUser$3 → NO_COVERAGE
        .map(project -> mapToDto(project, userId));
86
  }
87
88
  /** Documentação. */
89
  @Transactional
90
  @CacheEvict(value = "projects", allEntries = true)
91
  public void addMember(UUID projectId, ProjectMemberRequestDto dto, User authenticatedUser) {
92
    Project project =
93
        projectRepository
94
            .findById(projectId)
95 1 1. lambda$addMember$4 : replaced return value with null for com/edtech/service/ProjectService::lambda$addMember$4 → KILLED
            .orElseThrow(() -> new RuntimeException("Project not found"));
96
97
    UUID targetUserId =
98 2 1. addMember : negated conditional → KILLED
2. addMember : negated conditional → KILLED
        (dto != null && dto.getUserId() != null) ? dto.getUserId() : authenticatedUser.getId();
99
100
    // Se o usuário que está tentando associar alguém for diferente do alvo, ele deve ser ADVISOR do
101
    // projeto.
102 1 1. addMember : negated conditional → KILLED
    if (!targetUserId.equals(authenticatedUser.getId())) {
103
      ProjectMember advisorMember =
104
          projectMemberRepository
105
              .findByProjectIdAndUserId(projectId, authenticatedUser.getId())
106
              .orElseThrow(
107 1 1. lambda$addMember$5 : replaced return value with null for com/edtech/service/ProjectService::lambda$addMember$5 → KILLED
                  () -> new RuntimeException("User is not part of the project to add members"));
108
109 1 1. addMember : negated conditional → KILLED
      if (advisorMember.getRole() != ProjectRole.ADVISOR) {
110
        throw new RuntimeException("Only ADVISORS can add other members");
111
      }
112
    }
113
114 1 1. addMember : negated conditional → KILLED
    if (projectMemberRepository.findByProjectIdAndUserId(projectId, targetUserId).isPresent()) {
115
      throw new com.edtech.exception.UserAlreadyMemberException(
116
          "User is already a member of this project");
117
    }
118
119
    User newUser =
120
        userRepository
121
            .findById(targetUserId)
122 1 1. lambda$addMember$6 : replaced return value with null for com/edtech/service/ProjectService::lambda$addMember$6 → KILLED
            .orElseThrow(() -> new RuntimeException("User not found"));
123
124
    String roleStr =
125 2 1. addMember : negated conditional → KILLED
2. addMember : negated conditional → KILLED
        (dto != null && dto.getRole() != null) ? dto.getRole().toUpperCase() : "RESEARCHER";
126
127
    ProjectMember newMember = new ProjectMember();
128 1 1. addMember : removed call to com/edtech/model/ProjectMember::setProject → SURVIVED
    newMember.setProject(project);
129 1 1. addMember : removed call to com/edtech/model/ProjectMember::setUser → KILLED
    newMember.setUser(newUser);
130 1 1. addMember : removed call to com/edtech/model/ProjectMember::setRole → KILLED
    newMember.setRole(ProjectRole.valueOf(roleStr));
131
    projectMemberRepository.save(newMember);
132
133
    auditLogService.logAction(
134
        authenticatedUser.getId(),
135
        AuditAction.MEMBER_JOINED,
136
        "User " + newUser.getEmail() + " joined project " + project.getTitle());
137
  }
138
139
  private ProjectResponseDto mapToDto(Project project) {
140 1 1. mapToDto : replaced return value with null for com/edtech/service/ProjectService::mapToDto → KILLED
    return mapToDto(project, null);
141
  }
142
143
  private ProjectResponseDto mapToDto(Project project, UUID currentUserId) {
144
    ProjectResponseDto dto = new ProjectResponseDto();
145 1 1. mapToDto : removed call to com/edtech/dto/ProjectResponseDto::setId → KILLED
    dto.setId(project.getId());
146 1 1. mapToDto : removed call to com/edtech/dto/ProjectResponseDto::setTitle → KILLED
    dto.setTitle(project.getTitle());
147 1 1. mapToDto : removed call to com/edtech/dto/ProjectResponseDto::setDescription → KILLED
    dto.setDescription(project.getDescription());
148 1 1. mapToDto : removed call to com/edtech/dto/ProjectResponseDto::setAdvisorId → KILLED
    dto.setAdvisorId(project.getAdvisor().getId());
149 1 1. mapToDto : removed call to com/edtech/dto/ProjectResponseDto::setCreatedAt → SURVIVED
    dto.setCreatedAt(project.getCreatedAt());
150 2 1. mapToDto : removed call to com/edtech/dto/ProjectResponseDto::setMember → SURVIVED
2. mapToDto : negated conditional → SURVIVED
    dto.setMember(
151
        currentUserId != null
152
            && projectMemberRepository
153
                .findByProjectIdAndUserId(project.getId(), currentUserId)
154 1 1. mapToDto : negated conditional → SURVIVED
                .isPresent());
155 1 1. mapToDto : replaced return value with null for com/edtech/service/ProjectService::mapToDto → KILLED
    return dto;
156
  }
157
}

Mutations

48

1.1
Location : lambda$createProject$0
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:createProject_UserNotFound_ThrowsException()]
replaced return value with null for com/edtech/service/ProjectService::lambda$createProject$0 → KILLED

51

1.1
Location : createProject
Killed by : none
removed call to com/edtech/model/Project::setTitle → SURVIVED
Covering tests

52

1.1
Location : createProject
Killed by : none
removed call to com/edtech/model/Project::setDescription → SURVIVED
Covering tests

53

1.1
Location : createProject
Killed by : none
removed call to com/edtech/model/Project::setAdvisor → SURVIVED
Covering tests

58

1.1
Location : createProject
Killed by : none
removed call to com/edtech/model/ProjectMember::setProject → SURVIVED
Covering tests

59

1.1
Location : createProject
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:createProject_WithValidData_ReturnsProjectDto()]
removed call to com/edtech/model/ProjectMember::setUser → KILLED

60

1.1
Location : createProject
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:createProject_WithValidData_ReturnsProjectDto()]
removed call to com/edtech/model/ProjectMember::setRole → KILLED

63

1.1
Location : createProject
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:createProject_WithValidData_ReturnsProjectDto()]
replaced return value with null for com/edtech/service/ProjectService::createProject → KILLED

73

1.1
Location : listProjectsByUser
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:listProjectsByUser_ReturnsList()]
negated conditional → KILLED

74

1.1
Location : listProjectsByUser
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:listProjectsByUser_ReturnsList()]
replaced return value with null for com/edtech/service/ProjectService::listProjectsByUser → KILLED

76

1.1
Location : lambda$listProjectsByUser$1
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:listProjectsByUser_ReturnsList()]
replaced return value with null for com/edtech/service/ProjectService::lambda$listProjectsByUser$1 → KILLED

78

1.1
Location : listProjectsByUser
Killed by : none
negated conditional → NO_COVERAGE

79

1.1
Location : listProjectsByUser
Killed by : none
replaced return value with null for com/edtech/service/ProjectService::listProjectsByUser → NO_COVERAGE

81

1.1
Location : lambda$listProjectsByUser$2
Killed by : none
replaced return value with null for com/edtech/service/ProjectService::lambda$listProjectsByUser$2 → NO_COVERAGE

83

1.1
Location : listProjectsByUser
Killed by : none
replaced return value with null for com/edtech/service/ProjectService::listProjectsByUser → NO_COVERAGE

85

1.1
Location : lambda$listProjectsByUser$3
Killed by : none
replaced return value with null for com/edtech/service/ProjectService::lambda$listProjectsByUser$3 → NO_COVERAGE

95

1.1
Location : lambda$addMember$4
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:addMember_ProjectNotFound_ThrowsException()]
replaced return value with null for com/edtech/service/ProjectService::lambda$addMember$4 → KILLED

98

1.1
Location : addMember
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:addMember_TargetUserDifferent_AuthUserNotMember_ThrowsException()]
negated conditional → KILLED

2.2
Location : addMember
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:addMember_TargetUserDifferent_AuthUserNotMember_ThrowsException()]
negated conditional → KILLED

102

1.1
Location : addMember
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:addMember_UserNotFound_ThrowsException()]
negated conditional → KILLED

107

1.1
Location : lambda$addMember$5
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:addMember_TargetUserDifferent_AuthUserNotMember_ThrowsException()]
replaced return value with null for com/edtech/service/ProjectService::lambda$addMember$5 → KILLED

109

1.1
Location : addMember
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:addMember_TargetUserDifferent_AuthUserNotAdvisor_ThrowsException()]
negated conditional → KILLED

114

1.1
Location : addMember
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:addMember_UserNotFound_ThrowsException()]
negated conditional → KILLED

122

1.1
Location : lambda$addMember$6
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:addMember_UserNotFound_ThrowsException()]
replaced return value with null for com/edtech/service/ProjectService::lambda$addMember$6 → KILLED

125

1.1
Location : addMember
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:addMember_WithNullUserIdInDto_DefaultsToAuthUserId()]
negated conditional → KILLED

2.2
Location : addMember
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:addMember_WithNullUserIdInDto_DefaultsToAuthUserId()]
negated conditional → KILLED

128

1.1
Location : addMember
Killed by : none
removed call to com/edtech/model/ProjectMember::setProject → SURVIVED
Covering tests

129

1.1
Location : addMember
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:addMember_WithNullUserIdInDto_DefaultsToAuthUserId()]
removed call to com/edtech/model/ProjectMember::setUser → KILLED

130

1.1
Location : addMember
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:addMember_WithNullUserIdInDto_DefaultsToAuthUserId()]
removed call to com/edtech/model/ProjectMember::setRole → KILLED

140

1.1
Location : mapToDto
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:createProject_WithValidData_ReturnsProjectDto()]
replaced return value with null for com/edtech/service/ProjectService::mapToDto → KILLED

145

1.1
Location : mapToDto
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:listProjectsByUser_ReturnsList()]
removed call to com/edtech/dto/ProjectResponseDto::setId → KILLED

146

1.1
Location : mapToDto
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:listProjectsByUser_ReturnsList()]
removed call to com/edtech/dto/ProjectResponseDto::setTitle → KILLED

147

1.1
Location : mapToDto
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:createProject_WithValidData_ReturnsProjectDto()]
removed call to com/edtech/dto/ProjectResponseDto::setDescription → KILLED

148

1.1
Location : mapToDto
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:createProject_WithValidData_ReturnsProjectDto()]
removed call to com/edtech/dto/ProjectResponseDto::setAdvisorId → KILLED

149

1.1
Location : mapToDto
Killed by : none
removed call to com/edtech/dto/ProjectResponseDto::setCreatedAt → SURVIVED
Covering tests

150

1.1
Location : mapToDto
Killed by : none
removed call to com/edtech/dto/ProjectResponseDto::setMember → SURVIVED
Covering tests

2.2
Location : mapToDto
Killed by : none
negated conditional → SURVIVED Covering tests

154

1.1
Location : mapToDto
Killed by : none
negated conditional → SURVIVED
Covering tests

155

1.1
Location : mapToDto
Killed by : com.edtech.service.ProjectServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.ProjectServiceTest]/[method:listProjectsByUser_ReturnsList()]
replaced return value with null for com/edtech/service/ProjectService::mapToDto → KILLED

Active mutators

Tests examined


Report generated by PIT 1.25.9 support