diff --git a/src/test/java/fr/iut_fbleau/but3/dev62/mylibrary/features/avis/AvisSteps.java b/src/test/java/fr/iut_fbleau/but3/dev62/mylibrary/features/avis/AvisSteps.java new file mode 100644 index 0000000..b71b08e --- /dev/null +++ b/src/test/java/fr/iut_fbleau/but3/dev62/mylibrary/features/avis/AvisSteps.java @@ -0,0 +1,185 @@ +package fr.iut_fbleau.but3.dev62.mylibrary.features.avis; + +import static org.junit.jupiter.api.Assertions.*; + +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.exception.NotValidAvisException; +import fr.iut_fbleau.but3.dev62.mylibrary.avis.repository.AvisRepository; +import fr.iut_fbleau.but3.dev62.mylibrary.avis.usecase.AvisUseCase; +import fr.iut_fbleau.but3.dev62.mylibrary.book.entity.Book; +import fr.iut_fbleau.but3.dev62.mylibrary.book.repository.BookRepository; +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 io.cucumber.datatable.DataTable; +import io.cucumber.java.Before; +import io.cucumber.java.en.And; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +public class AvisSteps { + + private final CustomerRepository customerRepository = new CustomerRepository(); + private final BookRepository bookRepository = new BookRepository(); + private final AvisRepository avisRepository = new AvisRepository(); + private final AvisUseCase avisUseCase = new AvisUseCase(avisRepository, customerRepository); + + private final Map customerPhoneUUID = new HashMap<>(); + private final Map bookIsbnUUID = new HashMap<>(); + + private AvisDTO avisResult; + private NotValidAvisException notValidAvisException; + private boolean customerNotFoundThrown = false; + + @Before + public void setUp() { + customerRepository.deleteAll(); + bookRepository.deleteAll(); + avisRepository.deleteAll(); + customerPhoneUUID.clear(); + bookIsbnUUID.clear(); + avisResult = null; + notValidAvisException = null; + customerNotFoundThrown = false; + } + + @Given("the system has the following customers for avis:") + public void theSystemHasTheFollowingCustomersForAvis(DataTable dataTable) { + List> customers = dataTable.asMaps(String.class, String.class); + + for (Map customer : customers) { + String phone = customer.get("numeroTelephone"); + Customer newCustomer = Customer.builder() + .firstName(customer.get("prenom")) + .lastName(customer.get("nom")) + .phoneNumber(phone) + .loyaltyPoints(Integer.parseInt(customer.get("pointsFidelite"))) + .build(); + Customer saved = customerRepository.save(newCustomer); + customerPhoneUUID.put(phone, saved.getId()); + } + + assertEquals(customers.size(), customerRepository.findAll().size()); + } + + @And("the catalog has the following books for avis:") + public void theCatalogHasTheFollowingBooksForAvis(DataTable dataTable) { + List> books = dataTable.asMaps(String.class, String.class); + + for (Map book : books) { + String isbn = book.get("isbn"); + Book newBook = Book.builder() + .isbn(isbn) + .title(book.get("titre")) + .author(book.get("auteur")) + .publisher(book.get("editeur")) + .publicationDate(LocalDate.parse(book.get("datePublication"))) + .price(new BigDecimal(book.get("prix"))) + .stock(Integer.parseInt(book.get("stockInitial"))) + .categories(List.of(book.get("categories").split(";"))) + .description(book.get("description")) + .language(book.get("langue")) + .build(); + Book saved = bookRepository.save(newBook); + bookIsbnUUID.put(isbn, saved.getId()); + } + + assertEquals(books.size(), bookRepository.findAll().size()); + } + + @When("customer {string} submits a review for book {string} with:") + public void customerSubmitsAReviewForBookWith(String phoneNumber, String isbn, DataTable dataTable) + throws NotValidAvisException, CustomerNotFoundException { + Map row = dataTable.asMaps(String.class, String.class).getFirst(); + + UUID customerId = customerPhoneUUID.get(phoneNumber); + UUID livreId = bookIsbnUUID.get(isbn); + + AvisInfo avisInfo = new AvisInfo( + customerId, + livreId, + Integer.parseInt(row.get("note")), + row.get("commentaire"), + LocalDate.parse(row.get("dateAchat")) + ); + + avisResult = avisUseCase.gererAvis(avisInfo); + } + + @Then("a new review is created") + public void aNewReviewIsCreated() { + assertNotNull(avisResult); + assertNotNull(avisResult.getAvisId()); + } + + @And("the system now has {int} reviews") + public void theSystemNowHasReviews(int expectedCount) { + assertEquals(expectedCount, avisRepository.findAll().size()); + } + + @When("customer {string} tries to submit a review for book {string} with:") + public void customerTriesToSubmitAReviewForBookWith(String phoneNumber, String isbn, DataTable dataTable) { + Map row = dataTable.asMaps(String.class, String.class).getFirst(); + + UUID customerId = customerPhoneUUID.get(phoneNumber); + UUID livreId = bookIsbnUUID.get(isbn); + + AvisInfo avisInfo = new AvisInfo( + customerId, + livreId, + Integer.parseInt(row.get("note")), + row.get("commentaire"), + LocalDate.parse(row.get("dateAchat")) + ); + + notValidAvisException = assertThrows(NotValidAvisException.class, + () -> avisUseCase.gererAvis(avisInfo)); + } + + @When("an unknown customer tries to submit a review for book {string} with:") + public void anUnknownCustomerTriesToSubmitAReviewForBookWith(String isbn, DataTable dataTable) { + Map row = dataTable.asMaps(String.class, String.class).getFirst(); + + UUID unknownId = UUID.randomUUID(); + UUID livreId = bookIsbnUUID.get(isbn); + + AvisInfo avisInfo = new AvisInfo( + unknownId, + livreId, + Integer.parseInt(row.get("note")), + row.get("commentaire"), + LocalDate.parse(row.get("dateAchat")) + ); + + try { + avisUseCase.gererAvis(avisInfo); + } catch (CustomerNotFoundException e) { + customerNotFoundThrown = true; + } catch (NotValidAvisException e) { + notValidAvisException = e; + } + } + + @Then("the review creation fails") + public void theReviewCreationFails() { + assertNotNull(notValidAvisException); + } + + @Then("the review creation fails with customer not found") + public void theReviewCreationFailsWithCustomerNotFound() { + assertTrue(customerNotFoundThrown); + } + + @And("I receive a validation avis error containing {string}") + public void iReceiveAValidationAvisErrorContaining(String errorMessage) { + assertEquals(errorMessage, notValidAvisException.getMessage()); + } +} \ No newline at end of file diff --git a/src/test/resources/features/avis.feature b/src/test/resources/features/avis.feature new file mode 100644 index 0000000..24e6950 --- /dev/null +++ b/src/test/resources/features/avis.feature @@ -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