DocumentService.java

1
package com.edtech.service;
2
3
import com.edtech.dto.DocumentResponseDto;
4
import com.edtech.model.AuditAction;
5
import com.edtech.model.Document;
6
import com.edtech.model.DocumentStatus;
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.DocumentCommentRepository;
12
import com.edtech.repository.DocumentRepository;
13
import com.edtech.repository.ProjectMemberRepository;
14
import com.edtech.repository.ProjectRepository;
15
import com.edtech.repository.UserRepository;
16
import com.fasterxml.jackson.databind.ObjectMapper;
17
import java.io.IOException;
18
import java.util.Locale;
19
import java.util.Map;
20
import java.util.Set;
21
import java.util.UUID;
22
import org.apache.tika.Tika;
23
import org.springframework.data.domain.Page;
24
import org.springframework.data.domain.Pageable;
25
import org.springframework.stereotype.Service;
26
import org.springframework.transaction.annotation.Transactional;
27
import org.springframework.web.multipart.MultipartFile;
28
29
/** Documentacao para DocumentService. */
30
@Service
31
public class DocumentService {
32
33
  private static final String MIME_PDF = "application/pdf";
34
  private static final String MIME_CSV = "text/csv";
35
  private static final String MIME_JSON = "application/json";
36
  private static final Map<String, String> ALLOWED_MIME_BY_EXTENSION =
37
      Map.of(".pdf", MIME_PDF, ".csv", MIME_CSV, ".json", MIME_JSON);
38
  private static final Set<String> CSV_COMPATIBLE_DETECTED_TYPES =
39
      Set.of(MIME_CSV, "text/plain", "application/csv", "application/vnd.ms-excel");
40
  private static final Set<String> JSON_COMPATIBLE_DETECTED_TYPES = Set.of(MIME_JSON, "text/plain");
41
42
  private final DocumentRepository documentRepository;
43
  private final ProjectRepository projectRepository;
44
  private final UserRepository userRepository;
45
  private final ProjectMemberRepository projectMemberRepository;
46
  private final DocumentCommentRepository documentCommentRepository;
47
  private final AuditLogService auditLogService;
48
  private final StorageService storageService;
49
  private final NotificationService notificationService;
50
  private final Tika tika = new Tika();
51
  private final ObjectMapper objectMapper = new ObjectMapper();
52
  private final ClamAvService clamAvService;
53
54
  /** Documentacao. */
55
  public DocumentService(
56
      DocumentRepository documentRepository,
57
      ProjectRepository projectRepository,
58
      UserRepository userRepository,
59
      ProjectMemberRepository projectMemberRepository,
60
      DocumentCommentRepository documentCommentRepository,
61
      AuditLogService auditLogService,
62
      StorageService storageService,
63
      NotificationService notificationService,
64
      ClamAvService clamAvService) {
65
    this.documentRepository = documentRepository;
66
    this.projectRepository = projectRepository;
67
    this.userRepository = userRepository;
68
    this.projectMemberRepository = projectMemberRepository;
69
    this.documentCommentRepository = documentCommentRepository;
70
    this.auditLogService = auditLogService;
71
    this.storageService = storageService;
72
    this.notificationService = notificationService;
73
    this.clamAvService = clamAvService;
74
  }
75
76
  /** Documentacao. */
77
  @Transactional
78
  public DocumentResponseDto uploadDocument(
79
      MultipartFile file, String title, UUID projectId, UUID authorId) {
80
    User author =
81
        userRepository
82
            .findById(authorId)
83 1 1. lambda$uploadDocument$0 : replaced return value with null for com/edtech/service/DocumentService::lambda$uploadDocument$0 → KILLED
            .orElseThrow(() -> new RuntimeException("Author not found"));
84
    Project project =
85
        projectRepository
86
            .findById(projectId)
87 1 1. lambda$uploadDocument$1 : replaced return value with null for com/edtech/service/DocumentService::lambda$uploadDocument$1 → KILLED
            .orElseThrow(() -> new RuntimeException("Project not found"));
88
89
    projectMemberRepository
90
        .findByProjectIdAndUserId(projectId, authorId)
91 1 1. lambda$uploadDocument$2 : replaced return value with null for com/edtech/service/DocumentService::lambda$uploadDocument$2 → KILLED
        .orElseThrow(() -> new RuntimeException("Author is not a member of the project"));
92
93
    try {
94
      String originalFilename = file.getOriginalFilename();
95 1 1. uploadDocument : negated conditional → KILLED
      if (originalFilename == null) {
96
        throw new IllegalArgumentException("Filename cannot be null");
97
      }
98
99
      String contentType = validateAllowedFile(file, originalFilename);
100
101 1 1. uploadDocument : negated conditional → KILLED
      if (!clamAvService.isFileSafe(file)) {
102
        throw new IllegalArgumentException(
103
            "Upload rejeitado: Assinatura de vírus detectada no arquivo.");
104
      }
105
106
      String fileKey = UUID.randomUUID() + "_" + originalFilename;
107
108 1 1. uploadDocument : removed call to com/edtech/service/StorageService::uploadFile → KILLED
      storageService.uploadFile(file, fileKey, contentType);
109
110
      Document document = new Document();
111 1 1. uploadDocument : removed call to com/edtech/model/Document::setTitle → KILLED
      document.setTitle(title);
112 1 1. uploadDocument : removed call to com/edtech/model/Document::setFileUrl → KILLED
      document.setFileUrl(fileKey);
113 1 1. uploadDocument : removed call to com/edtech/model/Document::setStatus → KILLED
      document.setStatus(DocumentStatus.PENDING_REVIEW);
114 1 1. uploadDocument : removed call to com/edtech/model/Document::setAuthor → KILLED
      document.setAuthor(author);
115 1 1. uploadDocument : removed call to com/edtech/model/Document::setProject → KILLED
      document.setProject(project);
116
117
      document = documentRepository.save(document);
118
119
      auditLogService.logDocumentAction(
120
          authorId,
121
          AuditAction.UPLOAD_SUCCESS,
122
          document.getId(),
123
          "Documento anexado no Cloud Storage: " + title);
124
125
      DocumentResponseDto responseDto = mapToDto(document);
126 1 1. uploadDocument : removed call to com/edtech/service/NotificationService::sendToTopic → SURVIVED
      notificationService.sendToTopic(
127
          "/topic/projects/" + projectId,
128
          Map.of("type", "DOCUMENT_UPLOADED", "document", responseDto));
129
130 1 1. uploadDocument : replaced return value with null for com/edtech/service/DocumentService::uploadDocument → KILLED
      return responseDto;
131
    } catch (IOException e) {
132
      throw new RuntimeException("Falha ao analisar o conteudo do arquivo", e);
133
    } catch (IllegalArgumentException e) {
134
      throw e;
135
    } catch (Exception e) {
136
      throw new RuntimeException("Failed to upload file to Cloud Storage: " + e.getMessage());
137
    }
138
  }
139
140
  /** Documentacao para o metodo getPresignedUrl. */
141
  public String getPresignedUrl(UUID documentId, UUID userId) {
142
    Document document =
143
        documentRepository
144
            .findById(documentId)
145 1 1. lambda$getPresignedUrl$3 : replaced return value with null for com/edtech/service/DocumentService::lambda$getPresignedUrl$3 → NO_COVERAGE
            .orElseThrow(() -> new RuntimeException("Document not found"));
146
147
    projectMemberRepository
148
        .findByProjectIdAndUserId(document.getProject().getId(), userId)
149
        .orElseThrow(
150 1 1. lambda$getPresignedUrl$4 : replaced return value with null for com/edtech/service/DocumentService::lambda$getPresignedUrl$4 → KILLED
            () -> new RuntimeException("Access denied: You are not a member of this project"));
151
152
    String presignedUrl;
153
    try {
154
      presignedUrl = storageService.getPresignedUrl(document.getFileUrl());
155
    } catch (Exception e) {
156
      throw new RuntimeException("Failed to generate presigned URL", e);
157
    }
158
159
    auditLogService.logDocumentAction(
160
        userId,
161
        AuditAction.DOWNLOAD,
162
        documentId,
163
        "Gerada URL presigned para download: " + document.getTitle());
164 1 1. getPresignedUrl : replaced return value with "" for com/edtech/service/DocumentService::getPresignedUrl → KILLED
    return presignedUrl;
165
  }
166
167
  /** Documentacao. */
168
  public Page<DocumentResponseDto> listDocumentsByUser(
169
      UUID userId, UUID projectId, String title, DocumentStatus status, Pageable pageable) {
170 1 1. listDocumentsByUser : replaced return value with null for com/edtech/service/DocumentService::listDocumentsByUser → KILLED
    return documentRepository
171
        .findDocumentsByUserIdAndFilters(userId, projectId, title, status, pageable)
172
        .map(this::mapToDto);
173
  }
174
175
  /** Documentacao. */
176
  @Transactional
177
  public void deleteDocument(UUID documentId, UUID userId) {
178
    Document document =
179
        documentRepository
180
            .findById(documentId)
181 1 1. lambda$deleteDocument$5 : replaced return value with null for com/edtech/service/DocumentService::lambda$deleteDocument$5 → KILLED
            .orElseThrow(() -> new RuntimeException("Document not found"));
182
183 1 1. deleteDocument : negated conditional → KILLED
    if (!document.getAuthor().getId().equals(userId)) {
184
      throw new RuntimeException("Only the author can delete this document");
185
    }
186 1 1. deleteDocument : negated conditional → KILLED
    if (document.getStatus() == DocumentStatus.APPROVED) {
187
      throw new RuntimeException("APPROVED documents cannot be deleted");
188
    }
189
190
    try {
191 1 1. deleteDocument : removed call to com/edtech/service/StorageService::deleteFile → KILLED
      storageService.deleteFile(document.getFileUrl());
192
    } catch (Exception e) {
193
      throw new RuntimeException("Erro ao excluir arquivo fisico: " + e.getMessage());
194
    }
195
196 1 1. deleteDocument : removed call to com/edtech/repository/DocumentRepository::delete → KILLED
    documentRepository.delete(document);
197
    auditLogService.logDocumentAction(
198
        userId,
199
        AuditAction.DELETE_DOCUMENT,
200
        documentId,
201
        "Documento excluido: " + document.getTitle());
202
  }
203
204
  private String validateAllowedFile(MultipartFile file, String originalFilename)
205
      throws IOException {
206
    String extension = extractExtension(originalFilename);
207
    String expectedMimeType = ALLOWED_MIME_BY_EXTENSION.get(extension);
208 1 1. validateAllowedFile : negated conditional → KILLED
    if (expectedMimeType == null) {
209
      throw new IllegalArgumentException(
210
          "Tipo de arquivo nao permitido. Formatos aceitos: PDF, CSV e JSON.");
211
    }
212
213
    String declaredType = normalizeMimeType(file.getContentType());
214 1 1. validateAllowedFile : negated conditional → KILLED
    if (!expectedMimeType.equals(declaredType)) {
215
      throw new IllegalArgumentException(
216
          "Content-Type nao permitido para "
217
              + extension
218
              + ". Esperado: "
219
              + expectedMimeType
220
              + ". Recebido: "
221
              + declaredType);
222
    }
223
224
    String detectedType = normalizeMimeType(tika.detect(file.getInputStream(), originalFilename));
225 1 1. validateAllowedFile : negated conditional → KILLED
    if (!isDetectedTypeCompatible(expectedMimeType, detectedType)) {
226
      throw new IllegalArgumentException(
227
          "Conteudo do arquivo nao corresponde ao tipo permitido. Tipo detectado: " + detectedType);
228
    }
229
230 1 1. validateAllowedFile : negated conditional → KILLED
    if (MIME_JSON.equals(expectedMimeType)) {
231 1 1. validateAllowedFile : removed call to com/edtech/service/DocumentService::validateJsonContent → SURVIVED
      validateJsonContent(file);
232
    }
233
234 1 1. validateAllowedFile : replaced return value with "" for com/edtech/service/DocumentService::validateAllowedFile → KILLED
    return expectedMimeType;
235
  }
236
237
  private String extractExtension(String filename) {
238
    int lastDotIndex = filename.lastIndexOf('.');
239 4 1. extractExtension : changed conditional boundary → SURVIVED
2. extractExtension : Replaced integer subtraction with addition → SURVIVED
3. extractExtension : negated conditional → KILLED
4. extractExtension : negated conditional → KILLED
    if (lastDotIndex < 0 || lastDotIndex == filename.length() - 1) {
240
      return "";
241
    }
242 1 1. extractExtension : replaced return value with "" for com/edtech/service/DocumentService::extractExtension → KILLED
    return filename.substring(lastDotIndex).toLowerCase(Locale.ROOT);
243
  }
244
245
  private boolean isDetectedTypeCompatible(String expectedMimeType, String detectedType) {
246 1 1. isDetectedTypeCompatible : negated conditional → KILLED
    if (MIME_CSV.equals(expectedMimeType)) {
247 2 1. isDetectedTypeCompatible : replaced boolean return with true for com/edtech/service/DocumentService::isDetectedTypeCompatible → SURVIVED
2. isDetectedTypeCompatible : replaced boolean return with false for com/edtech/service/DocumentService::isDetectedTypeCompatible → KILLED
      return CSV_COMPATIBLE_DETECTED_TYPES.contains(detectedType);
248
    }
249 1 1. isDetectedTypeCompatible : negated conditional → KILLED
    if (MIME_JSON.equals(expectedMimeType)) {
250 2 1. isDetectedTypeCompatible : replaced boolean return with true for com/edtech/service/DocumentService::isDetectedTypeCompatible → SURVIVED
2. isDetectedTypeCompatible : replaced boolean return with false for com/edtech/service/DocumentService::isDetectedTypeCompatible → KILLED
      return JSON_COMPATIBLE_DETECTED_TYPES.contains(detectedType);
251
    }
252 2 1. isDetectedTypeCompatible : replaced boolean return with true for com/edtech/service/DocumentService::isDetectedTypeCompatible → SURVIVED
2. isDetectedTypeCompatible : replaced boolean return with false for com/edtech/service/DocumentService::isDetectedTypeCompatible → KILLED
    return expectedMimeType.equals(detectedType);
253
  }
254
255
  private String normalizeMimeType(String mimeType) {
256 2 1. normalizeMimeType : negated conditional → KILLED
2. normalizeMimeType : negated conditional → KILLED
    if (mimeType == null || mimeType.isBlank()) {
257
      return "";
258
    }
259 1 1. normalizeMimeType : replaced return value with "" for com/edtech/service/DocumentService::normalizeMimeType → KILLED
    return mimeType.split(";")[0].trim().toLowerCase(Locale.ROOT);
260
  }
261
262
  private void validateJsonContent(MultipartFile file) throws IOException {
263
    objectMapper.readTree(file.getInputStream());
264
  }
265
266
  private DocumentResponseDto mapToDto(Document document) {
267
    DocumentResponseDto dto = new DocumentResponseDto();
268 1 1. mapToDto : removed call to com/edtech/dto/DocumentResponseDto::setId → KILLED
    dto.setId(document.getId());
269 1 1. mapToDto : removed call to com/edtech/dto/DocumentResponseDto::setTitle → KILLED
    dto.setTitle(document.getTitle());
270 1 1. mapToDto : removed call to com/edtech/dto/DocumentResponseDto::setFileUrl → KILLED
    dto.setFileUrl(document.getFileUrl());
271 1 1. mapToDto : removed call to com/edtech/dto/DocumentResponseDto::setStatus → KILLED
    dto.setStatus(document.getStatus());
272 1 1. mapToDto : removed call to com/edtech/dto/DocumentResponseDto::setAuthorId → KILLED
    dto.setAuthorId(document.getAuthor().getId());
273 1 1. mapToDto : removed call to com/edtech/dto/DocumentResponseDto::setAuthorName → SURVIVED
    dto.setAuthorName(document.getAuthor().getName());
274 1 1. mapToDto : removed call to com/edtech/dto/DocumentResponseDto::setAuthorEmail → SURVIVED
    dto.setAuthorEmail(document.getAuthor().getEmail());
275 1 1. mapToDto : removed call to com/edtech/dto/DocumentResponseDto::setProjectId → KILLED
    dto.setProjectId(document.getProject().getId());
276 1 1. mapToDto : removed call to com/edtech/dto/DocumentResponseDto::setProjectTitle → SURVIVED
    dto.setProjectTitle(document.getProject().getTitle());
277 1 1. mapToDto : removed call to com/edtech/dto/DocumentResponseDto::setFileType → SURVIVED
    dto.setFileType(
278
        extractExtension(document.getTitle()).replace(".", "").toUpperCase(Locale.ROOT));
279 1 1. mapToDto : removed call to com/edtech/dto/DocumentResponseDto::setCreatedAt → SURVIVED
    dto.setCreatedAt(document.getCreatedAt());
280 1 1. mapToDto : removed call to com/edtech/dto/DocumentResponseDto::setFeedback → KILLED
    dto.setFeedback(document.getFeedback());
281 1 1. mapToDto : removed call to com/edtech/dto/DocumentResponseDto::setStarred → KILLED
    dto.setStarred(document.isStarred());
282 1 1. mapToDto : replaced return value with null for com/edtech/service/DocumentService::mapToDto → KILLED
    return dto;
283
  }
284
285
  /** Javadoc. */
286
  @Transactional(readOnly = true)
287
  public java.util.List<com.edtech.dto.CommentResponseDto> getComments(
288
      UUID documentId, UUID userId) {
289
    Document document =
290
        documentRepository
291
            .findById(documentId)
292 1 1. lambda$getComments$6 : replaced return value with null for com/edtech/service/DocumentService::lambda$getComments$6 → NO_COVERAGE
            .orElseThrow(() -> new RuntimeException("Document not found"));
293
    projectMemberRepository
294
        .findByProjectIdAndUserId(document.getProject().getId(), userId)
295 1 1. lambda$getComments$7 : replaced return value with null for com/edtech/service/DocumentService::lambda$getComments$7 → NO_COVERAGE
        .orElseThrow(() -> new RuntimeException("Access denied"));
296
297 1 1. getComments : replaced return value with Collections.emptyList for com/edtech/service/DocumentService::getComments → KILLED
    return documentCommentRepository.findByDocumentIdOrderByCreatedAtAsc(documentId).stream()
298
        .map(
299
            c -> {
300
              com.edtech.dto.CommentResponseDto dto = new com.edtech.dto.CommentResponseDto();
301 1 1. lambda$getComments$8 : removed call to com/edtech/dto/CommentResponseDto::setId → KILLED
              dto.setId(c.getId());
302 1 1. lambda$getComments$8 : removed call to com/edtech/dto/CommentResponseDto::setContent → KILLED
              dto.setContent(c.getContent());
303 1 1. lambda$getComments$8 : removed call to com/edtech/dto/CommentResponseDto::setCreatedAt → SURVIVED
              dto.setCreatedAt(c.getCreatedAt());
304 1 1. lambda$getComments$8 : removed call to com/edtech/dto/CommentResponseDto::setAuthorId → KILLED
              dto.setAuthorId(c.getAuthor().getId());
305 1 1. lambda$getComments$8 : removed call to com/edtech/dto/CommentResponseDto::setAuthorName → KILLED
              dto.setAuthorName(c.getAuthor().getName());
306 1 1. lambda$getComments$8 : replaced return value with null for com/edtech/service/DocumentService::lambda$getComments$8 → KILLED
              return dto;
307
            })
308
        .collect(java.util.stream.Collectors.toList());
309
  }
310
311
  /** Javadoc. */
312
  @Transactional
313
  public com.edtech.dto.CommentResponseDto addComment(
314
      UUID documentId, UUID userId, String content) {
315
    Document document =
316
        documentRepository
317
            .findById(documentId)
318 1 1. lambda$addComment$9 : replaced return value with null for com/edtech/service/DocumentService::lambda$addComment$9 → NO_COVERAGE
            .orElseThrow(() -> new RuntimeException("Document not found"));
319
    User user =
320 1 1. lambda$addComment$10 : replaced return value with null for com/edtech/service/DocumentService::lambda$addComment$10 → NO_COVERAGE
        userRepository.findById(userId).orElseThrow(() -> new RuntimeException("User not found"));
321
    projectMemberRepository
322
        .findByProjectIdAndUserId(document.getProject().getId(), userId)
323 1 1. lambda$addComment$11 : replaced return value with null for com/edtech/service/DocumentService::lambda$addComment$11 → NO_COVERAGE
        .orElseThrow(() -> new RuntimeException("Access denied"));
324
325
    com.edtech.model.DocumentComment comment = new com.edtech.model.DocumentComment();
326 1 1. addComment : removed call to com/edtech/model/DocumentComment::setDocument → SURVIVED
    comment.setDocument(document);
327 1 1. addComment : removed call to com/edtech/model/DocumentComment::setAuthor → KILLED
    comment.setAuthor(user);
328 1 1. addComment : removed call to com/edtech/model/DocumentComment::setContent → KILLED
    comment.setContent(content);
329
330
    comment = documentCommentRepository.save(comment);
331
332
    auditLogService.logDocumentAction(
333
        userId, AuditAction.REVIEW_DOCUMENT, documentId, "Adicionou um comentário ao documento.");
334
335
    com.edtech.dto.CommentResponseDto dto = new com.edtech.dto.CommentResponseDto();
336 1 1. addComment : removed call to com/edtech/dto/CommentResponseDto::setId → KILLED
    dto.setId(comment.getId());
337 1 1. addComment : removed call to com/edtech/dto/CommentResponseDto::setContent → KILLED
    dto.setContent(comment.getContent());
338 1 1. addComment : removed call to com/edtech/dto/CommentResponseDto::setCreatedAt → KILLED
    dto.setCreatedAt(comment.getCreatedAt());
339 1 1. addComment : removed call to com/edtech/dto/CommentResponseDto::setAuthorId → KILLED
    dto.setAuthorId(comment.getAuthor().getId());
340 1 1. addComment : removed call to com/edtech/dto/CommentResponseDto::setAuthorName → KILLED
    dto.setAuthorName(comment.getAuthor().getName());
341
342 1 1. addComment : removed call to com/edtech/service/NotificationService::sendToTopic → KILLED
    notificationService.sendToTopic(
343
        "/topic/projects/" + document.getProject().getId(),
344
        Map.of("type", "NEW_COMMENT", "documentId", documentId, "comment", dto));
345
346 1 1. addComment : replaced return value with null for com/edtech/service/DocumentService::addComment → KILLED
    return dto;
347
  }
348
349
  /** Documentacao. */
350
  @Transactional
351
  public DocumentResponseDto reviewDocument(
352
      UUID documentId, UUID reviewerId, DocumentStatus newStatus, String feedback) {
353 2 1. reviewDocument : negated conditional → KILLED
2. reviewDocument : negated conditional → KILLED
    if (newStatus != DocumentStatus.APPROVED && newStatus != DocumentStatus.REJECTED) {
354
      throw new IllegalArgumentException(
355
          "Status invalido. Apenas APPROVED ou REJECTED sao permitidos na revisao.");
356
    }
357
    Document document =
358
        documentRepository
359
            .findById(documentId)
360 1 1. lambda$reviewDocument$12 : replaced return value with null for com/edtech/service/DocumentService::lambda$reviewDocument$12 → NO_COVERAGE
            .orElseThrow(() -> new RuntimeException("Document not found"));
361
    ProjectMember member =
362
        projectMemberRepository
363
            .findByProjectIdAndUserId(document.getProject().getId(), reviewerId)
364
            .orElseThrow(
365 1 1. lambda$reviewDocument$13 : replaced return value with null for com/edtech/service/DocumentService::lambda$reviewDocument$13 → KILLED
                () -> new RuntimeException("Acess denied: You are not a member of this project"));
366 1 1. reviewDocument : negated conditional → KILLED
    if (member.getRole() != ProjectRole.ADVISOR) {
367
      throw new RuntimeException("Acess denied: Only an ADVISOR can review documents");
368
    }
369 1 1. reviewDocument : negated conditional → KILLED
    if (document.getStatus() != DocumentStatus.PENDING_REVIEW) {
370
      throw new RuntimeException("Document is not pending review");
371
    }
372 1 1. reviewDocument : removed call to com/edtech/model/Document::setStatus → KILLED
    document.setStatus(newStatus);
373 1 1. reviewDocument : removed call to com/edtech/model/Document::setFeedback → KILLED
    document.setFeedback(feedback);
374
    Document savedDocument = documentRepository.save(document);
375
    AuditAction action =
376 1 1. reviewDocument : negated conditional → KILLED
        (newStatus == DocumentStatus.APPROVED)
377
            ? AuditAction.DOCUMENT_APPROVED
378
            : AuditAction.DOCUMENT_REJECTED;
379
    String details =
380
        "Status alterado para "
381
            + newStatus
382
            + ".Feedback: "
383 2 1. reviewDocument : negated conditional → SURVIVED
2. reviewDocument : negated conditional → KILLED
            + (feedback != null && !feedback.trim().isEmpty() ? feedback : "Sem feedback");
384
    auditLogService.logDocumentAction(reviewerId, action, documentId, details);
385
386
    DocumentResponseDto responseDto = mapToDto(savedDocument);
387 1 1. reviewDocument : removed call to com/edtech/service/NotificationService::sendToTopic → SURVIVED
    notificationService.sendToTopic(
388
        "/topic/projects/" + document.getProject().getId(),
389
        Map.of("type", "DOCUMENT_REVIEWED", "document", responseDto));
390
391 1 1. reviewDocument : replaced return value with null for com/edtech/service/DocumentService::reviewDocument → KILLED
    return responseDto;
392
  }
393
394
  /** Javadoc. */
395
  @Transactional
396
  public DocumentResponseDto toggleStar(UUID documentId, UUID userId) {
397
    Document document =
398
        documentRepository
399
            .findById(documentId)
400 1 1. lambda$toggleStar$14 : replaced return value with null for com/edtech/service/DocumentService::lambda$toggleStar$14 → NO_COVERAGE
            .orElseThrow(() -> new RuntimeException("Document not found"));
401
402
    projectMemberRepository
403
        .findByProjectIdAndUserId(document.getProject().getId(), userId)
404
        .orElseThrow(
405 1 1. lambda$toggleStar$15 : replaced return value with null for com/edtech/service/DocumentService::lambda$toggleStar$15 → NO_COVERAGE
            () -> new RuntimeException("Access denied: You are not a member of this project"));
406
407 2 1. toggleStar : negated conditional → KILLED
2. toggleStar : removed call to com/edtech/model/Document::setStarred → KILLED
    document.setStarred(!document.isStarred());
408
    Document savedDocument = documentRepository.save(document);
409
410 1 1. toggleStar : replaced return value with null for com/edtech/service/DocumentService::toggleStar → KILLED
    return mapToDto(savedDocument);
411
  }
412
}

