Avis #4
+76
@@ -0,0 +1,76 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.avis.converter;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.AvisDTO;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.AvisInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.entity.Avis;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@DisplayName("AvisConverter Unit Tests")
|
||||
class AvisConverterTest {
|
||||
|
||||
private final UUID clientId = UUID.randomUUID();
|
||||
private final UUID livreId = UUID.randomUUID();
|
||||
|
||||
@Nested
|
||||
@DisplayName("toDomain() method tests")
|
||||
class ToDomainTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should convert AvisInfo to Avis domain object")
|
||||
void shouldConvertAvisInfoToDomain() {
|
||||
AvisInfo avisInfo = new AvisInfo(
|
||||
clientId, livreId, 5, "Excellent livre !", LocalDate.of(2024, 1, 15)
|
||||
);
|
||||
|
||||
Avis result = AvisConverter.toDomain(avisInfo);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(clientId, result.getClientId());
|
||||
assertEquals(livreId, result.getLivreId());
|
||||
assertEquals(5, result.getNote());
|
||||
assertEquals("Excellent livre !", result.getCommentaire());
|
||||
assertEquals(LocalDate.of(2024, 1, 15), result.getDateAchat());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should have null ID after toDomain (set by repository)")
|
||||
void shouldHaveNullIdAfterToDomain() {
|
||||
AvisInfo avisInfo = new AvisInfo(clientId, livreId, 3, "Commentaire", LocalDate.now());
|
||||
|
||||
Avis result = AvisConverter.toDomain(avisInfo);
|
||||
|
||||
assertNull(result.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("toDTO() method tests")
|
||||
class ToDTOTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should convert Avis domain object to AvisDTO")
|
||||
void shouldConvertAvisToDTO() {
|
||||
UUID avisId = UUID.randomUUID();
|
||||
Avis avis = Avis.builder()
|
||||
.id(avisId)
|
||||
.clientId(clientId)
|
||||
.livreId(livreId)
|
||||
.note(5)
|
||||
.commentaire("Excellent !")
|
||||
.dateAchat(LocalDate.of(2024, 1, 15))
|
||||
.build();
|
||||
|
||||
AvisDTO result = AvisConverter.toDTO(avis);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(avisId, result.getAvisId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.avis.entity;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class AvisTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Builder should create a valid Avis instance")
|
||||
void testAvisBuilder() {
|
||||
UUID id = UUID.randomUUID();
|
||||
UUID clientId = UUID.randomUUID();
|
||||
UUID livreId = UUID.randomUUID();
|
||||
|
||||
Avis avis = Avis.builder()
|
||||
.id(id)
|
||||
.clientId(clientId)
|
||||
.livreId(livreId)
|
||||
.note(5)
|
||||
.commentaire("Excellent livre !")
|
||||
.dateAchat(LocalDate.of(2024, 1, 15))
|
||||
.build();
|
||||
|
||||
assertEquals(id, avis.getId());
|
||||
assertEquals(clientId, avis.getClientId());
|
||||
assertEquals(livreId, avis.getLivreId());
|
||||
assertEquals(5, avis.getNote());
|
||||
assertEquals("Excellent livre !", avis.getCommentaire());
|
||||
assertEquals(LocalDate.of(2024, 1, 15), avis.getDateAchat());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("setRandomUUID should set a new non-null UUID")
|
||||
void testSetRandomUUID() {
|
||||
Avis avis = Avis.builder().build();
|
||||
UUID originalId = avis.getId();
|
||||
|
||||
avis.setRandomUUID();
|
||||
|
||||
assertNotNull(avis.getId());
|
||||
assertNotEquals(originalId, avis.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Two setRandomUUID calls should produce different UUIDs")
|
||||
void testSetRandomUUIDTwice() {
|
||||
Avis avis = Avis.builder().build();
|
||||
avis.setRandomUUID();
|
||||
UUID firstId = avis.getId();
|
||||
|
||||
avis.setRandomUUID();
|
||||
|
||||
assertNotEquals(firstId, avis.getId());
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.avis.exception;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class AvisNotFoundExceptionTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception message should contain the UUID provided")
|
||||
void testExceptionMessageContainsUUID() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
|
||||
AvisNotFoundException exception = new AvisNotFoundException(uuid);
|
||||
|
||||
String expectedMessage = String.format("The avis with id %s does not exist", uuid);
|
||||
assertEquals(expectedMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should use the correct constant message format")
|
||||
void testExceptionUsesConstantMessageFormat() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
|
||||
AvisNotFoundException exception = new AvisNotFoundException(uuid);
|
||||
|
||||
assertEquals("The avis with id {0} does not exist",
|
||||
AvisNotFoundException.THE_AVIS_WITH_ID_DOES_NOT_EXIST_MESSAGE);
|
||||
assertTrue(exception.getMessage().contains(uuid.toString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should be properly thrown and caught")
|
||||
void testExceptionCanBeThrownAndCaught() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
|
||||
try {
|
||||
throw new AvisNotFoundException(uuid);
|
||||
} catch (AvisNotFoundException e) {
|
||||
assertTrue(e.getMessage().contains(uuid.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.avis.exception;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
class NotValidAvisExceptionTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should be created with the provided message")
|
||||
void testExceptionCreation() {
|
||||
String errorMessage = "Note must be between 1 and 5";
|
||||
|
||||
NotValidAvisException exception = new NotValidAvisException(errorMessage);
|
||||
|
||||
assertEquals(errorMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"Note must be between 1 and 5",
|
||||
"Commentaire cannot be blank",
|
||||
"Client id cannot be null",
|
||||
"Livre id cannot be null",
|
||||
"Date achat cannot be null"
|
||||
})
|
||||
@DisplayName("Exception should handle different validation messages")
|
||||
void testExceptionWithDifferentMessages(String errorMessage) {
|
||||
NotValidAvisException exception = new NotValidAvisException(errorMessage);
|
||||
|
||||
assertEquals(errorMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should be properly thrown and caught")
|
||||
void testExceptionCanBeThrownAndCaught() {
|
||||
String errorMessage = "Note must be between 1 and 5";
|
||||
|
||||
Exception exception = assertThrows(NotValidAvisException.class, () -> {
|
||||
throw new NotValidAvisException(errorMessage);
|
||||
});
|
||||
|
||||
assertEquals(errorMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should be catchable as a general Exception")
|
||||
void testExceptionInheritance() {
|
||||
String errorMessage = "Commentaire cannot be blank";
|
||||
|
||||
try {
|
||||
throw new NotValidAvisException(errorMessage);
|
||||
} catch (Exception e) {
|
||||
assertEquals(NotValidAvisException.class, e.getClass());
|
||||
assertEquals(errorMessage, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.avis.repository;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.entity.Avis;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class AvisRepositoryTest {
|
||||
|
||||
private AvisRepository repository;
|
||||
private Avis avis1;
|
||||
private Avis avis2;
|
||||
private UUID clientId1;
|
||||
private UUID livreId1;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
repository = new AvisRepository();
|
||||
clientId1 = UUID.randomUUID();
|
||||
livreId1 = UUID.randomUUID();
|
||||
|
||||
avis1 = Avis.builder()
|
||||
.clientId(clientId1)
|
||||
.livreId(livreId1)
|
||||
.note(5)
|
||||
.commentaire("Excellent livre !")
|
||||
.dateAchat(LocalDate.of(2024, 1, 15))
|
||||
.build();
|
||||
avis1.setRandomUUID();
|
||||
|
||||
avis2 = Avis.builder()
|
||||
.clientId(UUID.randomUUID())
|
||||
.livreId(livreId1)
|
||||
.note(3)
|
||||
.commentaire("Pas mal")
|
||||
.dateAchat(LocalDate.of(2024, 2, 10))
|
||||
.build();
|
||||
avis2.setRandomUUID();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("New repository should be empty")
|
||||
void testNewRepositoryIsEmpty() {
|
||||
assertTrue(repository.findAll().isEmpty());
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Save operations")
|
||||
class SaveOperations {
|
||||
|
||||
@Test
|
||||
@DisplayName("Save should add a new avis")
|
||||
void testSaveNewAvis() {
|
||||
Avis saved = repository.save(avis1);
|
||||
|
||||
assertEquals(1, repository.findAll().size());
|
||||
assertEquals(avis1.getId(), saved.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Save should update existing avis with same ID")
|
||||
void testSaveUpdatesExistingAvis() {
|
||||
repository.save(avis1);
|
||||
UUID id = avis1.getId();
|
||||
|
||||
Avis updated = Avis.builder()
|
||||
.id(id)
|
||||
.clientId(clientId1)
|
||||
.livreId(livreId1)
|
||||
.note(3)
|
||||
.commentaire("Finalement moyen")
|
||||
.dateAchat(LocalDate.of(2024, 1, 15))
|
||||
.build();
|
||||
|
||||
Avis saved = repository.save(updated);
|
||||
|
||||
assertEquals(1, repository.findAll().size());
|
||||
assertEquals(id, saved.getId());
|
||||
assertEquals(3, saved.getNote());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Save multiple avis should add all of them")
|
||||
void testSaveMultipleAvis() {
|
||||
repository.save(avis1);
|
||||
repository.save(avis2);
|
||||
|
||||
assertEquals(2, repository.findAll().size());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Find operations")
|
||||
class FindOperations {
|
||||
|
||||
@BeforeEach
|
||||
void setUpAvis() {
|
||||
repository.save(avis1);
|
||||
repository.save(avis2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindById should return avis with matching ID")
|
||||
void testFindById() {
|
||||
Optional<Avis> found = repository.findById(avis1.getId());
|
||||
|
||||
assertTrue(found.isPresent());
|
||||
assertEquals(avis1.getId(), found.get().getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindById should return empty Optional when ID doesn't exist")
|
||||
void testFindByIdNotFound() {
|
||||
Optional<Avis> found = repository.findById(UUID.randomUUID());
|
||||
|
||||
assertTrue(found.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindByLivreId should return all avis for a book")
|
||||
void testFindByLivreId() {
|
||||
List<Avis> found = repository.findByLivreId(livreId1);
|
||||
|
||||
assertEquals(2, found.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindByClientId should return all avis for a client")
|
||||
void testFindByClientId() {
|
||||
List<Avis> found = repository.findByClientId(clientId1);
|
||||
|
||||
assertEquals(1, found.size());
|
||||
assertEquals(avis1.getId(), found.getFirst().getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ExistsById should return true when ID exists")
|
||||
void testExistsByIdExists() {
|
||||
assertTrue(repository.existsById(avis1.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ExistsById should return false when ID doesn't exist")
|
||||
void testExistsByIdNotExists() {
|
||||
assertFalse(repository.existsById(UUID.randomUUID()));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Delete operations")
|
||||
class DeleteOperations {
|
||||
|
||||
@BeforeEach
|
||||
void setUpAvis() {
|
||||
repository.save(avis1);
|
||||
repository.save(avis2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Delete should remove the specified avis")
|
||||
void testDelete() {
|
||||
repository.delete(avis1);
|
||||
|
||||
assertEquals(1, repository.findAll().size());
|
||||
assertFalse(repository.findAll().contains(avis1));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("DeleteAll should remove all avis")
|
||||
void testDeleteAll() {
|
||||
repository.deleteAll();
|
||||
|
||||
assertTrue(repository.findAll().isEmpty());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.avis.usecase;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.AvisDTO;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.AvisInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.entity.Avis;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.exception.NotValidAvisException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.repository.AvisRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.entity.Customer;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.exception.CustomerNotFoundException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.repository.CustomerRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class AvisUseCaseTest {
|
||||
|
||||
@Mock
|
||||
private AvisRepository avisRepository;
|
||||
|
||||
@Mock
|
||||
private CustomerRepository customerRepository;
|
||||
|
||||
@InjectMocks
|
||||
private AvisUseCase avisUseCase;
|
||||
|
||||
private UUID clientId;
|
||||
private UUID livreId;
|
||||
private Customer testCustomer;
|
||||
private AvisInfo validAvisInfo;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
clientId = UUID.randomUUID();
|
||||
livreId = UUID.randomUUID();
|
||||
|
||||
testCustomer = Customer.builder()
|
||||
.id(clientId)
|
||||
.firstName("Marie")
|
||||
.lastName("Dupont")
|
||||
.phoneNumber("0612345678")
|
||||
.loyaltyPoints(100)
|
||||
.build();
|
||||
|
||||
validAvisInfo = new AvisInfo(clientId, livreId, 5, "Excellent livre !", LocalDate.of(2024, 1, 15));
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("GererAvis tests")
|
||||
class GererAvisTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should create avis when valid data is provided")
|
||||
void testGererAvisWithValidData() throws NotValidAvisException, CustomerNotFoundException {
|
||||
when(customerRepository.findById(clientId)).thenReturn(Optional.of(testCustomer));
|
||||
|
||||
UUID avisId = UUID.randomUUID();
|
||||
Avis savedAvis = Avis.builder()
|
||||
.id(avisId)
|
||||
.clientId(clientId)
|
||||
.livreId(livreId)
|
||||
.note(5)
|
||||
.commentaire("Excellent livre !")
|
||||
.dateAchat(LocalDate.of(2024, 1, 15))
|
||||
.build();
|
||||
when(avisRepository.save(any(Avis.class))).thenReturn(savedAvis);
|
||||
|
||||
AvisDTO result = avisUseCase.gererAvis(validAvisInfo);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(avisId, result.getAvisId());
|
||||
verify(avisRepository, times(1)).save(any(Avis.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when customer does not exist")
|
||||
void testGererAvisWithUnknownCustomer() {
|
||||
when(customerRepository.findById(clientId)).thenReturn(Optional.empty());
|
||||
|
||||
assertThrows(CustomerNotFoundException.class,
|
||||
() -> avisUseCase.gererAvis(validAvisInfo));
|
||||
|
||||
verify(avisRepository, never()).save(any(Avis.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when note is invalid")
|
||||
void testGererAvisWithInvalidNote() {
|
||||
AvisInfo invalidAvis = new AvisInfo(clientId, livreId, 6, "Commentaire", LocalDate.now());
|
||||
|
||||
assertThrows(NotValidAvisException.class,
|
||||
() -> avisUseCase.gererAvis(invalidAvis));
|
||||
|
||||
verify(avisRepository, never()).save(any(Avis.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when commentaire is blank")
|
||||
void testGererAvisWithBlankCommentaire() {
|
||||
AvisInfo invalidAvis = new AvisInfo(clientId, livreId, 5, "", LocalDate.now());
|
||||
|
||||
assertThrows(NotValidAvisException.class,
|
||||
() -> avisUseCase.gererAvis(invalidAvis));
|
||||
|
||||
verify(avisRepository, never()).save(any(Avis.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when clientId is null")
|
||||
void testGererAvisWithNullClientId() {
|
||||
AvisInfo invalidAvis = new AvisInfo(null, livreId, 5, "Commentaire", LocalDate.now());
|
||||
|
||||
assertThrows(NotValidAvisException.class,
|
||||
() -> avisUseCase.gererAvis(invalidAvis));
|
||||
|
||||
verify(avisRepository, never()).save(any(Avis.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("FindAvis tests")
|
||||
class FindAvisTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should return avis when ID exists")
|
||||
void testFindAvisById() {
|
||||
UUID avisId = UUID.randomUUID();
|
||||
Avis avis = Avis.builder()
|
||||
.id(avisId)
|
||||
.clientId(clientId)
|
||||
.livreId(livreId)
|
||||
.note(5)
|
||||
.commentaire("Excellent !")
|
||||
.dateAchat(LocalDate.now())
|
||||
.build();
|
||||
|
||||
when(avisRepository.findById(avisId)).thenReturn(Optional.of(avis));
|
||||
|
||||
Optional<AvisDTO> result = avisUseCase.findAvisById(avisId);
|
||||
|
||||
assertTrue(result.isPresent());
|
||||
assertEquals(avisId, result.get().getAvisId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should return empty Optional when ID does not exist")
|
||||
void testFindAvisByIdNotFound() {
|
||||
UUID nonExistentId = UUID.randomUUID();
|
||||
when(avisRepository.findById(nonExistentId)).thenReturn(Optional.empty());
|
||||
|
||||
Optional<AvisDTO> result = avisUseCase.findAvisById(nonExistentId);
|
||||
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.avis.validator;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.AvisInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.exception.NotValidAvisException;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class AvisValidatorTest {
|
||||
|
||||
private final UUID clientId = UUID.randomUUID();
|
||||
private final UUID livreId = UUID.randomUUID();
|
||||
|
||||
private AvisInfo validAvis() {
|
||||
return new AvisInfo(clientId, livreId, 5, "Excellent livre !", LocalDate.of(2024, 1, 15));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should validate avis with valid data")
|
||||
void testValidateValidAvis() {
|
||||
assertDoesNotThrow(() -> AvisValidator.validate(validAvis()));
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("ClientId validation tests")
|
||||
class ClientIdValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when clientId is null")
|
||||
void testValidateNullClientId() {
|
||||
AvisInfo avis = new AvisInfo(null, livreId, 5, "Commentaire", LocalDate.now());
|
||||
|
||||
NotValidAvisException exception = assertThrows(NotValidAvisException.class,
|
||||
() -> AvisValidator.validate(avis));
|
||||
|
||||
assertEquals(AvisValidator.CLIENT_ID_CANNOT_BE_NULL, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("LivreId validation tests")
|
||||
class LivreIdValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when livreId is null")
|
||||
void testValidateNullLivreId() {
|
||||
AvisInfo avis = new AvisInfo(clientId, null, 5, "Commentaire", LocalDate.now());
|
||||
|
||||
NotValidAvisException exception = assertThrows(NotValidAvisException.class,
|
||||
() -> AvisValidator.validate(avis));
|
||||
|
||||
assertEquals(AvisValidator.LIVRE_ID_CANNOT_BE_NULL, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Note validation tests")
|
||||
class NoteValidationTests {
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {1, 2, 3, 4, 5})
|
||||
@DisplayName("Should validate when note is between 1 and 5")
|
||||
void testValidateValidNote(int validNote) {
|
||||
AvisInfo avis = new AvisInfo(clientId, livreId, validNote, "Commentaire", LocalDate.now());
|
||||
assertDoesNotThrow(() -> AvisValidator.validate(avis));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {0, -1, 6, 10})
|
||||
@DisplayName("Should throw exception when note is out of range")
|
||||
void testValidateInvalidNote(int invalidNote) {
|
||||
AvisInfo avis = new AvisInfo(clientId, livreId, invalidNote, "Commentaire", LocalDate.now());
|
||||
|
||||
NotValidAvisException exception = assertThrows(NotValidAvisException.class,
|
||||
() -> AvisValidator.validate(avis));
|
||||
|
||||
assertEquals(AvisValidator.NOTE_MUST_BE_BETWEEN_1_AND_5, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Commentaire validation tests")
|
||||
class CommentaireValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when commentaire is blank")
|
||||
void testValidateBlankCommentaire() {
|
||||
AvisInfo avis = new AvisInfo(clientId, livreId, 5, "", LocalDate.now());
|
||||
|
||||
NotValidAvisException exception = assertThrows(NotValidAvisException.class,
|
||||
() -> AvisValidator.validate(avis));
|
||||
|
||||
assertEquals(AvisValidator.COMMENTAIRE_CANNOT_BE_BLANK, exception.getMessage());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {" ", " ", "\t", "\n"})
|
||||
@DisplayName("Should throw exception when commentaire contains only whitespace")
|
||||
void testValidateWhitespaceCommentaire(String whitespace) {
|
||||
AvisInfo avis = new AvisInfo(clientId, livreId, 5, whitespace, LocalDate.now());
|
||||
|
||||
NotValidAvisException exception = assertThrows(NotValidAvisException.class,
|
||||
() -> AvisValidator.validate(avis));
|
||||
|
||||
assertEquals(AvisValidator.COMMENTAIRE_CANNOT_BE_BLANK, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("DateAchat validation tests")
|
||||
class DateAchatValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when dateAchat is null")
|
||||
void testValidateNullDateAchat() {
|
||||
AvisInfo avis = new AvisInfo(clientId, livreId, 5, "Commentaire", null);
|
||||
|
||||
NotValidAvisException exception = assertThrows(NotValidAvisException.class,
|
||||
() -> AvisValidator.validate(avis));
|
||||
|
||||
assertEquals(AvisValidator.DATE_ACHAT_CANNOT_BE_NULL, exception.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.avis.converter;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.AvisDTO;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.AvisInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.entity.Avis;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@DisplayName("AvisConverter Unit Tests")
|
||||
class AvisConverterTest {
|
||||
|
||||
private final UUID clientId = UUID.randomUUID();
|
||||
private final UUID livreId = UUID.randomUUID();
|
||||
|
||||
@Nested
|
||||
@DisplayName("toDomain() method tests")
|
||||
class ToDomainTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should convert AvisInfo to Avis domain object")
|
||||
void shouldConvertAvisInfoToDomain() {
|
||||
AvisInfo avisInfo = new AvisInfo(
|
||||
clientId, livreId, 5, "Excellent livre !", LocalDate.of(2024, 1, 15)
|
||||
);
|
||||
|
||||
Avis result = AvisConverter.toDomain(avisInfo);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(clientId, result.getClientId());
|
||||
assertEquals(livreId, result.getLivreId());
|
||||
assertEquals(5, result.getNote());
|
||||
assertEquals("Excellent livre !", result.getCommentaire());
|
||||
assertEquals(LocalDate.of(2024, 1, 15), result.getDateAchat());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should have null ID after toDomain (set by repository)")
|
||||
void shouldHaveNullIdAfterToDomain() {
|
||||
AvisInfo avisInfo = new AvisInfo(clientId, livreId, 3, "Commentaire", LocalDate.now());
|
||||
|
||||
Avis result = AvisConverter.toDomain(avisInfo);
|
||||
|
||||
assertNull(result.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("toDTO() method tests")
|
||||
class ToDTOTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should convert Avis domain object to AvisDTO")
|
||||
void shouldConvertAvisToDTO() {
|
||||
UUID avisId = UUID.randomUUID();
|
||||
Avis avis = Avis.builder()
|
||||
.id(avisId)
|
||||
.clientId(clientId)
|
||||
.livreId(livreId)
|
||||
.note(5)
|
||||
.commentaire("Excellent !")
|
||||
.dateAchat(LocalDate.of(2024, 1, 15))
|
||||
.build();
|
||||
|
||||
AvisDTO result = AvisConverter.toDTO(avis);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(avisId, result.getAvisId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.avis.entity;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class AvisTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Builder should create a valid Avis instance")
|
||||
void testAvisBuilder() {
|
||||
UUID id = UUID.randomUUID();
|
||||
UUID clientId = UUID.randomUUID();
|
||||
UUID livreId = UUID.randomUUID();
|
||||
|
||||
Avis avis = Avis.builder()
|
||||
.id(id)
|
||||
.clientId(clientId)
|
||||
.livreId(livreId)
|
||||
.note(5)
|
||||
.commentaire("Excellent livre !")
|
||||
.dateAchat(LocalDate.of(2024, 1, 15))
|
||||
.build();
|
||||
|
||||
assertEquals(id, avis.getId());
|
||||
assertEquals(clientId, avis.getClientId());
|
||||
assertEquals(livreId, avis.getLivreId());
|
||||
assertEquals(5, avis.getNote());
|
||||
assertEquals("Excellent livre !", avis.getCommentaire());
|
||||
assertEquals(LocalDate.of(2024, 1, 15), avis.getDateAchat());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("setRandomUUID should set a new non-null UUID")
|
||||
void testSetRandomUUID() {
|
||||
Avis avis = Avis.builder().build();
|
||||
UUID originalId = avis.getId();
|
||||
|
||||
avis.setRandomUUID();
|
||||
|
||||
assertNotNull(avis.getId());
|
||||
assertNotEquals(originalId, avis.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Two setRandomUUID calls should produce different UUIDs")
|
||||
void testSetRandomUUIDTwice() {
|
||||
Avis avis = Avis.builder().build();
|
||||
avis.setRandomUUID();
|
||||
UUID firstId = avis.getId();
|
||||
|
||||
avis.setRandomUUID();
|
||||
|
||||
assertNotEquals(firstId, avis.getId());
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.avis.exception;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class AvisNotFoundExceptionTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception message should contain the UUID provided")
|
||||
void testExceptionMessageContainsUUID() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
|
||||
AvisNotFoundException exception = new AvisNotFoundException(uuid);
|
||||
|
||||
String expectedMessage = String.format("The avis with id %s does not exist", uuid);
|
||||
assertEquals(expectedMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should use the correct constant message format")
|
||||
void testExceptionUsesConstantMessageFormat() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
|
||||
AvisNotFoundException exception = new AvisNotFoundException(uuid);
|
||||
|
||||
assertEquals("The avis with id {0} does not exist",
|
||||
AvisNotFoundException.THE_AVIS_WITH_ID_DOES_NOT_EXIST_MESSAGE);
|
||||
assertTrue(exception.getMessage().contains(uuid.toString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should be properly thrown and caught")
|
||||
void testExceptionCanBeThrownAndCaught() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
|
||||
try {
|
||||
throw new AvisNotFoundException(uuid);
|
||||
} catch (AvisNotFoundException e) {
|
||||
assertTrue(e.getMessage().contains(uuid.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.avis.exception;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
class NotValidAvisExceptionTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should be created with the provided message")
|
||||
void testExceptionCreation() {
|
||||
String errorMessage = "Note must be between 1 and 5";
|
||||
|
||||
NotValidAvisException exception = new NotValidAvisException(errorMessage);
|
||||
|
||||
assertEquals(errorMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"Note must be between 1 and 5",
|
||||
"Commentaire cannot be blank",
|
||||
"Client id cannot be null",
|
||||
"Livre id cannot be null",
|
||||
"Date achat cannot be null"
|
||||
})
|
||||
@DisplayName("Exception should handle different validation messages")
|
||||
void testExceptionWithDifferentMessages(String errorMessage) {
|
||||
NotValidAvisException exception = new NotValidAvisException(errorMessage);
|
||||
|
||||
assertEquals(errorMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should be properly thrown and caught")
|
||||
void testExceptionCanBeThrownAndCaught() {
|
||||
String errorMessage = "Note must be between 1 and 5";
|
||||
|
||||
Exception exception = assertThrows(NotValidAvisException.class, () -> {
|
||||
throw new NotValidAvisException(errorMessage);
|
||||
});
|
||||
|
||||
assertEquals(errorMessage, exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Exception should be catchable as a general Exception")
|
||||
void testExceptionInheritance() {
|
||||
String errorMessage = "Commentaire cannot be blank";
|
||||
|
||||
try {
|
||||
throw new NotValidAvisException(errorMessage);
|
||||
} catch (Exception e) {
|
||||
assertEquals(NotValidAvisException.class, e.getClass());
|
||||
assertEquals(errorMessage, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.avis.repository;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.entity.Avis;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class AvisRepositoryTest {
|
||||
|
||||
private AvisRepository repository;
|
||||
private Avis avis1;
|
||||
private Avis avis2;
|
||||
private UUID clientId1;
|
||||
private UUID livreId1;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
repository = new AvisRepository();
|
||||
clientId1 = UUID.randomUUID();
|
||||
livreId1 = UUID.randomUUID();
|
||||
|
||||
avis1 = Avis.builder()
|
||||
.clientId(clientId1)
|
||||
.livreId(livreId1)
|
||||
.note(5)
|
||||
.commentaire("Excellent livre !")
|
||||
.dateAchat(LocalDate.of(2024, 1, 15))
|
||||
.build();
|
||||
avis1.setRandomUUID();
|
||||
|
||||
avis2 = Avis.builder()
|
||||
.clientId(UUID.randomUUID())
|
||||
.livreId(livreId1)
|
||||
.note(3)
|
||||
.commentaire("Pas mal")
|
||||
.dateAchat(LocalDate.of(2024, 2, 10))
|
||||
.build();
|
||||
avis2.setRandomUUID();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("New repository should be empty")
|
||||
void testNewRepositoryIsEmpty() {
|
||||
assertTrue(repository.findAll().isEmpty());
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Save operations")
|
||||
class SaveOperations {
|
||||
|
||||
@Test
|
||||
@DisplayName("Save should add a new avis")
|
||||
void testSaveNewAvis() {
|
||||
Avis saved = repository.save(avis1);
|
||||
|
||||
assertEquals(1, repository.findAll().size());
|
||||
assertEquals(avis1.getId(), saved.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Save should update existing avis with same ID")
|
||||
void testSaveUpdatesExistingAvis() {
|
||||
repository.save(avis1);
|
||||
UUID id = avis1.getId();
|
||||
|
||||
Avis updated = Avis.builder()
|
||||
.id(id)
|
||||
.clientId(clientId1)
|
||||
.livreId(livreId1)
|
||||
.note(3)
|
||||
.commentaire("Finalement moyen")
|
||||
.dateAchat(LocalDate.of(2024, 1, 15))
|
||||
.build();
|
||||
|
||||
Avis saved = repository.save(updated);
|
||||
|
||||
assertEquals(1, repository.findAll().size());
|
||||
assertEquals(id, saved.getId());
|
||||
assertEquals(3, saved.getNote());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Save multiple avis should add all of them")
|
||||
void testSaveMultipleAvis() {
|
||||
repository.save(avis1);
|
||||
repository.save(avis2);
|
||||
|
||||
assertEquals(2, repository.findAll().size());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Find operations")
|
||||
class FindOperations {
|
||||
|
||||
@BeforeEach
|
||||
void setUpAvis() {
|
||||
repository.save(avis1);
|
||||
repository.save(avis2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindById should return avis with matching ID")
|
||||
void testFindById() {
|
||||
Optional<Avis> found = repository.findById(avis1.getId());
|
||||
|
||||
assertTrue(found.isPresent());
|
||||
assertEquals(avis1.getId(), found.get().getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindById should return empty Optional when ID doesn't exist")
|
||||
void testFindByIdNotFound() {
|
||||
Optional<Avis> found = repository.findById(UUID.randomUUID());
|
||||
|
||||
assertTrue(found.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindByLivreId should return all avis for a book")
|
||||
void testFindByLivreId() {
|
||||
List<Avis> found = repository.findByLivreId(livreId1);
|
||||
|
||||
assertEquals(2, found.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("FindByClientId should return all avis for a client")
|
||||
void testFindByClientId() {
|
||||
List<Avis> found = repository.findByClientId(clientId1);
|
||||
|
||||
assertEquals(1, found.size());
|
||||
assertEquals(avis1.getId(), found.getFirst().getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ExistsById should return true when ID exists")
|
||||
void testExistsByIdExists() {
|
||||
assertTrue(repository.existsById(avis1.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ExistsById should return false when ID doesn't exist")
|
||||
void testExistsByIdNotExists() {
|
||||
assertFalse(repository.existsById(UUID.randomUUID()));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Delete operations")
|
||||
class DeleteOperations {
|
||||
|
||||
@BeforeEach
|
||||
void setUpAvis() {
|
||||
repository.save(avis1);
|
||||
repository.save(avis2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Delete should remove the specified avis")
|
||||
void testDelete() {
|
||||
repository.delete(avis1);
|
||||
|
||||
assertEquals(1, repository.findAll().size());
|
||||
assertFalse(repository.findAll().contains(avis1));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("DeleteAll should remove all avis")
|
||||
void testDeleteAll() {
|
||||
repository.deleteAll();
|
||||
|
||||
assertTrue(repository.findAll().isEmpty());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.avis.usecase;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.AvisDTO;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.AvisInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.entity.Avis;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.exception.NotValidAvisException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.repository.AvisRepository;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.entity.Customer;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.exception.CustomerNotFoundException;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.customer.repository.CustomerRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class AvisUseCaseTest {
|
||||
|
||||
@Mock
|
||||
private AvisRepository avisRepository;
|
||||
|
||||
@Mock
|
||||
private CustomerRepository customerRepository;
|
||||
|
||||
@InjectMocks
|
||||
private AvisUseCase avisUseCase;
|
||||
|
||||
private UUID clientId;
|
||||
private UUID livreId;
|
||||
private Customer testCustomer;
|
||||
private AvisInfo validAvisInfo;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
clientId = UUID.randomUUID();
|
||||
livreId = UUID.randomUUID();
|
||||
|
||||
testCustomer = Customer.builder()
|
||||
.id(clientId)
|
||||
.firstName("Marie")
|
||||
.lastName("Dupont")
|
||||
.phoneNumber("0612345678")
|
||||
.loyaltyPoints(100)
|
||||
.build();
|
||||
|
||||
validAvisInfo = new AvisInfo(clientId, livreId, 5, "Excellent livre !", LocalDate.of(2024, 1, 15));
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("GererAvis tests")
|
||||
class GererAvisTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should create avis when valid data is provided")
|
||||
void testGererAvisWithValidData() throws NotValidAvisException, CustomerNotFoundException {
|
||||
when(customerRepository.findById(clientId)).thenReturn(Optional.of(testCustomer));
|
||||
|
||||
UUID avisId = UUID.randomUUID();
|
||||
Avis savedAvis = Avis.builder()
|
||||
.id(avisId)
|
||||
.clientId(clientId)
|
||||
.livreId(livreId)
|
||||
.note(5)
|
||||
.commentaire("Excellent livre !")
|
||||
.dateAchat(LocalDate.of(2024, 1, 15))
|
||||
.build();
|
||||
when(avisRepository.save(any(Avis.class))).thenReturn(savedAvis);
|
||||
|
||||
AvisDTO result = avisUseCase.gererAvis(validAvisInfo);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(avisId, result.getAvisId());
|
||||
verify(avisRepository, times(1)).save(any(Avis.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when customer does not exist")
|
||||
void testGererAvisWithUnknownCustomer() {
|
||||
when(customerRepository.findById(clientId)).thenReturn(Optional.empty());
|
||||
|
||||
assertThrows(CustomerNotFoundException.class,
|
||||
() -> avisUseCase.gererAvis(validAvisInfo));
|
||||
|
||||
verify(avisRepository, never()).save(any(Avis.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when note is invalid")
|
||||
void testGererAvisWithInvalidNote() {
|
||||
AvisInfo invalidAvis = new AvisInfo(clientId, livreId, 6, "Commentaire", LocalDate.now());
|
||||
|
||||
assertThrows(NotValidAvisException.class,
|
||||
() -> avisUseCase.gererAvis(invalidAvis));
|
||||
|
||||
verify(avisRepository, never()).save(any(Avis.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when commentaire is blank")
|
||||
void testGererAvisWithBlankCommentaire() {
|
||||
AvisInfo invalidAvis = new AvisInfo(clientId, livreId, 5, "", LocalDate.now());
|
||||
|
||||
assertThrows(NotValidAvisException.class,
|
||||
() -> avisUseCase.gererAvis(invalidAvis));
|
||||
|
||||
verify(avisRepository, never()).save(any(Avis.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when clientId is null")
|
||||
void testGererAvisWithNullClientId() {
|
||||
AvisInfo invalidAvis = new AvisInfo(null, livreId, 5, "Commentaire", LocalDate.now());
|
||||
|
||||
assertThrows(NotValidAvisException.class,
|
||||
() -> avisUseCase.gererAvis(invalidAvis));
|
||||
|
||||
verify(avisRepository, never()).save(any(Avis.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("FindAvis tests")
|
||||
class FindAvisTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should return avis when ID exists")
|
||||
void testFindAvisById() {
|
||||
UUID avisId = UUID.randomUUID();
|
||||
Avis avis = Avis.builder()
|
||||
.id(avisId)
|
||||
.clientId(clientId)
|
||||
.livreId(livreId)
|
||||
.note(5)
|
||||
.commentaire("Excellent !")
|
||||
.dateAchat(LocalDate.now())
|
||||
.build();
|
||||
|
||||
when(avisRepository.findById(avisId)).thenReturn(Optional.of(avis));
|
||||
|
||||
Optional<AvisDTO> result = avisUseCase.findAvisById(avisId);
|
||||
|
||||
assertTrue(result.isPresent());
|
||||
assertEquals(avisId, result.get().getAvisId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should return empty Optional when ID does not exist")
|
||||
void testFindAvisByIdNotFound() {
|
||||
UUID nonExistentId = UUID.randomUUID();
|
||||
when(avisRepository.findById(nonExistentId)).thenReturn(Optional.empty());
|
||||
|
||||
Optional<AvisDTO> result = avisUseCase.findAvisById(nonExistentId);
|
||||
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
package fr.iut_fbleau.but3.dev62.mylibrary.avis.validator;
|
||||
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.AvisInfo;
|
||||
import fr.iut_fbleau.but3.dev62.mylibrary.avis.exception.NotValidAvisException;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class AvisValidatorTest {
|
||||
|
||||
private final UUID clientId = UUID.randomUUID();
|
||||
private final UUID livreId = UUID.randomUUID();
|
||||
|
||||
private AvisInfo validAvis() {
|
||||
return new AvisInfo(clientId, livreId, 5, "Excellent livre !", LocalDate.of(2024, 1, 15));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Should validate avis with valid data")
|
||||
void testValidateValidAvis() {
|
||||
assertDoesNotThrow(() -> AvisValidator.validate(validAvis()));
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("ClientId validation tests")
|
||||
class ClientIdValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when clientId is null")
|
||||
void testValidateNullClientId() {
|
||||
AvisInfo avis = new AvisInfo(null, livreId, 5, "Commentaire", LocalDate.now());
|
||||
|
||||
NotValidAvisException exception = assertThrows(NotValidAvisException.class,
|
||||
() -> AvisValidator.validate(avis));
|
||||
|
||||
assertEquals(AvisValidator.CLIENT_ID_CANNOT_BE_NULL, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("LivreId validation tests")
|
||||
class LivreIdValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when livreId is null")
|
||||
void testValidateNullLivreId() {
|
||||
AvisInfo avis = new AvisInfo(clientId, null, 5, "Commentaire", LocalDate.now());
|
||||
|
||||
NotValidAvisException exception = assertThrows(NotValidAvisException.class,
|
||||
() -> AvisValidator.validate(avis));
|
||||
|
||||
assertEquals(AvisValidator.LIVRE_ID_CANNOT_BE_NULL, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Note validation tests")
|
||||
class NoteValidationTests {
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {1, 2, 3, 4, 5})
|
||||
@DisplayName("Should validate when note is between 1 and 5")
|
||||
void testValidateValidNote(int validNote) {
|
||||
AvisInfo avis = new AvisInfo(clientId, livreId, validNote, "Commentaire", LocalDate.now());
|
||||
assertDoesNotThrow(() -> AvisValidator.validate(avis));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {0, -1, 6, 10})
|
||||
@DisplayName("Should throw exception when note is out of range")
|
||||
void testValidateInvalidNote(int invalidNote) {
|
||||
AvisInfo avis = new AvisInfo(clientId, livreId, invalidNote, "Commentaire", LocalDate.now());
|
||||
|
||||
NotValidAvisException exception = assertThrows(NotValidAvisException.class,
|
||||
() -> AvisValidator.validate(avis));
|
||||
|
||||
assertEquals(AvisValidator.NOTE_MUST_BE_BETWEEN_1_AND_5, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Commentaire validation tests")
|
||||
class CommentaireValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when commentaire is blank")
|
||||
void testValidateBlankCommentaire() {
|
||||
AvisInfo avis = new AvisInfo(clientId, livreId, 5, "", LocalDate.now());
|
||||
|
||||
NotValidAvisException exception = assertThrows(NotValidAvisException.class,
|
||||
() -> AvisValidator.validate(avis));
|
||||
|
||||
assertEquals(AvisValidator.COMMENTAIRE_CANNOT_BE_BLANK, exception.getMessage());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {" ", " ", "\t", "\n"})
|
||||
@DisplayName("Should throw exception when commentaire contains only whitespace")
|
||||
void testValidateWhitespaceCommentaire(String whitespace) {
|
||||
AvisInfo avis = new AvisInfo(clientId, livreId, 5, whitespace, LocalDate.now());
|
||||
|
||||
NotValidAvisException exception = assertThrows(NotValidAvisException.class,
|
||||
() -> AvisValidator.validate(avis));
|
||||
|
||||
assertEquals(AvisValidator.COMMENTAIRE_CANNOT_BE_BLANK, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("DateAchat validation tests")
|
||||
class DateAchatValidationTests {
|
||||
|
||||
@Test
|
||||
@DisplayName("Should throw exception when dateAchat is null")
|
||||
void testValidateNullDateAchat() {
|
||||
AvisInfo avis = new AvisInfo(clientId, livreId, 5, "Commentaire", null);
|
||||
|
||||
NotValidAvisException exception = assertThrows(NotValidAvisException.class,
|
||||
() -> AvisValidator.validate(avis));
|
||||
|
||||
assertEquals(AvisValidator.DATE_ACHAT_CANNOT_BE_NULL, exception.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
# language: en
|
||||
|
||||
Feature: Manage customer reviews
|
||||
|
||||
Background:
|
||||
Given the system has the following customers for avis:
|
||||
| prenom | nom | numeroTelephone | pointsFidelite |
|
||||
| Marie | Dupont | 0612345678 | 100 |
|
||||
| Jean | Martin | 0687654321 | 50 |
|
||||
And the catalog has the following books for avis:
|
||||
| isbn | titre | auteur | editeur | datePublication | prix | stockInitial | categories | description | langue |
|
||||
| 9782016289308 | Le Petit Prince | Antoine de Saint-Exupery | Gallimard | 1943-04-06 | 12.90 | 10 | Roman | Un classique | FR |
|
||||
| 9782070409189 | L Etranger | Albert Camus | Gallimard | 1942-05-19 | 9.50 | 5 | Roman | Philosophique| FR |
|
||||
|
||||
Scenario: Submit a valid review
|
||||
When customer "0612345678" submits a review for book "9782016289308" with:
|
||||
| note | commentaire | dateAchat |
|
||||
| 5 | Excellent livre ! | 2024-01-15 |
|
||||
Then a new review is created
|
||||
And the system now has 1 reviews
|
||||
|
||||
Scenario: Submit a review with minimum note
|
||||
When customer "0687654321" submits a review for book "9782070409189" with:
|
||||
| note | commentaire | dateAchat |
|
||||
| 1 | Pas mon style | 2024-02-10 |
|
||||
Then a new review is created
|
||||
And the system now has 1 reviews
|
||||
|
||||
Scenario: Attempt to submit a review with invalid note too high
|
||||
When customer "0612345678" tries to submit a review for book "9782016289308" with:
|
||||
| note | commentaire | dateAchat |
|
||||
| 6 | Trop bien ! | 2024-01-15 |
|
||||
Then the review creation fails
|
||||
And I receive a validation avis error containing "Note must be between 1 and 5"
|
||||
|
||||
Scenario: Attempt to submit a review with invalid note too low
|
||||
When customer "0612345678" tries to submit a review for book "9782016289308" with:
|
||||
| note | commentaire | dateAchat |
|
||||
| 0 | Nul ! | 2024-01-15 |
|
||||
Then the review creation fails
|
||||
And I receive a validation avis error containing "Note must be between 1 and 5"
|
||||
|
||||
Scenario: Attempt to submit a review with blank comment
|
||||
When customer "0612345678" tries to submit a review for book "9782016289308" with:
|
||||
| note | commentaire | dateAchat |
|
||||
| 4 | | 2024-01-15 |
|
||||
Then the review creation fails
|
||||
And I receive a validation avis error containing "Commentaire cannot be blank"
|
||||
|
||||
Scenario: Attempt to submit a review for unknown customer
|
||||
When an unknown customer tries to submit a review for book "9782016289308" with:
|
||||
| note | commentaire | dateAchat |
|
||||
| 4 | Bon livre | 2024-01-15 |
|
||||
Then the review creation fails with customer not found
|
||||
Reference in New Issue
Block a user