diff --git a/airports-planes-service/pom.xml b/airports-planes-service/pom.xml index a3330430954b0737ecfbe0afddf4a0a99a631330..ed7521d2fc19860be96f69a32a19f6bd6a8eb363 100644 --- a/airports-planes-service/pom.xml +++ b/airports-planes-service/pom.xml @@ -20,15 +20,24 @@ <dependencies> <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-web</artifactId> - <version>5.3.4</version> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>${project.groupId}</groupId> <artifactId>airport-manager-api</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + <version>4.0.1</version> <!-- Replace {version} with the appropriate version, e.g., 4.0.1 --> + <scope>provided</scope> + </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa --> <dependency> <groupId>org.springframework.boot</groupId> @@ -46,7 +55,6 @@ <dependency> <groupId>org.modelmapper</groupId> <artifactId>modelmapper</artifactId> - <version>3.2.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> @@ -60,32 +68,24 @@ <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> </dependency> - <dependency> - <groupId>io.micrometer</groupId> - <artifactId>micrometer-core</artifactId> - </dependency> - <dependency> - <groupId>org.junit.jupiter</groupId> - <artifactId>junit-jupiter-api</artifactId> - <scope>test</scope> - </dependency> <dependency> <groupId>org.mockito</groupId> - <artifactId>mockito-core</artifactId> + <artifactId>mockito-junit-jupiter</artifactId> <scope>test</scope> </dependency> <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <scope>test</scope> </dependency> <dependency> - <groupId>org.mockito</groupId> - <artifactId>mockito-junit-jupiter</artifactId> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> - <groupId>org.assertj</groupId> - <artifactId>assertj-core</artifactId> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-test-autoconfigure</artifactId> <scope>test</scope> </dependency> </dependencies> diff --git a/airports-planes-service/src/main/java/cz/muni/fi/pa165/planes/facade/PlaneFacade.java b/airports-planes-service/src/main/java/cz/muni/fi/pa165/planes/facade/PlaneFacade.java index 635c0a14288aa156e4a6afbe4b162eb5192a90e7..b9579addd522bf4354279d36e743cf475657cf59 100644 --- a/airports-planes-service/src/main/java/cz/muni/fi/pa165/planes/facade/PlaneFacade.java +++ b/airports-planes-service/src/main/java/cz/muni/fi/pa165/planes/facade/PlaneFacade.java @@ -1,10 +1,10 @@ package cz.muni.fi.pa165.planes.facade; -import cz.muni.fi.pa165.api.plane.PlaneType; import cz.muni.fi.pa165.api.plane.Plane; +import cz.muni.fi.pa165.api.plane.PlaneType; import cz.muni.fi.pa165.api.plane.requests.PlaneRequest; import cz.muni.fi.pa165.planes.service.PlaneService; -import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; import org.modelmapper.ModelMapper; import org.springframework.stereotype.Service; @@ -12,7 +12,7 @@ import java.util.List; import java.util.UUID; @Service -@AllArgsConstructor +@RequiredArgsConstructor public class PlaneFacade { private final PlaneService planeService; @@ -34,7 +34,7 @@ public class PlaneFacade { } public List<Plane> getByType(PlaneType planeType) { - var result = planeService.getByType(modelMapper.map(planeType,cz.muni.fi.pa165.planes.dao.PlaneType.class)); + var result = planeService.getByType(modelMapper.map(planeType, cz.muni.fi.pa165.planes.dao.PlaneType.class)); return result.stream().map(p -> modelMapper.map(p, Plane.class)).toList(); } } diff --git a/airports-planes-service/src/main/java/cz/muni/fi/pa165/planes/rest/PlaneController.java b/airports-planes-service/src/main/java/cz/muni/fi/pa165/planes/rest/PlaneController.java index 3a18f9d95f4417e231eecc1e4450be70ebc4497e..5b2d64fd77d65f446dea5be89d25e8dca5c8c3f7 100644 --- a/airports-planes-service/src/main/java/cz/muni/fi/pa165/planes/rest/PlaneController.java +++ b/airports-planes-service/src/main/java/cz/muni/fi/pa165/planes/rest/PlaneController.java @@ -1,9 +1,9 @@ package cz.muni.fi.pa165.planes.rest; -import cz.muni.fi.pa165.planes.facade.PlaneFacade; -import cz.muni.fi.pa165.api.plane.PlaneType; import cz.muni.fi.pa165.api.plane.Plane; +import cz.muni.fi.pa165.api.plane.PlaneType; import cz.muni.fi.pa165.api.plane.requests.PlaneRequest; +import cz.muni.fi.pa165.planes.facade.PlaneFacade; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -14,7 +14,7 @@ import java.util.UUID; @RequiredArgsConstructor public class PlaneController { - private PlaneFacade planeFacade; + private final PlaneFacade planeFacade; @PostMapping("/plane") public Plane create(@RequestBody PlaneRequest request) { diff --git a/airports-planes-service/src/test/java/cz/muni/fi/pa165/planes/facade/PlaneFacadeTest.java b/airports-planes-service/src/test/java/cz/muni/fi/pa165/planes/facade/PlaneFacadeTest.java index 8ac574eb537cbd6458a6cb11a3b875679693fa06..f1bc964d9390770ca4fe3c750ba0a2e685b8bdaa 100644 --- a/airports-planes-service/src/test/java/cz/muni/fi/pa165/planes/facade/PlaneFacadeTest.java +++ b/airports-planes-service/src/test/java/cz/muni/fi/pa165/planes/facade/PlaneFacadeTest.java @@ -22,7 +22,7 @@ import java.util.Optional; import java.util.Set; import java.util.UUID; -import static org.junit.Assert.assertThrows; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.Mockito.*; diff --git a/airports-planes-service/src/test/java/cz/muni/fi/pa165/planes/rest/PlaneControllerTest.java b/airports-planes-service/src/test/java/cz/muni/fi/pa165/planes/rest/PlaneControllerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..39822844589898bdf033ed08f2266c5a9bb2caa4 --- /dev/null +++ b/airports-planes-service/src/test/java/cz/muni/fi/pa165/planes/rest/PlaneControllerTest.java @@ -0,0 +1,116 @@ +package cz.muni.fi.pa165.planes.rest; + +import cz.muni.fi.pa165.api.plane.Plane; +import cz.muni.fi.pa165.api.plane.PlaneType; +import cz.muni.fi.pa165.planes.exception.PlaneNotFoundException; +import cz.muni.fi.pa165.planes.facade.PlaneFacade; +import cz.muni.fi.pa165.planes.utils.ObjectConverter; +import cz.muni.fi.pa165.planes.utils.TestApiFactory; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(controllers = {PlaneController.class}) +class PlaneControllerTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private PlaneFacade planeFacade; + + @Test + void findById_planeFound_returnsPlane() throws Exception { + UUID id = new UUID(0x1, 0xf); + Mockito.when(planeFacade.get(id)).thenReturn(TestApiFactory.getPlaneEntity()); + + String responseJson = mockMvc.perform(get("/plane/{id}", id) + .accept(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isOk()) + .andReturn() + .getResponse() + .getContentAsString(StandardCharsets.UTF_8); + Plane response = ObjectConverter.convertJsonToObject(responseJson, Plane.class); + + assertThat(responseJson).isEqualTo("{\"id\":\"00000000-0000-0001-0000-00000000000f\",\"name\":\"Name\",\"planeType\":\"AIRBUS_A380\",\"maxCapacity\":600,\"pilotsRequired\":2}"); + assertThat(response).isEqualTo(TestApiFactory.getPlaneEntity()); + } + + @Test + void findById_planeNotFound_throws404() throws Exception { + UUID id = UUID.randomUUID(); + Mockito.when(planeFacade.get(id)).thenThrow(new PlaneNotFoundException()); + + mockMvc.perform(get("/plane/{id}", id) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isNotFound()); + + Mockito.verify(planeFacade, Mockito.times(1)).get(id); + } + + @Test + void updatePlaneName_planeFound_returnsUpdatedPlane() throws Exception { + UUID id = UUID.randomUUID(); + String updatedName = "UpdatedName"; + Plane updatedPlane = TestApiFactory.getPlaneEntity(); + updatedPlane.setName(updatedName); + + Mockito.when(planeFacade.updateName(Mockito.eq(id), Mockito.eq(updatedName))).thenReturn(updatedPlane); + + String responseJson = mockMvc.perform(put("/plane/{id}", id) + .param("name", updatedName)) + .andExpect(status().isOk()) + .andReturn() + .getResponse() + .getContentAsString(StandardCharsets.UTF_8); + + Plane response = ObjectConverter.convertJsonToObject(responseJson, Plane.class); + + assertThat(response).isEqualTo(updatedPlane); + Mockito.verify(planeFacade, Mockito.times(1)).updateName(Mockito.eq(id), Mockito.eq(updatedName)); + } + + @Test + void updatePlaneName_planeNotFound_throws404() throws Exception { + UUID id = UUID.randomUUID(); + String updatedName = "UpdatedName"; + + Mockito.when(planeFacade.updateName(Mockito.eq(id), Mockito.eq(updatedName))).thenThrow(new PlaneNotFoundException()); + + mockMvc.perform(put("/plane/{id}", id) + .param("name", updatedName)) + .andExpect(status().isNotFound()); + + Mockito.verify(planeFacade, Mockito.times(1)).updateName(Mockito.eq(id), Mockito.eq(updatedName)); + } + + @Test + void getByType_returnsPlanes() throws Exception { + PlaneType planeType = PlaneType.AIRBUS_A380; + List<Plane> planes = new ArrayList<>(); + Plane plane1 = TestApiFactory.getPlaneEntity(); + Plane plane2 = TestApiFactory.getPlaneEntity(); + plane2.setPlaneType(planeType); + planes.add(plane1); + planes.add(plane2); + + Mockito.when(planeFacade.getByType(planeType)).thenReturn(planes); + + mockMvc.perform(get("/plane/type").param("planeType", planeType.toString()).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } +} \ No newline at end of file diff --git a/airports-planes-service/src/test/java/cz/muni/fi/pa165/planes/utils/ObjectConverter.java b/airports-planes-service/src/test/java/cz/muni/fi/pa165/planes/utils/ObjectConverter.java new file mode 100644 index 0000000000000000000000000000000000000000..314e8d450603767dc0d92b52ec4b359be4deaee2 --- /dev/null +++ b/airports-planes-service/src/test/java/cz/muni/fi/pa165/planes/utils/ObjectConverter.java @@ -0,0 +1,32 @@ +package cz.muni.fi.pa165.planes.utils; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +import java.io.IOException; + +public class ObjectConverter { + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .registerModule(new JavaTimeModule()) + .setSerializationInclusion(JsonInclude.Include.NON_NULL); + + public static <T> T convertJsonToObject(String serializedObject, Class<T> objectClass) throws JsonProcessingException { + return OBJECT_MAPPER.readValue(serializedObject, objectClass); + } + + public static String convertObjectToJson(Object object) throws JsonProcessingException { + return OBJECT_MAPPER.writeValueAsString(object); + } + + public static <T> T convertJsonToObject(String object, TypeReference<T> typeReference) throws IOException { + return OBJECT_MAPPER.readValue(object, typeReference); + } +} + +