Mutations

83

1.1
Location : lambda$uploadDocument$0
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_AuthorNotFound_ThrowsException()]
replaced return value with null for com/edtech/service/DocumentService::lambda$uploadDocument$0 → KILLED

87

1.1
Location : lambda$uploadDocument$1
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_ProjectNotFound_ThrowsException()]
replaced return value with null for com/edtech/service/DocumentService::lambda$uploadDocument$1 → KILLED

91

1.1
Location : lambda$uploadDocument$2
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_NotMember_ThrowsException()]
replaced return value with null for com/edtech/service/DocumentService::lambda$uploadDocument$2 → KILLED

95

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

101

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

108

1.1
Location : uploadDocument
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_CsvSuccess()]
removed call to com/edtech/service/StorageService::uploadFile → KILLED

111

1.1
Location : uploadDocument
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_CsvSuccess()]
removed call to com/edtech/model/Document::setTitle → KILLED

112

1.1
Location : uploadDocument
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_Success()]
removed call to com/edtech/model/Document::setFileUrl → KILLED

113

1.1
Location : uploadDocument
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_Success()]
removed call to com/edtech/model/Document::setStatus → KILLED

114

1.1
Location : uploadDocument
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_CsvSuccess()]
removed call to com/edtech/model/Document::setAuthor → KILLED

