diff --git a/.gitignore b/.gitignore index a4093fb..549e00a 100644 --- a/.gitignore +++ b/.gitignore @@ -28,5 +28,6 @@ target/ build/ !**/src/main/**/build/ !**/src/test/**/build/ + ### VS Code ### .vscode/ diff --git a/pom.xml b/pom.xml index 4a0f317..8a20f18 100644 --- a/pom.xml +++ b/pom.xml @@ -8,13 +8,13 @@ 2.7.0 - ro.radu + ro.cristi curs 1.0.0 - java-app - Java App + java + JavaApp - 11 + 17 @@ -57,6 +57,12 @@ spring-security-test test + + org.mockito + mockito-junit-jupiter + 5.2.0 + test + diff --git a/src/main/java/ro/cristi/curs/Repository/CarRepository.java b/src/main/java/ro/cristi/curs/Repository/CarRepository.java index a6cd0d9..def3b2d 100644 --- a/src/main/java/ro/cristi/curs/Repository/CarRepository.java +++ b/src/main/java/ro/cristi/curs/Repository/CarRepository.java @@ -1,4 +1,4 @@ -package ro.cristi.curs.Repository; +package ro.cristi.curs.repository; import java.util.List; diff --git a/src/main/java/ro/cristi/curs/Repository/MemoryRepository.java b/src/main/java/ro/cristi/curs/Repository/MemoryRepository.java index 661261a..44b3e77 100644 --- a/src/main/java/ro/cristi/curs/Repository/MemoryRepository.java +++ b/src/main/java/ro/cristi/curs/Repository/MemoryRepository.java @@ -1,4 +1,4 @@ -package ro.cristi.curs.Repository; +package ro.cristi.curs.repository; import java.util.*; diff --git a/src/main/java/ro/cristi/curs/configuration/cristi/CarRepositoryConfigCristi.java b/src/main/java/ro/cristi/curs/configuration/cristi/CarRepositoryConfigCristi.java index 0c1d969..3b88204 100644 --- a/src/main/java/ro/cristi/curs/configuration/cristi/CarRepositoryConfigCristi.java +++ b/src/main/java/ro/cristi/curs/configuration/cristi/CarRepositoryConfigCristi.java @@ -4,15 +4,18 @@ import java.util.ArrayList; import java.util.List; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; -import ro.cristi.curs.Repository.MemoryRepository; import ro.cristi.curs.model.Car; +import ro.cristi.curs.repository.MemoryRepository; @Configuration @Profile("cristi") public class CarRepositoryConfigCristi { + + @Bean public void loadDataCristi() { List list = new ArrayList<>(); diff --git a/src/main/java/ro/cristi/curs/configuration/dev/CarRepositoryConfigDev.java b/src/main/java/ro/cristi/curs/configuration/dev/CarRepositoryConfigDev.java index 77f0cd0..2cb7aa2 100644 --- a/src/main/java/ro/cristi/curs/configuration/dev/CarRepositoryConfigDev.java +++ b/src/main/java/ro/cristi/curs/configuration/dev/CarRepositoryConfigDev.java @@ -9,7 +9,7 @@ import org.springframework.context.annotation.Profile; import ro.cristi.curs.model.Car; -import ro.cristi.curs.Repository.*; +import ro.cristi.curs.repository.*; @Configuration @Profile("dev") diff --git a/src/main/java/ro/cristi/curs/configuration/local/CarRepositoryConfigLocal.java b/src/main/java/ro/cristi/curs/configuration/local/CarRepositoryConfigLocal.java index bef0e6a..34d6223 100644 --- a/src/main/java/ro/cristi/curs/configuration/local/CarRepositoryConfigLocal.java +++ b/src/main/java/ro/cristi/curs/configuration/local/CarRepositoryConfigLocal.java @@ -9,7 +9,7 @@ import org.springframework.context.annotation.Profile; import ro.cristi.curs.model.Car; -import ro.cristi.curs.Repository.*; +import ro.cristi.curs.repository.*; @Configuration @Profile("local") diff --git a/src/main/java/ro/cristi/curs/controller/v1/HelloWorldController.java b/src/main/java/ro/cristi/curs/controller/v1/HelloWorldController.java index 2b5387e..d33d127 100644 --- a/src/main/java/ro/cristi/curs/controller/v1/HelloWorldController.java +++ b/src/main/java/ro/cristi/curs/controller/v1/HelloWorldController.java @@ -21,6 +21,6 @@ public String getHello1() { @PostMapping(path = "/helloworld/hello1", consumes = { MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) public String postHello1(@RequestBody HelloRequest helloRequest) { - return "Hello World : " + helloRequest.getInput(); + return "Hello World : " + helloRequest.getA(); } } diff --git a/src/main/java/ro/cristi/curs/controller/v2/HelloWorldButBetter.java b/src/main/java/ro/cristi/curs/controller/v2/HelloWorldButBetter.java new file mode 100644 index 0000000..9e2ee6b --- /dev/null +++ b/src/main/java/ro/cristi/curs/controller/v2/HelloWorldButBetter.java @@ -0,0 +1,58 @@ +package ro.cristi.curs.controller.v2; + +import java.util.ArrayList; + +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import ro.cristi.curs.dto.HelloResponseButBetter; + +@RestController +@RequestMapping("/v2") +public class HelloWorldButBetter { + + @GetMapping(path = "/lista/limbaje") + public String getLimbaje(){ + ArrayList listaLimbaje = new ArrayList(){ + { + add("Java"); + add("C++"); + add("Python"); + add("N-am avut inspiratie"); + } + }; + return listaLimbaje.toString(); + } + + + @GetMapping(path = "/lista/jocuri") + public String getJocuri(){ + ArrayList listaJocuri = new ArrayList() { + { + add("Osu!"); + add("Genshin"); + add("Sekai"); + add("Adofai"); + } + }; + return listaJocuri.toString(); + } + + @GetMapping(path = "/vorbe_intelepte") + public HelloResponseButBetter responseVorba(){ + HelloResponseButBetter respo = new HelloResponseButBetter(); + respo.setMotivational("iti merge bine vere"); + respo.setDemotivational("sau poate ca nu cred ca o sa iti mearga (plangi)"); + return respo; + } + + @PostMapping(path = "/vorbe_neintelepte", consumes = {MediaType.APPLICATION_JSON_VALUE}, produces = {MediaType.APPLICATION_JSON_VALUE}) + public String postHelloV2(@RequestBody HelloResponseButBetter helloRequest){ + return "Vorbele tale motivationale: " + helloRequest.getMotivational() + "\nSi alea demotivationale: " + helloRequest.getDemotivational(); + } + +} diff --git a/src/main/java/ro/cristi/curs/controller/v3/CarController.java b/src/main/java/ro/cristi/curs/controller/v3/CarController.java index f40c320..776719e 100644 --- a/src/main/java/ro/cristi/curs/controller/v3/CarController.java +++ b/src/main/java/ro/cristi/curs/controller/v3/CarController.java @@ -6,16 +6,16 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import ro.cristi.curs.Repository.CarRepository; import ro.cristi.curs.dto.CarDto; import ro.cristi.curs.mapper.CarMapper; import ro.cristi.curs.model.Car; -import ro.cristi.curs.service.CarService; +import ro.cristi.curs.repository.CarRepository; +import ro.cristi.curs.service.CarServiceBasic; import java.util.*; @RestController -@RequestMapping("/v1") +@RequestMapping("/v3") public class CarController { @Autowired @@ -25,7 +25,7 @@ public class CarController { CarMapper carMapper; @Autowired - CarService carService; + CarServiceBasic carService; @GetMapping("/car/list") public List getCars() { diff --git a/src/main/java/ro/cristi/curs/dto/HelloRequest.java b/src/main/java/ro/cristi/curs/dto/HelloRequest.java index 05c0cf3..5a37404 100644 --- a/src/main/java/ro/cristi/curs/dto/HelloRequest.java +++ b/src/main/java/ro/cristi/curs/dto/HelloRequest.java @@ -7,6 +7,8 @@ @Data public class HelloRequest { - @JsonProperty("input") - String input; -} + @JsonProperty("a") + String a; + @JsonProperty("b") + String b; +} \ No newline at end of file diff --git a/src/main/java/ro/cristi/curs/dto/HelloRequestButBetter.java b/src/main/java/ro/cristi/curs/dto/HelloRequestButBetter.java new file mode 100644 index 0000000..bd1c23f --- /dev/null +++ b/src/main/java/ro/cristi/curs/dto/HelloRequestButBetter.java @@ -0,0 +1,14 @@ +package ro.cristi.curs.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.Data; + +@Data +public class HelloRequestButBetter { + + @JsonProperty("motivational") + String motivational; + @JsonProperty("demotivational") + String demotivational; +} diff --git a/src/main/java/ro/cristi/curs/dto/HelloResponseButBetter.java b/src/main/java/ro/cristi/curs/dto/HelloResponseButBetter.java new file mode 100644 index 0000000..52a8b7d --- /dev/null +++ b/src/main/java/ro/cristi/curs/dto/HelloResponseButBetter.java @@ -0,0 +1,14 @@ +package ro.cristi.curs.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.Data; + +@Data +public class HelloResponseButBetter { + + @JsonProperty("motivational") + String motivational; + @JsonProperty("demotivational") + String demotivational; +} diff --git a/src/main/java/ro/cristi/curs/dto/SedanDto.java b/src/main/java/ro/cristi/curs/dto/SedanDto.java index eac1a6e..23e6341 100644 --- a/src/main/java/ro/cristi/curs/dto/SedanDto.java +++ b/src/main/java/ro/cristi/curs/dto/SedanDto.java @@ -7,3 +7,4 @@ public class SedanDto extends CarDto{ private Integer doors; private Boolean isElectric; } + diff --git a/src/main/java/ro/cristi/curs/dto/VanDto.java b/src/main/java/ro/cristi/curs/dto/VanDto.java index b9d6ca6..be89fcc 100644 --- a/src/main/java/ro/cristi/curs/dto/VanDto.java +++ b/src/main/java/ro/cristi/curs/dto/VanDto.java @@ -4,6 +4,7 @@ @Data public class VanDto extends CarDto{ + private String capacity; private Integer payload; } diff --git a/src/main/java/ro/cristi/curs/exception/CarServiceException.java b/src/main/java/ro/cristi/curs/exception/CarServiceException.java new file mode 100644 index 0000000..29d49f9 --- /dev/null +++ b/src/main/java/ro/cristi/curs/exception/CarServiceException.java @@ -0,0 +1,16 @@ +package ro.cristi.curs.exception; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = false) +public class CarServiceException extends RuntimeException{ + + private Integer errorCode; + + public CarServiceException(Integer errorCode, String message){ + super(message); + this.errorCode = errorCode; + } +} diff --git a/src/main/java/ro/cristi/curs/exception/CarValidatorException.java b/src/main/java/ro/cristi/curs/exception/CarValidatorException.java new file mode 100644 index 0000000..906f371 --- /dev/null +++ b/src/main/java/ro/cristi/curs/exception/CarValidatorException.java @@ -0,0 +1,17 @@ +package ro.cristi.curs.exception; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = false) +public class CarValidatorException extends RuntimeException { + + private Integer errorCode; + + public CarValidatorException(Integer errorCode, String message) { + super(message); + this.errorCode = errorCode; + } +} + diff --git a/src/main/java/ro/cristi/curs/service/CarService.java b/src/main/java/ro/cristi/curs/service/CarServiceBasic.java similarity index 92% rename from src/main/java/ro/cristi/curs/service/CarService.java rename to src/main/java/ro/cristi/curs/service/CarServiceBasic.java index 9bdd0f7..9f66f39 100644 --- a/src/main/java/ro/cristi/curs/service/CarService.java +++ b/src/main/java/ro/cristi/curs/service/CarServiceBasic.java @@ -6,10 +6,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import ro.cristi.curs.Repository.CarRepository; import ro.cristi.curs.model.Car; +import ro.cristi.curs.repository.CarRepository; + @Service -public class CarService { +public class CarServiceBasic { @Autowired CarRepository carRepository; diff --git a/src/main/java/ro/cristi/curs/service/CarServiceMemory.java b/src/main/java/ro/cristi/curs/service/CarServiceMemory.java new file mode 100644 index 0000000..04df0ec --- /dev/null +++ b/src/main/java/ro/cristi/curs/service/CarServiceMemory.java @@ -0,0 +1,13 @@ +package ro.cristi.curs.service; + +import java.util.List; + +import ro.cristi.curs.model.Car; + +public interface CarServiceMemory { + List getExpensiveCars(Integer percent); + + List getOlderCars(Integer years); + + List getEfficientCars(Integer units); +} diff --git a/src/main/java/ro/cristi/curs/service/CarServiceMemoryImpl.java b/src/main/java/ro/cristi/curs/service/CarServiceMemoryImpl.java new file mode 100644 index 0000000..b6df2b3 --- /dev/null +++ b/src/main/java/ro/cristi/curs/service/CarServiceMemoryImpl.java @@ -0,0 +1,60 @@ +package ro.cristi.curs.service; + +import java.math.BigDecimal; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Profile; +import org.springframework.stereotype.Service; + +import ro.cristi.curs.exception.CarServiceException; +import ro.cristi.curs.model.Car; +import ro.cristi.curs.repository.CarRepository; + +@Service +@Profile("local") +public class CarServiceMemoryImpl implements CarServiceMemory { + + @Autowired + CarRepository carRepository; + + @Override + public List getExpensiveCars(Integer percent) throws CarServiceException { + + List cars = carRepository.getAllCars(); + + if(percent > 100){ + throw new CarServiceException(40001, "Percent must be less"); + } + if (cars == null || cars.isEmpty()) { + throw new CarServiceException(50001, "No cars found"); + } else if (cars.size()>1000) { + throw new CarServiceException(50002, "Too many cars found"); + } + //after error checks + for (Car car : cars) { + car.setPrice(car.getPrice().multiply(BigDecimal.valueOf((100 + percent) / 100))); + } + return cars; + } + + @Override + public List getOlderCars(Integer years){ + //todo: exceptions + List cars = carRepository.getAllCars(); + for(Car car : cars){ + car.setYear(car.getYear() - years); + } + return cars; + } + + @Override + public List getEfficientCars(Integer units){ + //todo: exceptions + List cars = carRepository.getAllCars(); + for(Car car : cars){ + car.setConsumption(car.getConsumption() - units); + } + return cars; + } +} \ No newline at end of file diff --git a/src/main/java/ro/cristi/curs/validator/CarValidator.java b/src/main/java/ro/cristi/curs/validator/CarValidator.java new file mode 100644 index 0000000..e2c5293 --- /dev/null +++ b/src/main/java/ro/cristi/curs/validator/CarValidator.java @@ -0,0 +1,63 @@ +package ro.cristi.curs.validator; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +import lombok.experimental.UtilityClass; +import ro.cristi.curs.exception.CarValidatorException; +import ro.cristi.curs.model.Car; + +@UtilityClass +public class CarValidator { + + public static Boolean validateCar(Car car) throws CarValidatorException { + validateCarMaker(car.getMaker()); + validateCarModel(car.getModel()); + validateCarYear(car.getYear()); + return true; + } + + public static void validateCarMaker(String name) throws CarValidatorException { + if (name == null || name.isEmpty()) { + throw new CarValidatorException(90001, "Maker is null or empty"); + } + if (name.length() > 15) { + throw new CarValidatorException(90002, "Maker is too long"); + } + if (name.toLowerCase().charAt(0) == name.charAt(0)) { + throw new CarValidatorException(90003, "Maker must start with uppercase"); + } + } + + + public static void validateCarModel(String name) throws CarValidatorException { + if (name == null || name.isEmpty()) { + throw new CarValidatorException(90004, "Model is null or empty"); + } + if (name.length() > 15) { + throw new CarValidatorException(90005, "Model is too long"); + } + if (name.toLowerCase().charAt(0) == name.charAt(0)) { + throw new CarValidatorException(90006, "Model must start with uppercase"); + } + } + + public static void validateCarYear(Integer year) throws CarValidatorException { + if(year == null){ + throw new CarValidatorException(90007, "Year is null"); + } + if (year < 1980){ + throw new CarValidatorException(90008, "Year is too low"); + } + if (year > getCurrentYear()) { + throw new CarValidatorException(90009, "Year is too high"); + } + } + + public Integer getCurrentYear(){ + DateTimeFormatter timp = DateTimeFormatter.ofPattern("yyyy"); + LocalDateTime now = LocalDateTime.now(); + Integer currentYear = Integer.parseInt(timp.format(now)); + return currentYear; + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 705d36c..1fb268e 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,2 @@ -management.endpoints.web.exposure.include=* \ No newline at end of file +management.endpoints.web.exposure.include=* +spring.profiles.active=cristi diff --git a/src/test/java/ro/cristi/curs/JavaApplicationTests.java b/src/test/java/ro/cristi/curs/JavaApplicationTests.java new file mode 100644 index 0000000..9e8c909 --- /dev/null +++ b/src/test/java/ro/cristi/curs/JavaApplicationTests.java @@ -0,0 +1,13 @@ +package ro.cristi.curs; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class JavaApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/src/test/java/ro/cristi/curs/controller/v1/HelloWorldControllerTest.java b/src/test/java/ro/cristi/curs/controller/v1/HelloWorldControllerTest.java new file mode 100644 index 0000000..8a9c2e2 --- /dev/null +++ b/src/test/java/ro/cristi/curs/controller/v1/HelloWorldControllerTest.java @@ -0,0 +1,75 @@ +package ro.cristi.curs.controller.v1; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +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.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +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.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import ro.cristi.curs.dto.HelloRequest; + +@SpringBootTest +@AutoConfigureMockMvc +public class HelloWorldControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @Test + void testA_get() throws Exception{ + + mockMvc.perform(get("/v1/helloworld/hello1")) + .andExpect(status().isOk()) + .andExpect(content().string("Hello World")); + assertTrue(true); + } + + @Test + void testA_post() throws Exception { + + HelloRequest req = new HelloRequest(); + req.setA("valoarea lui a"); + req.setB("valoarea lui b"); + + String reqJson = objectMapper.writeValueAsString(req); + // mockMvc.perform(post("/v1/helloworld/hello1").contentType(MediaType.APPLICATION_JSON).content(reqJson)) + // .andExpect(status().isOk()) + // .andExpect(content().string("Hello World : " + req.getA())); + + HelloRequest req2 = new HelloRequest(); + req2.setA(req.getA() + "x"); + req2.setB(req.getB()); + + String reqJson2 = objectMapper.writeValueAsString(req2); + // mockMvc.perform(post("/v1/helloworld/hello1").contentType(MediaType.APPLICATION_JSON).content(reqJson2)) + // .andExpect(status().isOk()) + // .andExpect(content().string("Hello World : " + req2.getA())); + + + // String payload = "{\"a\":\"valoare a\", \"b\":\"valoare b\"}"; + // mockMvc.perform(post("/v1/helloworld/hello1").contentType(MediaType.APPLICATION_JSON).content(payload)) + // .andExpect(status().isOk()) + // .andExpect(content().string("Hello World : valoare a")); + + + } + + private void sendAndExpect(String body, String expectedResponse) throws Exception { + mockMvc.perform(post("/v1/helloworld/hello1").contentType(MediaType.APPLICATION_JSON).content(body)) + .andExpect(status().isOk()) + .andExpect(content().string(expectedResponse)); + } +} diff --git a/src/test/java/ro/cristi/curs/controller/v2/HelloWorldButBetterTest.java b/src/test/java/ro/cristi/curs/controller/v2/HelloWorldButBetterTest.java new file mode 100644 index 0000000..2889444 --- /dev/null +++ b/src/test/java/ro/cristi/curs/controller/v2/HelloWorldButBetterTest.java @@ -0,0 +1,93 @@ +package ro.cristi.curs.controller.v2; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +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.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.util.ArrayList; + +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.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import ro.cristi.curs.dto.HelloRequest; +import ro.cristi.curs.dto.HelloRequestButBetter; +import ro.cristi.curs.dto.HelloResponseButBetter; + +@SpringBootTest +@AutoConfigureMockMvc +public class HelloWorldButBetterTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @Test + void testListaJocuri() throws Exception{ + ArrayList listaJocuri = new ArrayList() { + { + add("Osu!"); + add("Genshin"); + add("Sekai"); + add("Adofai"); + } + }; + String jsonString = objectMapper.writeValueAsString(listaJocuri); + mockMvc.perform(get("/v2/lista/jocuri")) + .andExpect(status().isOk()) + .andExpect(content().string(jsonString)); + } + + @Test + void testListaLimbaje() throws Exception{ + ArrayList listaLimbaje = new ArrayList(){ + { + add("Java"); + add("C++"); + add("Python"); + add("N-am avut inspiratie"); + } + }; + String jsonString = objectMapper.writeValueAsString(listaLimbaje); + + mockMvc.perform(get("/v2/lista/limbaje")) + .andExpect(status().isOk()) + .andExpect(content().string(jsonString)); + } + + @Test + void testVorbeIntelepte() throws Exception{ + HelloResponseButBetter resp = new HelloResponseButBetter(); + resp.setMotivational("iti merge bine vere"); + resp.setDemotivational("sau poate ca nu cred ca o sa iti mearga (plangi)"); + String jsonString = objectMapper.writeValueAsString(resp); + + mockMvc.perform(get("/v2/vorbe_intelepte")) + .andExpect(status().isOk()) + .andExpect(content().string(jsonString)); + + } + + @Test + void testVorbeNeintelepte() throws Exception{ + HelloRequestButBetter req = new HelloRequestButBetter(); + req.setMotivational("da"); + req.setDemotivational("poate"); + String jsonReq = objectMapper.writeValueAsString(req); + mockMvc.perform(post("/v2/vorbe_neintelepte") + .contentType(MediaType.APPLICATION_JSON_VALUE).content(jsonReq)) + .andExpect(status().isOk()) + .andExpect(content().string("Vorbele tale motivationale: " + req.getMotivational() + "\nSi alea demotivationale: " + req.getDemotivational())); + } + +} diff --git a/src/test/java/ro/cristi/curs/service/CarServiceMemoryTest.java b/src/test/java/ro/cristi/curs/service/CarServiceMemoryTest.java new file mode 100644 index 0000000..e4ec877 --- /dev/null +++ b/src/test/java/ro/cristi/curs/service/CarServiceMemoryTest.java @@ -0,0 +1,130 @@ +package ro.cristi.curs.service; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.when; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import ro.cristi.curs.exception.CarServiceException; +import ro.cristi.curs.model.Car; +import ro.cristi.curs.repository.CarRepository; + +@SpringBootTest +@ActiveProfiles("local") +class CarServiceMemoryTest { + + @Mock + CarRepository carRepository; + + @InjectMocks + CarServiceMemoryImpl carServiceMemoryImpl = new CarServiceMemoryImpl(); + + @Autowired + ObjectMapper objectMapper; + + List cars; + + @BeforeEach + void setUp() { + cars = getAllCars(); + when(carRepository.getAllCars()).thenReturn(cars); + } + + @Test + void testGetExpensiveCars() throws Exception { + + // setup (always on setUp() @BeforeEach) + + String oldCarsJson = objectMapper.writeValueAsString(cars); + Car[] oldCars = objectMapper.readValue(oldCarsJson, Car[].class); + + // act + List expensiveCars = carServiceMemoryImpl.getExpensiveCars(100); + + // assert + assertEquals(expensiveCars.size(), oldCars.length); + for (Integer i = 0; i < expensiveCars.size() - 1; i++) { + assertEquals(oldCars[i].getPrice().multiply(BigDecimal.valueOf(2)), + expensiveCars.get(i).getPrice()); + } + } + + @Test + void testGetExpensiveCars_exceptionNull(){ + when(carRepository.getAllCars()).thenReturn(null); + try { + carServiceMemoryImpl.getExpensiveCars(100); + } catch (CarServiceException e) { + assertEquals(50001, e.getErrorCode()); + } + } + + @Test + void testGetExpensiveCars_exceptionPercent(){ + try{ + carServiceMemoryImpl.getExpensiveCars(150); + } catch(CarServiceException e) { + assertEquals(40001, e.getErrorCode()); + } + } + + @Test + void testGetExpensiveCars_exceptionSize(){ + when(carRepository.getAllCars()).thenReturn(getTooManyCars()); + try{ + carServiceMemoryImpl.getExpensiveCars(50); + } catch(CarServiceException e) { + assertEquals(50002, e.getErrorCode()); + } + } + + private List getAllCars() { + List list = new ArrayList<>(); + + Car car1 = new Car(); + car1.setMaker("BMW"); + car1.setColor("yellow"); + car1.setModel("x5"); + car1.setYear(2023); + car1.setCurrency("EUR"); + car1.setPrice(BigDecimal.valueOf(98000)); + list.add(car1); + + Car car2 = new Car(); + car2.setMaker("Mecedes"); + car2.setColor("red"); + car2.setModel("GLE"); + car2.setYear(2020); + car2.setCurrency("EUR"); + car2.setPrice(BigDecimal.valueOf(124000)); + list.add(car2); + + return list; + } + private List getTooManyCars(){ + List list = new ArrayList<>(); + for(Integer i = 0; i<=1000; i++){ + Car car1 = new Car(); + car1.setMaker("BMW"); + car1.setColor("yellow"); + car1.setModel("x5"); + car1.setYear(2023); + car1.setCurrency("EUR"); + car1.setPrice(BigDecimal.valueOf(98000)); + list.add(car1); + } + return list; + } +} diff --git a/src/test/java/ro/cristi/curs/validator/CarValidatorTest.java b/src/test/java/ro/cristi/curs/validator/CarValidatorTest.java new file mode 100644 index 0000000..d7eb30f --- /dev/null +++ b/src/test/java/ro/cristi/curs/validator/CarValidatorTest.java @@ -0,0 +1,151 @@ +package ro.cristi.curs.validator; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import ro.cristi.curs.exception.CarValidatorException; +import ro.cristi.curs.model.Car; + +@SpringBootTest +class CarValidatorTest { + + private Car goodCar() { + Car car = new Car(); + car.setMaker("Audi"); + car.setModel("xd"); + car.setYear(2015); + return car; + + } + + @Test + public void validateCarMakerNullName() throws CarValidatorException { + Car car = goodCar(); + car.setMaker(null); + try { + CarValidator.validateCarMaker(car.getMaker()); + } catch (CarValidatorException e) { + assertEquals(90001, e.getErrorCode()); + } + } + + @Test + public void validateCarMakerEmptyName() throws CarValidatorException { + Car car = goodCar(); + car.setMaker(""); + try { + CarValidator.validateCarMaker(car.getMaker()); + } catch (CarValidatorException e) { + assertEquals(90001, e.getErrorCode()); + } + } + + @Test + public void validateCarMakerLongName() throws CarValidatorException { + Car car = goodCar(); + car.setMaker("DaciaBestCarOngFrfrassdsdsad"); + try { + CarValidator.validateCarMaker(car.getMaker()); + } catch (CarValidatorException e) { + assertEquals(90002, e.getErrorCode()); + } + } + + @Test + public void validateCarMakerLowerCase() throws CarValidatorException { + Car car = goodCar(); + car.setMaker("dACIA"); + try { + CarValidator.validateCarMaker(car.getMaker()); + } catch (CarValidatorException e) { + assertEquals(90003, e.getErrorCode()); + } + } + + @Test + public void validateCarModelNullName() throws CarValidatorException { + Car car = goodCar(); + car.setModel(null); + try { + CarValidator.validateCarModel(car.getModel()); + } catch (CarValidatorException e) { + assertEquals(90004, e.getErrorCode()); + } + } + + @Test + public void validateCarModelEmptyName() throws CarValidatorException { + Car car = goodCar(); + car.setModel(""); + try { + CarValidator.validateCarModel(car.getModel()); + } catch (CarValidatorException e) { + assertEquals(90004, e.getErrorCode()); + } + } + + @Test + public void validateCarModelLongName() throws CarValidatorException { + Car car = goodCar(); + car.setModel("DaciaBestCarOngFrfrassdsdsad"); + try { + CarValidator.validateCarModel(car.getModel()); + } catch (CarValidatorException e) { + assertEquals(90005, e.getErrorCode()); + } + } + + @Test + public void validateCarModelLowerCase() throws CarValidatorException { + Car car = goodCar(); + car.setModel("dACIA"); + try { + CarValidator.validateCarModel(car.getModel()); + } catch (CarValidatorException e) { + assertEquals(90006, e.getErrorCode()); + } + } + + @Test + public void validateCarYearNull() throws CarValidatorException{ + Car car = goodCar(); + car.setYear(null); + try{ + CarValidator.validateCarYear(car.getYear()); + } catch(CarValidatorException e) { + assertEquals(90007, e.getErrorCode()); + } + } + + @Test + public void validateCarYearLow() throws CarValidatorException{ + Car car = goodCar(); + car.setYear(1977); + try{ + CarValidator.validateCarYear(car.getYear()); + } catch(CarValidatorException e) { + assertEquals(90008, e.getErrorCode()); + } + } + + @Test + public void validateCarYearHigh() throws CarValidatorException{ + Car car = goodCar(); + car.setYear(2024); + try{ + CarValidator.validateCarYear(car.getYear()); + } catch(CarValidatorException e) { + assertEquals(90009, e.getErrorCode()); + } + } + + @Test + public void validateCarTestGood() throws CarValidatorException { + Car car = goodCar(); + assertEquals(true, CarValidator.validateCar(car)); + } +} +