diff --git a/car/src/main/java/cz/muni/pa165/car/rest/CarComponentPairController.java b/car/src/main/java/cz/muni/pa165/car/rest/CarComponentPairController.java index 8cbf5a412fee36051c429724beaf427698a88b8f..43cf40b0b66143af418f82c9820ab94525f63cc4 100644 --- a/car/src/main/java/cz/muni/pa165/car/rest/CarComponentPairController.java +++ b/car/src/main/java/cz/muni/pa165/car/rest/CarComponentPairController.java @@ -1,14 +1,16 @@ package cz.muni.pa165.car.rest; +import cz.muni.pa165.car.restemplate.DbGetter; import cz.muni.pa165.car.service.CarComponentPairService; -import cz.muni.pa165.common_library.dtos.CarComponentDto; -import cz.muni.pa165.common_library.dtos.CarRequestDto; +import cz.muni.pa165.common_library.dtos.CarComponentResponseDto; import cz.muni.pa165.common_library.dtos.CarResponseDto; import io.swagger.v3.oas.annotations.Operation; +import java.util.ArrayList; import java.util.List; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -65,11 +67,47 @@ public class CarComponentPairController { * @return List of components. */ @Operation(summary = "Get all components of a car") - @PutMapping(path = "/getcomponents", + @GetMapping(path = "/getcomponents", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity<List<CarComponentDto>> getAllComponentsOfCar(@RequestParam Long carId) { + public ResponseEntity<List<CarComponentResponseDto>> + getAllComponentsOfCar(@RequestParam Long carId) { return ResponseEntity.ok(carComponentService.getAllComponentsOfCar(carId)); } + /** + * For a given car ID and a component ID of that car returns a list of components + * of the same name. + * + * @param carId Id of a car. + * @param componentId Id of a component of the given car. + * @return list of all spare components of the same name. + */ + @Operation(summary = "Get all components from component repo") + @GetMapping(path = "/getsparecomponents", + produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity<List<CarComponentResponseDto>> + getAllCarComponents(@RequestParam Long carId, @RequestParam Long componentId) { + List<CarComponentResponseDto> allComponents = DbGetter.getAllComponentsFromDb(); + var carComponentsResponse = getAllComponentsOfCar(carId); + var carComponents = carComponentsResponse.getBody(); + CarComponentResponseDto requestedComponent = null; + assert carComponents != null; + for (CarComponentResponseDto carComponent : allComponents) { + if (carComponent.getId().equals(componentId)) { + requestedComponent = carComponent; + break; + } + } + assert requestedComponent != null; + List<CarComponentResponseDto> allViableReplacements = new ArrayList<>(); + for (CarComponentResponseDto carComponent : allComponents) { + if (carComponent.getName().equals(requestedComponent.getName()) + && !carComponent.getId().equals(componentId)) { + allViableReplacements.add(carComponent); + } + } + return ResponseEntity.ok(allViableReplacements); + } + } diff --git a/car/src/main/java/cz/muni/pa165/car/restemplate/DbGetter.java b/car/src/main/java/cz/muni/pa165/car/restemplate/DbGetter.java index 54a6b16b852ed60be6370c302da1dc134cbe3167..d417c46ae9bfbaae719183f16c7eca1f0a9d8f63 100644 --- a/car/src/main/java/cz/muni/pa165/car/restemplate/DbGetter.java +++ b/car/src/main/java/cz/muni/pa165/car/restemplate/DbGetter.java @@ -1,7 +1,9 @@ package cz.muni.pa165.car.restemplate; -import cz.muni.pa165.common_library.dtos.CarComponentDto; +import cz.muni.pa165.common_library.dtos.CarComponentResponseDto; import cz.muni.pa165.common_library.dtos.DriverInsightDto; +import java.util.Arrays; +import java.util.List; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; @@ -14,8 +16,9 @@ public class DbGetter { private RestTemplate client = new RestTemplate(); - private final String GET_DRIVER_URL = "http://localhost:8083/driver/get/id="; - private final String GET_COMPONENT_URL = "http://localhost:8084/component/id?componentId="; + private static final String GET_DRIVER_URL = "http://localhost:8083/driver/get/id="; + private static final String GET_COMPONENT_URL = "http://localhost:8084/component/id?componentId="; + private static final String GET_ALL_COMPONENTS = "http://localhost:8084/component/"; /** * Get a driver using RestTemplate client. @@ -35,10 +38,25 @@ public class DbGetter { * @param id component id * @return Component object */ - public CarComponentDto getComponentFromDb(Long id) { + public CarComponentResponseDto getComponentFromDb(Long id) { String url = GET_COMPONENT_URL + id; - ResponseEntity<CarComponentDto> response = client.getForEntity(url, CarComponentDto.class); + ResponseEntity<CarComponentResponseDto> response = + client.getForEntity(url, CarComponentResponseDto.class); return response.getBody(); } + /** + * Calls endpoint of the CarComponent module and retrieves all the car components in db. + * + * @return List of all car components in database. + */ + public List<CarComponentResponseDto> getAllComponentsFromDb() { + String url = GET_ALL_COMPONENTS; + var response = + client.getForEntity(url, CarComponentResponseDto[].class); + CarComponentResponseDto[] carComponents = response.getBody(); + assert carComponents != null; + return Arrays.stream(carComponents).toList(); + } + } diff --git a/car/src/main/java/cz/muni/pa165/car/service/CarComponentPairService.java b/car/src/main/java/cz/muni/pa165/car/service/CarComponentPairService.java index fe30d471d2b315044e7716718298aed3a230d51f..cc07096cba91a37a51a067259def6fdb5206b0f8 100644 --- a/car/src/main/java/cz/muni/pa165/car/service/CarComponentPairService.java +++ b/car/src/main/java/cz/muni/pa165/car/service/CarComponentPairService.java @@ -1,6 +1,6 @@ package cz.muni.pa165.car.service; -import cz.muni.pa165.common_library.dtos.CarComponentDto; +import cz.muni.pa165.common_library.dtos.CarComponentResponseDto; import cz.muni.pa165.common_library.dtos.CarResponseDto; import java.util.List; @@ -32,6 +32,5 @@ public interface CarComponentPairService { * @param carId Id of the car. * @return Components of the cat. */ - List<CarComponentDto> getAllComponentsOfCar(Long carId); - + List<CarComponentResponseDto> getAllComponentsOfCar(Long carId); } diff --git a/car/src/main/java/cz/muni/pa165/car/service/CarComponentPairServiceImpl.java b/car/src/main/java/cz/muni/pa165/car/service/CarComponentPairServiceImpl.java index f955921101baabe7ac0c072778e630da463567b5..f18115ff348ccfaab83eff7e3e2be9a6f6c07cc4 100644 --- a/car/src/main/java/cz/muni/pa165/car/service/CarComponentPairServiceImpl.java +++ b/car/src/main/java/cz/muni/pa165/car/service/CarComponentPairServiceImpl.java @@ -5,7 +5,7 @@ import cz.muni.pa165.car.restemplate.DbGetter; import cz.muni.pa165.car.data.model.Car; import cz.muni.pa165.car.data.repository.CarRepository; import cz.muni.pa165.car.mapper.CarMapper; -import cz.muni.pa165.common_library.dtos.CarComponentDto; +import cz.muni.pa165.common_library.dtos.CarComponentResponseDto; import cz.muni.pa165.common_library.dtos.CarResponseDto; import cz.muni.pa165.common_library.exception.DatabaseException; import java.util.ArrayList; @@ -15,6 +15,7 @@ import java.util.Objects; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; /** * Service for manipulation with car's components. @@ -37,6 +38,7 @@ public class CarComponentPairServiceImpl implements CarComponentPairService { } @Override + @Transactional public CarResponseDto addComponent(Long componentId, Long carId) { var car = carRepository.findById(carId).orElseThrow( () -> new DatabaseException("Car not found")); @@ -45,7 +47,7 @@ public class CarComponentPairServiceImpl implements CarComponentPairService { throw new DatabaseException("Component with id " + componentId + " already in use"); } var components = car.getComponents(); - CarComponentDto carComponent = dbGetter.getComponentFromDb(componentId); + CarComponentResponseDto carComponent = dbGetter.getComponentFromDb(componentId); components.add(carComponent.getId()); car.setComponents(components); carRepository.save(car); @@ -68,14 +70,15 @@ public class CarComponentPairServiceImpl implements CarComponentPairService { } @Override - public List<CarComponentDto> getAllComponentsOfCar(Long carId) { + @Transactional(readOnly = true) + public List<CarComponentResponseDto> getAllComponentsOfCar(Long carId) { var car = carRepository.findById(carId).orElseThrow( () -> new DatabaseException("Car not found")); - var componentDtos = new ArrayList<CarComponentDto>(); + var componentDtos = new ArrayList<CarComponentResponseDto>(); for (Long id : car.getComponents()) { - CarComponentDto carComponent = dbGetter.getComponentFromDb(id); + CarComponentResponseDto carComponent = dbGetter.getComponentFromDb(id); componentDtos.add( - new CarComponentDto( + new CarComponentResponseDto( carComponent.getId(), carComponent.getWeight(), carComponent.getPrice(), diff --git a/car/src/main/java/cz/muni/pa165/car/service/CarDriverPairServiceImpl.java b/car/src/main/java/cz/muni/pa165/car/service/CarDriverPairServiceImpl.java index dcfc6401d1066f9abe1604f66b03ff36a3d88ec9..06ff7817356b5b602ec3a1d96e04ee19faefd4c7 100644 --- a/car/src/main/java/cz/muni/pa165/car/service/CarDriverPairServiceImpl.java +++ b/car/src/main/java/cz/muni/pa165/car/service/CarDriverPairServiceImpl.java @@ -1,5 +1,6 @@ package cz.muni.pa165.car.service; + import cz.muni.pa165.car.data.repository.CarRepository; import cz.muni.pa165.car.mapper.CarMapper; import cz.muni.pa165.car.restemplate.DbGetter; @@ -14,6 +15,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Objects; +import org.springframework.transaction.annotation.Transactional; /** * Service for Driver Manager. @@ -36,6 +38,7 @@ public class CarDriverPairServiceImpl implements CarDriverPairService { } @Override + @Transactional public CarResponseDto assignDriverToCar(Long driverId, Long carId) { var car = carRepository.findById(carId).orElseThrow( () -> new DatabaseException("Car not found")); @@ -50,6 +53,7 @@ public class CarDriverPairServiceImpl implements CarDriverPairService { } @Override + @Transactional public CarResponseDto unassignDriverFromCar(Long driverId, Long carId) { var car = carRepository.findById(carId).orElseThrow( () -> new DatabaseException("Car not found")); @@ -81,6 +85,7 @@ public class CarDriverPairServiceImpl implements CarDriverPairService { } @Override + @Transactional public CarResponseDto setMainDriver(Long carId, Long driverId) { var car = carRepository.findById(carId).orElseThrow( () -> new DatabaseException("Car not found")); @@ -96,6 +101,7 @@ public class CarDriverPairServiceImpl implements CarDriverPairService { } @Override + @Transactional public CarResponseDto removeMainDriver(Long carId) { var car = carRepository.findById(carId).orElseThrow( () -> new DatabaseException("Car not found")); diff --git a/car/src/main/java/cz/muni/pa165/car/service/CarServiceImpl.java b/car/src/main/java/cz/muni/pa165/car/service/CarServiceImpl.java index 1f2d832d06f35b77fcfa17bc07d75f92dd241165..40c903fa063f5653f93fdaa24096286795b53b21 100644 --- a/car/src/main/java/cz/muni/pa165/car/service/CarServiceImpl.java +++ b/car/src/main/java/cz/muni/pa165/car/service/CarServiceImpl.java @@ -11,6 +11,7 @@ import cz.muni.pa165.common_library.dtos.CarResponseDto; import cz.muni.pa165.common_library.exception.DatabaseException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.List; @@ -36,6 +37,7 @@ public class CarServiceImpl implements CarService { } @Override + @Transactional public CarResponseDto postCar(CarRequestDto carRequestDto) { var componentIds = carRequestDto.getComponentIds(); @@ -49,6 +51,7 @@ public class CarServiceImpl implements CarService { } @Override + @Transactional(readOnly = true) public CarResponseDto getCarById(Long carId) { return carConverterToDto(carRepository.findById(carId).orElseThrow( () -> new DatabaseException( @@ -58,6 +61,7 @@ public class CarServiceImpl implements CarService { } @Override + @Transactional(readOnly = true) public List<CarResponseDto> getAllCars() { return carRepository .findAll() @@ -67,6 +71,7 @@ public class CarServiceImpl implements CarService { } @Override + @Transactional public String deleteById(Long carId) { carRepository.deleteById(carId); return "Car with id = " + carId + " deleted!"; diff --git a/common_library/pom.xml b/common_library/pom.xml index c01b20c9c8ec27c1f8320d5de771b70a9b75a92b..195dc97c6e5d310186319549d04c1595b23b0a1f 100644 --- a/common_library/pom.xml +++ b/common_library/pom.xml @@ -55,7 +55,7 @@ <dependency> <groupId>io.swagger</groupId> <artifactId>swagger-annotations</artifactId> - <version>1.6.2</version> + <version>1.6.9</version> </dependency> <dependency> <groupId>org.apache.httpcomponents.client5</groupId> diff --git a/common_library/src/main/java/cz/muni/pa165/common_library/dtos/CarComponentRequestDto.java b/common_library/src/main/java/cz/muni/pa165/common_library/dtos/CarComponentRequestDto.java new file mode 100644 index 0000000000000000000000000000000000000000..24e808786ece2cc9a7c0b01e54d831716d231f8d --- /dev/null +++ b/common_library/src/main/java/cz/muni/pa165/common_library/dtos/CarComponentRequestDto.java @@ -0,0 +1,34 @@ +package cz.muni.pa165.common_library.dtos; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import java.math.BigDecimal; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Data Transfer object for CarComponent class. + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class CarComponentRequestDto { + @NotNull + @Schema(description = "component weight", example = "50") + BigDecimal weight; + + @NotNull + @Schema(description = "component price", example = "24000") + BigDecimal price; + + @NotNull + @Schema(description = "name of the manufacturer", example = "Michellin") + String manufacturer; + + @NotNull + @Schema(description = "component name", example = "Default engine") + String name; +} diff --git a/common_library/src/main/java/cz/muni/pa165/common_library/dtos/CarComponentDto.java b/common_library/src/main/java/cz/muni/pa165/common_library/dtos/CarComponentResponseDto.java similarity index 95% rename from common_library/src/main/java/cz/muni/pa165/common_library/dtos/CarComponentDto.java rename to common_library/src/main/java/cz/muni/pa165/common_library/dtos/CarComponentResponseDto.java index f34f23030a25f4e365386384f09ceddaa031a978..3d8c5a12c7aab3a4b4b45d8309f28890aac81c00 100644 --- a/common_library/src/main/java/cz/muni/pa165/common_library/dtos/CarComponentDto.java +++ b/common_library/src/main/java/cz/muni/pa165/common_library/dtos/CarComponentResponseDto.java @@ -15,7 +15,7 @@ import lombok.NoArgsConstructor; @Builder @NoArgsConstructor @AllArgsConstructor -public class CarComponentDto { +public class CarComponentResponseDto { @NotNull @Schema(description = "component id", example = "1") 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/component/src/main/java/cz/muni/pa165/component/rest/ComponentController.java b/component/src/main/java/cz/muni/pa165/component/rest/ComponentController.java index d4d15522bb67540e27ac43cfbff78cffff2c34d6..9fa71ac3049f58f753eb57e2ad2d33075ce2460b 100644 --- a/component/src/main/java/cz/muni/pa165/component/rest/ComponentController.java +++ b/component/src/main/java/cz/muni/pa165/component/rest/ComponentController.java @@ -1,6 +1,7 @@ package cz.muni.pa165.component.rest; -import cz.muni.pa165.common_library.dtos.CarComponentDto; +import cz.muni.pa165.common_library.dtos.CarComponentRequestDto; +import cz.muni.pa165.common_library.dtos.CarComponentResponseDto; import cz.muni.pa165.component.service.ComponentServiceInterface; import io.swagger.v3.oas.annotations.Operation; import jakarta.validation.Valid; @@ -33,8 +34,8 @@ public class ComponentController { @Operation(summary = "Create new component") @PostMapping(path = "/", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity<CarComponentDto> createComponent( - @Valid @RequestBody CarComponentDto carComponent) { + public ResponseEntity<CarComponentResponseDto> createComponent( + @Valid @RequestBody CarComponentRequestDto carComponent) { return ResponseEntity.ok(componentService.postCarComponent(carComponent)); } @@ -48,14 +49,15 @@ public class ComponentController { @Operation(summary = "Get a car component") @GetMapping(path = "/id", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity<CarComponentDto> getComponent(@Valid @RequestParam long componentId) { + public ResponseEntity<CarComponentResponseDto> + getComponent(@Valid @RequestParam long componentId) { return ResponseEntity.ok(componentService.getCarComponentById(componentId)); } @Operation(summary = "Get all car components") @GetMapping(path = "/", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity<List<CarComponentDto>> getComponents() { + public ResponseEntity<List<CarComponentResponseDto>> getComponents() { return ResponseEntity.ok(componentService.getAllCarComponents()); } } diff --git a/component/src/main/java/cz/muni/pa165/component/service/ComponentService.java b/component/src/main/java/cz/muni/pa165/component/service/ComponentService.java index 67fbb02d068d48abe0c2728616177187f06d5137..58042fa226dda885ed35bf5a77938d8dc014bd0a 100644 --- a/component/src/main/java/cz/muni/pa165/component/service/ComponentService.java +++ b/component/src/main/java/cz/muni/pa165/component/service/ComponentService.java @@ -1,12 +1,14 @@ package cz.muni.pa165.component.service; -import cz.muni.pa165.common_library.dtos.CarComponentDto; +import cz.muni.pa165.common_library.dtos.CarComponentRequestDto; +import cz.muni.pa165.common_library.dtos.CarComponentResponseDto; import cz.muni.pa165.common_library.exception.DatabaseException; import cz.muni.pa165.component.data.model.CarComponent; import cz.muni.pa165.component.data.repository.ComponentRepositoryInterface; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; /** @@ -22,9 +24,9 @@ public class ComponentService implements ComponentServiceInterface { this.componentRepository = componentRepository; } - public CarComponentDto postCarComponent(CarComponentDto carComponentDto) { + public CarComponentResponseDto postCarComponent(CarComponentRequestDto carComponentDto) { return carComponentConverter(componentRepository.save( - carComponentDtoConverter(carComponentDto))); + carComponentDtoConverterWithoutId(carComponentDto))); } /** @@ -33,7 +35,8 @@ public class ComponentService implements ComponentServiceInterface { * @param carComponentId id of the component. * @return found car component. */ - public CarComponentDto getCarComponentById(Long carComponentId) { + @Transactional(readOnly = true) + public CarComponentResponseDto getCarComponentById(Long carComponentId) { return carComponentConverter(componentRepository.findById(carComponentId).orElseThrow( () -> new DatabaseException("Something went wrong when finding car component with id: " + carComponentId + " in the database."))); @@ -44,7 +47,8 @@ public class ComponentService implements ComponentServiceInterface { * * @return list of stored car components. */ - public List<CarComponentDto> getAllCarComponents() { + @Transactional(readOnly = true) + public List<CarComponentResponseDto> getAllCarComponents() { return componentRepository.findAll() .stream() .map(this::carComponentConverter) @@ -56,12 +60,23 @@ public class ComponentService implements ComponentServiceInterface { * * @param carComponentId of the car component for removal. */ + @Transactional public String deleteById(Long carComponentId) { componentRepository.deleteById(carComponentId); return "Car component with id: " + carComponentId + "was successfully deleted"; } - CarComponent carComponentDtoConverter(CarComponentDto carComponentDto) { + CarComponent carComponentDtoConverterWithoutId(CarComponentRequestDto carComponentDto) { + return CarComponent.builder() + .id(null) + .weight(carComponentDto.getWeight()) + .price(carComponentDto.getPrice()) + .manufacturer(carComponentDto.getManufacturer()) + .name(carComponentDto.getName()) + .build(); + } + + CarComponent carComponentDtoConverter(CarComponentResponseDto carComponentDto) { return CarComponent.builder() .id(carComponentDto.getId()) .weight(carComponentDto.getWeight()) @@ -71,8 +86,8 @@ public class ComponentService implements ComponentServiceInterface { .build(); } - CarComponentDto carComponentConverter(CarComponent carComponent) { - return CarComponentDto.builder() + CarComponentResponseDto carComponentConverter(CarComponent carComponent) { + return CarComponentResponseDto.builder() .id(carComponent.getId()) .weight(carComponent.getWeight()) .price(carComponent.getPrice()) diff --git a/component/src/main/java/cz/muni/pa165/component/service/ComponentServiceInterface.java b/component/src/main/java/cz/muni/pa165/component/service/ComponentServiceInterface.java index 4ce60cfef740497e72bff9a7b9025491c74d45c5..3cb71c2fa7e8a4dde9cc15388b63d643d9a0f869 100644 --- a/component/src/main/java/cz/muni/pa165/component/service/ComponentServiceInterface.java +++ b/component/src/main/java/cz/muni/pa165/component/service/ComponentServiceInterface.java @@ -1,6 +1,7 @@ package cz.muni.pa165.component.service; -import cz.muni.pa165.common_library.dtos.CarComponentDto; +import cz.muni.pa165.common_library.dtos.CarComponentRequestDto; +import cz.muni.pa165.common_library.dtos.CarComponentResponseDto; import java.util.List; @@ -9,11 +10,11 @@ import java.util.List; */ public interface ComponentServiceInterface { - public CarComponentDto postCarComponent(CarComponentDto carComponentDto); + public CarComponentResponseDto postCarComponent(CarComponentRequestDto carComponentDto); - public CarComponentDto getCarComponentById(Long carComponentId); + public CarComponentResponseDto getCarComponentById(Long carComponentId); - public List<CarComponentDto> getAllCarComponents(); + public List<CarComponentResponseDto> getAllCarComponents(); public String deleteById(Long carComponentId); diff --git a/driver/src/main/java/cz/muni/pa165/driver/App.java b/driver/src/main/java/cz/muni/pa165/driver/App.java index d506128e67d67d4270ed020b3d05a4edb9567a2d..0e89a464efbfb9a0f5ad78993ba5329829cd0b7e 100644 --- a/driver/src/main/java/cz/muni/pa165/driver/App.java +++ b/driver/src/main/java/cz/muni/pa165/driver/App.java @@ -11,7 +11,7 @@ import org.springframework.data.jpa.repository.config.EnableJpaRepositories; * Main app. */ @SpringBootApplication -@EnableJpaRepositories(basePackages = {"cz.muni.pa165.driver.data.repository"}) +//@EnableJpaRepositories(basePackages = {"cz.muni.pa165.driver.data.repository"}) @EntityScan(basePackages = {"cz.muni.pa165.driver.data.model"}) @Import(RestExceptionHandler.class) public class App { diff --git a/driver/src/main/java/cz/muni/pa165/driver/service/DriverServiceImpl.java b/driver/src/main/java/cz/muni/pa165/driver/service/DriverServiceImpl.java index e6b0e4b37dbd711fef628ef0ee5ac687944ab97d..3aa0f458c1b74cd297b3bc7aa1a9dfb8a0b728b4 100644 --- a/driver/src/main/java/cz/muni/pa165/driver/service/DriverServiceImpl.java +++ b/driver/src/main/java/cz/muni/pa165/driver/service/DriverServiceImpl.java @@ -12,6 +12,7 @@ import java.util.List; import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; /** * Implementation of driver service. @@ -34,6 +35,7 @@ public class DriverServiceImpl implements DriverService { * @param driverAddDto driver dto object * @return dto of added driver */ + @Transactional public DriverResponseDto addDriver(DriverAddDto driverAddDto) { var driver = driverMapper.convertToDriver(driverAddDto); return driverMapper.convertToResponseDto(driverRepository.save(driver)); @@ -46,6 +48,7 @@ public class DriverServiceImpl implements DriverService { * @param driverUpdateDto data to be updated * @return dto of updated driver */ + @Transactional public DriverResponseDto updateDriverById(Long id, DriverUpdateDto driverUpdateDto) { var driver = driverRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("Driver with given id not found.")); @@ -59,6 +62,7 @@ public class DriverServiceImpl implements DriverService { * @param driver existing driver * @param driverUpdateDto driver update dto */ + @Transactional private static void updateDriverAttributes(Driver driver, DriverUpdateDto driverUpdateDto) { if (driverUpdateDto.name() != null) { driver.setName(driverUpdateDto.name()); @@ -80,6 +84,7 @@ public class DriverServiceImpl implements DriverService { * @param id driver id * @return dto of removed driver */ + @Transactional public DriverResponseDto removeDriverById(Long id) { var found = driverRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException( @@ -93,7 +98,9 @@ public class DriverServiceImpl implements DriverService { * * @return all stored drivers dto list */ + @Transactional(readOnly = true) public List<DriverInsightDto> getAllDrivers() { + System.out.println(); return driverRepository.findAll() .stream() .map(driverMapper::convertToInsightDto) @@ -106,6 +113,7 @@ public class DriverServiceImpl implements DriverService { * @param id driver id * @return found driver dto if successful */ + @Transactional(readOnly = true) public DriverInsightDto getDriverById(Long id) { return driverMapper.convertToInsightDto(driverRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException( diff --git a/driver/src/test/java/cz/muni/pa165/driver/rest/DriverControllerItTest.java b/driver/src/test/java/cz/muni/pa165/driver/rest/DriverControllerItTest.java deleted file mode 100644 index 13814dafebd455689e3caa59be35518bb2b68a8a..0000000000000000000000000000000000000000 --- a/driver/src/test/java/cz/muni/pa165/driver/rest/DriverControllerItTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package cz.muni.pa165.driver.rest; - -import cz.muni.pa165.driver.data.model.Driver; -import cz.muni.pa165.driver.data.repository.DriverRepository; -import java.util.Map; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@DataJpaTest -class DriverControllerItTest { - - @Autowired - private TestEntityManager entityManager; - - @Autowired - private DriverRepository driverRepository; - - @Test - public void testSave() { - Driver driver = Driver.builder() - .name("name") - .surname("surname") - .nationality("nationality") - .characteristics(Map.of()).build(); - - Driver savedDriver = driverRepository.save(driver); - - Assertions.assertEquals(savedDriver, driver); - Assertions.assertEquals(entityManager.find(Driver.class, 1L).getId(), 1); - } - -} diff --git a/driver/src/test/java/cz/muni/pa165/driver/rest/DriverControllerTest.java b/driver/src/test/java/cz/muni/pa165/driver/rest/DriverControllerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..269f098673181be0e2146a68417090983c4c85d8 --- /dev/null +++ b/driver/src/test/java/cz/muni/pa165/driver/rest/DriverControllerTest.java @@ -0,0 +1,135 @@ +package cz.muni.pa165.driver.rest; + +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.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.fasterxml.jackson.databind.ObjectMapper; +import cz.muni.pa165.common_library.dtos.DriverInsightDto; +import cz.muni.pa165.common_library.dtos.DriverResponseDto; +import cz.muni.pa165.common_library.dtos.DriverUpdateDto; +import cz.muni.pa165.driver.service.DriverService; +import java.util.List; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +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; + +@WebMvcTest(controllers = DriverController.class) +class DriverControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @MockBean + private DriverService driverService; + + @Test + void driverAddTest() throws Exception { + + var driver = DriverTestUtil.getAddDriver(); + given(driverService.addDriver(driver)).willReturn(new DriverResponseDto(1L)); + + String response = mockMvc.perform(post("/driver/add") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(driver))) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + DriverResponseDto driverResponseDto = objectMapper.readValue(response, DriverResponseDto.class); + Assertions.assertEquals(1L, driverResponseDto.id()); + } + + @Test + void badRequestTest() throws Exception { + + var driver = DriverTestUtil.getAddDriver(); + given(driverService.addDriver(driver)).willReturn(new DriverResponseDto(1L)); + + mockMvc.perform(post("/driver/add") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString("INVALID CONTENT"))) + .andExpect(status().isBadRequest()); + + } + + @Test + void driverGetAllTest() throws Exception { + + var driver = DriverTestUtil.getAddDriver(); + given(driverService.getAllDrivers()).willReturn(List.of(DriverTestUtil.getInsightDriver())); + + String response = mockMvc.perform(get("/driver/get/all")) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + var driverResponseDto = objectMapper.readValue(response, DriverInsightDto[].class); + Assertions.assertAll( + () -> Assertions.assertEquals(1L, driverResponseDto[0].id()), + () -> Assertions.assertEquals(driver.name(), driverResponseDto[0].name()), + () -> Assertions.assertEquals(driver.surname(), driverResponseDto[0].surname()), + () -> Assertions.assertEquals(driver.characteristics(), + driverResponseDto[0].characteristics()) + ); + } + + @Test + void driverDeleteTest() throws Exception { + + given(driverService.removeDriverById(anyLong())).willReturn(new DriverResponseDto(1L)); + + String response = mockMvc.perform(delete("/driver/remove/id=1")) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + var driverResponseDto = objectMapper.readValue(response, DriverResponseDto.class); + Assertions.assertEquals(1L, driverResponseDto.id()); + } + + @Test + void invalidPathTest() throws Exception { + + mockMvc.perform(get("/invalidPath")) + .andExpect(status().isNotFound()); + } + + @Test + void driverGetByIdTest() throws Exception { + + var driver = DriverTestUtil.getAddDriver(); + given(driverService.getDriverById(anyLong())).willReturn(DriverTestUtil.getInsightDriver()); + + String response = mockMvc.perform(get("/driver/get/id=1")) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + var driverResponseDto = objectMapper.readValue(response, DriverInsightDto.class); + Assertions.assertAll( + () -> Assertions.assertEquals(1L, driverResponseDto.id()), + () -> Assertions.assertEquals(driver.name(), driverResponseDto.name()), + () -> Assertions.assertEquals(driver.surname(), driverResponseDto.surname()), + () -> Assertions.assertEquals(driver.characteristics(), driverResponseDto.characteristics()) + ); + } + + @Test + void driverUpdateByIdTest() throws Exception { + DriverUpdateDto driverUpdateDto = DriverTestUtil.getUpdateDriver(); + given(driverService.updateDriverById(1L, driverUpdateDto)).willReturn( + new DriverResponseDto(1L)); + + String response = mockMvc.perform(put("/driver/update/id=1") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(driverUpdateDto))) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + var driverResponseDto = objectMapper.readValue(response, DriverResponseDto.class); + Assertions.assertEquals(1L, driverResponseDto.id()); + } +} diff --git a/driver/src/test/java/cz/muni/pa165/driver/rest/DriverInitControllerTest.java b/driver/src/test/java/cz/muni/pa165/driver/rest/DriverInitControllerTest.java deleted file mode 100644 index 1cf26d819fdf90fff4946145a8f85bbe465a6eb4..0000000000000000000000000000000000000000 --- a/driver/src/test/java/cz/muni/pa165/driver/rest/DriverInitControllerTest.java +++ /dev/null @@ -1,74 +0,0 @@ -package cz.muni.pa165.driver.rest; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; - -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -@AutoConfigureMockMvc -class DriverInitControllerTest { - -// @Autowired -// private MockMvc mockMvc; -// -// @Autowired -// private ObjectMapper objectMapper; -// -// @Autowired -// private DriverInitService driverInitService; -// -// @Test -// void driverAddTest() throws Exception { -// -// Driver driver = getDriver(); -// Driver driverService = driverInitService.addDriver(driver); -// -// String response = mockMvc.perform(post("/driver/add") -// .contentType(MediaType.APPLICATION_JSON) -// .content(objectMapper.writeValueAsString(driver))) -// .andExpect(status().isOk()) -// .andReturn(). ().getContentAsString(); -// Driver driverController = objectMapper.readValue(response, Driver.class); -// assertingDriver(driverService, driverController); -// } -// -// @Test -// void driverRemoveTest() throws Exception { -// -// Driver driver = getDriver(); -// Driver driverService = driverInitService.removeDriver(driver.getId()); -// -// String response = mockMvc.perform(delete("/driver/remove").queryParam("driverId", -// String.valueOf(driver.getId()))) -// .andExpect(status().isOk()) -// .andReturn().getResponse().getContentAsString(); -// Driver driverController = objectMapper.readValue(response, Driver.class); -// assertingDriver(driverService, driverController); -// } -// -// private void assertingDriver(Driver driverService, Driver driverController) { -// Assertions.assertAll( -// () -> Assertions.assertEquals(driverService.getId(), driverController.getId()), -// () -> Assertions.assertEquals(driverService.getName(), driverController.getName()), -// () -> Assertions.assertEquals(driverService.getCharacteristics(), -// driverController.getCharacteristics()), -// () -> Assertions.assertEquals(driverService.getNationality(), -// driverController.getNationality()), -// () -> Assertions.assertEquals(driverService.isMain(), driverController.isMain()), -// () -> Assertions.assertEquals(driverService.getSurname(), driverController.getSurname()) -// ); -// } -// -// private Driver getDriver() { -// Driver driver = new Driver(); -// driver.setId(2L); -// driver.setMain(false); -// driver.setSurname("surname"); -// driver.setName("name"); -// driver.setCharacteristics(Set.of(Characteristic.INTELLIGENCE)); -// driver.setNationality("nationality"); -// return driver; -// } -} diff --git a/driver/src/test/java/cz/muni/pa165/driver/rest/DriverInitControllerUnitTest.java b/driver/src/test/java/cz/muni/pa165/driver/rest/DriverInitControllerUnitTest.java deleted file mode 100644 index 17491c352ab50632a4a7bddacce349f0bb0e2e86..0000000000000000000000000000000000000000 --- a/driver/src/test/java/cz/muni/pa165/driver/rest/DriverInitControllerUnitTest.java +++ /dev/null @@ -1,78 +0,0 @@ -package cz.muni.pa165.driver.rest; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; - -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; - - -/** - * Tests for driver initialization controller. - */ -@WebMvcTest(controllers = DriverController.class) -class DriverInitControllerUnitTest { -// -// @Autowired -// private MockMvc mockMvc; -// -// @MockBean -// private DriverInitFacade driverInitFacade; -// -// @Autowired -// private ObjectMapper objectMapper; -// -// Driver driver; -// long id = 1L; -// String driverName = "Tom"; -// String driverSurname = "Marek"; -// String driverNationality = "Czech"; -// -// @BeforeEach -// void settingUp() { -// driver = new Driver(); -// driver.setId(id); -// driver.setMain(true); -// driver.setName(driverName); -// driver.setSurname(driverSurname); -// driver.setNationality(driverNationality); -// } -// -// -// @Test -// void createDriverTest() throws Exception { -// given(driverInitFacade.addDriver(driver)).willReturn( -// driver); -// mockMvc.perform(post("/driver/add").contentType(MediaType.APPLICATION_JSON) -// .content(objectMapper.writeValueAsString(driver))) -// .andExpect(status().isOk()); -// } -// -// @Test -// void createDriverWithAttributesTest() throws Exception { -// given(driverInitFacade.addDriver(driver)).willReturn( -// driver); -// mockMvc.perform(post("/driver/add").contentType(MediaType.APPLICATION_JSON) -// .content(objectMapper.writeValueAsString(driver))) -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.id").value(id)) -// .andExpect(jsonPath("$.name").value(driverName)) -// .andExpect(jsonPath("$.surname").value(driverSurname)) -// .andExpect(jsonPath("$.main").value(true)) -// .andExpect(jsonPath("$.nationality").value(driverNationality)); -// } -// -// @Test -// void removeDriver() throws Exception { -// given(driverInitFacade.removeDriver(driver.getId())).willReturn( -// driver); -// mockMvc.perform(delete("/driver/remove") -// .queryParam("driverId", String.valueOf(driver.getId()))) -// .andExpect(status().isOk()) -// .andExpect(jsonPath("$.id").value(id)) -// .andExpect(jsonPath("$.name").value(driverName)) -// .andExpect(jsonPath("$.surname").value(driverSurname)) -// .andExpect(jsonPath("$.main").value(true)) -// .andExpect(jsonPath("$.nationality").value(driverNationality)); -// } -} diff --git a/driver/src/test/java/cz/muni/pa165/driver/rest/DriverRepositoryTest.java b/driver/src/test/java/cz/muni/pa165/driver/rest/DriverRepositoryTest.java new file mode 100644 index 0000000000000000000000000000000000000000..50e813f6784f8b1ff1b6f127726d7c54a126f123 --- /dev/null +++ b/driver/src/test/java/cz/muni/pa165/driver/rest/DriverRepositoryTest.java @@ -0,0 +1,109 @@ +package cz.muni.pa165.driver.rest; + +import cz.muni.pa165.driver.data.model.Driver; +import cz.muni.pa165.driver.data.repository.DriverRepository; +import java.util.Map; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@DataJpaTest +class DriverRepositoryTest { + + @Autowired + private TestEntityManager entityManager; + + @Autowired + private DriverRepository driverRepository; + + @Test + void testSave() { + Driver driver = Driver.builder() + .name("name") + .surname("surname") + .nationality("nationality") + .characteristics(Map.of()).build(); + + Driver savedDriver = driverRepository.save(driver); + + Assertions.assertEquals(savedDriver, driver); + Assertions.assertEquals(entityManager.find(Driver.class, savedDriver.getId()), savedDriver); + } + + @Test + void testUpdate() { + Driver driver = Driver.builder() + .name("Name") + .surname("Surname") + .nationality("Nationality") + .characteristics(Map.of()).build(); + + Driver savedDriver = driverRepository.save(driver); + + savedDriver.setName("Updated name"); + savedDriver.setSurname("Updated surname"); + savedDriver.setNationality("Updated nat"); + + driverRepository.save(savedDriver); + + var updatedDriver = driverRepository.findById(savedDriver.getId()).orElseThrow(); + Assertions.assertNotEquals(DriverTestUtil.getDaoDriver(), updatedDriver); + var original = DriverTestUtil.getDaoDriver(); + Assertions.assertAll( + () -> Assertions.assertNotEquals(original.getName(), updatedDriver.getName()), + () -> Assertions.assertNotEquals(original.getSurname(), updatedDriver.getSurname()), + () -> Assertions.assertNotEquals(original.getNationality(), updatedDriver.getNationality()) + ); + Assertions.assertEquals(entityManager.find(Driver.class, savedDriver.getId()), savedDriver); + + } + + @Test + void testNonExistingFind() { + Assertions.assertThrows(Exception.class, () -> driverRepository.findById(-1L).orElseThrow()); + } + + @Test + void testDelete() { + Driver driver = Driver.builder() + .name("Name") + .surname("Surname") + .nationality("Nationality") + .characteristics(Map.of()).build(); + + Driver savedDriver = driverRepository.save(driver); + driverRepository.delete(savedDriver); + + Assertions.assertThrows(Exception.class, () -> driverRepository + .findById(savedDriver.getId()).orElseThrow()); + } + + @Test + void testFindAll() { + Driver driver = Driver.builder() + .name("Name") + .surname("Surname") + .nationality("Nationality") + .characteristics(Map.of()).build(); + + Driver driver2 = Driver.builder() + .name("Name2") + .surname("Surname2") + .nationality("Nationality2") + .characteristics(Map.of()).build(); + + var savedDriver1 = driverRepository.save(driver); + var savedDriver2 = driverRepository.save(driver2); + + var savedDrivers = driverRepository.findAll(); + Assertions.assertEquals(2, savedDrivers.size()); + + Assertions.assertEquals(entityManager.find(Driver.class, savedDriver1.getId()), savedDriver1); + Assertions.assertEquals(entityManager.find(Driver.class, savedDriver2.getId()), savedDriver2); + } +} diff --git a/driver/src/test/java/cz/muni/pa165/driver/rest/DriverServiceTest.java b/driver/src/test/java/cz/muni/pa165/driver/rest/DriverServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..6eb536cc450f63c930e5fca6f0e3b5bf5c615d08 --- /dev/null +++ b/driver/src/test/java/cz/muni/pa165/driver/rest/DriverServiceTest.java @@ -0,0 +1,132 @@ +package cz.muni.pa165.driver.rest; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.when; +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.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.fasterxml.jackson.databind.ObjectMapper; +import cz.muni.pa165.common_library.dtos.DriverInsightDto; +import cz.muni.pa165.common_library.dtos.DriverResponseDto; +import cz.muni.pa165.common_library.dtos.DriverUpdateDto; +import cz.muni.pa165.driver.data.model.Driver; +import cz.muni.pa165.driver.data.repository.DriverRepository; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.Assertions; +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 DriverServiceTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @MockBean + private DriverRepository driverRepository; + + @Test + void driverAddTest() throws Exception { + var driverAddDto = DriverTestUtil.getAddDriver(); + Driver driverDao = DriverTestUtil.getDaoDriver(); + given(driverRepository.save(any(Driver.class))).willReturn( + driverDao); + given(driverRepository.findById(anyLong())).willReturn( + Optional.of(driverDao)); + + String response = mockMvc.perform(post("/driver/add") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(driverAddDto))) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + var driverResponseDto = objectMapper.readValue(response, DriverResponseDto.class); + //Assertions.assertEquals(1L, driverResponseDto.id()); + } + + @Test + void driverGetAllTest() throws Exception { + + var driver = DriverTestUtil.getAddDriver(); + when(driverRepository.findAll()).thenReturn(List.of(DriverTestUtil.getDaoDriver())); + + String response = mockMvc.perform(get("/driver/get/all")) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + var driverResponseDto = objectMapper.readValue(response, DriverInsightDto[].class); + Assertions.assertAll( + () -> Assertions.assertEquals(1L, driverResponseDto[0].id()), + () -> Assertions.assertEquals(driver.name(), driverResponseDto[0].name()), + () -> Assertions.assertEquals(driver.surname(), driverResponseDto[0].surname()), + () -> Assertions.assertEquals(driver.characteristics(), + driverResponseDto[0].characteristics()) + ); + } + + @Test + void driverGetByIdTest() throws Exception { + + var driver = DriverTestUtil.getAddDriver(); + when(driverRepository.findById(1L)).thenReturn(Optional.of(DriverTestUtil.getDaoDriver())); + + String response = mockMvc.perform(get("/driver/get/id=1")) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + var driverResponseDto = objectMapper.readValue(response, DriverInsightDto.class); + Assertions.assertAll( + () -> Assertions.assertEquals(1L, driverResponseDto.id()), + () -> Assertions.assertEquals(driver.name(), driverResponseDto.name()), + () -> Assertions.assertEquals(driver.surname(), driverResponseDto.surname()), + () -> Assertions.assertEquals(driver.characteristics(), + driverResponseDto.characteristics()) + ); + } + + @Test + void driverUpdateByIdTest() throws Exception { + DriverUpdateDto driverUpdateDto = DriverTestUtil.getUpdateDriver(); + Driver driverDao = DriverTestUtil.getDaoDriver(); + given(driverRepository.save(driverDao)).willReturn( + driverDao); + given(driverRepository.findById(anyLong())).willReturn( + Optional.of(driverDao)); + + String response = mockMvc.perform(put("/driver/update/id=1") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(driverUpdateDto))) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + var driverResponseDto = objectMapper.readValue(response, DriverResponseDto.class); + Assertions.assertEquals(1L, driverResponseDto.id()); + } + + @Test + void driverDeleteTest() throws Exception { + DriverUpdateDto driverUpdateDto = DriverTestUtil.getUpdateDriver(); + Driver driverDao = DriverTestUtil.getDaoDriver(); + given(driverRepository.findById(anyLong())).willReturn( + Optional.of(driverDao)); + + String response = mockMvc.perform(delete("/driver/remove/id=1") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(driverUpdateDto))) + .andExpect(status().isOk()) + .andReturn().getResponse().getContentAsString(); + var driverResponseDto = objectMapper.readValue(response, DriverResponseDto.class); + Assertions.assertEquals(1L, driverResponseDto.id()); + } +} diff --git a/driver/src/test/java/cz/muni/pa165/driver/rest/DriverTestUtil.java b/driver/src/test/java/cz/muni/pa165/driver/rest/DriverTestUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..17636a80e5c0aa5660252912ab4028d0c41d630f --- /dev/null +++ b/driver/src/test/java/cz/muni/pa165/driver/rest/DriverTestUtil.java @@ -0,0 +1,58 @@ +package cz.muni.pa165.driver.rest; + +import cz.muni.pa165.common_library.dtos.DriverAddDto; +import cz.muni.pa165.common_library.dtos.DriverInsightDto; +import cz.muni.pa165.common_library.dtos.DriverUpdateDto; +import cz.muni.pa165.driver.data.model.Driver; +import java.util.HashMap; + +/** + * Util for getting driver objects. + */ +public class DriverTestUtil { + + /** + * Get add driver dto. + * + * @return add driver dto object. + */ + public static DriverAddDto getAddDriver() { + return new DriverAddDto("Name", + "Surname", "Nationality", new HashMap<>()); + } + + /** + * Get insight driver dto. + * + * @return insight driver dto object. + */ + public static DriverInsightDto getInsightDriver() { + return new DriverInsightDto(1L, "Name", + "Surname", "Nationality", new HashMap<>()); + } + + /** + * Get update driver dto. + * + * @return update driver dto object. + */ + public static DriverUpdateDto getUpdateDriver() { + return new DriverUpdateDto("Name", + "Surname", "Nationality", new HashMap<>()); + } + + /** + * Get entity driver object. + * + * @return entity driver object. + */ + public static Driver getDaoDriver() { + return Driver.builder() + .name("Name") + .id(1L) + .surname("Surname") + .nationality("Nationality") + .characteristics(new HashMap<>()) + .build(); + } +} diff --git a/race/src/main/java/cz/muni/pa165/race/rest/RaceController.java b/race/src/main/java/cz/muni/pa165/race/rest/RaceController.java index 907c1066bfcde52f66c95b7c435817bd4d882bde..d9ef0981a81cd5921c9a4e8afa7e93edf58dbb99 100644 --- a/race/src/main/java/cz/muni/pa165/race/rest/RaceController.java +++ b/race/src/main/java/cz/muni/pa165/race/rest/RaceController.java @@ -88,7 +88,7 @@ public class RaceController { return ResponseEntity.ok(raceService.assignPositionForDriverTwo(raceId, position)); } - @Operation(summary = "Assign position for driver two") + @Operation(summary = "Assign position for driver one") @PatchMapping(path = "/assignPointsDriverOne", produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<RaceDto> assignPositionDriverOne(@RequestParam Long raceId, 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 48797427e5a4ea415d066893b00fbc75636b3fbc..ad0ff086584e5b069e37b0b1a937903042b8bc0f 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 @@ -18,6 +18,7 @@ import java.util.Objects; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.client.RestTemplate; /** @@ -44,6 +45,7 @@ public class RaceService implements RaceServiceI { * @param raceDto race to insert. * @return inserted race. */ + @Transactional public RaceDto postRace(RaceDto raceDto) { raceDto.setId(null); return convertRace(raceRepository.save(convertRaceDto(raceDto))); @@ -54,6 +56,7 @@ public class RaceService implements RaceServiceI { * * @param raceId race id */ + @Transactional public String deleteRace(Long raceId) { raceRepository.deleteById(raceId); return "Race with id: " + raceId + "was succesfully deleted"; @@ -62,6 +65,7 @@ public class RaceService implements RaceServiceI { /** * Assigns driver one. */ + @Transactional public RaceDto assignDriverOne(Long driverId, Long raceId, Long carId) { var race = raceRepository.findById(raceId) .orElseThrow(() -> new DatabaseException("Race not found")); @@ -83,6 +87,7 @@ public class RaceService implements RaceServiceI { /** * Assigns driver two. */ + @Transactional public RaceDto assignDriverTwo(Long driverId, Long raceId, Long carId) { var race = raceRepository.findById(raceId) .orElseThrow(() -> new DatabaseException("Race not found")); @@ -108,6 +113,7 @@ public class RaceService implements RaceServiceI { * @param raceId id of race. * @return found race. */ + @Transactional(readOnly = true) public RaceDto findRaceById(Long raceId) { return convertRace(raceRepository.findById(raceId).orElseThrow( () -> new DatabaseException("Something went wrong when" @@ -119,6 +125,7 @@ public class RaceService implements RaceServiceI { * * @return found races. */ + @Transactional(readOnly = true) public List<RaceDto> findRaces() { return raceRepository.findAll().stream().map(this::convertRace).toList(); } @@ -130,6 +137,7 @@ public class RaceService implements RaceServiceI { * @param position position of driver two. * @return updated race. */ + @Transactional public RaceDto assignPositionForDriverTwo(Long raceId, Integer position) { var race = raceRepository.findById(raceId).orElseThrow(() -> new DatabaseException("Race not found")); @@ -144,10 +152,11 @@ public class RaceService implements RaceServiceI { * @param position position of driver one. * @return updated race. */ + @Transactional public RaceDto assignPositionForDriverOne(Long raceId, Integer position) { var race = raceRepository.findById(raceId).orElseThrow(() -> new DatabaseException("Race not found")); - race.getDriver2().setFinalPosition(position); + race.getDriver1().setFinalPosition(position); return convertRace(raceRepository.save(race)); } @@ -157,6 +166,7 @@ public class RaceService implements RaceServiceI { * @param location location of the race. * @return set if ids of most suitable drivers for given location. */ + @Transactional(readOnly = true) public Set<Long> findMostSuitableDriver(Location location) { var races = raceRepository.findRacesByLocation(location); Map<Long, Integer> driverWithPoints = new HashMap<>(); diff --git a/race/src/main/java/cz/muni/pa165/race/service/SeasonService.java b/race/src/main/java/cz/muni/pa165/race/service/SeasonService.java index 78670308be1f9f75ec5a07814ebf7bb58841bf21..1cfe9d6140c24fa11898d66ad9b9250d2cf1fbb6 100644 --- a/race/src/main/java/cz/muni/pa165/race/service/SeasonService.java +++ b/race/src/main/java/cz/muni/pa165/race/service/SeasonService.java @@ -10,6 +10,7 @@ import cz.muni.pa165.race.data.repository.SeasonRepository; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; /** * Season service. @@ -33,6 +34,7 @@ public class SeasonService implements SeasonServiceI { * @param seasonDto season to insert. * @return inserted season. */ + @Transactional public SeasonDto postSeason(SeasonDto seasonDto) { seasonDto.setId(null); return seasonConverter(seasonRepository.save(seasonDtoConverter(seasonDto))); @@ -44,6 +46,7 @@ public class SeasonService implements SeasonServiceI { * @param seasonId season id. * @return found season. */ + @Transactional(readOnly = true) public SeasonDto getSeasonById(Long seasonId) { return seasonConverter(seasonRepository.findById(seasonId).orElseThrow( () -> new DatabaseException("Something went wrong when" @@ -55,6 +58,7 @@ public class SeasonService implements SeasonServiceI { * * @return found seasons. */ + @Transactional(readOnly = true) public List<SeasonDto> getAllSeasons() { return seasonRepository.findAll() .stream() @@ -68,6 +72,7 @@ public class SeasonService implements SeasonServiceI { * @param seasonId season id. * @return found season. */ + @Transactional public String deleteById(Long seasonId) { seasonRepository.deleteById(seasonId); return "Season with id: " + seasonId + "was succesfully deleted"; @@ -80,6 +85,7 @@ public class SeasonService implements SeasonServiceI { * @param seasonId season id. * @return modified race. */ + @Transactional(readOnly = true) public SeasonDto addRace(Long raceId, Long seasonId) { var season = seasonRepository.findById(seasonId) .orElseThrow(() -> new DatabaseException("Season not found")); 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..590aab0fd9b382404aa1322a5d4be641588997f5 --- /dev/null +++ b/race/src/test/java/cz/muni/pa165/race/rest/RaceControllerTest.java @@ -0,0 +1,126 @@ +package cz.muni.pa165.race.rest; + +import cz.muni.pa165.race.data.model.Race; +import cz.muni.pa165.race.data.repository.RaceRepository; +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; + +import java.util.List; +import java.util.Optional; + +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.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + + +@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}}"; + + + @Autowired + private MockMvc mockMvc; + + @MockBean + private RaceRepository raceRepository; + + @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)); + } + + + @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 { + String expectedMessage = "{\"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}}"; + + 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(expectedMessage)); + } + + @Test + void getAllRaces() throws Exception { + var requestGet = get("/race/"); + String expectedMessage = "[{\"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}}]"; + + this.mockMvc.perform(requestGet) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(expectedMessage)); + } + + @Test + void assignDriverOne() throws Exception { + var requestAssign = patch("/race/assignDriverOne") + .param("driverOneId", "1") + .param("raceId", "1") + .param("carId", "2") + .contentType(MediaType.APPLICATION_JSON_VALUE); + + this.mockMvc.perform(requestAssign) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(expectedMessagePost)); + } + +} 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..7606cb9b4b26666ccf9602499725af47818942e1 --- /dev/null +++ b/race/src/test/java/cz/muni/pa165/race/rest/RaceTestUtil.java @@ -0,0 +1,34 @@ +package cz.muni.pa165.race.rest; + +import cz.muni.pa165.common_library.dtos.Location; +import cz.muni.pa165.common_library.dtos.RaceDto; +import cz.muni.pa165.race.data.model.Race; + +/** + * @author Oto Stanko + */ +public class RaceTestUtil { + 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(); + } + +} 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..6164708954390fad410090539a09da6e5640bd09 --- /dev/null +++ b/race/src/test/java/cz/muni/pa165/race/rest/SeasonControllerTest.java @@ -0,0 +1,119 @@ +package cz.muni.pa165.race.rest; + +import cz.muni.pa165.race.data.model.Season; +import cz.muni.pa165.race.data.repository.SeasonRepository; +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; + +import java.util.List; +import java.util.Optional; + +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; + +@SpringBootTest +@AutoConfigureMockMvc +public class SeasonControllerTest { + private String bodyContent = """ + { + "id": 1, + "year": 2020, + "races": [] + } + """; + private String expectedMessagePost = "{\"id\":1,\"year\":2023,\"races\":[]}"; + + + @Autowired + private MockMvc mockMvc; + + @MockBean + private SeasonRepository seasonRepository; + + @BeforeEach + void setup() { + Season seasonDao = SeasonTestUtil.getDaoSeason(); + given(seasonRepository.save(any(Season.class))).willReturn( + seasonDao); + given(seasonRepository.findById(anyLong())).willReturn( + Optional.of(seasonDao)); + given(seasonRepository.findAll()).willReturn(List.of(seasonDao)); + } + + + @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 { + String expectedMessage = "Season with id: 1was succesfully deleted"; + + var requestDelete = delete("/season/") + .param("seasonId", "1") + .contentType(MediaType.APPLICATION_JSON_VALUE); + this.mockMvc.perform(requestDelete) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(expectedMessage)); + } + + @Test + void getExistingRace() throws Exception { + String expectedMessage = "{\"id\":1,\"year\":2023,\"races\":[]}"; + + 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(expectedMessage)); + } + + @Test + void getAllRaces() throws Exception { + var requestGet = get("/season/"); + String expectedMessage = "[{\"id\":1,\"year\":2023,\"races\":[]}]"; + + this.mockMvc.perform(requestGet) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(expectedMessage)); + } + + @Test + void addRace() throws Exception { + var requestPatch = patch("/season/addRace") + .param("seasonId", "1") + .param("raceId", "1"); + String expectedMessage = "[{\"id\":1,\"year\":2023,\"races\":[]}]"; + + this.mockMvc.perform(requestPatch) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().string(expectedMessage)); + } +} 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..4655a413d3a3233d94f251c4f1fbebebff724fa5 --- /dev/null +++ b/race/src/test/java/cz/muni/pa165/race/rest/SeasonTestUtil.java @@ -0,0 +1,17 @@ +package cz.muni.pa165.race.rest; + +import cz.muni.pa165.race.data.model.Season; +import java.util.ArrayList; + +/** + * @author Oto Stanko + */ +public class SeasonTestUtil { + public static Season getDaoSeason() { + return Season.builder() + .id(1L) + .seasonYear(2023) + .races(new ArrayList<>()) + .build(); + } +}