115

1.1
Location : uploadDocument
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_CsvSuccess()]
removed call to com/edtech/model/Document::setProject → KILLED

126

1.1
Location : uploadDocument
Killed by : none
removed call to com/edtech/service/NotificationService::sendToTopic → SURVIVED
Covering tests

130

1.1
Location : uploadDocument
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_CsvSuccess()]
replaced return value with null for com/edtech/service/DocumentService::uploadDocument → KILLED

145

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

150

1.1
Location : lambda$getPresignedUrl$4
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testGetPresignedUrl_NotMember_ThrowsException()]
replaced return value with null for com/edtech/service/DocumentService::lambda$getPresignedUrl$4 → KILLED

164

1.1
Location : getPresignedUrl
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testGetPresignedUrl_Success()]
replaced return value with "" for com/edtech/service/DocumentService::getPresignedUrl → KILLED

170

1.1
Location : listDocumentsByUser
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testListDocumentsByUser_Success()]
replaced return value with null for com/edtech/service/DocumentService::listDocumentsByUser → KILLED

181

1.1
Location : lambda$deleteDocument$5
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testDeleteDocument_NotFound_ThrowsException()]
replaced return value with null for com/edtech/service/DocumentService::lambda$deleteDocument$5 → KILLED

183

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

186

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

