diff --git a/src/main/java/com/kepler/controller/VacationCalculatorController.java b/src/main/java/com/kepler/controller/VacationCalculatorController.java index a7c4dd1..49f2e2e 100644 --- a/src/main/java/com/kepler/controller/VacationCalculatorController.java +++ b/src/main/java/com/kepler/controller/VacationCalculatorController.java @@ -3,8 +3,10 @@ import com.kepler.model.VacationRequest; import com.kepler.model.VacationResponse; import com.kepler.service.VacationCalculatorService; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -13,15 +15,16 @@ @RestController @RequestMapping("/api/v1") +@Slf4j public class VacationCalculatorController { @Autowired private VacationCalculatorService vacationCalculatorService; @GetMapping("/calculate") - public ResponseEntity calculateVacationPay(@RequestParam double averageSalary, - @RequestParam int vacationDays, - @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate, - @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) { + public ResponseEntity calculateVacationPay(@RequestParam double averageSalary, + @RequestParam int vacationDays, + @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate, + @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) { VacationRequest request = VacationRequest .builder() @@ -31,13 +34,21 @@ public ResponseEntity calculateVacationPay(@RequestParam doubl .endDate(endDate) .build(); + Double totalPay = vacationCalculatorService.calculateVacationPay(request); + VacationResponse response = VacationResponse .builder() - .totalPay( - vacationCalculatorService.calculateVacationPay(request) - ) + .totalPay(totalPay) .build(); - return ResponseEntity.ok(response); + HttpStatus httpStatus; + if (totalPay != null) { // service returns null if wrong request + httpStatus = HttpStatus.OK; + } else { + httpStatus = HttpStatus.BAD_REQUEST; + } + + return new ResponseEntity<>(response, httpStatus); + } } diff --git a/src/main/java/com/kepler/model/VacationResponse.java b/src/main/java/com/kepler/model/VacationResponse.java index ced19ec..8595d21 100644 --- a/src/main/java/com/kepler/model/VacationResponse.java +++ b/src/main/java/com/kepler/model/VacationResponse.java @@ -6,5 +6,5 @@ @Data @Builder public class VacationResponse { - private double totalPay; + private Double totalPay; } diff --git a/src/main/java/com/kepler/service/VacationCalculatorService.java b/src/main/java/com/kepler/service/VacationCalculatorService.java index 44406a8..a537c91 100644 --- a/src/main/java/com/kepler/service/VacationCalculatorService.java +++ b/src/main/java/com/kepler/service/VacationCalculatorService.java @@ -15,11 +15,18 @@ public class VacationCalculatorService { @Autowired private DayOffProxy dayOffProxy; + @Autowired + private ValidatorService validatorService; + /** * @param request salary, days, start / end vacation * @return cash for vacation */ - public double calculateVacationPay(VacationRequest request) { + public Double calculateVacationPay(VacationRequest request) { + if(!validatorService.isRequestCorrect(request)) { // if validation input parameters is failed - don't need to calculate + return null; + } + double dailySalary = request.getAverageSalary() / 29.3; // average salary int totalVacationDays = request.getVacationDays(); diff --git a/src/main/java/com/kepler/service/ValidatorService.java b/src/main/java/com/kepler/service/ValidatorService.java new file mode 100644 index 0000000..807f91a --- /dev/null +++ b/src/main/java/com/kepler/service/ValidatorService.java @@ -0,0 +1,41 @@ +package com.kepler.service; + +import com.kepler.model.VacationRequest; +import org.springframework.stereotype.Service; + +@Service +public class ValidatorService { + public boolean isRequestCorrect(VacationRequest request) { + if (request.getAverageSalary() < 0) { + return false; + } + + if (request.getAverageSalary() == 0) { + return false; + } + + if (request.getVacationDays() < 0) { + return false; + } + + if (request.getVacationDays() == 0) { + return false; + } + + if (request.getStartDate() != null + && request.getEndDate() != null + && request.getStartDate().isAfter(request.getEndDate())) { + return false; + } + + if(request.getStartDate() != null && request.getEndDate() == null) { + return false; + } + + if(request.getEndDate() != null && request.getStartDate() == null) { + return false; + } + + return true; + } +} diff --git a/src/test/java/com/kepler/AppTests.java b/src/test/java/com/kepler/AppTests.java index 676af11..667a490 100644 --- a/src/test/java/com/kepler/AppTests.java +++ b/src/test/java/com/kepler/AppTests.java @@ -6,24 +6,43 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.web.client.RestTemplate; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; import java.time.LocalDate; -import static org.junit.jupiter.api.Assertions.assertEquals; + +import static org.junit.jupiter.api.Assertions.*; @ExtendWith(SpringExtension.class) @SpringBootTest +@TestMethodOrder(OrderAnnotation.class) class AppTests { @Autowired private VacationCalculatorService vacationCalculatorService; + @Autowired + private RestTemplate restTemplate; + @Value("${point.url}") + private String dayOffUrl; + + @Test + @Order(10) + @DisplayName("availability external api") + public void testIsDayOffApi() { + String url = "https://isdayoff.ru/api/getdata?year=2024&month=3&day=8"; + ResponseEntity response = restTemplate.getForEntity(url, String.class); + assertEquals(response.getBody(), "1"); + } - /** - * case: user define only salary and count days - */ @Test - @DisplayName("partial test case") + @Order(20) + @DisplayName("partial request") public void testCalculateVacationPayWithoutDates() { VacationRequest request = VacationRequest .builder() @@ -34,11 +53,9 @@ public void testCalculateVacationPayWithoutDates() { assertEquals(14334.47, vacationPay, 0.1); } - /** - * case: user define salary, count days, start vacation, end vacation - */ @Test - @DisplayName("full test case") + @Order(30) + @DisplayName("full request") public void testCalculateVacationPayWithHolidays() { VacationRequest request = VacationRequest .builder() @@ -51,4 +68,79 @@ public void testCalculateVacationPayWithHolidays() { assertEquals(8191.12, vacationPay, 0.1); } + @Test + @Order(40) + @DisplayName("negative salary") + void testNegativeAverageSalary() { + VacationRequest request = VacationRequest + .builder() + .averageSalary(-100000) + .vacationDays(20) + .startDate(LocalDate.now()) + .endDate(LocalDate.now().plusDays(10)) + .build(); + + assertNull(vacationCalculatorService.calculateVacationPay(request)); + } + + @Test + @Order(50) + @DisplayName("zero salary") + void testZeroAverageSalary() { + VacationRequest request = VacationRequest + .builder() + .averageSalary(0) + .vacationDays(20) + .startDate(LocalDate.now()) + .endDate(LocalDate.now().plusDays(10)) + .build(); + + assertNull(vacationCalculatorService.calculateVacationPay(request)); + } + + @Test + @Order(60) + @DisplayName("negative days") + void testNegativeDays() { + VacationRequest request = VacationRequest + .builder() + .averageSalary(100000) + .vacationDays(-20) + .startDate(LocalDate.now()) + .endDate(LocalDate.now().plusDays(10)) + .build(); + + assertNull(vacationCalculatorService.calculateVacationPay(request)); + } + + @Test + @Order(70) + @DisplayName("zero days") + void testZeroDays() { + VacationRequest request = VacationRequest + .builder() + .averageSalary(100000) + .vacationDays(0) + .startDate(LocalDate.now()) + .endDate(LocalDate.now().plusDays(10)) + .build(); + + assertNull(vacationCalculatorService.calculateVacationPay(request)); + } + + @Test + @Order(80) + @DisplayName("start day is after end day") + void testStartDateAfterEndDate() { + VacationRequest request = VacationRequest + .builder() + .averageSalary(100000) + .vacationDays(0) + .startDate(LocalDate.now().plusDays(10)) + .endDate(LocalDate.now()) + .build(); + + assertNull(vacationCalculatorService.calculateVacationPay(request)); + } + }