diff --git a/rent-service/build.gradle b/rent-service/build.gradle index 753c3ca..485f3d7 100644 --- a/rent-service/build.gradle +++ b/rent-service/build.gradle @@ -15,6 +15,8 @@ dependencies { implementation 'org.postgresql:postgresql:42.2.23' annotationProcessor 'org.hibernate:hibernate-jpamodelgen:6.1.6.Final' + testImplementation 'io.github.benas:random-beans:3.9.0' + intTestImplementation 'org.testcontainers:testcontainers:1.16.0' intTestImplementation 'org.testcontainers:junit-jupiter:1.16.0' intTestImplementation 'org.testcontainers:postgresql:1.16.0' diff --git a/rent-service/src/int-test/java/it/vincenzocorso/carsharing/rentservice/adapters/persistence/jpa/RentJPARepositoryAdapterIntegrationTest.java b/rent-service/src/int-test/java/it/vincenzocorso/carsharing/rentservice/adapters/persistence/jpa/RentJPARepositoryAdapterIntegrationTest.java index 0c4bff1..5d362dc 100644 --- a/rent-service/src/int-test/java/it/vincenzocorso/carsharing/rentservice/adapters/persistence/jpa/RentJPARepositoryAdapterIntegrationTest.java +++ b/rent-service/src/int-test/java/it/vincenzocorso/carsharing/rentservice/adapters/persistence/jpa/RentJPARepositoryAdapterIntegrationTest.java @@ -1,7 +1,7 @@ package it.vincenzocorso.carsharing.rentservice.adapters.persistence.jpa; import it.vincenzocorso.carsharing.rentservice.adapters.persistence.RentWrapper; -import it.vincenzocorso.carsharing.rentservice.domain.FakeRent; +import it.vincenzocorso.carsharing.rentservice.domain.models.RandomRent; import it.vincenzocorso.carsharing.rentservice.domain.models.Rent; import it.vincenzocorso.carsharing.rentservice.domain.models.RentState; import it.vincenzocorso.carsharing.rentservice.domain.models.SearchRentCriteria; @@ -15,13 +15,14 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; -import static it.vincenzocorso.carsharing.rentservice.domain.FakeRent.*; +import static it.vincenzocorso.carsharing.rentservice.domain.models.RandomRent.randomRent; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; @@ -54,18 +55,23 @@ void cleanUp() { @Test void shouldSave() { - Rent rent = rentInState(RentState.STARTED); + Rent rent = randomRent(); + rent.setId(null); + Rent savedRent = this.rentJPARepositoryAdapter.save(rent); - rent.setId(savedRent.getId()); assertThat(this.rentRepository.count()).isEqualTo(1); assertThat(savedRent).isInstanceOf(RentWrapper.class); - assertEqualsWithRent(rent, savedRent); + assertThat(((RentWrapper)savedRent).getVersion()).isZero(); + assertThat(savedRent) + .usingRecursiveComparison() + .ignoringFields("id", "version") + .isEqualTo(rent); } @Test void shouldGenerateUUID() { - Rent newRent = rentInState(RentState.PENDING); + Rent newRent = randomRent(); newRent.setId(null); Rent savedRent = this.rentJPARepositoryAdapter.save(newRent); @@ -86,14 +92,16 @@ void shouldFindAllRents() { @Test void shouldFindRentById() { - Rent savedRent = this.rentJPARepositoryAdapter.save(rentInState(RentState.STARTED)); + Rent savedRent = this.rentJPARepositoryAdapter.save(randomRent()); Optional optionalRent = this.rentJPARepositoryAdapter.findById(savedRent.getId()); assertTrue(optionalRent.isPresent()); Rent retrievedRent = optionalRent.get(); assertThat(retrievedRent).isInstanceOf(RentWrapper.class); - assertEqualsWithRent(savedRent, retrievedRent); + assertThat(retrievedRent) + .usingRecursiveComparison() + .isEqualTo(savedRent); } @Test @@ -111,8 +119,10 @@ void shouldFindRentsByStateCriteria() { @Test void shouldFindRentsByCustomerIdCriteria() { List savedRents = this.initializeRentsTable(); - List expectedRentsIds = savedRents.stream().map(Rent::getId).collect(Collectors.toList()); - SearchRentCriteria searchCriteria = SearchRentCriteria.builder().customerId(CUSTOMER_ID).build(); + Collections.shuffle(savedRents); + Rent expectedRent = savedRents.get(0); + List expectedRentsIds = Stream.of(expectedRent).map(Rent::getId).toList(); + SearchRentCriteria searchCriteria = SearchRentCriteria.builder().customerId(expectedRent.getDetails().customerId()).build(); List retrievedRentsIds = this.rentJPARepositoryAdapter.findByCriteria(searchCriteria).stream().map(Rent::getId).collect(Collectors.toList()); @@ -132,7 +142,7 @@ void shouldFindRentsByPagination() { private List initializeRentsTable() { RentEntityMapper rentMapper = new RentEntityMapper(); return Stream.of(RentState.PENDING, RentState.STARTED, RentState.ENDED) - .map(FakeRent::rentInState) + .map(RandomRent::randomRent) .peek(rent -> rent.setId(null)) .map(rentMapper::convertToEntity) .map(this.rentRepository::save) diff --git a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/persistence/jpa/FakeRentEntity.java b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/persistence/jpa/FakeRentEntity.java deleted file mode 100644 index c19fae8..0000000 --- a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/persistence/jpa/FakeRentEntity.java +++ /dev/null @@ -1,35 +0,0 @@ -package it.vincenzocorso.carsharing.rentservice.adapters.persistence.jpa; - -import it.vincenzocorso.carsharing.rentservice.adapters.persistence.RentWrapper; -import it.vincenzocorso.carsharing.rentservice.domain.models.Rent; -import it.vincenzocorso.carsharing.rentservice.domain.models.RentStateTransition; - -import java.time.ZoneOffset; -import java.util.Optional; -import java.util.UUID; - -import static it.vincenzocorso.carsharing.rentservice.domain.FakeRent.*; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -public class FakeRentEntity { - public static final Long RENT_VERSION = 3L; - public static final Rent RENT_WRAPPER = new RentWrapper(RENT_ID, RENT_DETAILS, ORDERED_STATE_TRANSITIONS, RENT_VERSION); - - public static final RentEntity RENT_ENTITY = new RentEntityMapper().convertToEntity(RENT_WRAPPER); - - public static void assertEqualsWithRent(RentEntity actualRentEntity) { - assertEquals(RENT_ID, Optional.ofNullable(actualRentEntity.getId()).map(UUID::toString).orElse(null)); - assertEquals(CUSTOMER_ID, actualRentEntity.getCustomerId()); - assertEquals(VEHICLE_ID, actualRentEntity.getVehicleId()); - for(RentStateTransition expectedTransition : ORDERED_STATE_TRANSITIONS) { - RentStateTransitionEntity actualTransition = actualRentEntity.getStateTransitions().stream() - .filter(t -> t.getId().getSequenceNumber().equals(expectedTransition.getSequenceNumber())) - .findFirst() - .orElse(null); - assertNotNull(actualTransition); - assertEquals(expectedTransition.getState().toString(), actualTransition.getState()); - assertEquals(expectedTransition.getTimestamp(), actualTransition.getTimestamp().toInstant(ZoneOffset.UTC)); - } - } -} diff --git a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/persistence/jpa/RandomRentEntity.java b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/persistence/jpa/RandomRentEntity.java new file mode 100644 index 0000000..d1c1c8b --- /dev/null +++ b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/persistence/jpa/RandomRentEntity.java @@ -0,0 +1,147 @@ +package it.vincenzocorso.carsharing.rentservice.adapters.persistence.jpa; + +import io.github.benas.randombeans.EnhancedRandomBuilder; +import io.github.benas.randombeans.api.EnhancedRandom; +import it.vincenzocorso.carsharing.rentservice.adapters.persistence.RentWrapper; +import it.vincenzocorso.carsharing.rentservice.domain.models.Rent; +import it.vincenzocorso.carsharing.rentservice.domain.models.RentState; +import it.vincenzocorso.carsharing.rentservice.domain.models.RentStateTransition; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static it.vincenzocorso.carsharing.rentservice.domain.models.RandomRent.randomRent; +import static it.vincenzocorso.carsharing.rentservice.domain.models.RentState.*; +import static it.vincenzocorso.carsharing.rentservice.domain.models.RentState.STARTED; +import static java.time.temporal.ChronoUnit.MINUTES; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class RandomRentEntity { + private static final EnhancedRandom enhancedRandom = EnhancedRandomBuilder.aNewEnhancedRandom(); + + public static RentWrapper randomRentWrapper() { + Rent rent = randomRent(); + Long version = enhancedRandom.nextObject(Long.class); + return new RentWrapper(rent.getId(), rent.getDetails(), rent.getStateTransitions(), version); + } + + public static RentEntity randomRentEntity() { + RentState finalState = enhancedRandom.nextObject(RentState.class); + + RentEntity rentEntity = new RentEntity(); + rentEntity.setId(UUID.randomUUID()); + rentEntity.setCustomerId(enhancedRandom.nextObject(String.class)); + rentEntity.setVehicleId(enhancedRandom.nextObject(String.class)); + rentEntity.setCurrentState(finalState.toString()); + rentEntity.setVersion(enhancedRandom.nextObject(Long.class)); + rentEntity.setStateTransitions(randomRentStateTransitionEntityList(rentEntity, finalState)); + return rentEntity; + } + + public static List randomRentStateTransitionEntityList(RentEntity rentEntity, RentState finalState) { + List transitions = new ArrayList<>(); + int sequenceNumber = 1; + + RentStateTransitionEntity t = new RentStateTransitionEntity(); + t.setId(new RentStateTransitionId(rentEntity, sequenceNumber)); + t.setState(PENDING.toString()); + t.setTimestamp(getFutureInstant(sequenceNumber++)); + transitions.add(t); + if(PENDING.equals(finalState)) { + return transitions; + } + + if(ACCEPTED.equals(finalState) || REJECTED.equals(finalState)) { + t = new RentStateTransitionEntity(); + t.setId(new RentStateTransitionId(rentEntity, sequenceNumber)); + t.setState(finalState.toString()); + t.setTimestamp(getFutureInstant(sequenceNumber)); + transitions.add(t); + return transitions; + } + t = new RentStateTransitionEntity(); + t.setId(new RentStateTransitionId(rentEntity, sequenceNumber)); + t.setState(ACCEPTED.toString()); + t.setTimestamp(getFutureInstant(sequenceNumber++)); + transitions.add(t); + + if(CANCELLED.equals(finalState)) { + t = new RentStateTransitionEntity(); + t.setId(new RentStateTransitionId(rentEntity, sequenceNumber)); + t.setState(finalState.toString()); + t.setTimestamp(getFutureInstant(sequenceNumber)); + transitions.add(t); + return transitions; + } + + t = new RentStateTransitionEntity(); + t.setId(new RentStateTransitionId(rentEntity, sequenceNumber)); + t.setState(STARTED.toString()); + t.setTimestamp(getFutureInstant(sequenceNumber++)); + transitions.add(t); + if(STARTED.equals(finalState)) { + return transitions; + } + + t = new RentStateTransitionEntity(); + t.setId(new RentStateTransitionId(rentEntity, sequenceNumber)); + t.setState(ENDED.toString()); + t.setTimestamp(getFutureInstant(sequenceNumber)); + transitions.add(t); + + return transitions; + } + + private static LocalDateTime getFutureInstant(int sequenceNumber) { + return LocalDateTime.ofInstant(Instant.now() + .minus(10 + (long) (Math.random() * 3000), MINUTES) + .plus(sequenceNumber, MINUTES), ZoneOffset.UTC); + } + + public static void assertEqualsWithRent(Rent expected, RentEntity actual) { + assertEquals(expected.getId(), actual.getId().toString()); + assertEquals(expected.getDetails().customerId(), actual.getCustomerId()); + assertEquals(expected.getDetails().vehicleId(), actual.getVehicleId()); + assertEqualsWithRentStateTransitionList(expected.getStateTransitions(), actual.getStateTransitions()); + if (expected instanceof RentWrapper r) { + assertEquals(r.getVersion(), actual.getVersion()); + } + } + + public static void assertEqualsWithRentStateTransitionList(List expected, List actual) { + assertEquals(expected.size(), actual.size()); + for(int i = 0; i < expected.size(); i++) { + RentStateTransition stateTransition = expected.get(i); + RentStateTransitionEntity stateTransitionEntity = actual.get(i); + + assertEquals(stateTransition.getTimestamp(), stateTransitionEntity.getTimestamp().toInstant(ZoneOffset.UTC)); + assertEquals(stateTransition.getState().toString(), stateTransitionEntity.getState()); + assertEquals(stateTransition.getSequenceNumber(), stateTransitionEntity.getId().getSequenceNumber()); + } + } + + public static void assertEqualsWithRentEntity(RentEntity expected, Rent actual) { + assertEquals(expected.getId().toString(), actual.getId()); + assertEquals(expected.getCustomerId(), actual.getDetails().customerId()); + assertEquals(expected.getVehicleId(), actual.getDetails().vehicleId()); + assertEquals(expected.getCurrentState(), actual.getStateTransitions().get(actual.getStateTransitions().size() - 1).getState().toString()); + assertEquals(expected.getVersion(), actual instanceof RentWrapper r ? r.getVersion() : null); + assertEqualsWithRentStateTransitionEntityList(expected.getStateTransitions(), actual.getStateTransitions()); + } + + public static void assertEqualsWithRentStateTransitionEntityList(List expected, List actual) { + assertEquals(expected.size(), actual.size()); + for(int i = 0; i < expected.size(); i++) { + RentStateTransitionEntity stateTransitionEntity = expected.get(i); + RentStateTransition stateTransition = actual.get(i); + + assertEquals(stateTransitionEntity.getId().getSequenceNumber(), stateTransition.getSequenceNumber()); + assertEquals(stateTransitionEntity.getTimestamp(), LocalDateTime.ofInstant(stateTransition.getTimestamp(), ZoneOffset.UTC)); + assertEquals(stateTransitionEntity.getState(), stateTransition.getState().toString()); + } + } +} diff --git a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/persistence/jpa/RentEntityMapperTest.java b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/persistence/jpa/RentEntityMapperTest.java index 0a2f96f..bc8818f 100644 --- a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/persistence/jpa/RentEntityMapperTest.java +++ b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/persistence/jpa/RentEntityMapperTest.java @@ -4,8 +4,8 @@ import it.vincenzocorso.carsharing.rentservice.domain.models.Rent; import org.junit.jupiter.api.Test; -import static it.vincenzocorso.carsharing.rentservice.adapters.persistence.jpa.FakeRentEntity.*; -import static it.vincenzocorso.carsharing.rentservice.domain.FakeRent.*; +import static it.vincenzocorso.carsharing.rentservice.adapters.persistence.jpa.RandomRentEntity.*; +import static it.vincenzocorso.carsharing.rentservice.domain.models.RandomRent.randomRent; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; @@ -14,25 +14,29 @@ class RentEntityMapperTest { @Test void shouldConvertToEntity() { - RentEntity rentEntity = this.rentEntityMapper.convertToEntity(RENT); + Rent rent = randomRent(); - FakeRentEntity.assertEqualsWithRent(rentEntity); - assertNull(rentEntity.getVersion()); + RentEntity rentEntity = this.rentEntityMapper.convertToEntity(rent); + + assertEqualsWithRent(rent, rentEntity); } @Test void shouldSetEntityVersion() { - RentEntity rentEntity = this.rentEntityMapper.convertToEntity(RENT_WRAPPER); + RentWrapper rentWrapper = randomRentWrapper(); + + RentEntity rentEntity = this.rentEntityMapper.convertToEntity(rentWrapper); - assertEquals(RENT_VERSION, rentEntity.getVersion()); + assertEquals(rentWrapper.getVersion(), rentEntity.getVersion()); } @Test void shouldConvertFromEntity() { - Rent rent = this.rentEntityMapper.convertFromEntity(RENT_ENTITY); + RentEntity rentEntity = randomRentEntity(); + + Rent rent = this.rentEntityMapper.convertFromEntity(rentEntity); assertThat(rent).isInstanceOf(RentWrapper.class); - assertEqualsWithRent(rent); - assertEquals(RENT_VERSION, ((RentWrapper)rent).getVersion()); + assertEqualsWithRentEntity(rentEntity, rent); } } \ No newline at end of file diff --git a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/web/RentControllerTest.java b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/web/RentControllerTest.java index 4fb0a99..1f6b9de 100644 --- a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/web/RentControllerTest.java +++ b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/web/RentControllerTest.java @@ -3,7 +3,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import it.vincenzocorso.carsharing.rentservice.config.WebConfig; import it.vincenzocorso.carsharing.rentservice.domain.exceptions.RentNotFoundException; -import it.vincenzocorso.carsharing.rentservice.domain.models.RentState; +import it.vincenzocorso.carsharing.rentservice.domain.models.Rent; import it.vincenzocorso.carsharing.rentservice.domain.models.SearchRentCriteria; import it.vincenzocorso.carsharing.rentservice.domain.ports.in.RentVehicle; import it.vincenzocorso.carsharing.rentservice.domain.ports.in.SearchRent; @@ -18,8 +18,10 @@ import org.springframework.test.web.servlet.MockMvc; import java.util.List; +import java.util.UUID; -import static it.vincenzocorso.carsharing.rentservice.domain.FakeRent.*; +import static it.vincenzocorso.carsharing.rentservice.domain.models.RandomRent.randomRent; +import static it.vincenzocorso.carsharing.rentservice.domain.models.RentState.*; import static org.hamcrest.Matchers.hasSize; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; @@ -43,19 +45,28 @@ class RentControllerTest { @ParameterizedTest @ValueSource(strings = {"", "?limit=150", "?offset=0", "?states=PENDING,REJECTED,ACCEPTED,STARTED,ENDED"}) void shouldGetRents(String queryParameters) throws Exception { - when(this.searchRent.getRents(any(SearchRentCriteria.class))).thenReturn(List.of(RENT)); + Rent rent1 = randomRent(ENDED); + Rent rent2 = randomRent(PENDING); + when(this.searchRent.getRents(any(SearchRentCriteria.class))).thenReturn(List.of(rent1, rent2)); this.mockMvc.perform(get("/rents" + queryParameters)) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(jsonPath("$").isArray()) - .andExpect(jsonPath("$[0].rentId").value(RENT_ID)) - .andExpect(jsonPath("$[0].customerId").value(CUSTOMER_ID)) - .andExpect(jsonPath("$[0].vehicleId").value(VEHICLE_ID)) - .andExpect(jsonPath("$[0].state").value(TRANSITION_4_STATE.toString())) - .andExpect(jsonPath("$[0].acceptedAt").value(TRANSITION_2_TIMESTAMP.toString())) - .andExpect(jsonPath("$[0].startedAt").value(TRANSITION_3_TIMESTAMP.toString())) - .andExpect(jsonPath("$[0].endedAt").value(TRANSITION_4_TIMESTAMP.toString())); + .andExpect(jsonPath("$[0].rentId").value(rent1.getId())) + .andExpect(jsonPath("$[0].customerId").value(rent1.getDetails().customerId())) + .andExpect(jsonPath("$[0].vehicleId").value(rent1.getDetails().vehicleId())) + .andExpect(jsonPath("$[0].state").value(ENDED.toString())) + .andExpect(jsonPath("$[0].acceptedAt").value(rent1.getStateTransitions().get(1).getTimestamp().toString())) + .andExpect(jsonPath("$[0].startedAt").value(rent1.getStateTransitions().get(2).getTimestamp().toString())) + .andExpect(jsonPath("$[0].endedAt").value(rent1.getStateTransitions().get(3).getTimestamp().toString())) + .andExpect(jsonPath("$[1].rentId").value(rent2.getId())) + .andExpect(jsonPath("$[1].customerId").value(rent2.getDetails().customerId())) + .andExpect(jsonPath("$[1].vehicleId").value(rent2.getDetails().vehicleId())) + .andExpect(jsonPath("$[1].state").value(PENDING.toString())) + .andExpect(jsonPath("$[1].acceptedAt").doesNotExist()) + .andExpect(jsonPath("$[1].startedAt").doesNotExist()) + .andExpect(jsonPath("$[1].endedAt").doesNotExist()); } @ParameterizedTest @@ -70,41 +81,46 @@ void shouldNotGetRentsWhenCriteriaAreNotValid(String queryParameters) throws Exc @Test void shouldGetRent() throws Exception { - when(this.searchRent.getRent(RENT_ID)).thenReturn(RENT); + Rent rent = randomRent(ENDED); + when(this.searchRent.getRent(rent.getId())).thenReturn(rent); - this.mockMvc.perform(get("/rents/" + RENT_ID)) + this.mockMvc.perform(get("/rents/" + rent.getId())) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.rentId").value(RENT_ID)) - .andExpect(jsonPath("$.customerId").value(CUSTOMER_ID)) - .andExpect(jsonPath("$.vehicleId").value(VEHICLE_ID)) - .andExpect(jsonPath("$.state").value(TRANSITION_4_STATE.toString())) - .andExpect(jsonPath("$.acceptedAt").value(TRANSITION_2_TIMESTAMP.toString())) - .andExpect(jsonPath("$.startedAt").value(TRANSITION_3_TIMESTAMP.toString())) - .andExpect(jsonPath("$.endedAt").value(TRANSITION_4_TIMESTAMP.toString())); + .andExpect(jsonPath("$.rentId").value(rent.getId())) + .andExpect(jsonPath("$.customerId").value(rent.getDetails().customerId())) + .andExpect(jsonPath("$.vehicleId").value(rent.getDetails().vehicleId())) + .andExpect(jsonPath("$.state").value(ENDED.toString())) + .andExpect(jsonPath("$.acceptedAt").value(rent.getStateTransitions().get(1).getTimestamp().toString())) + .andExpect(jsonPath("$.startedAt").value(rent.getStateTransitions().get(2).getTimestamp().toString())) + .andExpect(jsonPath("$.endedAt").value(rent.getStateTransitions().get(3).getTimestamp().toString())); } @Test void shouldNotGetRent() throws Exception { - when(this.searchRent.getRent(RENT_ID)).thenThrow(RentNotFoundException.class); + String rentId = UUID.randomUUID().toString(); + when(this.searchRent.getRent(rentId)).thenThrow(RentNotFoundException.class); - this.mockMvc.perform(get("/rents/" + RENT_ID)) + this.mockMvc.perform(get("/rents/" + rentId)) .andExpect(status().isNotFound()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)); } @Test void shouldCreateRent() throws Exception { - String request = this.objectMapper.writeValueAsString(new CreateRentRequest(CUSTOMER_ID, VEHICLE_ID)); - when(this.rentVehicle.createRent(CUSTOMER_ID, VEHICLE_ID)).thenReturn(rentInState(RentState.PENDING)); + Rent persistedRent = randomRent(PENDING); + String customerId = persistedRent.getDetails().customerId(); + String vehicleId = persistedRent.getDetails().vehicleId(); + String request = this.objectMapper.writeValueAsString(new CreateRentRequest(customerId, vehicleId)); + when(this.rentVehicle.createRent(customerId, vehicleId)).thenReturn(persistedRent); this.mockMvc.perform(post("/rents").content(request).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(jsonPath("$.rentId").value(RENT_ID)) - .andExpect(jsonPath("$.customerId").value(CUSTOMER_ID)) - .andExpect(jsonPath("$.vehicleId").value(VEHICLE_ID)) - .andExpect(jsonPath("$.state").value(RentState.PENDING.toString())) + .andExpect(jsonPath("$.rentId").value(persistedRent.getId())) + .andExpect(jsonPath("$.customerId").value(customerId)) + .andExpect(jsonPath("$.vehicleId").value(vehicleId)) + .andExpect(jsonPath("$.state").value(PENDING.toString())) .andExpect(jsonPath("$.acceptedAt").doesNotExist()) .andExpect(jsonPath("$.startedAt").doesNotExist()) .andExpect(jsonPath("$.endedAt").doesNotExist()); @@ -113,7 +129,7 @@ void shouldCreateRent() throws Exception { @ParameterizedTest @ValueSource(strings = {"", "{}"}) void shouldNotCreateRentWhenRequestBodyIsNotValid(String request) throws Exception { - when(this.rentVehicle.createRent(CUSTOMER_ID, VEHICLE_ID)).thenThrow(RentNotFoundException.class); + when(this.rentVehicle.createRent(any(), any())).thenThrow(RentNotFoundException.class); this.mockMvc.perform(post("/rents").content(request).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()) diff --git a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/web/RentMapperTest.java b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/web/RentMapperTest.java index 5640140..ea1660c 100644 --- a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/web/RentMapperTest.java +++ b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/adapters/web/RentMapperTest.java @@ -1,29 +1,34 @@ package it.vincenzocorso.carsharing.rentservice.adapters.web; -import it.vincenzocorso.carsharing.rentservice.domain.models.RentState; -import org.assertj.core.api.Assertions; +import it.vincenzocorso.carsharing.rentservice.domain.models.Rent; import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; -import static it.vincenzocorso.carsharing.rentservice.domain.FakeRent.*; +import static it.vincenzocorso.carsharing.rentservice.domain.models.RandomRent.*; +import static it.vincenzocorso.carsharing.rentservice.domain.models.RentState.*; +import static org.assertj.core.api.Assertions.assertThat; class RentMapperTest { - private final RentMapper rentMapper = new RentMapper(); + @InjectMocks + private RentMapper rentMapper; @Test void shouldConvertToDto() { + Rent rent = randomRent(ENDED); RentResponse expectedRentResponse = RentResponse.builder() - .rentId(RENT_ID) - .customerId(CUSTOMER_ID) - .vehicleId(VEHICLE_ID) - .state(RentState.ENDED.toString()) - .acceptedAt(TRANSITION_2_TIMESTAMP) - .startedAt(TRANSITION_3_TIMESTAMP) - .endedAt(TRANSITION_4_TIMESTAMP) + .rentId(rent.getId()) + .customerId(rent.getDetails().customerId()) + .vehicleId(rent.getDetails().vehicleId()) + .state(ENDED.toString()) + .acceptedAt(rent.getStateTransitions().get(1).getTimestamp()) + .startedAt(rent.getStateTransitions().get(2).getTimestamp()) + .endedAt(rent.getStateTransitions().get(3).getTimestamp()) .build(); - RentResponse actualRentResponse = this.rentMapper.convertToDto(RENT); + RentResponse actualRentResponse = this.rentMapper.convertToDto(rent); - Assertions.assertThat(actualRentResponse) + assertThat(actualRentResponse) + .hasNoNullFieldsOrProperties() .usingRecursiveComparison() .isEqualTo(expectedRentResponse); } diff --git a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/FakeRent.java b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/FakeRent.java deleted file mode 100644 index e72ad8a..0000000 --- a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/FakeRent.java +++ /dev/null @@ -1,99 +0,0 @@ -package it.vincenzocorso.carsharing.rentservice.domain; - -import it.vincenzocorso.carsharing.rentservice.domain.models.Rent; -import it.vincenzocorso.carsharing.rentservice.domain.models.RentDetails; -import it.vincenzocorso.carsharing.rentservice.domain.models.RentState; -import it.vincenzocorso.carsharing.rentservice.domain.models.RentStateTransition; - -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; - -import static org.junit.jupiter.api.Assertions.*; - -public class FakeRent { - public static final String RENT_ID = UUID.randomUUID().toString(); - - public static final String CUSTOMER_ID = "CST-ABCD-1234-EFGH"; - public static final String VEHICLE_ID = "VH-4567-RTYU-8901"; - public static final RentDetails RENT_DETAILS = new RentDetails(CUSTOMER_ID, VEHICLE_ID); - - public static final RentState TRANSITION_1_STATE = RentState.PENDING; - public static final Instant TRANSITION_1_TIMESTAMP = Instant.from(LocalDateTime.of(2021, 8, 14, 14, 3, 2).atZone(ZoneId.of("UTC"))); - public static final RentStateTransition TRANSITION_1 = new RentStateTransition(TRANSITION_1_TIMESTAMP, TRANSITION_1_STATE, 1); - - public static final RentState TRANSITION_2_STATE = RentState.ACCEPTED; - public static final Instant TRANSITION_2_TIMESTAMP = Instant.from(LocalDateTime.of(2021, 8, 14, 14, 3, 10).atZone(ZoneId.of("UTC"))); - public static final RentStateTransition TRANSITION_2 = new RentStateTransition(TRANSITION_2_TIMESTAMP, TRANSITION_2_STATE, 2); - - public static final RentState TRANSITION_3_STATE = RentState.STARTED; - public static final Instant TRANSITION_3_TIMESTAMP = Instant.from(LocalDateTime.of(2021, 8, 14, 14, 10, 52).atZone(ZoneId.of("UTC"))); - public static final RentStateTransition TRANSITION_3 = new RentStateTransition(TRANSITION_3_TIMESTAMP, TRANSITION_3_STATE, 3); - - public static final RentState TRANSITION_4_STATE = RentState.ENDED; - public static final Instant TRANSITION_4_TIMESTAMP = Instant.from(LocalDateTime.of(2021, 8, 14, 15, 32, 40).atZone(ZoneId.of("UTC"))); - public static final RentStateTransition TRANSITION_4 = new RentStateTransition(TRANSITION_4_TIMESTAMP, TRANSITION_4_STATE, 4); - - public static final List ORDERED_STATE_TRANSITIONS = Arrays.asList(TRANSITION_1, TRANSITION_2, TRANSITION_3, TRANSITION_4); - - public static final Rent RENT = new Rent(RENT_ID, RENT_DETAILS, ORDERED_STATE_TRANSITIONS); - - public static Rent rentInState(RentState state) { - List transitions = new ArrayList<>(); - int counter = 1; - - transitions.add(new RentStateTransition(getFakeInstant(counter), RentState.PENDING, counter++)); - if(state.equals(RentState.PENDING)) - return makeRent(transitions); - - if(state.equals(RentState.ACCEPTED) || state.equals(RentState.REJECTED)) { - transitions.add(new RentStateTransition(getFakeInstant(counter), state, counter)); - return makeRent(transitions); - } - transitions.add(new RentStateTransition(getFakeInstant(counter), RentState.ACCEPTED, counter++)); - - if(state.equals(RentState.CANCELLED)) { - transitions.add(new RentStateTransition(getFakeInstant(counter), state, counter)); - return makeRent(transitions); - } - - transitions.add(new RentStateTransition(getFakeInstant(counter), RentState.STARTED, counter++)); - if(state.equals(RentState.STARTED)) - return makeRent(transitions); - - transitions.add(new RentStateTransition(getFakeInstant(counter), RentState.ENDED, counter)); - return makeRent(transitions); - } - - private static Instant getFakeInstant(int counter) { - return Instant.from(LocalDateTime.of(2021, 8, 14, 14, 3, counter).atZone(ZoneId.of("UTC"))); - } - - private static Rent makeRent(List transitions) { - RentDetails rentDetails = new RentDetails(CUSTOMER_ID, VEHICLE_ID); - return new Rent(RENT_ID, rentDetails, transitions); - } - - public static void assertEqualsWithRent(Rent actualRent) { - assertEqualsWithRent(RENT, actualRent); - } - - public static void assertEqualsWithRent(Rent expectedRent, Rent actualRent) { - assertEquals(expectedRent.getId(), actualRent.getId()); - assertEquals(expectedRent.getDetails().customerId(), actualRent.getDetails().customerId()); - assertEquals(expectedRent.getDetails().vehicleId(), actualRent.getDetails().vehicleId()); - for(RentStateTransition expectedTransition : expectedRent.getStateTransitions()) { - RentStateTransition actualTransition = actualRent.getStateTransitions().stream() - .filter(t -> t.getSequenceNumber().equals(expectedTransition.getSequenceNumber())) - .findFirst() - .orElse(null); - assertNotNull(actualTransition); - assertEquals(expectedTransition.getState(), actualTransition.getState()); - assertEquals(expectedTransition.getTimestamp(), actualTransition.getTimestamp()); - } - } -} diff --git a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/RentServiceTest.java b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/RentServiceTest.java index d315696..a727cf1 100644 --- a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/RentServiceTest.java +++ b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/RentServiceTest.java @@ -6,7 +6,6 @@ import it.vincenzocorso.carsharing.rentservice.domain.events.RentStateTransitionEvent; import it.vincenzocorso.carsharing.rentservice.domain.exceptions.RentNotFoundException; import it.vincenzocorso.carsharing.rentservice.domain.models.Rent; -import it.vincenzocorso.carsharing.rentservice.domain.models.RentState; import it.vincenzocorso.carsharing.rentservice.domain.models.SearchRentCriteria; import it.vincenzocorso.carsharing.rentservice.domain.ports.out.RentRepository; import org.junit.jupiter.api.Test; @@ -17,10 +16,11 @@ import java.util.List; import java.util.Optional; +import java.util.UUID; -import static it.vincenzocorso.carsharing.rentservice.domain.FakeRent.*; +import static it.vincenzocorso.carsharing.rentservice.domain.models.RandomRent.*; +import static it.vincenzocorso.carsharing.rentservice.domain.models.RentState.*; import static org.assertj.core.api.Assertions.*; -import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) @@ -36,115 +36,122 @@ class RentServiceTest { @Test void shouldCreateRent() { - DomainEvent event = new RentCreatedEvent(CUSTOMER_ID, VEHICLE_ID); + String rentId = UUID.randomUUID().toString(); + String customerId = UUID.randomUUID().toString(); + String vehicleId = UUID.randomUUID().toString(); + DomainEvent event = new RentCreatedEvent(customerId, vehicleId); when(this.rentRepository.save(any(Rent.class))).then(invocation -> { Rent rent = invocation.getArgument(0); - rent.setId(RENT_ID); + rent.setId(rentId); return rent; }); - Rent createdRent = this.rentService.createRent(CUSTOMER_ID, VEHICLE_ID); + Rent createdRent = this.rentService.createRent(customerId, vehicleId); verify(this.rentRepository).save(createdRent); - verify(this.domainEventProducer).publish(RentService.EVENTS_CHANNEL, RENT_ID, List.of(event)); + verify(this.domainEventProducer).publish(RentService.EVENTS_CHANNEL, rentId, List.of(event)); } @Test void shouldRejectRent() { - Rent persistedRent = rentInState(RentState.PENDING); - DomainEvent event = new RentStateTransitionEvent(RentState.PENDING.toString(), RentState.REJECTED.toString()); - when(this.rentRepository.findById(RENT_ID)).thenReturn(Optional.of(persistedRent)); + Rent persistedRent = randomRent(PENDING); + DomainEvent event = new RentStateTransitionEvent(PENDING.toString(), REJECTED.toString()); + when(this.rentRepository.findById(persistedRent.getId())).thenReturn(Optional.of(persistedRent)); when(this.rentRepository.save(any(Rent.class))).thenReturn(persistedRent); - Rent rejectedRent = this.rentService.rejectRent(RENT_ID); + Rent rejectedRent = this.rentService.rejectRent(persistedRent.getId()); verify(this.rentRepository).save(rejectedRent); - verify(this.domainEventProducer).publish(RentService.EVENTS_CHANNEL, RENT_ID, List.of(event)); + verify(this.domainEventProducer).publish(RentService.EVENTS_CHANNEL, persistedRent.getId(), List.of(event)); } @Test void shouldAcceptRent() { - Rent persistedRent = rentInState(RentState.PENDING); - DomainEvent event = new RentStateTransitionEvent(RentState.PENDING.toString(), RentState.ACCEPTED.toString()); - when(this.rentRepository.findById(RENT_ID)).thenReturn(Optional.of(persistedRent)); + Rent persistedRent = randomRent(PENDING); + DomainEvent event = new RentStateTransitionEvent(PENDING.toString(), ACCEPTED.toString()); + when(this.rentRepository.findById(persistedRent.getId())).thenReturn(Optional.of(persistedRent)); when(this.rentRepository.save(any(Rent.class))).thenReturn(persistedRent); - Rent acceptedRent = this.rentService.acceptRent(RENT_ID); + Rent acceptedRent = this.rentService.acceptRent(persistedRent.getId()); verify(this.rentRepository).save(acceptedRent); - verify(this.domainEventProducer).publish(RentService.EVENTS_CHANNEL, RENT_ID, List.of(event)); + verify(this.domainEventProducer).publish(RentService.EVENTS_CHANNEL, persistedRent.getId(), List.of(event)); } @Test void shouldNotAcceptRentWhenRentDoesntExists() { when(this.rentRepository.findById(anyString())).thenReturn(Optional.empty()); - assertThrows(RentNotFoundException.class, () -> this.rentService.acceptRent("NotExistingId")); + assertThatExceptionOfType(RentNotFoundException.class) + .isThrownBy(() -> this.rentService.acceptRent("NotExistingId")); } @Test void shouldCancelRent() { - Rent persistedRent = rentInState(RentState.ACCEPTED); - DomainEvent event = new RentStateTransitionEvent(RentState.ACCEPTED.toString(), RentState.CANCELLED.toString()); - when(this.rentRepository.findById(RENT_ID)).thenReturn(Optional.of(persistedRent)); + Rent persistedRent = randomRent(ACCEPTED); + DomainEvent event = new RentStateTransitionEvent(ACCEPTED.toString(), CANCELLED.toString()); + when(this.rentRepository.findById(persistedRent.getId())).thenReturn(Optional.of(persistedRent)); when(this.rentRepository.save(any(Rent.class))).thenReturn(persistedRent); - Rent cancelledRent = this.rentService.cancelRent(RENT_ID); + Rent cancelledRent = this.rentService.cancelRent(persistedRent.getId()); verify(this.rentRepository).save(cancelledRent); - verify(this.domainEventProducer).publish(RentService.EVENTS_CHANNEL, RENT_ID, List.of(event)); + verify(this.domainEventProducer).publish(RentService.EVENTS_CHANNEL, persistedRent.getId(), List.of(event)); } @Test void shouldNotCancelRentWhenRentIdDoesntExists() { when(this.rentRepository.findById(anyString())).thenReturn(Optional.empty()); - assertThrows(RentNotFoundException.class, () -> this.rentService.cancelRent("NotExistingId")); + assertThatExceptionOfType(RentNotFoundException.class) + .isThrownBy(() -> this.rentService.cancelRent("NotExistingId")); } @Test void shouldStartRent() { - Rent persistedRent = rentInState(RentState.ACCEPTED); - DomainEvent event = new RentStateTransitionEvent(RentState.ACCEPTED.toString(), RentState.STARTED.toString()); - when(this.rentRepository.findById(RENT_ID)).thenReturn(Optional.of(persistedRent)); + Rent persistedRent = randomRent(ACCEPTED); + DomainEvent event = new RentStateTransitionEvent(ACCEPTED.toString(), STARTED.toString()); + when(this.rentRepository.findById(persistedRent.getId())).thenReturn(Optional.of(persistedRent)); when(this.rentRepository.save(any(Rent.class))).thenReturn(persistedRent); - Rent startedRent = this.rentService.startRent(RENT_ID); + Rent startedRent = this.rentService.startRent(persistedRent.getId()); verify(this.rentRepository).save(startedRent); - verify(this.domainEventProducer).publish(RentService.EVENTS_CHANNEL, RENT_ID, List.of(event)); + verify(this.domainEventProducer).publish(RentService.EVENTS_CHANNEL, persistedRent.getId(), List.of(event)); } @Test void shouldNotStartRentWhenRentIdDoesntExists() { when(this.rentRepository.findById(anyString())).thenReturn(Optional.empty()); - assertThrows(RentNotFoundException.class, () -> this.rentService.startRent("NotExistingId")); + assertThatExceptionOfType(RentNotFoundException.class) + .isThrownBy(() -> this.rentService.startRent("NotExistingId")); } @Test void shouldEndRent() { - Rent persistedRent = rentInState(RentState.STARTED); - DomainEvent event = new RentStateTransitionEvent(RentState.STARTED.toString(), RentState.ENDED.toString()); - when(this.rentRepository.findById(RENT_ID)).thenReturn(Optional.of(persistedRent)); + Rent persistedRent = randomRent(STARTED); + DomainEvent event = new RentStateTransitionEvent(STARTED.toString(), ENDED.toString()); + when(this.rentRepository.findById(persistedRent.getId())).thenReturn(Optional.of(persistedRent)); when(this.rentRepository.save(any(Rent.class))).thenReturn(persistedRent); - Rent endedRent = this.rentService.endRent(RENT_ID); + Rent endedRent = this.rentService.endRent(persistedRent.getId()); verify(this.rentRepository).save(endedRent); - verify(this.domainEventProducer).publish(RentService.EVENTS_CHANNEL, RENT_ID, List.of(event)); + verify(this.domainEventProducer).publish(RentService.EVENTS_CHANNEL, persistedRent.getId(), List.of(event)); } @Test void shouldNotEndRentWhenRentIdDoesntExists() { when(this.rentRepository.findById(anyString())).thenReturn(Optional.empty()); - assertThrows(RentNotFoundException.class, () -> this.rentService.endRent("NotExistingId")); + assertThatExceptionOfType(RentNotFoundException.class) + .isThrownBy(() -> this.rentService.endRent("NotExistingId")); } @Test void shouldGetRents() { - List persistedRents = List.of(rentInState(RentState.PENDING)); + List persistedRents = List.of(randomRent(PENDING)); SearchRentCriteria searchRentCriteria = SearchRentCriteria.empty(); when(this.rentRepository.findByCriteria(searchRentCriteria)).thenReturn(persistedRents); @@ -155,18 +162,20 @@ void shouldGetRents() { @Test void shouldGetRent() { - Rent persistedRent = rentInState(RentState.PENDING); - when(this.rentRepository.findById(RENT_ID)).thenReturn(Optional.of(persistedRent)); + Rent persistedRent = randomRent(PENDING); + when(this.rentRepository.findById(persistedRent.getId())).thenReturn(Optional.of(persistedRent)); - Rent retrievedRent = this.rentService.getRent(RENT_ID); + Rent retrievedRent = this.rentService.getRent(persistedRent.getId()); - assertEquals(retrievedRent, persistedRent); + assertThat(retrievedRent).isEqualTo(persistedRent); } @Test void shouldNotGetRent() { + String rentId = UUID.randomUUID().toString(); when(this.rentRepository.findById(anyString())).thenReturn(Optional.empty()); - assertThrows(RentNotFoundException.class, () -> this.rentService.getRent(RENT_ID)); + assertThatExceptionOfType(RentNotFoundException.class) + .isThrownBy(() -> this.rentService.getRent(rentId)); } } \ No newline at end of file diff --git a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/models/RandomRent.java b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/models/RandomRent.java new file mode 100644 index 0000000..41b6a23 --- /dev/null +++ b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/models/RandomRent.java @@ -0,0 +1,68 @@ +package it.vincenzocorso.carsharing.rentservice.domain.models; + +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static it.vincenzocorso.carsharing.rentservice.domain.models.RentState.*; +import static java.time.temporal.ChronoUnit.MINUTES; + +public class RandomRent { + public static Rent randomRent() { + return randomRent(ENDED); + } + + public static Rent randomRent(RentState finalState) { + String rentId = UUID.randomUUID().toString(); + RentDetails rentDetails = randomRentDetails(); + List rentStateTransitions = randomRentStateTransitionList(finalState); + return new Rent(rentId, rentDetails, rentStateTransitions); + } + + public static RentDetails randomRentDetails() { + String customerId = UUID.randomUUID().toString(); + String vehicleId = UUID.randomUUID().toString(); + return new RentDetails(customerId, vehicleId); + } + + public static RentRegistry randomRentRegistry(RentState finalState) { + List rentStateTransitions = randomRentStateTransitionList(finalState); + return new RentRegistry(rentStateTransitions); + } + + public static List randomRentStateTransitionList(RentState finalState) { + List transitions = new ArrayList<>(); + int sequenceNumber = 1; + + transitions.add(new RentStateTransition(getFutureInstant(sequenceNumber), PENDING, sequenceNumber++)); + if(PENDING.equals(finalState)) { + return transitions; + } + + if(ACCEPTED.equals(finalState) || REJECTED.equals(finalState)) { + transitions.add(new RentStateTransition(getFutureInstant(sequenceNumber), finalState, sequenceNumber)); + return transitions; + } + transitions.add(new RentStateTransition(getFutureInstant(sequenceNumber), ACCEPTED, sequenceNumber++)); + + if(CANCELLED.equals(finalState)) { + transitions.add(new RentStateTransition(getFutureInstant(sequenceNumber), finalState, sequenceNumber)); + return transitions; + } + + transitions.add(new RentStateTransition(getFutureInstant(sequenceNumber), RentState.STARTED, sequenceNumber++)); + if(STARTED.equals(finalState)) { + return transitions; + } + + transitions.add(new RentStateTransition(getFutureInstant(sequenceNumber), RentState.ENDED, sequenceNumber)); + return transitions; + } + + private static Instant getFutureInstant(int sequenceNumber) { + return Instant.now() + .minus(10 + (long) (Math.random() * 3000), MINUTES) + .plus(sequenceNumber, MINUTES); + } +} diff --git a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/models/RentRegistryTest.java b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/models/RentRegistryTest.java index 8ff5ca0..be1caef 100644 --- a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/models/RentRegistryTest.java +++ b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/models/RentRegistryTest.java @@ -3,43 +3,43 @@ import org.junit.jupiter.api.Test; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collections; import java.util.List; -import static it.vincenzocorso.carsharing.rentservice.domain.FakeRent.*; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static it.vincenzocorso.carsharing.rentservice.domain.models.RandomRent.*; +import static it.vincenzocorso.carsharing.rentservice.domain.models.RentState.*; +import static org.assertj.core.api.Assertions.*; class RentRegistryTest { @Test void shouldCreateOrderedRegistry() { - List unorderedTransitions = Arrays.asList(TRANSITION_3, TRANSITION_1, TRANSITION_4, TRANSITION_2); + List orderedTransitions = randomRentStateTransitionList(CANCELLED); + List unorderedTransitions = new ArrayList<>(orderedTransitions); + Collections.shuffle(unorderedTransitions); RentRegistry rentRegistry = new RentRegistry(unorderedTransitions); List storedTransitions = rentRegistry.getTransitions(); - assertThat(storedTransitions).hasSameElementsAs(ORDERED_STATE_TRANSITIONS); + assertThat(storedTransitions).hasSameElementsAs(orderedTransitions); } @Test - void shouldAddOrder() { - List transitions = new ArrayList<>(List.of(TRANSITION_1, TRANSITION_2, TRANSITION_3)); - RentRegistry rentRegistry = new RentRegistry(transitions); + void shouldAddInOrder() { + RentRegistry rentRegistry = randomRentRegistry(STARTED); rentRegistry.appendTransitionTo(RentState.ENDED); - List storedTransitions = rentRegistry.getTransitions(); - assertEquals(RentState.ENDED, rentRegistry.getCurrentState()); - assertEquals(4, rentRegistry.getTransitions().get(3).getSequenceNumber()); + assertThat(rentRegistry.getCurrentState()).isEqualTo(ENDED); + assertThat(rentRegistry.getTransitions().get(3).getSequenceNumber()).isEqualTo(4); } @Test - void shouldAddOrderWhenEmpty() { + void shouldAddInOrderWhenEmpty() { RentRegistry rentRegistry = RentRegistry.empty(); rentRegistry.appendTransitionTo(RentState.ACCEPTED); - assertEquals(RentState.ACCEPTED, rentRegistry.getCurrentState()); - assertEquals(1, rentRegistry.getTransitions().size()); + assertThat(rentRegistry.getCurrentState()).isEqualTo(ACCEPTED); + assertThat(rentRegistry.getTransitions()).hasSize(1); } } \ No newline at end of file diff --git a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/models/RentTest.java b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/models/RentTest.java index 09c9284..c1c10b0 100644 --- a/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/models/RentTest.java +++ b/rent-service/src/test/java/it/vincenzocorso/carsharing/rentservice/domain/models/RentTest.java @@ -5,99 +5,113 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; -import static it.vincenzocorso.carsharing.rentservice.domain.FakeRent.*; -import static org.junit.jupiter.api.Assertions.*; +import static it.vincenzocorso.carsharing.rentservice.domain.models.RandomRent.*; +import static it.vincenzocorso.carsharing.rentservice.domain.models.RentState.*; +import static org.assertj.core.api.Assertions.*; class RentTest { @Test void shouldCreateRentInPendingState() { - Rent createdRent = Rent.create(RENT_DETAILS).result; + RentDetails rentDetails = randomRentDetails(); - assertEquals(RentState.PENDING, createdRent.getCurrentState()); + Rent createdRent = Rent.create(rentDetails).result; + + assertThat(createdRent.getCurrentState()) + .isEqualTo(PENDING); } @Test void shouldRejectRent() { - Rent rent = rentInState(RentState.PENDING); + Rent rent = randomRent(PENDING); rent.reject(); - assertEquals(RentState.REJECTED, rent.getCurrentState()); + assertThat(rent.getCurrentState()) + .isEqualTo(REJECTED); } @ParameterizedTest @EnumSource(value = RentState.class, mode = EnumSource.Mode.EXCLUDE, names = {"PENDING"}) void shouldNotRejectRent(RentState state) { - Rent rent = rentInState(state); + Rent rent = randomRent(state); - assertThrows(IllegalRentStateTransitionException.class, rent::reject); + assertThatExceptionOfType(IllegalRentStateTransitionException.class) + .isThrownBy(rent::reject); } @Test void shouldAcceptRent() { - Rent rent = rentInState(RentState.PENDING); + Rent rent = randomRent(PENDING); rent.accept(); - assertEquals(RentState.ACCEPTED, rent.getCurrentState()); + assertThat(rent.getCurrentState()) + .isEqualTo(ACCEPTED); } @ParameterizedTest @EnumSource(value = RentState.class, mode = EnumSource.Mode.EXCLUDE, names = {"PENDING"}) void shouldNotAcceptRent(RentState state) { - Rent rent = rentInState(state); + Rent rent = randomRent(state); - assertThrows(IllegalRentStateTransitionException.class, rent::accept); + assertThatExceptionOfType(IllegalRentStateTransitionException.class) + .isThrownBy(rent::accept); } @Test void shouldCancelRent() { - Rent rent = rentInState(RentState.ACCEPTED); + Rent rent = randomRent(ACCEPTED); rent.cancel(); - assertEquals(RentState.CANCELLED, rent.getCurrentState()); + assertThat(rent.getCurrentState()) + .isEqualTo(CANCELLED); } @ParameterizedTest @EnumSource(value = RentState.class, mode = EnumSource.Mode.EXCLUDE, names = {"ACCEPTED"}) void shouldNotCancelRent(RentState state) { - Rent rent = rentInState(state); + Rent rent = randomRent(state); - assertThrows(IllegalRentStateTransitionException.class, rent::cancel); + assertThatExceptionOfType(IllegalRentStateTransitionException.class) + .isThrownBy(rent::cancel); } @Test void shouldStartRent() { - Rent rent = rentInState(RentState.ACCEPTED); + Rent rent = randomRent(ACCEPTED); rent.start(); - assertEquals(RentState.STARTED, rent.getCurrentState()); + assertThat(rent.getCurrentState()) + .isEqualTo(STARTED); } @ParameterizedTest @EnumSource(value = RentState.class, mode = EnumSource.Mode.EXCLUDE, names = {"ACCEPTED"}) void shouldNotStartRent(RentState state) { - Rent rent = rentInState(state); + Rent rent = randomRent(state); - assertThrows(IllegalRentStateTransitionException.class, rent::start); + assertThatExceptionOfType(IllegalRentStateTransitionException.class) + .isThrownBy(rent::start); } @Test void shouldEndRent() { - Rent rent = rentInState(RentState.STARTED); + Rent rent = randomRent(RentState.STARTED); rent.end(); - assertEquals(RentState.ENDED, rent.getCurrentState()); + assertThat(rent.getCurrentState()) + .isEqualTo(ENDED); } @ParameterizedTest @EnumSource(value = RentState.class, mode = EnumSource.Mode.EXCLUDE, names = {"STARTED"}) void shouldNotEndRent(RentState state) { - Rent rent = rentInState(state); + Rent rent = randomRent(state); - assertThrows(IllegalRentStateTransitionException.class, rent::end); + assertThatExceptionOfType(IllegalRentStateTransitionException.class) + .isThrownBy(rent::end); } } \ No newline at end of file