191

1.1
Location : deleteDocument
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testDeleteDocument_Success()]
removed call to com/edtech/service/StorageService::deleteFile → KILLED

196

1.1
Location : deleteDocument
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testDeleteDocument_Success()]
removed call to com/edtech/repository/DocumentRepository::delete → KILLED

208

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

214

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

225

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

230

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

231

1.1
Location : validateAllowedFile
Killed by : none
removed call to com/edtech/service/DocumentService::validateJsonContent → SURVIVED
Covering tests

234

1.1
Location : validateAllowedFile
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_CsvSuccess()]
replaced return value with "" for com/edtech/service/DocumentService::validateAllowedFile → KILLED

239

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

2.2
Location : extractExtension
Killed by : none
changed conditional boundary → SURVIVED
Covering tests

3.3
Location : extractExtension
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testListDocumentsByUser_Success()]
negated conditional → KILLED

4.4
Location : extractExtension
Killed by : none
Replaced integer subtraction with addition → SURVIVED Covering tests

242

1.1
Location : extractExtension
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_TikaIOException_ThrowsException()]
replaced return value with "" for com/edtech/service/DocumentService::extractExtension → KILLED

246

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

247

1.1
Location : isDetectedTypeCompatible
Killed by : none
replaced boolean return with true for com/edtech/service/DocumentService::isDetectedTypeCompatible → SURVIVED
Covering tests

