diff --git a/src/test/java/org/example/vet1177/dto/response/medicalrecord/MedicalRecordResponseTest.java b/src/test/java/org/example/vet1177/dto/response/medicalrecord/MedicalRecordResponseTest.java new file mode 100644 index 0000000..c32181b --- /dev/null +++ b/src/test/java/org/example/vet1177/dto/response/medicalrecord/MedicalRecordResponseTest.java @@ -0,0 +1,174 @@ +package org.example.vet1177.dto.response.medicalrecord; + +import org.example.vet1177.entities.Clinic; +import org.example.vet1177.entities.MedicalRecord; +import org.example.vet1177.entities.Pet; +import org.example.vet1177.entities.RecordStatus; +import org.example.vet1177.entities.Role; +import org.example.vet1177.entities.User; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.time.LocalDate; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class MedicalRecordResponseTest { + + private MedicalRecord record; + private Pet pet; + private User owner; + private Clinic clinic; + private User vet; + private User createdBy; + + private UUID recordId; + private UUID petId; + private UUID ownerId; + private UUID clinicId; + private UUID vetId; + private UUID createdById; + + @BeforeEach + void setUp() throws Exception { + recordId = UUID.randomUUID(); + petId = UUID.randomUUID(); + ownerId = UUID.randomUUID(); + clinicId = UUID.randomUUID(); + vetId = UUID.randomUUID(); + createdById = UUID.randomUUID(); + + owner = new User("Anna Ägare", "anna@mail.se", "hash", Role.OWNER); + setPrivateField(owner, "id", ownerId); + + vet = new User("Dr. Elin Svensson", "elin@vet.se", "hash", Role.VET); + setPrivateField(vet, "id", vetId); + + createdBy = new User("Dr. Sara Lindqvist", "sara@vet.se", "hash", Role.VET); + setPrivateField(createdBy, "id", createdById); + + pet = new Pet(owner, "Lassie", "Hund", "Collie", LocalDate.of(2020, 1, 1), null); + setPrivateField(pet, "id", petId); + + clinic = new Clinic("Vetkliniken", "Storgatan 1", "0701234567"); + setPrivateField(clinic, "id", clinicId); + + record = new MedicalRecord(); + record.setId(recordId); + record.setTitle("Årlig kontroll"); + record.setDescription("Patienten är vid god hälsa."); + record.setStatus(RecordStatus.OPEN); + record.setPet(pet); + record.setOwner(owner); + record.setClinic(clinic); + record.setAssignedVet(vet); + record.setCreatedBy(createdBy); + callProtectedMethod(record, "onCreate"); + } + + // --- Happy path --- + + @Test + void from_shouldMapAllFieldsCorrectly() { + MedicalRecordResponse response = MedicalRecordResponse.from(record); + + assertThat(response.id()).isEqualTo(recordId); + assertThat(response.title()).isEqualTo("Årlig kontroll"); + assertThat(response.description()).isEqualTo("Patienten är vid god hälsa."); + assertThat(response.status()).isEqualTo(RecordStatus.OPEN); + assertThat(response.petId()).isEqualTo(petId); + assertThat(response.petName()).isEqualTo("Lassie"); + assertThat(response.petSpecies()).isEqualTo("Hund"); + assertThat(response.ownerId()).isEqualTo(ownerId); + assertThat(response.ownerName()).isEqualTo("Anna Ägare"); + assertThat(response.clinicId()).isEqualTo(clinicId); + assertThat(response.clinicName()).isEqualTo("Vetkliniken"); + assertThat(response.assignedVetId()).isEqualTo(vetId); + assertThat(response.assignedVetName()).isEqualTo("Dr. Elin Svensson"); + assertThat(response.createdById()).isEqualTo(createdById); + assertThat(response.createdByName()).isEqualTo("Dr. Sara Lindqvist"); + assertThat(response.createdAt()).isNotNull(); + assertThat(response.updatedAt()).isNotNull(); + assertThat(response.closedAt()).isNull(); + } + + @Test + void from_timestampsShouldReflectRecordTimestamps() { + MedicalRecordResponse response = MedicalRecordResponse.from(record); + + assertThat(response.createdAt()).isEqualTo(record.getCreatedAt()); + assertThat(response.updatedAt()).isEqualTo(record.getUpdatedAt()); + } + + @Test + void from_shouldMapClosedAtWhenStatusIsClosed() { + record.setStatus(RecordStatus.CLOSED); + + MedicalRecordResponse response = MedicalRecordResponse.from(record); + + assertThat(response.status()).isEqualTo(RecordStatus.CLOSED); + assertThat(response.closedAt()).isEqualTo(record.getClosedAt()); + } + + @Test + void from_shouldMapNullAssignedVetToNullIdAndName() { + record.setAssignedVet(null); + + MedicalRecordResponse response = MedicalRecordResponse.from(record); + + assertThat(response.assignedVetId()).isNull(); + assertThat(response.assignedVetName()).isNull(); + } + + // --- Sad paths --- + + @Test + void from_shouldThrowWhenPetIsNull() { + record.setPet(null); + + assertThatThrownBy(() -> MedicalRecordResponse.from(record)) + .isInstanceOf(NullPointerException.class); + } + + @Test + void from_shouldThrowWhenOwnerIsNull() { + record.setOwner(null); + + assertThatThrownBy(() -> MedicalRecordResponse.from(record)) + .isInstanceOf(NullPointerException.class); + } + + @Test + void from_shouldThrowWhenClinicIsNull() { + record.setClinic(null); + + assertThatThrownBy(() -> MedicalRecordResponse.from(record)) + .isInstanceOf(NullPointerException.class); + } + + @Test + void from_shouldThrowWhenCreatedByIsNull() { + record.setCreatedBy(null); + + assertThatThrownBy(() -> MedicalRecordResponse.from(record)) + .isInstanceOf(NullPointerException.class); + } + + // --- Helpers --- + + private static void setPrivateField(Object target, String fieldName, Object value) throws Exception { + Field field = target.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + field.set(target, value); + } + + private static void callProtectedMethod(Object target, String methodName) throws Exception { + Method method = target.getClass().getDeclaredMethod(methodName); + method.setAccessible(true); + method.invoke(target); + } +} diff --git a/src/test/java/org/example/vet1177/dto/response/medicalrecord/MedicalRecordSummaryResponseTest.java b/src/test/java/org/example/vet1177/dto/response/medicalrecord/MedicalRecordSummaryResponseTest.java new file mode 100644 index 0000000..92bca5f --- /dev/null +++ b/src/test/java/org/example/vet1177/dto/response/medicalrecord/MedicalRecordSummaryResponseTest.java @@ -0,0 +1,123 @@ +package org.example.vet1177.dto.response.medicalrecord; + +import org.example.vet1177.entities.Clinic; +import org.example.vet1177.entities.MedicalRecord; +import org.example.vet1177.entities.Pet; +import org.example.vet1177.entities.RecordStatus; +import org.example.vet1177.entities.Role; +import org.example.vet1177.entities.User; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.time.LocalDate; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class MedicalRecordSummaryResponseTest { + + private MedicalRecord record; + private Pet pet; + private User owner; + private Clinic clinic; + private User vet; + private User createdBy; + private UUID recordId; + + @BeforeEach + void setUp() throws Exception { + recordId = UUID.randomUUID(); + + owner = new User("Anna Ägare", "anna@mail.se", "hash", Role.OWNER); + setPrivateField(owner, "id", UUID.randomUUID()); + + vet = new User("Dr. Elin Svensson", "elin@vet.se", "hash", Role.VET); + setPrivateField(vet, "id", UUID.randomUUID()); + + createdBy = new User("Dr. Sara Lindqvist", "sara@vet.se", "hash", Role.VET); + setPrivateField(createdBy, "id", UUID.randomUUID()); + + pet = new Pet(owner, "Lassie", "Hund", "Collie", LocalDate.of(2020, 1, 1), null); + setPrivateField(pet, "id", UUID.randomUUID()); + + clinic = new Clinic("Vetkliniken", "Storgatan 1", "0701234567"); + setPrivateField(clinic, "id", UUID.randomUUID()); + + record = new MedicalRecord(); + record.setId(recordId); + record.setTitle("Årlig kontroll"); + record.setStatus(RecordStatus.OPEN); + record.setPet(pet); + record.setOwner(owner); + record.setClinic(clinic); + record.setAssignedVet(vet); + record.setCreatedBy(createdBy); + callProtectedMethod(record, "onCreate"); + } + + // --- Happy path --- + + @Test + void from_shouldMapAllFieldsCorrectly() { + MedicalRecordSummaryResponse response = MedicalRecordSummaryResponse.from(record); + + assertThat(response.id()).isEqualTo(recordId); + assertThat(response.title()).isEqualTo("Årlig kontroll"); + assertThat(response.status()).isEqualTo(RecordStatus.OPEN); + assertThat(response.petName()).isEqualTo("Lassie"); + assertThat(response.ownerName()).isEqualTo("Anna Ägare"); + assertThat(response.assignedVetName()).isEqualTo("Dr. Elin Svensson"); + assertThat(response.createdAt()).isNotNull(); + } + + @Test + void from_createdAtShouldReflectRecordCreatedAt() { + MedicalRecordSummaryResponse response = MedicalRecordSummaryResponse.from(record); + + assertThat(response.createdAt()).isEqualTo(record.getCreatedAt()); + } + + @Test + void from_shouldMapNullAssignedVetToNullName() { + record.setAssignedVet(null); + + MedicalRecordSummaryResponse response = MedicalRecordSummaryResponse.from(record); + + assertThat(response.assignedVetName()).isNull(); + } + + // --- Sad paths --- + + @Test + void from_shouldThrowWhenPetIsNull() { + record.setPet(null); + + assertThatThrownBy(() -> MedicalRecordSummaryResponse.from(record)) + .isInstanceOf(NullPointerException.class); + } + + @Test + void from_shouldThrowWhenOwnerIsNull() { + record.setOwner(null); + + assertThatThrownBy(() -> MedicalRecordSummaryResponse.from(record)) + .isInstanceOf(NullPointerException.class); + } + + // --- Helpers --- + + private static void setPrivateField(Object target, String fieldName, Object value) throws Exception { + Field field = target.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + field.set(target, value); + } + + private static void callProtectedMethod(Object target, String methodName) throws Exception { + Method method = target.getClass().getDeclaredMethod(methodName); + method.setAccessible(true); + method.invoke(target); + } +} diff --git a/src/test/java/org/example/vet1177/entities/MedicalRecordEntityTest.java b/src/test/java/org/example/vet1177/entities/MedicalRecordEntityTest.java new file mode 100644 index 0000000..bceef5e --- /dev/null +++ b/src/test/java/org/example/vet1177/entities/MedicalRecordEntityTest.java @@ -0,0 +1,301 @@ +package org.example.vet1177.entities; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.time.Instant; + +import static org.assertj.core.api.Assertions.assertThat; + +class MedicalRecordEntityTest { + + private MedicalRecord record; + private Pet pet; + private User owner; + private Clinic clinic; + private User vet; + private User createdBy; + + @BeforeEach + void setUp() { + record = new MedicalRecord(); + owner = new User("Anna Ägare", "anna@mail.se", "hash", Role.OWNER); + vet = new User("Dr. Elin Svensson", "elin@vet.se", "hash", Role.VET); + createdBy = new User("Dr. Sara Lindqvist", "sara@vet.se", "hash", Role.VET); + pet = new Pet(); + clinic = new Clinic("Vetkliniken", "Storgatan 1", "0701234567"); + } + + // --- Getters & setters --- + + @Test + void setTitle_shouldStoreAndReturnCorrectValue() { + record.setTitle("Årlig kontroll"); + + assertThat(record.getTitle()).isEqualTo("Årlig kontroll"); + } + + @Test + void setDescription_shouldStoreAndReturnCorrectValue() { + record.setDescription("Patienten är vid god hälsa."); + + assertThat(record.getDescription()).isEqualTo("Patienten är vid god hälsa."); + } + + @Test + void setPet_shouldStoreAndReturnCorrectPet() { + record.setPet(pet); + + assertThat(record.getPet()).isSameAs(pet); + } + + @Test + void setOwner_shouldStoreAndReturnCorrectOwner() { + record.setOwner(owner); + + assertThat(record.getOwner()).isSameAs(owner); + } + + @Test + void setClinic_shouldStoreAndReturnCorrectClinic() { + record.setClinic(clinic); + + assertThat(record.getClinic()).isSameAs(clinic); + } + + @Test + void setAssignedVet_shouldStoreAndReturnCorrectVet() { + record.setAssignedVet(vet); + + assertThat(record.getAssignedVet()).isSameAs(vet); + } + + @Test + void setCreatedBy_shouldStoreAndReturnCorrectUser() { + record.setCreatedBy(createdBy); + + assertThat(record.getCreatedBy()).isSameAs(createdBy); + } + + @Test + void setUpdatedBy_shouldStoreAndReturnCorrectUser() { + record.setUpdatedBy(vet); + + assertThat(record.getUpdatedBy()).isSameAs(vet); + } + + // --- Status & closedAt logik --- + + @Test + void defaultStatus_shouldBeOpen() { + assertThat(record.getStatus()).isEqualTo(RecordStatus.OPEN); + } + + @Test + void setStatus_toClosed_shouldSetClosedAt() { + record.setStatus(RecordStatus.CLOSED); + + assertThat(record.getStatus()).isEqualTo(RecordStatus.CLOSED); + assertThat(record.getClosedAt()).isNotNull(); + } + + @Test + void setStatus_fromClosedToOpen_shouldClearClosedAt() { + record.setStatus(RecordStatus.CLOSED); + assertThat(record.getClosedAt()).isNotNull(); + + record.setStatus(RecordStatus.OPEN); + + assertThat(record.getStatus()).isEqualTo(RecordStatus.OPEN); + assertThat(record.getClosedAt()).isNull(); + } + + @Test + void setStatus_toClosedTwice_shouldNotOverwriteExistingClosedAt() { + record.setStatus(RecordStatus.CLOSED); + Instant firstClosedAt = record.getClosedAt(); + + record.setStatus(RecordStatus.CLOSED); + + assertThat(record.getClosedAt()).isEqualTo(firstClosedAt); + } + + @Test + void setClosedAt_shouldStoreAndReturnCorrectValue() { + Instant now = Instant.now(); + record.setClosedAt(now); + + assertThat(record.getClosedAt()).isEqualTo(now); + } + + // --- Attachments --- + + @Test + void getAttachments_shouldBeEmptyByDefault() { + assertThat(record.getAttachments()).isEmpty(); + } + + @Test + void addAttachment_shouldAddAndSetBackReference() { + Attachment attachment = new Attachment(); + + record.addAttachment(attachment); + + assertThat(record.getAttachments()).containsExactly(attachment); + assertThat(attachment.getMedicalRecord()).isSameAs(record); + } + + @Test + void addAttachment_withNull_shouldBeIgnored() { + record.addAttachment(null); + + assertThat(record.getAttachments()).isEmpty(); + } + + @Test + void removeAttachment_shouldRemoveAndClearBackReference() { + Attachment attachment = new Attachment(); + record.addAttachment(attachment); + + record.removeAttachment(attachment); + + assertThat(record.getAttachments()).isEmpty(); + assertThat(attachment.getMedicalRecord()).isNull(); + } + + @Test + void removeAttachment_withNull_shouldBeIgnored() { + Attachment attachment = new Attachment(); + record.addAttachment(attachment); + + record.removeAttachment(null); + + assertThat(record.getAttachments()).containsExactly(attachment); + } + + @Test + void setAttachments_shouldReplaceExistingAttachments() { + Attachment first = new Attachment(); + Attachment second = new Attachment(); + record.addAttachment(first); + + record.setAttachments(java.util.List.of(second)); + + assertThat(record.getAttachments()).containsExactly(second); + assertThat(first.getMedicalRecord()).isNull(); + assertThat(second.getMedicalRecord()).isSameAs(record); + } + + @Test + void setAttachments_withNull_shouldClearExisting() { + Attachment attachment = new Attachment(); + record.addAttachment(attachment); + + record.setAttachments(null); + + assertThat(record.getAttachments()).isEmpty(); + assertThat(attachment.getMedicalRecord()).isNull(); + } + + @Test + void getAttachments_shouldReturnUnmodifiableList() { + org.assertj.core.api.Assertions.assertThatThrownBy( + () -> record.getAttachments().add(new Attachment()) + ).isInstanceOf(UnsupportedOperationException.class); + } + + // --- Lifecycle: onCreate --- + + @Test + void onCreate_shouldSetBothTimestampsToNonNull() { + record.onCreate(); + + assertThat(record.getCreatedAt()).isNotNull(); + assertThat(record.getUpdatedAt()).isNotNull(); + } + + // --- Lifecycle: onUpdate --- + + @Test + void onUpdate_shouldRefreshUpdatedAtWithoutModifyingCreatedAt() { + record.onCreate(); + Instant createdAt = record.getCreatedAt(); + + record.onUpdate(); + + assertThat(record.getUpdatedAt()).isNotNull(); + assertThat(record.getCreatedAt()).isEqualTo(createdAt); + } + + @Test + void onUpdate_shouldNotModifyCreatedAt() { + record.onCreate(); + Instant originalCreatedAt = record.getCreatedAt(); + + record.onUpdate(); + + assertThat(record.getCreatedAt()).isEqualTo(originalCreatedAt); + } + + // --- Sad paths: standardvärden innan persist --- + + @Test + void getId_shouldBeNullBeforePersist() { + assertThat(record.getId()).isNull(); + } + + @Test + void getTitle_shouldBeNullWhenNotSet() { + assertThat(record.getTitle()).isNull(); + } + + @Test + void getDescription_shouldBeNullWhenNotSet() { + assertThat(record.getDescription()).isNull(); + } + + @Test + void getPet_shouldBeNullWhenNotSet() { + assertThat(record.getPet()).isNull(); + } + + @Test + void getOwner_shouldBeNullWhenNotSet() { + assertThat(record.getOwner()).isNull(); + } + + @Test + void getClinic_shouldBeNullWhenNotSet() { + assertThat(record.getClinic()).isNull(); + } + + @Test + void getAssignedVet_shouldBeNullWhenNotSet() { + assertThat(record.getAssignedVet()).isNull(); + } + + @Test + void getCreatedBy_shouldBeNullWhenNotSet() { + assertThat(record.getCreatedBy()).isNull(); + } + + @Test + void getUpdatedBy_shouldBeNullWhenNotSet() { + assertThat(record.getUpdatedBy()).isNull(); + } + + @Test + void getCreatedAt_shouldBeNullBeforeOnCreate() { + assertThat(record.getCreatedAt()).isNull(); + } + + @Test + void getUpdatedAt_shouldBeNullBeforeOnCreate() { + assertThat(record.getUpdatedAt()).isNull(); + } + + @Test + void getClosedAt_shouldBeNullByDefault() { + assertThat(record.getClosedAt()).isNull(); + } +}