diff --git a/src/main/java/org/example/visacasemanagementsystem/audit/CommentEventType.java b/src/main/java/org/example/visacasemanagementsystem/audit/CommentEventType.java new file mode 100644 index 0000000..e841a44 --- /dev/null +++ b/src/main/java/org/example/visacasemanagementsystem/audit/CommentEventType.java @@ -0,0 +1,7 @@ +package org.example.visacasemanagementsystem.audit; + +public enum CommentEventType { + ADDED, + UPDATED, + DELETED +} diff --git a/src/main/java/org/example/visacasemanagementsystem/audit/FileEventType.java b/src/main/java/org/example/visacasemanagementsystem/audit/FileEventType.java new file mode 100644 index 0000000..6679f49 --- /dev/null +++ b/src/main/java/org/example/visacasemanagementsystem/audit/FileEventType.java @@ -0,0 +1,8 @@ +package org.example.visacasemanagementsystem.audit; + +public enum FileEventType { + UPLOADED, + DELETED, + DOWNLOADED + +} diff --git a/src/main/java/org/example/visacasemanagementsystem/audit/dto/CommentLogDTO.java b/src/main/java/org/example/visacasemanagementsystem/audit/dto/CommentLogDTO.java new file mode 100644 index 0000000..1b65beb --- /dev/null +++ b/src/main/java/org/example/visacasemanagementsystem/audit/dto/CommentLogDTO.java @@ -0,0 +1,15 @@ +package org.example.visacasemanagementsystem.audit.dto; + +import org.example.visacasemanagementsystem.audit.CommentEventType; + +import java.time.LocalDateTime; + +public record CommentLogDTO( + Long id, + LocalDateTime timeStamp, + Long actorUserId, + Long visaCaseId, + Long commentId, + CommentEventType commentEventType, + String description) { +} diff --git a/src/main/java/org/example/visacasemanagementsystem/audit/dto/FileLogDTO.java b/src/main/java/org/example/visacasemanagementsystem/audit/dto/FileLogDTO.java new file mode 100644 index 0000000..b986eca --- /dev/null +++ b/src/main/java/org/example/visacasemanagementsystem/audit/dto/FileLogDTO.java @@ -0,0 +1,15 @@ +package org.example.visacasemanagementsystem.audit.dto; + +import org.example.visacasemanagementsystem.audit.FileEventType; + +import java.time.LocalDateTime; + +public record FileLogDTO( + Long id, + LocalDateTime timeStamp, + Long actorUserId, + Long visaCaseId, + String fileName, + FileEventType fileEventType, + String description){ +} diff --git a/src/main/java/org/example/visacasemanagementsystem/audit/entity/CommentLog.java b/src/main/java/org/example/visacasemanagementsystem/audit/entity/CommentLog.java new file mode 100644 index 0000000..ffaf495 --- /dev/null +++ b/src/main/java/org/example/visacasemanagementsystem/audit/entity/CommentLog.java @@ -0,0 +1,65 @@ +package org.example.visacasemanagementsystem.audit.entity; + + +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.example.visacasemanagementsystem.audit.CommentEventType; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.time.LocalDateTime; +import java.util.Objects; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@EntityListeners(AuditingEntityListener.class) +public class CommentLog { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "comment_log_id", nullable = false) + private Long id; + + @NotNull @CreatedDate + private LocalDateTime timeStamp; + + @NotNull private Long actorUserId; + + @NotNull private Long visaCaseId; + + @NotNull private Long commentId; + + @NotNull @Enumerated(EnumType.STRING) + private CommentEventType commentEventType; + + private String description; + + @Override + public boolean equals(Object o) { + if (!(o instanceof CommentLog that)) return false; + return Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hashCode(id); + } + + @Override + public String toString() { + return "CommentLog{" + + "id=" + id + + ", timeStamp=" + timeStamp + + ", actorUserId=" + actorUserId + + ", visaCaseId=" + visaCaseId + + ", commentId=" + commentId + + ", commentEventType=" + commentEventType + + ", description='" + description + '\'' + + '}'; + } +} diff --git a/src/main/java/org/example/visacasemanagementsystem/audit/entity/FileLog.java b/src/main/java/org/example/visacasemanagementsystem/audit/entity/FileLog.java new file mode 100644 index 0000000..7866adf --- /dev/null +++ b/src/main/java/org/example/visacasemanagementsystem/audit/entity/FileLog.java @@ -0,0 +1,64 @@ +package org.example.visacasemanagementsystem.audit.entity; + +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.example.visacasemanagementsystem.audit.FileEventType; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.time.LocalDateTime; +import java.util.Objects; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@EntityListeners(AuditingEntityListener.class) +public class FileLog { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "file_log_id", nullable = false) + private Long id; + + @NotNull @CreatedDate + private LocalDateTime timeStamp; + + @NotNull private Long actorUserId; + + @NotNull private Long visaCaseId; + + @NotNull private String fileName; + + @NotNull @Enumerated(EnumType.STRING) + private FileEventType fileEventType; + + private String description; + + @Override + public boolean equals(Object o) { + if (!(o instanceof FileLog fileLog)) return false; + return Objects.equals(id, fileLog.id); + } + + @Override + public int hashCode() { + return Objects.hashCode(id); + } + + @Override + public String toString() { + return "FileLog{" + + "id=" + id + + ", timeStamp=" + timeStamp + + ", actorUserId=" + actorUserId + + ", visaCaseId=" + visaCaseId + + ", fileName='" + fileName + '\'' + + ", fileEventType=" + fileEventType + + ", description='" + description + '\'' + + '}'; + } +} diff --git a/src/main/java/org/example/visacasemanagementsystem/audit/entity/VisaLog.java b/src/main/java/org/example/visacasemanagementsystem/audit/entity/VisaLog.java index e86535c..33583cf 100644 --- a/src/main/java/org/example/visacasemanagementsystem/audit/entity/VisaLog.java +++ b/src/main/java/org/example/visacasemanagementsystem/audit/entity/VisaLog.java @@ -27,14 +27,14 @@ public class VisaLog { @NotNull @CreatedDate private LocalDateTime timeStamp; - @NotNull private Long userId; // Vem gjorde vad? + @NotNull private Long userId; - @NotNull private Long visaCaseId; // Vilket ärende rör det? + @NotNull private Long visaCaseId; @NotNull @Enumerated(EnumType.STRING) private VisaEventType visaEventType; - private String description; // Beskrivning av händelse + private String description; @Override public boolean equals(Object o) { diff --git a/src/main/java/org/example/visacasemanagementsystem/audit/mapper/CommentLogMapper.java b/src/main/java/org/example/visacasemanagementsystem/audit/mapper/CommentLogMapper.java new file mode 100644 index 0000000..87f8bc1 --- /dev/null +++ b/src/main/java/org/example/visacasemanagementsystem/audit/mapper/CommentLogMapper.java @@ -0,0 +1,36 @@ +package org.example.visacasemanagementsystem.audit.mapper; + +import org.example.visacasemanagementsystem.audit.CommentEventType; +import org.example.visacasemanagementsystem.audit.dto.CommentLogDTO; +import org.example.visacasemanagementsystem.audit.entity.CommentLog; +import org.springframework.stereotype.Component; + +@Component +public class CommentLogMapper { + + // For viewing (Entity --> DTO) + public CommentLogDTO toDTO(CommentLog commentLog) { + if (commentLog == null) return null; + + return new CommentLogDTO( + commentLog.getId(), + commentLog.getTimeStamp(), + commentLog.getActorUserId(), + commentLog.getVisaCaseId(), + commentLog.getCommentId(), + commentLog.getCommentEventType(), + commentLog.getDescription() + ); + } + + // The service layer is responsible for creating the log entity + public CommentLog toEntity(Long actorUserId, Long visaCaseId, Long commentId, CommentEventType commentEventType, String description) { + CommentLog commentLog = new CommentLog(); + commentLog.setActorUserId(actorUserId); + commentLog.setVisaCaseId(visaCaseId); + commentLog.setCommentId(commentId); + commentLog.setCommentEventType(commentEventType); + commentLog.setDescription(description); + return commentLog; + } +} diff --git a/src/main/java/org/example/visacasemanagementsystem/audit/mapper/FileLogMapper.java b/src/main/java/org/example/visacasemanagementsystem/audit/mapper/FileLogMapper.java new file mode 100644 index 0000000..358eee1 --- /dev/null +++ b/src/main/java/org/example/visacasemanagementsystem/audit/mapper/FileLogMapper.java @@ -0,0 +1,38 @@ +package org.example.visacasemanagementsystem.audit.mapper; + +import org.example.visacasemanagementsystem.audit.FileEventType; +import org.example.visacasemanagementsystem.audit.dto.FileLogDTO; +import org.example.visacasemanagementsystem.audit.entity.FileLog; +import org.springframework.stereotype.Component; + + +@Component +public class FileLogMapper { + + // For viewing (Entity --> DTO) + public FileLogDTO toDTO(FileLog fileLog) { + if (fileLog == null) return null; + + return new FileLogDTO( + fileLog.getId(), + fileLog.getTimeStamp(), + fileLog.getActorUserId(), + fileLog.getVisaCaseId(), + fileLog.getFileName(), + fileLog.getFileEventType(), + fileLog.getDescription() + ); + } + + // The service layer is responsible for creating the log entity + public FileLog toEntity(Long actorUserId, Long visaCaseId, String fileName, FileEventType fileEventType, String description) { + FileLog fileLog = new FileLog(); + fileLog.setActorUserId(actorUserId); + fileLog.setVisaCaseId(visaCaseId); + fileLog.setFileName(fileName); + fileLog.setFileEventType(fileEventType); + fileLog.setDescription(description); + return fileLog; + + } +} diff --git a/src/main/java/org/example/visacasemanagementsystem/audit/repository/CommentLogRepository.java b/src/main/java/org/example/visacasemanagementsystem/audit/repository/CommentLogRepository.java new file mode 100644 index 0000000..a8f3d33 --- /dev/null +++ b/src/main/java/org/example/visacasemanagementsystem/audit/repository/CommentLogRepository.java @@ -0,0 +1,9 @@ +package org.example.visacasemanagementsystem.audit.repository; + +import org.example.visacasemanagementsystem.audit.entity.CommentLog; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface CommentLogRepository extends JpaRepository { +} diff --git a/src/main/java/org/example/visacasemanagementsystem/audit/repository/FileLogRepository.java b/src/main/java/org/example/visacasemanagementsystem/audit/repository/FileLogRepository.java new file mode 100644 index 0000000..416ac5a --- /dev/null +++ b/src/main/java/org/example/visacasemanagementsystem/audit/repository/FileLogRepository.java @@ -0,0 +1,9 @@ +package org.example.visacasemanagementsystem.audit.repository; + +import org.example.visacasemanagementsystem.audit.entity.FileLog; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface FileLogRepository extends JpaRepository { +} diff --git a/src/main/java/org/example/visacasemanagementsystem/audit/service/CommentLogService.java b/src/main/java/org/example/visacasemanagementsystem/audit/service/CommentLogService.java new file mode 100644 index 0000000..b5b9128 --- /dev/null +++ b/src/main/java/org/example/visacasemanagementsystem/audit/service/CommentLogService.java @@ -0,0 +1,37 @@ +package org.example.visacasemanagementsystem.audit.service; + +import org.example.visacasemanagementsystem.audit.CommentEventType; +import org.example.visacasemanagementsystem.audit.dto.CommentLogDTO; +import org.example.visacasemanagementsystem.audit.entity.CommentLog; +import org.example.visacasemanagementsystem.audit.mapper.CommentLogMapper; +import org.example.visacasemanagementsystem.audit.repository.CommentLogRepository; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class CommentLogService { + + private final CommentLogRepository commentLogRepository; + private final CommentLogMapper commentLogMapper; + + public CommentLogService(CommentLogRepository commentLogRepository, CommentLogMapper commentLogMapper) { + this.commentLogRepository = commentLogRepository; + this.commentLogMapper = commentLogMapper; + + } + + public void createCommentLog(Long actorUserId, Long visaCaseId, Long commentId, CommentEventType commentEventType, String description) { + CommentLog commentLog = commentLogMapper.toEntity(actorUserId, visaCaseId, commentId,commentEventType, description); + commentLogRepository.save(commentLog); + + } + + public List findAll() { + return commentLogRepository.findAll() + .stream() + .map(commentLogMapper::toDTO) + .toList(); + } + +} diff --git a/src/main/java/org/example/visacasemanagementsystem/audit/service/FileLogService.java b/src/main/java/org/example/visacasemanagementsystem/audit/service/FileLogService.java new file mode 100644 index 0000000..fc60634 --- /dev/null +++ b/src/main/java/org/example/visacasemanagementsystem/audit/service/FileLogService.java @@ -0,0 +1,35 @@ +package org.example.visacasemanagementsystem.audit.service; + +import org.example.visacasemanagementsystem.audit.FileEventType; +import org.example.visacasemanagementsystem.audit.dto.FileLogDTO; +import org.example.visacasemanagementsystem.audit.entity.FileLog; +import org.example.visacasemanagementsystem.audit.mapper.FileLogMapper; +import org.example.visacasemanagementsystem.audit.repository.FileLogRepository; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class FileLogService { + + private final FileLogRepository fileLogRepository; + private final FileLogMapper fileLogMapper; + + public FileLogService(FileLogRepository fileLogRepository, FileLogMapper fileLogMapper) { + this.fileLogRepository = fileLogRepository; + this.fileLogMapper = fileLogMapper; + } + + public void createFileLog(Long actorUserId, Long visaCaseId, String fileName, FileEventType fileEventType, String description) { + FileLog fileLog = fileLogMapper.toEntity(actorUserId, visaCaseId, fileName, fileEventType, description); + fileLogRepository.save(fileLog); + + } + + public List findAll() { + return fileLogRepository.findAll() + .stream() + .map(fileLogMapper::toDTO) + .toList(); + } +} diff --git a/src/main/java/org/example/visacasemanagementsystem/comment/service/CommentService.java b/src/main/java/org/example/visacasemanagementsystem/comment/service/CommentService.java index 7c8dbd5..a1e7311 100644 --- a/src/main/java/org/example/visacasemanagementsystem/comment/service/CommentService.java +++ b/src/main/java/org/example/visacasemanagementsystem/comment/service/CommentService.java @@ -1,7 +1,7 @@ package org.example.visacasemanagementsystem.comment.service; -import org.example.visacasemanagementsystem.audit.VisaEventType; -import org.example.visacasemanagementsystem.audit.service.VisaLogService; +import org.example.visacasemanagementsystem.audit.CommentEventType; +import org.example.visacasemanagementsystem.audit.service.CommentLogService; import org.example.visacasemanagementsystem.comment.dto.CommentDTO; import org.example.visacasemanagementsystem.comment.dto.CreateCommentDTO; import org.example.visacasemanagementsystem.comment.entity.Comment; @@ -24,18 +24,19 @@ public class CommentService { private final CommentMapper commentMapper; private final UserRepository userRepository; private final VisaRepository visaRepository; - private final VisaLogService visaLogService; + private final CommentLogService commentLogService; - public CommentService(CommentRepository commentRepository, CommentMapper commentMapper, UserRepository userRepository, VisaRepository visaRepository, VisaLogService visaLogService) { + public CommentService(CommentRepository commentRepository, CommentMapper commentMapper, UserRepository userRepository, VisaRepository visaRepository, CommentLogService commentLogService) { this.commentRepository = commentRepository; this.commentMapper = commentMapper; this.userRepository = userRepository; this.visaRepository = visaRepository; - this.visaLogService = visaLogService; + this.commentLogService = commentLogService; + } - // Create Comment + // Create Comment @Transactional public CommentDTO createComment(CreateCommentDTO dto, Long userId) { if (dto == null) { @@ -64,11 +65,13 @@ public CommentDTO createComment(CreateCommentDTO dto, Long userId) { Comment savedComment = commentRepository.save(comment); // Create log in database - visaLogService.createVisaLog( + commentLogService.createCommentLog( author.getId(), visa.getId(), - VisaEventType.UPDATED, - "Comment added by " + author.getFullName() + savedComment.getId(), + CommentEventType.ADDED, + "User added a new comment" + ); return commentMapper.toDTO(savedComment); @@ -90,4 +93,4 @@ public List getCommentsByVisaId(Long visaId) { .map(commentMapper::toDTO) .toList(); } -} \ No newline at end of file +} diff --git a/src/main/java/org/example/visacasemanagementsystem/file/FileService.java b/src/main/java/org/example/visacasemanagementsystem/file/FileService.java index 1535214..387fcec 100644 --- a/src/main/java/org/example/visacasemanagementsystem/file/FileService.java +++ b/src/main/java/org/example/visacasemanagementsystem/file/FileService.java @@ -147,7 +147,6 @@ public void deleteFile(String s3Key) { .key(s3Key) .build(); s3Client.deleteObject(deleteObjectRequest); - } - + } } diff --git a/src/main/java/org/example/visacasemanagementsystem/visa/service/VisaService.java b/src/main/java/org/example/visacasemanagementsystem/visa/service/VisaService.java index bbc1db1..607296c 100644 --- a/src/main/java/org/example/visacasemanagementsystem/visa/service/VisaService.java +++ b/src/main/java/org/example/visacasemanagementsystem/visa/service/VisaService.java @@ -1,6 +1,8 @@ package org.example.visacasemanagementsystem.visa.service; import jakarta.persistence.EntityNotFoundException; +import org.example.visacasemanagementsystem.audit.FileEventType; import org.example.visacasemanagementsystem.audit.VisaEventType; +import org.example.visacasemanagementsystem.audit.service.FileLogService; import org.example.visacasemanagementsystem.audit.service.VisaLogService; import org.example.visacasemanagementsystem.exception.UnauthorizedException; import org.example.visacasemanagementsystem.file.FileService; @@ -35,18 +37,21 @@ public class VisaService { private final VisaMapper visaMapper; private final FileService fileService; private final VisaLogService visaLogService; + private final FileLogService fileLogService; public VisaService(VisaRepository visaRepository, UserRepository userRepository, VisaMapper visaMapper, VisaLogService visaLogService, - FileService fileService) { + FileService fileService, + FileLogService fileLogService) { this.visaRepository = visaRepository; this.userRepository = userRepository; this.visaMapper = visaMapper; this.visaLogService = visaLogService; this.fileService = fileService; + this.fileLogService = fileLogService; } // --- For filtering in Frontend list-view --- @@ -204,18 +209,25 @@ public VisaDTO applyForVisa(CreateVisaDTO dto, Long userId, String s3Key) { visa.setApplicant(applicant); visa.setVisaStatus(VisaStatus.SUBMITTED); + Visa savedVisa = visaRepository.save(visa); + if (s3Key != null && !s3Key.isBlank()) { - visa.getS3Keys().add(s3Key); + savedVisa.getS3Keys().add(s3Key); + fileLogService.createFileLog( + userId, + savedVisa.getId(), + s3Key, + FileEventType.UPLOADED, + "Initial document attached during application creation." + ); } - Visa savedVisa = visaRepository.save(visa); - // Create log in database visaLogService.createVisaLog( userId, savedVisa.getId(), VisaEventType.CREATED, - "Visa application submitted." + (s3Key != null ? " Document attached." : "") + "Visa application submitted." + (s3Key != null && !s3Key.isBlank() ? " Document attached." : "") ); return visaMapper.toDTO(savedVisa); } @@ -246,6 +258,14 @@ public VisaDTO updateVisa(Long visaId, UpdateVisaDTO dto, Long userId, String ne if (newS3Key != null && !newS3Key.isBlank()) { visa.getS3Keys().add(newS3Key); + + fileLogService.createFileLog( + userId, + visaId, + newS3Key, + FileEventType.UPLOADED, + "Document attached during application update." + ); } visa.setVisaStatus(VisaStatus.SUBMITTED); @@ -290,6 +310,9 @@ public void removeVisaDocument(Long visaId, String s3Key, Long userId) { fileService.deleteFile(s3Key); visaLogService.createVisaLog(userId, visaId, VisaEventType.UPDATED, "Removed document: " + s3Key); + + String actor = isOwner ? "Applicant" : "Administrator"; + fileLogService.createFileLog(userId, visaId, s3Key, FileEventType.DELETED, actor + " removed file."); } } diff --git a/src/test/java/org/example/visacasemanagementsystem/audit/mapper/CommentLogMapperTest.java b/src/test/java/org/example/visacasemanagementsystem/audit/mapper/CommentLogMapperTest.java new file mode 100644 index 0000000..e0ecded --- /dev/null +++ b/src/test/java/org/example/visacasemanagementsystem/audit/mapper/CommentLogMapperTest.java @@ -0,0 +1,87 @@ +package org.example.visacasemanagementsystem.audit.mapper; + +import org.example.visacasemanagementsystem.audit.CommentEventType; +import org.example.visacasemanagementsystem.audit.dto.CommentLogDTO; +import org.example.visacasemanagementsystem.audit.entity.CommentLog; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.LocalDateTime; + +@DisplayName("CommentLogMapper unit tests") +class CommentLogMapperTest { + + private CommentLogMapper commentLogMapper; + + @BeforeEach + void setUp() { + commentLogMapper = new CommentLogMapper(); + } + + @Test + @DisplayName("Checking if toDTO copies every field from CommentLog entity to CommentLogDTO") + void toDTO_shouldCopyAllFields_WhenEntityIsPopulated() { + // Arrange + LocalDateTime timestamp = LocalDateTime.of(2026, 4, 24, 14, 0,0); + CommentLog entity = new CommentLog(); + entity.setId(50L); + entity.setTimeStamp(timestamp); + entity.setActorUserId(1L); + entity.setVisaCaseId(100L); + entity.setCommentId(20L); + entity.setCommentEventType(CommentEventType.ADDED); + entity.setDescription("User added a comment regarding missing documents."); + + // Act + CommentLogDTO dto = commentLogMapper.toDTO(entity); + + // Assert + assertThat(dto).isNotNull(); + assertThat(dto.id()).isEqualTo(50L); + assertThat(dto.timeStamp()).isEqualTo(timestamp); + assertThat(dto.actorUserId()).isEqualTo(1L); + assertThat(dto.visaCaseId()).isEqualTo(100L); + assertThat(dto.commentId()).isEqualTo(20L); + assertThat(dto.commentEventType()).isEqualTo(CommentEventType.ADDED); + assertThat(dto.description()).isEqualTo("User added a comment regarding missing documents."); + + } + + @Test + @DisplayName("Checking if toDTO returns null when entity is null") + void toDTO_shouldReturnNull_WhenEntityIsNull() { + // Act + CommentLogDTO dto = commentLogMapper.toDTO(null); + + // Assert + assertThat(dto).isNull(); + + } + + @Test + @DisplayName("Checking if toEntity sets all fields for a new log entry") + void toEntity_shouldSetAllFields_WhenAllArgumentsAreProvided() { + // Act + CommentLog entity = commentLogMapper.toEntity( + 1L, 100L, 20L, + CommentEventType.ADDED, "User added a comment" + ); + + // Assert + assertThat(entity).isNotNull(); + assertThat(entity.getActorUserId()).isEqualTo(1L); + assertThat(entity.getVisaCaseId()).isEqualTo(100L); + assertThat(entity.getCommentId()).isEqualTo(20L); + assertThat(entity.getCommentEventType()).isEqualTo(CommentEventType.ADDED); + assertThat(entity.getDescription()).isEqualTo("User added a comment"); + assertThat(entity.getId()).isNull(); + assertThat(entity.getTimeStamp()).isNull(); + } + + + + +} diff --git a/src/test/java/org/example/visacasemanagementsystem/audit/mapper/FileLogMapperTest.java b/src/test/java/org/example/visacasemanagementsystem/audit/mapper/FileLogMapperTest.java new file mode 100644 index 0000000..93ca4d6 --- /dev/null +++ b/src/test/java/org/example/visacasemanagementsystem/audit/mapper/FileLogMapperTest.java @@ -0,0 +1,114 @@ +package org.example.visacasemanagementsystem.audit.mapper; + + +import org.example.visacasemanagementsystem.audit.FileEventType; +import org.example.visacasemanagementsystem.audit.dto.FileLogDTO; +import org.example.visacasemanagementsystem.audit.entity.FileLog; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.LocalDateTime; + +@DisplayName("FileLogMapper unit tests") +class FileLogMapperTest { + + private FileLogMapper fileLogMapper; + + @BeforeEach + void setUp() { + fileLogMapper = new FileLogMapper(); + } + + @Test + @DisplayName("Checking if toDTO copies every field from FileLog entity to FileLogDTO") + void toDTO_shouldCopyAllFields_WhenEntityIsPopulated() { + // Arrange + LocalDateTime timestamp = LocalDateTime.of(2026, 4, 24, 15, 0, 0); + + FileLog entity = new FileLog(); + entity.setId(101L); + entity.setTimeStamp(timestamp); + entity.setActorUserId(7L); + entity.setVisaCaseId(200L); + entity.setFileName("passport_scan.pdf"); + entity.setFileEventType(FileEventType.UPLOADED); + entity.setDescription("Initial passport document uploaded."); + + // Act + FileLogDTO dto = fileLogMapper.toDTO(entity); + + // Assert + assertThat(dto).isNotNull(); + assertThat(dto.id()).isEqualTo(101L); + assertThat(dto.timeStamp()).isEqualTo(timestamp); + assertThat(dto.actorUserId()).isEqualTo(7L); + assertThat(dto.visaCaseId()).isEqualTo(200L); + assertThat(dto.fileName()).isEqualTo("passport_scan.pdf"); + assertThat(dto.fileEventType()).isEqualTo(FileEventType.UPLOADED); + assertThat(dto.description()).isEqualTo("Initial passport document uploaded."); + + } + + @Test + @DisplayName("Checking if toDTO returns null when entity is null") + void toDTO_shouldReturnNull_WhenEntityIsNull() { + // Act + FileLogDTO dto = fileLogMapper.toDTO(null); + + // Assert + assertThat(dto).isNull(); + } + + @Test + @DisplayName("Checking if toEntity sets all fields correctly for a new file log") + void toEntity_shouldSetAllFields_WhenAllArgumentsAreProvided() { + // Arrange + Long actorId = 7L; + Long visaId = 200L; + String fileName = "visa_photo.jpg"; + String description = "Applicant photo uploaded via web portal."; + + // Act + FileLog entity = fileLogMapper.toEntity( + actorId, + visaId, + fileName, + FileEventType.UPLOADED, + description + ); + + // Assert + assertThat(entity).isNotNull(); + assertThat(entity.getActorUserId()).isEqualTo(actorId); + assertThat(entity.getVisaCaseId()).isEqualTo(visaId); + assertThat(entity.getFileName()).isEqualTo("visa_photo.jpg"); + assertThat(entity.getFileEventType()).isEqualTo(FileEventType.UPLOADED); + assertThat(entity.getDescription()).isEqualTo(description); + + assertThat(entity.getId()).isNull(); + assertThat(entity.getTimeStamp()).isNull(); + + } + + @Test + @DisplayName("Checking if toEntity handles deletion events correctly") + void toEntity_shouldHandleDeletionEventType() { + // Act + FileLog entity = fileLogMapper.toEntity( + 1L, + 200L, + "old_document.pdf", + FileEventType.DELETED, + "Document removed due to incorrect format" + ); + + // Assert + assertThat(entity.getFileEventType()).isEqualTo(FileEventType.DELETED); + assertThat(entity.getFileName()).isEqualTo("old_document.pdf"); + } + + +}