2.2
Location : isDetectedTypeCompatible
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_CsvSuccess()]
replaced boolean return with false for com/edtech/service/DocumentService::isDetectedTypeCompatible → KILLED

249

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

250

1.1
Location : isDetectedTypeCompatible
Killed by : none
replaced boolean return with true for com/edtech/service/DocumentService::isDetectedTypeCompatible → SURVIVED
Covering tests

2.2
Location : isDetectedTypeCompatible
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_JsonSuccess()]
replaced boolean return with false for com/edtech/service/DocumentService::isDetectedTypeCompatible → KILLED

252

1.1
Location : isDetectedTypeCompatible
Killed by : none
replaced boolean return with true for com/edtech/service/DocumentService::isDetectedTypeCompatible → SURVIVED
Covering tests

2.2
Location : isDetectedTypeCompatible
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_RejectsMalware()]
replaced boolean return with false for com/edtech/service/DocumentService::isDetectedTypeCompatible → KILLED

256

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

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

259

1.1
Location : normalizeMimeType
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_TikaIOException_ThrowsException()]
replaced return value with "" for com/edtech/service/DocumentService::normalizeMimeType → KILLED

268

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

269

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

270

1.1
Location : mapToDto
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_Success()]
removed call to com/edtech/dto/DocumentResponseDto::setFileUrl → KILLED

