diff --git a/common_library/src/main/java/cz/muni/pa165/common_library/dtos/RaceDriverCarDto.java b/common_library/src/main/java/cz/muni/pa165/common_library/dtos/RaceDriverCarDto.java index 0e635504e632573c917679554c2b16ccd4e31935..163da951a77d1f16d721744234e0fa2c666a821a 100644 --- a/common_library/src/main/java/cz/muni/pa165/common_library/dtos/RaceDriverCarDto.java +++ b/common_library/src/main/java/cz/muni/pa165/common_library/dtos/RaceDriverCarDto.java @@ -2,14 +2,18 @@ package cz.muni.pa165.common_library.dtos; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; /** * Dto fro DriverCar entity. */ @Data @Builder +@NoArgsConstructor +@AllArgsConstructor public class RaceDriverCarDto { @Schema(description = "driver id", example = "1") diff --git a/race/src/main/java/cz/muni/pa165/race/service/DbGetter.java b/race/src/main/java/cz/muni/pa165/race/service/DbGetter.java new file mode 100644 index 0000000000000000000000000000000000000000..e8f0b5bc40e854f00e2c2e60d1b91312d6cb9913 --- /dev/null +++ b/race/src/main/java/cz/muni/pa165/race/service/DbGetter.java @@ -0,0 +1,41 @@ +package cz.muni.pa165.race.service; + +import cz.muni.pa165.common_library.dtos.CarResponseDto; +import cz.muni.pa165.common_library.dtos.DriverDto; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +/** + * Getter for driver and car from appropriate modules. + */ +@Component +public class DbGetter { + + @Autowired + RestTemplate client; + + /** + * Calls driver module for a driver given by id. + * + * @param driverId id of a driver. + * @return driverDto. + */ + public DriverDto getDriver(Long driverId) { + var response = + client.getForEntity("http://localhost:8083/driver/get/id=" + driverId, DriverDto.class); + return response.getBody(); + } + + /** + * Calls car module for a car given by id. + * + * @param carId id of a car. + * @return carDto. + */ + public CarResponseDto getCar(Long carId) { + var response = + client.getForEntity("http://localhost:8082/car/?carId=" + carId, CarResponseDto.class); + return response.getBody(); + } +} diff --git a/race/src/main/java/cz/muni/pa165/race/service/RaceService.java b/race/src/main/java/cz/muni/pa165/race/service/RaceService.java index ad0ff086584e5b069e37b0b1a937903042b8bc0f..2165c89ad614639b68514efa34ffa4938a5e495a 100644 --- a/race/src/main/java/cz/muni/pa165/race/service/RaceService.java +++ b/race/src/main/java/cz/muni/pa165/race/service/RaceService.java @@ -33,7 +33,7 @@ public class RaceService implements RaceServiceI { RaceRepository raceRepository; @Autowired - RestTemplate client; + DbGetter dbGetter; RaceService(RaceRepository raceRepository) { this.raceRepository = raceRepository; @@ -70,12 +70,12 @@ public class RaceService implements RaceServiceI { var race = raceRepository.findById(raceId) .orElseThrow(() -> new DatabaseException("Race not found")); - var driver = getDriver(driverId); + var driver = dbGetter.getDriver(driverId); if (race.getDriver2() != null && Objects.equals(race.getDriver2().getDriverId(), driverId)) { throw new BadRequestException("Driver already assigned to the race as driver two"); } - var car = getCar(carId); + var car = dbGetter.getCar(carId); if (race.getDriver2() != null && Objects.equals(race.getDriver2().getCarId(), carId)) { throw new BadRequestException("Car is already assigned to the race for driver two"); } @@ -92,11 +92,11 @@ public class RaceService implements RaceServiceI { var race = raceRepository.findById(raceId) .orElseThrow(() -> new DatabaseException("Race not found")); - var driver = getDriver(driverId); + var driver = dbGetter.getDriver(driverId); if (race.getDriver1() != null && Objects.equals(race.getDriver1().getDriverId(), driverId)) { throw new BadRequestException("Driver already assigned to the race as driver one"); } - var car = getCar(carId); + var car = dbGetter.getCar(carId); if (race.getDriver1() != null && Objects.equals(race.getDriver1().getCarId(), carId)) { throw new BadRequestException("Car is already assigned to the race for driver two"); } @@ -263,15 +263,5 @@ public class RaceService implements RaceServiceI { return raceDto; } - private DriverDto getDriver(Long driverId) { - var response = - client.getForEntity("http://localhost:8083/driver/get/id=" + driverId, DriverDto.class); - return response.getBody(); - } - private CarResponseDto getCar(Long carId) { - var response = - client.getForEntity("http://localhost:8082/car/?carId=" + carId, CarResponseDto.class); - return response.getBody(); - } } diff --git a/race/src/test/java/cz/muni/pa165/race/rest/CarManagerControllerItTest.java b/race/src/test/java/cz/muni/pa165/race/rest/CarManagerControllerItTest.java deleted file mode 100644 index e82f209188304e317bf15cc272844096c84690fc..0000000000000000000000000000000000000000 --- a/race/src/test/java/cz/muni/pa165/race/rest/CarManagerControllerItTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package cz.muni.pa165.race.rest; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.web.servlet.MockMvc; - -@SpringBootTest -@AutoConfigureMockMvc -class CarManagerControllerItTest { - - @Autowired - private MockMvc mockMvc; - - @Autowired - private ObjectMapper objectMapper; - - -} diff --git a/race/src/test/java/cz/muni/pa165/race/rest/RaceControllerTest.java b/race/src/test/java/cz/muni/pa165/race/rest/RaceControllerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..39665d916965a9603379237cae4c234eae5b1b50 --- /dev/null +++ b/race/src/test/java/cz/muni/pa165/race/rest/RaceControllerTest.java @@ -0,0 +1,154 @@ +package cz.muni.pa165.race.rest; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import cz.muni.pa165.common_library.dtos.CarResponseDto; +import cz.muni.pa165.common_library.dtos.DriverDto; +import cz.muni.pa165.race.data.model.Race; +import cz.muni.pa165.race.data.repository.RaceRepository; +import cz.muni.pa165.race.service.DbGetter; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +@SpringBootTest +@AutoConfigureMockMvc +class RaceControllerTest { + + private String bodyContent = """ + { + "id": 1, + "raceInfo": { + "location": "MONACO", + "name": "Monaco Grand Prix 2023", + "prizePool": 30000000 + } + } + """; + private String expectedMessagePost = "{\"id\":1,\"raceInfo\":{\"location\":\"MONACO\"," + + "\"name\":\"Monaco Grand Prix 2023\",\"prizePool\":30000000},\"driverOne\"" + + ":{\"driverId\":1,\"carId\":1,\"position\":null},\"driverTwo\":{\"driverId\"" + + ":2,\"carId\":2,\"position\":null}}"; + private String expectedMessageAssignTwo = "{\"id\":1,\"raceInfo\":{\"location\":" + + "\"MONACO\",\"name\":\"Monaco Grand Prix 2023\",\"prizePool\":30000000}," + + "\"driverOne\":{\"driverId\":1,\"carId\":1,\"position\":null},\"driverTwo\"" + + ":{\"driverId\":1,\"carId\":1,\"position\":null}}"; + private String expectedMessageGet = "{\"id\":1,\"raceInfo\":{\"location\":\"MONACO\"" + + ",\"name\":\"Monaco Grand Prix 2023\",\"prizePool\":30000000},\"driverOne\"" + + ":{\"driverId\":1,\"carId\":1,\"position\":null},\"driverTwo\":{\"driverId\"" + + ":2,\"carId\":2,\"position\":null}}"; + private String expectedMessageGetAll = "[{\"id\":1,\"raceInfo\":{\"location\"" + + ":\"MONACO\",\"name\":\"Monaco Grand Prix 2023\",\"prizePool\":30000000},\"" + + "driverOne\":{\"driverId\":1,\"carId\":1,\"position\":null},\"driverTwo\":{\"" + + "driverId\":2,\"carId\":2,\"position\":null}}]"; + + @Autowired + private MockMvc mockMvc; + + @MockBean + private RaceRepository raceRepository; + + @MockBean + private DbGetter dbGetter; + + @BeforeEach + void setup() { + Race raceDao = RaceTestUtil.getDaoRace(); + given(raceRepository.save(any(Race.class))).willReturn( + raceDao); + given(raceRepository.findById(anyLong())).willReturn( + Optional.of(raceDao)); + given(raceRepository.findAll()).willReturn(List.of(raceDao)); + CarResponseDto carDao = RaceTestUtil.getCarDao(); + given(dbGetter.getCar(anyLong())).willReturn(carDao); + DriverDto driverDto = RaceTestUtil.getDriverDao(); + given(dbGetter.getDriver(anyLong())).willReturn(driverDto); + } + + + @Test + void createRace() throws Exception { + var request = post("/race/") + .content(bodyContent) + .contentType(MediaType.APPLICATION_JSON_VALUE); + this.mockMvc.perform(request) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(expectedMessagePost)); + } + + @Test + void deleteRace() throws Exception { + String expectedMessage = "Race with id: 1was succesfully deleted"; + var requestDelete = delete("/race/") + .param("raceId", "1") + .contentType(MediaType.APPLICATION_JSON_VALUE); + this.mockMvc.perform(requestDelete) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(expectedMessage)); + } + + @Test + void getExistingRace() throws Exception { + var requestGet = get("/race/id") + .param("raceId", "1") + .contentType(MediaType.APPLICATION_JSON_VALUE); + this.mockMvc.perform(requestGet) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(expectedMessageGet)); + } + + @Test + void getAllRaces() throws Exception { + var requestGet = get("/race/"); + this.mockMvc.perform(requestGet) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(expectedMessageGetAll)); + } + + @Test + void assignDriverOne() throws Exception { + var requestAssign = patch("/race/assignDriverOne") + .param("driverOneId", "1") + .param("raceId", "1") + .param("carId", "1") + .contentType(MediaType.APPLICATION_JSON_VALUE); + this.mockMvc.perform(requestAssign) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(expectedMessagePost)); + } + + @Test + void assignDriverTwo() throws Exception { + var requestAssign = patch("/race/assignDriverTwo") + .param("driverTwoId", "2") + .param("raceId", "2") + .param("carId", "2") + .contentType(MediaType.APPLICATION_JSON_VALUE); + this.mockMvc.perform(requestAssign) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(expectedMessageAssignTwo)); + } + +} diff --git a/race/src/test/java/cz/muni/pa165/race/rest/RaceTestUtil.java b/race/src/test/java/cz/muni/pa165/race/rest/RaceTestUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..164179e3da60e8707866bd623ab3b462a4f1e49d --- /dev/null +++ b/race/src/test/java/cz/muni/pa165/race/rest/RaceTestUtil.java @@ -0,0 +1,47 @@ +package cz.muni.pa165.race.rest; + +import cz.muni.pa165.common_library.dtos.CarResponseDto; +import cz.muni.pa165.common_library.dtos.DriverDto; +import cz.muni.pa165.common_library.dtos.Location; +import cz.muni.pa165.race.data.model.Race; + +/** + * Util functions for race tests. + */ +public class RaceTestUtil { + /** + * Returns a created race. + * + * @return a race. + */ + public static Race getDaoRace() { + return Race.builder() + .id(1L) + .raceInfo(Race.RaceInfo.builder() + .id(1L) + .location(Location.MONACO) + .name("Monaco Grand Prix 2023") + .prizePool(30000000L).build()) + .driver1(Race.RaceDriverinfo.builder() + .id(1L) + .driverId(1L) + .carId(1L) + .finalPosition(1) + .build()) + .driver2(Race.RaceDriverinfo.builder() + .id(2L) + .driverId(2L) + .carId(2L) + .finalPosition(2) + .build()) + .build(); + } + + public static CarResponseDto getCarDao() { + return new CarResponseDto(1L, null, null, 1L); + } + + public static DriverDto getDriverDao() { + return new DriverDto(1L, "Name", "Surname"); + } +} diff --git a/race/src/test/java/cz/muni/pa165/race/rest/SeasonControllerTest.java b/race/src/test/java/cz/muni/pa165/race/rest/SeasonControllerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..bc1ce050604d6f00faae2409ba25fae8be4d9b0b --- /dev/null +++ b/race/src/test/java/cz/muni/pa165/race/rest/SeasonControllerTest.java @@ -0,0 +1,124 @@ +package cz.muni.pa165.race.rest; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import cz.muni.pa165.race.data.model.Race; +import cz.muni.pa165.race.data.model.Season; +import cz.muni.pa165.race.data.repository.RaceRepository; +import cz.muni.pa165.race.data.repository.SeasonRepository; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +/** + * Tests for season controller. + */ +@SpringBootTest +@AutoConfigureMockMvc +public class SeasonControllerTest { + private String bodyContent = """ + { + "id": 1, + "year": 2020, + "races": [] + } + """; + private String expectedMessagePost = "{\"id\":1,\"year\":2023,\"races\":[]}"; + private String expectedMessageDelete = "Season with id: 1was succesfully deleted"; + private String expectedMessageGet = "{\"id\":1,\"year\":2023,\"races\":[]}"; + private String expectedMessageGetAll = "[{\"id\":1,\"year\":2023,\"races\":[]}]"; + private String expectedMessageAddRace = "{\"id\":1,\"year\":2023,\"races\":[{\"" + + "id\":1,\"name\":\"Monaco Grand Prix 2023\"}]}"; + + @Autowired + private MockMvc mockMvc; + + @MockBean + private SeasonRepository seasonRepository; + + @MockBean + private RaceRepository raceRepository; + + @BeforeEach + void setup() { + Season seasonDao = SeasonTestUtil.getDaoSeason(); + Race raceDao = RaceTestUtil.getDaoRace(); + given(seasonRepository.save(any(Season.class))).willReturn( + seasonDao); + given(seasonRepository.findById(anyLong())).willReturn( + Optional.of(seasonDao)); + given(seasonRepository.findAll()).willReturn(List.of(seasonDao)); + given(raceRepository.findById(anyLong())).willReturn( + Optional.of(raceDao)); + } + + + @Test + void createSeason() throws Exception { + var request = post("/season/") + .content(bodyContent) + .contentType(MediaType.APPLICATION_JSON_VALUE); + this.mockMvc.perform(request) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(expectedMessagePost)); + } + + @Test + void deleteRace() throws Exception { + var requestDelete = delete("/season/") + .param("seasonId", "1") + .contentType(MediaType.APPLICATION_JSON_VALUE); + this.mockMvc.perform(requestDelete) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(expectedMessageDelete)); + } + + @Test + void getExistingRace() throws Exception { + var requestGet = get("/season/id") + .param("seasonId", "1") + .contentType(MediaType.APPLICATION_JSON_VALUE); + this.mockMvc.perform(requestGet) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(expectedMessageGet)); + } + + @Test + void getAllRaces() throws Exception { + var requestGet = get("/season/"); + this.mockMvc.perform(requestGet) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(expectedMessageGetAll)); + } + + @Test + void addRace() throws Exception { + var requestPatch = patch("/season/addRace") + .param("seasonId", "1") + .param("raceId", "1"); + this.mockMvc.perform(requestPatch) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(expectedMessageAddRace)); + } +} diff --git a/race/src/test/java/cz/muni/pa165/race/rest/SeasonTestUtil.java b/race/src/test/java/cz/muni/pa165/race/rest/SeasonTestUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..7c73931528a779d6004cb7db18fed7b641150cee --- /dev/null +++ b/race/src/test/java/cz/muni/pa165/race/rest/SeasonTestUtil.java @@ -0,0 +1,22 @@ +package cz.muni.pa165.race.rest; + +import cz.muni.pa165.race.data.model.Season; +import java.util.ArrayList; + +/** + * Utils for season tests. + */ +public class SeasonTestUtil { + /** + * Returns a created Season. + * + * @return a season. + */ + public static Season getDaoSeason() { + return Season.builder() + .id(1L) + .seasonYear(2023) + .races(new ArrayList<>()) + .build(); + } +}