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));
+ }
+}
+