271

1.1
Location : mapToDto
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testReviewDocument_Success_Rejected_EmptyFeedback()]
removed call to com/edtech/dto/DocumentResponseDto::setStatus → KILLED

272

1.1
Location : mapToDto
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_Success()]
removed call to com/edtech/dto/DocumentResponseDto::setAuthorId → KILLED

273

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

274

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

275

1.1
Location : mapToDto
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testUploadDocument_Success()]
removed call to com/edtech/dto/DocumentResponseDto::setProjectId → KILLED

276

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

277

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

279

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

280

1.1
Location : mapToDto
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testReviewDocument_Success_Rejected_EmptyFeedback()]
removed call to com/edtech/dto/DocumentResponseDto::setFeedback → KILLED

281

1.1
Location : mapToDto
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testToggleStar_Success()]
removed call to com/edtech/dto/DocumentResponseDto::setStarred → KILLED

282

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

292

1.1
Location : lambda$getComments$6
Killed by : none
replaced return value with null for com/edtech/service/DocumentService::lambda$getComments$6 → NO_COVERAGE

295

1.1
Location : lambda$getComments$7
Killed by : none
replaced return value with null for com/edtech/service/DocumentService::lambda$getComments$7 → NO_COVERAGE

297

1.1
Location : getComments
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testGetComments_Success()]
replaced return value with Collections.emptyList for com/edtech/service/DocumentService::getComments → KILLED

301

1.1
Location : lambda$getComments$8
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testGetComments_Success()]
removed call to com/edtech/dto/CommentResponseDto::setId → KILLED

302

1.1
Location : lambda$getComments$8
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testGetComments_Success()]
removed call to com/edtech/dto/CommentResponseDto::setContent → KILLED

303

1.1
Location : lambda$getComments$8
Killed by : none
removed call to com/edtech/dto/CommentResponseDto::setCreatedAt → SURVIVED
Covering tests

304

1.1
Location : lambda$getComments$8
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testGetComments_Success()]
removed call to com/edtech/dto/CommentResponseDto::setAuthorId → KILLED

305

1.1
Location : lambda$getComments$8
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testGetComments_Success()]
removed call to com/edtech/dto/CommentResponseDto::setAuthorName → KILLED

306

1.1
Location : lambda$getComments$8
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testGetComments_Success()]
replaced return value with null for com/edtech/service/DocumentService::lambda$getComments$8 → KILLED

318

1.1
Location : lambda$addComment$9
Killed by : none
replaced return value with null for com/edtech/service/DocumentService::lambda$addComment$9 → NO_COVERAGE

320

1.1
Location : lambda$addComment$10
Killed by : none
replaced return value with null for com/edtech/service/DocumentService::lambda$addComment$10 → NO_COVERAGE

323

1.1
Location : lambda$addComment$11
Killed by : none
replaced return value with null for com/edtech/service/DocumentService::lambda$addComment$11 → NO_COVERAGE

326

1.1
Location : addComment
Killed by : none
removed call to com/edtech/model/DocumentComment::setDocument → SURVIVED
Covering tests

327

1.1
Location : addComment
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testAddComment_Success()]
removed call to com/edtech/model/DocumentComment::setAuthor → KILLED

328

1.1
Location : addComment
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testAddComment_Success()]
removed call to com/edtech/model/DocumentComment::setContent → KILLED

336

1.1
Location : addComment
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testAddComment_Success()]
removed call to com/edtech/dto/CommentResponseDto::setId → KILLED

337

1.1
Location : addComment
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testAddComment_Success()]
removed call to com/edtech/dto/CommentResponseDto::setContent → KILLED

338

1.1
Location : addComment
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testAddComment_Success()]
removed call to com/edtech/dto/CommentResponseDto::setCreatedAt → KILLED

339

1.1
Location : addComment
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testAddComment_Success()]
removed call to com/edtech/dto/CommentResponseDto::setAuthorId → KILLED

340

1.1
Location : addComment
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testAddComment_Success()]
removed call to com/edtech/dto/CommentResponseDto::setAuthorName → KILLED

342

1.1
Location : addComment
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testAddComment_Success()]
removed call to com/edtech/service/NotificationService::sendToTopic → KILLED

346

1.1
Location : addComment
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testAddComment_Success()]
replaced return value with null for com/edtech/service/DocumentService::addComment → KILLED

353

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

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

360

1.1
Location : lambda$reviewDocument$12
Killed by : none
replaced return value with null for com/edtech/service/DocumentService::lambda$reviewDocument$12 → NO_COVERAGE

365

1.1
Location : lambda$reviewDocument$13
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testReviewDocument_NotMember_ThrowsException()]
replaced return value with null for com/edtech/service/DocumentService::lambda$reviewDocument$13 → KILLED

366

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

369

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

372

1.1
Location : reviewDocument
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testReviewDocument_Success_Rejected_EmptyFeedback()]
removed call to com/edtech/model/Document::setStatus → KILLED

373

1.1
Location : reviewDocument
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testReviewDocument_Success_Rejected_EmptyFeedback()]
removed call to com/edtech/model/Document::setFeedback → KILLED

376

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

383

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

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

387

1.1
Location : reviewDocument
Killed by : none
removed call to com/edtech/service/NotificationService::sendToTopic → SURVIVED
Covering tests

391

1.1
Location : reviewDocument
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testReviewDocument_Success_Rejected_EmptyFeedback()]
replaced return value with null for com/edtech/service/DocumentService::reviewDocument → KILLED

400

1.1
Location : lambda$toggleStar$14
Killed by : none
replaced return value with null for com/edtech/service/DocumentService::lambda$toggleStar$14 → NO_COVERAGE

405

1.1
Location : lambda$toggleStar$15
Killed by : none
replaced return value with null for com/edtech/service/DocumentService::lambda$toggleStar$15 → NO_COVERAGE

407

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

2.2
Location : toggleStar
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testToggleStar_Success()]
removed call to com/edtech/model/Document::setStarred → KILLED

410

1.1
Location : toggleStar
Killed by : com.edtech.service.DocumentServiceTest.[engine:junit-jupiter]/[class:com.edtech.service.DocumentServiceTest]/[method:testToggleStar_Success()]
replaced return value with null for com/edtech/service/DocumentService::toggleStar → KILLED

Active mutators

Tests examined


Report generated by PIT 1.25.9 support