From f4d0563ca4bf6cb520fafc9e16507f38b59189fb Mon Sep 17 00:00:00 2001 From: stvort Date: Mon, 10 Jun 2024 19:29:16 +0400 Subject: [PATCH] 2024-03 spring-17-mvc added --- 2024-03/spring-17-mvc/pom.xml | 20 +++ 2024-03/spring-17-mvc/spring-mvc-demo/pom.xml | 66 +++++++++ .../src/main/java/ru/otus/spring/Main.java | 28 ++++ .../java/ru/otus/spring/config/WebConfig.java | 21 +++ .../java/ru/otus/spring/domain/Person.java | 40 ++++++ .../ru/otus/spring/domain/SystemInfo.java | 31 +++++ .../spring/repostory/PersonRepository.java | 12 ++ .../ru/otus/spring/rest/PersonController.java | 64 +++++++++ .../spring/rest/SystemInfoController.java | 14 ++ .../ru/otus/spring/rest/dto/PersonDto.java | 54 ++++++++ .../rest/exceptions/NotFoundException.java | 7 + .../SystemInfoMethodArgumentResolver.java | 33 +++++ .../spring/service/SystemInfoService.java | 17 +++ .../spring/rest/PersonControllerTest.java | 127 ++++++++++++++++++ .../spring/rest/SystemInfoControllerTest.java | 39 ++++++ .../spring-17-mvc/spring-mvc-exercise/pom.xml | 65 +++++++++ .../src/main/java/ru/otus/spring/Main.java | 26 ++++ .../java/ru/otus/spring/domain/Person.java | 40 ++++++ .../spring/repostory/PersonRepository.java | 12 ++ .../ru/otus/spring/rest/PersonController.java | 13 ++ .../ru/otus/spring/rest/dto/PersonDto.java | 54 ++++++++ .../rest/exeptions/NotFoundException.java | 7 + .../spring/rest/PersonControllerTest.java | 83 ++++++++++++ .../spring-mvc-solution-1/pom.xml | 65 +++++++++ .../src/main/java/ru/otus/spring/Main.java | 26 ++++ .../java/ru/otus/spring/domain/Person.java | 40 ++++++ .../spring/repostory/PersonRepository.java | 12 ++ .../ru/otus/spring/rest/PersonController.java | 27 ++++ .../ru/otus/spring/rest/dto/PersonDto.java | 54 ++++++++ .../rest/exceptions/NotFoundException.java | 7 + .../spring/rest/PersonControllerTest.java | 83 ++++++++++++ .../spring-mvc-solution-2/pom.xml | 66 +++++++++ .../src/main/java/ru/otus/spring/Main.java | 26 ++++ .../java/ru/otus/spring/domain/Person.java | 40 ++++++ .../spring/repostory/PersonRepository.java | 12 ++ .../ru/otus/spring/rest/PersonController.java | 40 ++++++ .../ru/otus/spring/rest/dto/PersonDto.java | 54 ++++++++ .../rest/exceptions/NotFoundException.java | 7 + .../spring/rest/PersonControllerTest.java | 83 ++++++++++++ .../spring-mvc-solution-3/pom.xml | 66 +++++++++ .../spring-mvc-solution-3/requests.http | 10 ++ .../src/main/java/ru/otus/spring/Main.java | 26 ++++ .../java/ru/otus/spring/domain/Person.java | 40 ++++++ .../spring/repostory/PersonRepository.java | 12 ++ .../ru/otus/spring/rest/PersonController.java | 45 +++++++ .../ru/otus/spring/rest/dto/PersonDto.java | 54 ++++++++ .../rest/exceptions/NotFoundException.java | 7 + .../spring/rest/PersonControllerTest.java | 83 ++++++++++++ 48 files changed, 1858 insertions(+) create mode 100644 2024-03/spring-17-mvc/pom.xml create mode 100644 2024-03/spring-17-mvc/spring-mvc-demo/pom.xml create mode 100644 2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/Main.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/config/WebConfig.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/domain/Person.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/domain/SystemInfo.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/repostory/PersonRepository.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/PersonController.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/SystemInfoController.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/dto/PersonDto.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/exceptions/NotFoundException.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/resolvers/SystemInfoMethodArgumentResolver.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/service/SystemInfoService.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-demo/src/test/java/ru/otus/spring/rest/PersonControllerTest.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-demo/src/test/java/ru/otus/spring/rest/SystemInfoControllerTest.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-exercise/pom.xml create mode 100644 2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/Main.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/domain/Person.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/repostory/PersonRepository.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/rest/PersonController.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/rest/dto/PersonDto.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/rest/exeptions/NotFoundException.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-exercise/src/test/java/ru/otus/spring/rest/PersonControllerTest.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-1/pom.xml create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/Main.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/domain/Person.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/repostory/PersonRepository.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/rest/PersonController.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/rest/dto/PersonDto.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/rest/exceptions/NotFoundException.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-1/src/test/java/ru/otus/spring/rest/PersonControllerTest.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-2/pom.xml create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/Main.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/domain/Person.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/repostory/PersonRepository.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/rest/PersonController.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/rest/dto/PersonDto.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/rest/exceptions/NotFoundException.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-2/src/test/java/ru/otus/spring/rest/PersonControllerTest.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-3/pom.xml create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-3/requests.http create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/Main.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/domain/Person.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/repostory/PersonRepository.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/rest/PersonController.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/rest/dto/PersonDto.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/rest/exceptions/NotFoundException.java create mode 100644 2024-03/spring-17-mvc/spring-mvc-solution-3/src/test/java/ru/otus/spring/rest/PersonControllerTest.java diff --git a/2024-03/spring-17-mvc/pom.xml b/2024-03/spring-17-mvc/pom.xml new file mode 100644 index 00000000..c9bb3f66 --- /dev/null +++ b/2024-03/spring-17-mvc/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + ru.otus + spring-mvc-class-work + 1.0 + + pom + + + spring-mvc-exercise + spring-mvc-solution-1 + spring-mvc-solution-2 + spring-mvc-solution-3 + spring-mvc-demo + + diff --git a/2024-03/spring-17-mvc/spring-mvc-demo/pom.xml b/2024-03/spring-17-mvc/spring-mvc-demo/pom.xml new file mode 100644 index 00000000..1e7cd783 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-demo/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + ru.otus + spring-mvc-demo + 1.0 + + + org.springframework.boot + spring-boot-starter-parent + 3.3.0 + + + + + 17 + 17 + 17 + UTF-8 + 2.2.220 + 2.0 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + com.h2database + h2 + runtime + ${h2.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/Main.java b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/Main.java new file mode 100644 index 00000000..306644c8 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/Main.java @@ -0,0 +1,28 @@ +package ru.otus.spring; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import ru.otus.spring.domain.Person; +import ru.otus.spring.repostory.PersonRepository; + +import jakarta.annotation.PostConstruct; + +@SpringBootApplication +public class Main { + + // http://localhost:8080/server/system/info + + public static void main(String[] args) { + SpringApplication.run(Main.class); + } + + @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") + @Autowired + private PersonRepository repository; + + @PostConstruct + public void init() { + repository.save(new Person(1, "Pushkin")); + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/config/WebConfig.java b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/config/WebConfig.java new file mode 100644 index 00000000..e201fdcf --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/config/WebConfig.java @@ -0,0 +1,21 @@ +package ru.otus.spring.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import ru.otus.spring.rest.resolvers.SystemInfoMethodArgumentResolver; + +import java.util.List; + +@Configuration +public class WebConfig implements WebMvcConfigurer { + + @Autowired + private SystemInfoMethodArgumentResolver systemInfoMethodArgumentResolver; + + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(systemInfoMethodArgumentResolver); + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/domain/Person.java b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/domain/Person.java new file mode 100644 index 00000000..ecbb8d5b --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/domain/Person.java @@ -0,0 +1,40 @@ +package ru.otus.spring.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; + +@Entity +public class Person { + + @Id + private long id; + private String name; + + public Person() { + } + + public Person(String name) { + this.name = name; + } + + public Person(long id, String name) { + this.id = id; + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/domain/SystemInfo.java b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/domain/SystemInfo.java new file mode 100644 index 00000000..c16a8a78 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/domain/SystemInfo.java @@ -0,0 +1,31 @@ +package ru.otus.spring.domain; + +public class SystemInfo { + private final String osName; + private final String timeZone; + private final String osArch; + private final int processorsCount; + + public SystemInfo(String osName, String timeZone, String osArch, int processorsCount) { + this.osName = osName; + this.timeZone = timeZone; + this.osArch = osArch; + this.processorsCount = processorsCount; + } + + public String getOsName() { + return osName; + } + + public String getTimeZone() { + return timeZone; + } + + public String getOsArch() { + return osArch; + } + + public int getProcessorsCount() { + return processorsCount; + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/repostory/PersonRepository.java new file mode 100644 index 00000000..c43a877b --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/repostory/PersonRepository.java @@ -0,0 +1,12 @@ +package ru.otus.spring.repostory; + +import org.springframework.data.repository.ListCrudRepository; +import ru.otus.spring.domain.Person; + +import java.util.List; + +public interface PersonRepository extends ListCrudRepository { + + List findAll(); + List findByName(String name); +} diff --git a/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/PersonController.java b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/PersonController.java new file mode 100644 index 00000000..b195143e --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/PersonController.java @@ -0,0 +1,64 @@ +package ru.otus.spring.rest; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import ru.otus.spring.domain.Person; +import ru.otus.spring.repostory.PersonRepository; +import ru.otus.spring.rest.dto.PersonDto; +import ru.otus.spring.rest.exceptions.NotFoundException; + +import java.util.List; +import java.util.stream.Collectors; + +@RestController +public class PersonController { + + private final PersonRepository repository; + + public PersonController(PersonRepository repository) { + this.repository = repository; + } + + @RequestMapping(value = "/persons", method = RequestMethod.GET) + public List getAllPersons() { + return repository.findAll().stream() + .map(PersonDto::toDto) + .collect(Collectors.toList()); + } + + @RequestMapping(value = "/persons", method = RequestMethod.GET, params = "name") + public PersonDto getPersonByNameInRequest(@RequestParam("name") String name) { + Person person = repository.findByName(name).stream().findFirst().orElseThrow(NotFoundException::new); + return PersonDto.toDto(person); + } + + @GetMapping("/persons/{id}") + public PersonDto getPersonByIdInPath(@PathVariable("id") long id) { + Person person = repository.findById(id).orElseThrow(NotFoundException::new); + return PersonDto.toDto(person); + } + + @PostMapping("/persons") + public PersonDto createNewPerson(@RequestBody PersonDto dto) { + Person person = PersonDto.toDomainObject(dto); + Person savedPerson = repository.save(person); + return PersonDto.toDto(savedPerson); + } + + @PatchMapping("/persons/{id}/name") + public PersonDto updateNameById(@PathVariable("id") long id, @RequestParam("name") String name) { + Person person = repository.findById(id).orElseThrow(NotFoundException::new); + person.setName(name); + return PersonDto.toDto(repository.save(person)); + } + + @DeleteMapping("/persons/{id}") + public void deleteById(@PathVariable("id") long id) { + repository.deleteById(id); + } + + @ExceptionHandler(NotFoundException.class) + public ResponseEntity handleNotFound(NotFoundException ex) { + return ResponseEntity.badRequest().body("Таких тут нет!"); + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/SystemInfoController.java b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/SystemInfoController.java new file mode 100644 index 00000000..f188a94f --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/SystemInfoController.java @@ -0,0 +1,14 @@ +package ru.otus.spring.rest; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import ru.otus.spring.domain.SystemInfo; + +@RestController +public class SystemInfoController { + + @GetMapping("/server/system/info") + public SystemInfo getServerSystemInfo(SystemInfo systemInfo) { + return systemInfo; + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/dto/PersonDto.java b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/dto/PersonDto.java new file mode 100644 index 00000000..a2aeae8f --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/dto/PersonDto.java @@ -0,0 +1,54 @@ +/* + * Copyright 2016 Russian Post + * + * This source code is Russian Post Confidential Proprietary. + * This software is protected by copyright. All rights and titles are reserved. + * You shall not use, copy, distribute, modify, decompile, disassemble or reverse engineer the software. + * Otherwise this violation would be treated by law and would be subject to legal prosecution. + * Legal use of the software provides receipt of a license from the right name only. + */ +package ru.otus.spring.rest.dto; + +import ru.otus.spring.domain.Person; + +/** + * DTO that represents Person + */ +@SuppressWarnings("all") +public class PersonDto { + + private long id; + private String name; + + public PersonDto() { + } + + public PersonDto(long id, String name) { + this.id = id; + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public static Person toDomainObject(PersonDto dto) { + return new Person(dto.getId(), dto.getName()); + } + + public static PersonDto toDto(Person person) { + return new PersonDto(person.getId(), person.getName()); + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/exceptions/NotFoundException.java b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/exceptions/NotFoundException.java new file mode 100644 index 00000000..5dc475b8 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/exceptions/NotFoundException.java @@ -0,0 +1,7 @@ +package ru.otus.spring.rest.exceptions; + +public class NotFoundException extends RuntimeException{ + + public NotFoundException() { + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/resolvers/SystemInfoMethodArgumentResolver.java b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/resolvers/SystemInfoMethodArgumentResolver.java new file mode 100644 index 00000000..51f517a7 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/rest/resolvers/SystemInfoMethodArgumentResolver.java @@ -0,0 +1,33 @@ +package ru.otus.spring.rest.resolvers; + +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; +import ru.otus.spring.domain.SystemInfo; +import ru.otus.spring.service.SystemInfoService; + +@Component +public class SystemInfoMethodArgumentResolver implements HandlerMethodArgumentResolver { + + private final SystemInfoService systemInfoService; + + public SystemInfoMethodArgumentResolver(SystemInfoService systemInfoService) { + this.systemInfoService = systemInfoService; + } + + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.getParameterType().equals(SystemInfo.class); + } + + @Override + public Object resolveArgument(MethodParameter parameter, + ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, + WebDataBinderFactory binderFactory) throws Exception { + return systemInfoService.getSystemInfo(); + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/service/SystemInfoService.java b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/service/SystemInfoService.java new file mode 100644 index 00000000..26fb34d2 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-demo/src/main/java/ru/otus/spring/service/SystemInfoService.java @@ -0,0 +1,17 @@ +package ru.otus.spring.service; + +import org.springframework.stereotype.Service; +import ru.otus.spring.domain.SystemInfo; + +@Service +public class SystemInfoService { + + public SystemInfo getSystemInfo(){ + String osName = System.getProperty("os.name"); + String timeZone = System.getProperty("user.timezone"); + String osArch = System.getProperty("os.arch"); + int processorsCount = Runtime.getRuntime().availableProcessors(); + return new SystemInfo(osName, timeZone, osArch, processorsCount); + + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-demo/src/test/java/ru/otus/spring/rest/PersonControllerTest.java b/2024-03/spring-17-mvc/spring-mvc-demo/src/test/java/ru/otus/spring/rest/PersonControllerTest.java new file mode 100644 index 00000000..118a671a --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-demo/src/test/java/ru/otus/spring/rest/PersonControllerTest.java @@ -0,0 +1,127 @@ +package ru.otus.spring.rest; + +import com.fasterxml.jackson.databind.ObjectMapper; +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.test.web.servlet.MockMvc; +import ru.otus.spring.domain.Person; +import ru.otus.spring.repostory.PersonRepository; +import ru.otus.spring.rest.dto.PersonDto; +import ru.otus.spring.service.SystemInfoService; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(PersonController.class) +class PersonControllerTest { + + public static final String ERROR_STRING = "Таких тут нет!"; + + @Autowired + private MockMvc mvc; + + @Autowired + private ObjectMapper mapper; + + @MockBean + private PersonRepository repository; + + @MockBean + private SystemInfoService systemInfoService; + + @Test + void shouldReturnCorrectPersonsList() throws Exception { + List persons = List.of(new Person(1, "Person1"), new Person(2, "Person2")); + given(repository.findAll()).willReturn(persons); + + List expectedResult = persons.stream() + .map(PersonDto::toDto).collect(Collectors.toList()); + + mvc.perform(get("/persons")) + .andExpect(status().isOk()) + .andExpect(content().json(mapper.writeValueAsString(expectedResult))); + } + + @Test + void shouldReturnCorrectPersonByNameInRequest() throws Exception { + Person person = new Person(1, "Person1"); + given(repository.findByName(person.getName())).willReturn(List.of(person)); + PersonDto expectedResult = PersonDto.toDto(person); + + mvc.perform(get("/persons").param("name", person.getName())) + .andExpect(status().isOk()) + .andExpect(content().json(mapper.writeValueAsString(expectedResult))); + } + + @Test + void shouldReturnCorrectPersonByIdInPath() throws Exception { + Person person = new Person(1, "Person1"); + given(repository.findById(1L)).willReturn(Optional.of(person)); + PersonDto expectedResult = PersonDto.toDto(person); + + mvc.perform(get("/persons/1")) + .andExpect(status().isOk()) + .andExpect(content().json(mapper.writeValueAsString(expectedResult))); + } + + @Test + void shouldReturnExpectedErrorWhenPersonNotFound() throws Exception { + given(repository.findById(1L)).willReturn(Optional.empty()); + + mvc.perform(get("/persons").param("name", "Person1")) + .andExpect(status().isBadRequest()) + .andExpect(content().string(ERROR_STRING)); + + mvc.perform(get("/persons/1")) + .andExpect(status().isBadRequest()) + .andExpect(content().string(ERROR_STRING)); + } + + @Test + void shouldCorrectSaveNewPerson() throws Exception { + Person person = new Person(1, "Person1"); + given(repository.save(any())).willReturn(person); + String expectedResult = mapper.writeValueAsString(PersonDto.toDto(person)); + + mvc.perform(post("/persons").contentType(APPLICATION_JSON) + .content(expectedResult)) + .andExpect(status().isOk()) + .andExpect(content().json(expectedResult)); + } + + @Test + void shouldCorrectUpdatePersonName() throws Exception { + Person person = new Person(1, "Person1"); + given(repository.findById(1L)).willReturn(Optional.of(person)); + given(repository.save(any())).willAnswer(invocation -> invocation.getArgument(0)); + + Person expectedPerson = new Person(1, "Person2"); + String expectedResult = mapper.writeValueAsString(PersonDto.toDto(expectedPerson)); + + mvc.perform(patch("/persons/{id}/name", 1).param("name", expectedPerson.getName()) + .content(expectedResult)) + .andExpect(status().isOk()) + .andExpect(content().json(expectedResult)); + } + + @Test + void shouldCorrectDeletePerson() throws Exception { + mvc.perform(delete("/persons/1")) + .andExpect(status().isOk()); + verify(repository, times(1)).deleteById(1L); + } + + +} \ No newline at end of file diff --git a/2024-03/spring-17-mvc/spring-mvc-demo/src/test/java/ru/otus/spring/rest/SystemInfoControllerTest.java b/2024-03/spring-17-mvc/spring-mvc-demo/src/test/java/ru/otus/spring/rest/SystemInfoControllerTest.java new file mode 100644 index 00000000..3c35c11b --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-demo/src/test/java/ru/otus/spring/rest/SystemInfoControllerTest.java @@ -0,0 +1,39 @@ +package ru.otus.spring.rest; + +import com.fasterxml.jackson.databind.ObjectMapper; +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.context.annotation.Import; +import org.springframework.test.web.servlet.MockMvc; +import ru.otus.spring.domain.SystemInfo; +import ru.otus.spring.repostory.PersonRepository; +import ru.otus.spring.service.SystemInfoService; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; + +@WebMvcTest(SystemInfoController.class) +@Import(SystemInfoService.class) +class SystemInfoControllerTest { + + @Autowired + private MockMvc mvc; + + @Autowired + private ObjectMapper mapper; + + @MockBean + private PersonRepository repository; + + @Autowired + private SystemInfoService systemInfoService; + + @Test + void shouldReturnCorrectServerSystemInfo() throws Exception { + SystemInfo expectedSystemInfo = systemInfoService.getSystemInfo(); + mvc.perform(get("/server/system/info")) + .andExpect(content().json(mapper.writeValueAsString(expectedSystemInfo))); + } +} \ No newline at end of file diff --git a/2024-03/spring-17-mvc/spring-mvc-exercise/pom.xml b/2024-03/spring-17-mvc/spring-mvc-exercise/pom.xml new file mode 100644 index 00000000..e401dc50 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-exercise/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + ru.otus + spring-mvc-exercise + 1.0 + + + org.springframework.boot + spring-boot-starter-parent + 3.3.0 + + + + + 17 + 17 + 17 + UTF-8 + 2.2.220 + 2.0 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + com.h2database + h2 + runtime + ${h2.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/Main.java b/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/Main.java new file mode 100644 index 00000000..101a633b --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/Main.java @@ -0,0 +1,26 @@ +package ru.otus.spring; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import ru.otus.spring.domain.Person; +import ru.otus.spring.repostory.PersonRepository; + +import jakarta.annotation.PostConstruct; + +@SpringBootApplication +public class Main { + + public static void main(String[] args) { + SpringApplication.run(Main.class); + } + + @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") + @Autowired + private PersonRepository repository; + + @PostConstruct + public void init() { + repository.save(new Person(1, "Pushkin")); + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/domain/Person.java b/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/domain/Person.java new file mode 100644 index 00000000..ecbb8d5b --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/domain/Person.java @@ -0,0 +1,40 @@ +package ru.otus.spring.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; + +@Entity +public class Person { + + @Id + private long id; + private String name; + + public Person() { + } + + public Person(String name) { + this.name = name; + } + + public Person(long id, String name) { + this.id = id; + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/repostory/PersonRepository.java new file mode 100644 index 00000000..c43a877b --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/repostory/PersonRepository.java @@ -0,0 +1,12 @@ +package ru.otus.spring.repostory; + +import org.springframework.data.repository.ListCrudRepository; +import ru.otus.spring.domain.Person; + +import java.util.List; + +public interface PersonRepository extends ListCrudRepository { + + List findAll(); + List findByName(String name); +} diff --git a/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/rest/PersonController.java b/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/rest/PersonController.java new file mode 100644 index 00000000..344a34b7 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/rest/PersonController.java @@ -0,0 +1,13 @@ +package ru.otus.spring.rest; + +import ru.otus.spring.repostory.PersonRepository; + + +public class PersonController { + + private final PersonRepository repository; + + public PersonController(PersonRepository repository) { + this.repository = repository; + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/rest/dto/PersonDto.java b/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/rest/dto/PersonDto.java new file mode 100644 index 00000000..a2aeae8f --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/rest/dto/PersonDto.java @@ -0,0 +1,54 @@ +/* + * Copyright 2016 Russian Post + * + * This source code is Russian Post Confidential Proprietary. + * This software is protected by copyright. All rights and titles are reserved. + * You shall not use, copy, distribute, modify, decompile, disassemble or reverse engineer the software. + * Otherwise this violation would be treated by law and would be subject to legal prosecution. + * Legal use of the software provides receipt of a license from the right name only. + */ +package ru.otus.spring.rest.dto; + +import ru.otus.spring.domain.Person; + +/** + * DTO that represents Person + */ +@SuppressWarnings("all") +public class PersonDto { + + private long id; + private String name; + + public PersonDto() { + } + + public PersonDto(long id, String name) { + this.id = id; + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public static Person toDomainObject(PersonDto dto) { + return new Person(dto.getId(), dto.getName()); + } + + public static PersonDto toDto(Person person) { + return new PersonDto(person.getId(), person.getName()); + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/rest/exeptions/NotFoundException.java b/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/rest/exeptions/NotFoundException.java new file mode 100644 index 00000000..169b67b2 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-exercise/src/main/java/ru/otus/spring/rest/exeptions/NotFoundException.java @@ -0,0 +1,7 @@ +package ru.otus.spring.rest.exeptions; + +public class NotFoundException extends RuntimeException{ + + public NotFoundException() { + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-exercise/src/test/java/ru/otus/spring/rest/PersonControllerTest.java b/2024-03/spring-17-mvc/spring-mvc-exercise/src/test/java/ru/otus/spring/rest/PersonControllerTest.java new file mode 100644 index 00000000..2b7c8154 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-exercise/src/test/java/ru/otus/spring/rest/PersonControllerTest.java @@ -0,0 +1,83 @@ +package ru.otus.spring.rest; + +import com.fasterxml.jackson.databind.ObjectMapper; +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.test.web.servlet.MockMvc; +import ru.otus.spring.domain.Person; +import ru.otus.spring.repostory.PersonRepository; +import ru.otus.spring.rest.dto.PersonDto; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(PersonController.class) +class PersonControllerTest { + + public static final String ERROR_STRING = "Таких тут нет!"; + + @Autowired + private MockMvc mvc; + + @Autowired + private ObjectMapper mapper; + + @MockBean + private PersonRepository repository; + + @Test + void shouldReturnCorrectPersonsList() throws Exception { + List persons = List.of(new Person(1, "Person1"), new Person(2, "Person2")); + given(repository.findAll()).willReturn(persons); + + List expectedResult = persons.stream() + .map(PersonDto::toDto).collect(Collectors.toList()); + + mvc.perform(get("/persons")) + .andExpect(status().isOk()) + .andExpect(content().json(mapper.writeValueAsString(expectedResult))); + } + + @Test + void shouldReturnCorrectPersonByNameInRequest() throws Exception { + Person person = new Person(1, "Person1"); + given(repository.findByName(person.getName())).willReturn(List.of(person)); + PersonDto expectedResult = PersonDto.toDto(person); + + mvc.perform(get("/persons").param("name", person.getName())) + .andExpect(status().isOk()) + .andExpect(content().json(mapper.writeValueAsString(expectedResult))); + } + + @Test + void shouldReturnCorrectPersonByIdInPath() throws Exception { + Person person = new Person(1, "Person1"); + given(repository.findById(1L)).willReturn(Optional.of(person)); + PersonDto expectedResult = PersonDto.toDto(person); + + mvc.perform(get("/persons/1")) + .andExpect(status().isOk()) + .andExpect(content().json(mapper.writeValueAsString(expectedResult))); + } + + @Test + void shouldReturnExpectedErrorWhenPersonNotFound() throws Exception { + given(repository.findById(1L)).willReturn(Optional.empty()); + + mvc.perform(get("/persons").param("name", "Person1")) + .andExpect(status().isBadRequest()) + .andExpect(content().string(ERROR_STRING)); + + mvc.perform(get("/persons/1")) + .andExpect(status().isBadRequest()) + .andExpect(content().string(ERROR_STRING)); + } +} \ No newline at end of file diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-1/pom.xml b/2024-03/spring-17-mvc/spring-mvc-solution-1/pom.xml new file mode 100644 index 00000000..f8179ada --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-1/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + ru.otus + spring-mvc-solution-1 + 1.0 + + + org.springframework.boot + spring-boot-starter-parent + 3.3.0 + + + + + 17 + 17 + 17 + UTF-8 + 2.2.220 + 2.0 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + com.h2database + h2 + runtime + ${h2.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/Main.java b/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/Main.java new file mode 100644 index 00000000..101a633b --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/Main.java @@ -0,0 +1,26 @@ +package ru.otus.spring; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import ru.otus.spring.domain.Person; +import ru.otus.spring.repostory.PersonRepository; + +import jakarta.annotation.PostConstruct; + +@SpringBootApplication +public class Main { + + public static void main(String[] args) { + SpringApplication.run(Main.class); + } + + @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") + @Autowired + private PersonRepository repository; + + @PostConstruct + public void init() { + repository.save(new Person(1, "Pushkin")); + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/domain/Person.java b/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/domain/Person.java new file mode 100644 index 00000000..ecbb8d5b --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/domain/Person.java @@ -0,0 +1,40 @@ +package ru.otus.spring.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; + +@Entity +public class Person { + + @Id + private long id; + private String name; + + public Person() { + } + + public Person(String name) { + this.name = name; + } + + public Person(long id, String name) { + this.id = id; + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/repostory/PersonRepository.java new file mode 100644 index 00000000..c43a877b --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/repostory/PersonRepository.java @@ -0,0 +1,12 @@ +package ru.otus.spring.repostory; + +import org.springframework.data.repository.ListCrudRepository; +import ru.otus.spring.domain.Person; + +import java.util.List; + +public interface PersonRepository extends ListCrudRepository { + + List findAll(); + List findByName(String name); +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/rest/PersonController.java b/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/rest/PersonController.java new file mode 100644 index 00000000..c8e47c24 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/rest/PersonController.java @@ -0,0 +1,27 @@ +package ru.otus.spring.rest; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; +import ru.otus.spring.repostory.PersonRepository; +import ru.otus.spring.rest.dto.PersonDto; + +import java.util.List; +import java.util.stream.Collectors; + +@RestController +public class PersonController { + + private final PersonRepository repository; + + public PersonController(PersonRepository repository) { + this.repository = repository; + } + + @RequestMapping(value = "/persons", method = RequestMethod.GET) + public List getAllPersons() { + return repository.findAll().stream() + .map(PersonDto::toDto) + .collect(Collectors.toList()); + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/rest/dto/PersonDto.java b/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/rest/dto/PersonDto.java new file mode 100644 index 00000000..a2aeae8f --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/rest/dto/PersonDto.java @@ -0,0 +1,54 @@ +/* + * Copyright 2016 Russian Post + * + * This source code is Russian Post Confidential Proprietary. + * This software is protected by copyright. All rights and titles are reserved. + * You shall not use, copy, distribute, modify, decompile, disassemble or reverse engineer the software. + * Otherwise this violation would be treated by law and would be subject to legal prosecution. + * Legal use of the software provides receipt of a license from the right name only. + */ +package ru.otus.spring.rest.dto; + +import ru.otus.spring.domain.Person; + +/** + * DTO that represents Person + */ +@SuppressWarnings("all") +public class PersonDto { + + private long id; + private String name; + + public PersonDto() { + } + + public PersonDto(long id, String name) { + this.id = id; + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public static Person toDomainObject(PersonDto dto) { + return new Person(dto.getId(), dto.getName()); + } + + public static PersonDto toDto(Person person) { + return new PersonDto(person.getId(), person.getName()); + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/rest/exceptions/NotFoundException.java b/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/rest/exceptions/NotFoundException.java new file mode 100644 index 00000000..5dc475b8 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-1/src/main/java/ru/otus/spring/rest/exceptions/NotFoundException.java @@ -0,0 +1,7 @@ +package ru.otus.spring.rest.exceptions; + +public class NotFoundException extends RuntimeException{ + + public NotFoundException() { + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-1/src/test/java/ru/otus/spring/rest/PersonControllerTest.java b/2024-03/spring-17-mvc/spring-mvc-solution-1/src/test/java/ru/otus/spring/rest/PersonControllerTest.java new file mode 100644 index 00000000..2b7c8154 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-1/src/test/java/ru/otus/spring/rest/PersonControllerTest.java @@ -0,0 +1,83 @@ +package ru.otus.spring.rest; + +import com.fasterxml.jackson.databind.ObjectMapper; +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.test.web.servlet.MockMvc; +import ru.otus.spring.domain.Person; +import ru.otus.spring.repostory.PersonRepository; +import ru.otus.spring.rest.dto.PersonDto; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(PersonController.class) +class PersonControllerTest { + + public static final String ERROR_STRING = "Таких тут нет!"; + + @Autowired + private MockMvc mvc; + + @Autowired + private ObjectMapper mapper; + + @MockBean + private PersonRepository repository; + + @Test + void shouldReturnCorrectPersonsList() throws Exception { + List persons = List.of(new Person(1, "Person1"), new Person(2, "Person2")); + given(repository.findAll()).willReturn(persons); + + List expectedResult = persons.stream() + .map(PersonDto::toDto).collect(Collectors.toList()); + + mvc.perform(get("/persons")) + .andExpect(status().isOk()) + .andExpect(content().json(mapper.writeValueAsString(expectedResult))); + } + + @Test + void shouldReturnCorrectPersonByNameInRequest() throws Exception { + Person person = new Person(1, "Person1"); + given(repository.findByName(person.getName())).willReturn(List.of(person)); + PersonDto expectedResult = PersonDto.toDto(person); + + mvc.perform(get("/persons").param("name", person.getName())) + .andExpect(status().isOk()) + .andExpect(content().json(mapper.writeValueAsString(expectedResult))); + } + + @Test + void shouldReturnCorrectPersonByIdInPath() throws Exception { + Person person = new Person(1, "Person1"); + given(repository.findById(1L)).willReturn(Optional.of(person)); + PersonDto expectedResult = PersonDto.toDto(person); + + mvc.perform(get("/persons/1")) + .andExpect(status().isOk()) + .andExpect(content().json(mapper.writeValueAsString(expectedResult))); + } + + @Test + void shouldReturnExpectedErrorWhenPersonNotFound() throws Exception { + given(repository.findById(1L)).willReturn(Optional.empty()); + + mvc.perform(get("/persons").param("name", "Person1")) + .andExpect(status().isBadRequest()) + .andExpect(content().string(ERROR_STRING)); + + mvc.perform(get("/persons/1")) + .andExpect(status().isBadRequest()) + .andExpect(content().string(ERROR_STRING)); + } +} \ No newline at end of file diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-2/pom.xml b/2024-03/spring-17-mvc/spring-mvc-solution-2/pom.xml new file mode 100644 index 00000000..be5cbbf9 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-2/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + ru.otus + spring-mvc-solution-2 + 1.0 + + + org.springframework.boot + spring-boot-starter-parent + 3.3.0 + + + + + 17 + 17 + 17 + UTF-8 + 2.2.220 + 2.0 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + com.h2database + h2 + runtime + ${h2.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/Main.java b/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/Main.java new file mode 100644 index 00000000..101a633b --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/Main.java @@ -0,0 +1,26 @@ +package ru.otus.spring; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import ru.otus.spring.domain.Person; +import ru.otus.spring.repostory.PersonRepository; + +import jakarta.annotation.PostConstruct; + +@SpringBootApplication +public class Main { + + public static void main(String[] args) { + SpringApplication.run(Main.class); + } + + @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") + @Autowired + private PersonRepository repository; + + @PostConstruct + public void init() { + repository.save(new Person(1, "Pushkin")); + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/domain/Person.java b/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/domain/Person.java new file mode 100644 index 00000000..ecbb8d5b --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/domain/Person.java @@ -0,0 +1,40 @@ +package ru.otus.spring.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; + +@Entity +public class Person { + + @Id + private long id; + private String name; + + public Person() { + } + + public Person(String name) { + this.name = name; + } + + public Person(long id, String name) { + this.id = id; + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/repostory/PersonRepository.java new file mode 100644 index 00000000..c43a877b --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/repostory/PersonRepository.java @@ -0,0 +1,12 @@ +package ru.otus.spring.repostory; + +import org.springframework.data.repository.ListCrudRepository; +import ru.otus.spring.domain.Person; + +import java.util.List; + +public interface PersonRepository extends ListCrudRepository { + + List findAll(); + List findByName(String name); +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/rest/PersonController.java b/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/rest/PersonController.java new file mode 100644 index 00000000..2c1b02bc --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/rest/PersonController.java @@ -0,0 +1,40 @@ +package ru.otus.spring.rest; + +import org.springframework.web.bind.annotation.*; +import ru.otus.spring.domain.Person; +import ru.otus.spring.repostory.PersonRepository; +import ru.otus.spring.rest.dto.PersonDto; +import ru.otus.spring.rest.exceptions.NotFoundException; + +import java.util.List; +import java.util.stream.Collectors; + +@RestController +public class PersonController { + + private final PersonRepository repository; + + public PersonController(PersonRepository repository) { + this.repository = repository; + } + + @RequestMapping(value = "/persons", method = RequestMethod.GET) + public List getAllPersons() { + return repository.findAll().stream() + .map(PersonDto::toDto) + .collect(Collectors.toList()); + } + + @RequestMapping(value = "/persons", method = RequestMethod.GET, params = "name") + public PersonDto getPersonByNameInRequest(@RequestParam("name") String name) { + Person person = repository.findByName(name).stream().findFirst().orElseThrow(NotFoundException::new); + return PersonDto.toDto(person); + } + + @GetMapping("/persons/{id}") + public PersonDto getPersonByIdInPath(@PathVariable("id") long id) { + Person person = repository.findById(id).orElseThrow(NotFoundException::new); + return PersonDto.toDto(person); + } + +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/rest/dto/PersonDto.java b/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/rest/dto/PersonDto.java new file mode 100644 index 00000000..a2aeae8f --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/rest/dto/PersonDto.java @@ -0,0 +1,54 @@ +/* + * Copyright 2016 Russian Post + * + * This source code is Russian Post Confidential Proprietary. + * This software is protected by copyright. All rights and titles are reserved. + * You shall not use, copy, distribute, modify, decompile, disassemble or reverse engineer the software. + * Otherwise this violation would be treated by law and would be subject to legal prosecution. + * Legal use of the software provides receipt of a license from the right name only. + */ +package ru.otus.spring.rest.dto; + +import ru.otus.spring.domain.Person; + +/** + * DTO that represents Person + */ +@SuppressWarnings("all") +public class PersonDto { + + private long id; + private String name; + + public PersonDto() { + } + + public PersonDto(long id, String name) { + this.id = id; + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public static Person toDomainObject(PersonDto dto) { + return new Person(dto.getId(), dto.getName()); + } + + public static PersonDto toDto(Person person) { + return new PersonDto(person.getId(), person.getName()); + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/rest/exceptions/NotFoundException.java b/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/rest/exceptions/NotFoundException.java new file mode 100644 index 00000000..5dc475b8 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-2/src/main/java/ru/otus/spring/rest/exceptions/NotFoundException.java @@ -0,0 +1,7 @@ +package ru.otus.spring.rest.exceptions; + +public class NotFoundException extends RuntimeException{ + + public NotFoundException() { + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-2/src/test/java/ru/otus/spring/rest/PersonControllerTest.java b/2024-03/spring-17-mvc/spring-mvc-solution-2/src/test/java/ru/otus/spring/rest/PersonControllerTest.java new file mode 100644 index 00000000..6da9bef4 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-2/src/test/java/ru/otus/spring/rest/PersonControllerTest.java @@ -0,0 +1,83 @@ +package ru.otus.spring.rest; + +import com.fasterxml.jackson.databind.ObjectMapper; +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.test.web.servlet.MockMvc; +import ru.otus.spring.domain.Person; +import ru.otus.spring.repostory.PersonRepository; +import ru.otus.spring.rest.dto.PersonDto; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(PersonController.class) +class PersonControllerTest { + + public static final String ERROR_STRING = "Таких тут нет!"; + + @Autowired + private MockMvc mvc; + + @Autowired + private ObjectMapper mapper; + + @MockBean + private PersonRepository repository; + + @Test + void shouldReturnCorrectPersonsList() throws Exception { + List persons = List.of(new Person(1, "Person1"), new Person(2, "Person2")); + given(repository.findAll()).willReturn(persons); + + List expectedResult = persons.stream() + .map(PersonDto::toDto).collect(Collectors.toList()); + + mvc.perform(get("/persons")) + .andExpect(status().isOk()) + .andExpect(content().json(mapper.writeValueAsString(expectedResult))); + } + + @Test + void shouldReturnCorrectPersonByNameInRequest() throws Exception { + Person person = new Person(1, "Person1"); + given(repository.findByName(person.getName())).willReturn(List.of(person)); + PersonDto expectedResult = PersonDto.toDto(person); + + mvc.perform(get("/persons").param("name", person.getName())) + .andExpect(status().isOk()) + .andExpect(content().json(mapper.writeValueAsString(expectedResult))); + } + + @Test + void shouldReturnCorrectPersonByIdInPath() throws Exception { + Person person = new Person(1, "Person1"); + given(repository.findById(1L)).willReturn(Optional.of(person)); + PersonDto expectedResult = PersonDto.toDto(person); + + mvc.perform(get("/persons/1")) + .andExpect(status().isOk()) + .andExpect(content().json(mapper.writeValueAsString(expectedResult))); + } + + @Test + void shouldReturnExpectedErrorWhenPersonNotFound() throws Exception { + given(repository.findById(1L)).willReturn(Optional.empty()); + + mvc.perform(get("/persons").param("name", "Person1")) + .andExpect(status().isBadRequest()) + .andExpect(content().string(ERROR_STRING)); + + mvc.perform(get("/persons/1")) + .andExpect(status().isBadRequest()) + .andExpect(content().string(ERROR_STRING)); + } +} \ No newline at end of file diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-3/pom.xml b/2024-03/spring-17-mvc/spring-mvc-solution-3/pom.xml new file mode 100644 index 00000000..32fc8920 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-3/pom.xml @@ -0,0 +1,66 @@ + + + 4.0.0 + + ru.otus + spring-mvc-solution-3 + 1.0 + + + org.springframework.boot + spring-boot-starter-parent + 3.3.0 + + + + + 17 + 17 + 17 + UTF-8 + 2.2.220 + 2.0 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.yaml + snakeyaml + ${snakeyaml.version} + + + + com.h2database + h2 + runtime + ${h2.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-3/requests.http b/2024-03/spring-17-mvc/spring-mvc-solution-3/requests.http new file mode 100644 index 00000000..958a57b2 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-3/requests.http @@ -0,0 +1,10 @@ +POST http://localhost:8080/person +Content-Type: application/json + +{ + "id": "2", + "name": "Pushkin" +} + +### +GET http://localhost:8080/persons/all \ No newline at end of file diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/Main.java b/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/Main.java new file mode 100644 index 00000000..101a633b --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/Main.java @@ -0,0 +1,26 @@ +package ru.otus.spring; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import ru.otus.spring.domain.Person; +import ru.otus.spring.repostory.PersonRepository; + +import jakarta.annotation.PostConstruct; + +@SpringBootApplication +public class Main { + + public static void main(String[] args) { + SpringApplication.run(Main.class); + } + + @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") + @Autowired + private PersonRepository repository; + + @PostConstruct + public void init() { + repository.save(new Person(1, "Pushkin")); + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/domain/Person.java b/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/domain/Person.java new file mode 100644 index 00000000..ecbb8d5b --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/domain/Person.java @@ -0,0 +1,40 @@ +package ru.otus.spring.domain; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; + +@Entity +public class Person { + + @Id + private long id; + private String name; + + public Person() { + } + + public Person(String name) { + this.name = name; + } + + public Person(long id, String name) { + this.id = id; + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/repostory/PersonRepository.java b/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/repostory/PersonRepository.java new file mode 100644 index 00000000..c43a877b --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/repostory/PersonRepository.java @@ -0,0 +1,12 @@ +package ru.otus.spring.repostory; + +import org.springframework.data.repository.ListCrudRepository; +import ru.otus.spring.domain.Person; + +import java.util.List; + +public interface PersonRepository extends ListCrudRepository { + + List findAll(); + List findByName(String name); +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/rest/PersonController.java b/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/rest/PersonController.java new file mode 100644 index 00000000..f7ee302b --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/rest/PersonController.java @@ -0,0 +1,45 @@ +package ru.otus.spring.rest; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import ru.otus.spring.domain.Person; +import ru.otus.spring.repostory.PersonRepository; +import ru.otus.spring.rest.dto.PersonDto; +import ru.otus.spring.rest.exceptions.NotFoundException; + +import java.util.List; +import java.util.stream.Collectors; + +@RestController +public class PersonController { + + private final PersonRepository repository; + + public PersonController(PersonRepository repository) { + this.repository = repository; + } + + @RequestMapping(value = "/persons", method = RequestMethod.GET) + public List getAllPersons() { + return repository.findAll().stream() + .map(PersonDto::toDto) + .collect(Collectors.toList()); + } + + @RequestMapping(value = "/persons", method = RequestMethod.GET, params = "name") + public PersonDto getPersonByNameInRequest(@RequestParam("name") String name) { + Person person = repository.findByName(name).stream().findFirst().orElseThrow(NotFoundException::new); + return PersonDto.toDto(person); + } + + @GetMapping("/persons/{id}") + public PersonDto getPersonByIdInPath(@PathVariable("id") long id) { + Person person = repository.findById(id).orElseThrow(NotFoundException::new); + return PersonDto.toDto(person); + } + + @ExceptionHandler(NotFoundException.class) + public ResponseEntity handleNotFound(NotFoundException ex) { + return ResponseEntity.badRequest().body("Таких тут нет!"); + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/rest/dto/PersonDto.java b/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/rest/dto/PersonDto.java new file mode 100644 index 00000000..a2aeae8f --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/rest/dto/PersonDto.java @@ -0,0 +1,54 @@ +/* + * Copyright 2016 Russian Post + * + * This source code is Russian Post Confidential Proprietary. + * This software is protected by copyright. All rights and titles are reserved. + * You shall not use, copy, distribute, modify, decompile, disassemble or reverse engineer the software. + * Otherwise this violation would be treated by law and would be subject to legal prosecution. + * Legal use of the software provides receipt of a license from the right name only. + */ +package ru.otus.spring.rest.dto; + +import ru.otus.spring.domain.Person; + +/** + * DTO that represents Person + */ +@SuppressWarnings("all") +public class PersonDto { + + private long id; + private String name; + + public PersonDto() { + } + + public PersonDto(long id, String name) { + this.id = id; + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public static Person toDomainObject(PersonDto dto) { + return new Person(dto.getId(), dto.getName()); + } + + public static PersonDto toDto(Person person) { + return new PersonDto(person.getId(), person.getName()); + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/rest/exceptions/NotFoundException.java b/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/rest/exceptions/NotFoundException.java new file mode 100644 index 00000000..5dc475b8 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-3/src/main/java/ru/otus/spring/rest/exceptions/NotFoundException.java @@ -0,0 +1,7 @@ +package ru.otus.spring.rest.exceptions; + +public class NotFoundException extends RuntimeException{ + + public NotFoundException() { + } +} diff --git a/2024-03/spring-17-mvc/spring-mvc-solution-3/src/test/java/ru/otus/spring/rest/PersonControllerTest.java b/2024-03/spring-17-mvc/spring-mvc-solution-3/src/test/java/ru/otus/spring/rest/PersonControllerTest.java new file mode 100644 index 00000000..6da9bef4 --- /dev/null +++ b/2024-03/spring-17-mvc/spring-mvc-solution-3/src/test/java/ru/otus/spring/rest/PersonControllerTest.java @@ -0,0 +1,83 @@ +package ru.otus.spring.rest; + +import com.fasterxml.jackson.databind.ObjectMapper; +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.test.web.servlet.MockMvc; +import ru.otus.spring.domain.Person; +import ru.otus.spring.repostory.PersonRepository; +import ru.otus.spring.rest.dto.PersonDto; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(PersonController.class) +class PersonControllerTest { + + public static final String ERROR_STRING = "Таких тут нет!"; + + @Autowired + private MockMvc mvc; + + @Autowired + private ObjectMapper mapper; + + @MockBean + private PersonRepository repository; + + @Test + void shouldReturnCorrectPersonsList() throws Exception { + List persons = List.of(new Person(1, "Person1"), new Person(2, "Person2")); + given(repository.findAll()).willReturn(persons); + + List expectedResult = persons.stream() + .map(PersonDto::toDto).collect(Collectors.toList()); + + mvc.perform(get("/persons")) + .andExpect(status().isOk()) + .andExpect(content().json(mapper.writeValueAsString(expectedResult))); + } + + @Test + void shouldReturnCorrectPersonByNameInRequest() throws Exception { + Person person = new Person(1, "Person1"); + given(repository.findByName(person.getName())).willReturn(List.of(person)); + PersonDto expectedResult = PersonDto.toDto(person); + + mvc.perform(get("/persons").param("name", person.getName())) + .andExpect(status().isOk()) + .andExpect(content().json(mapper.writeValueAsString(expectedResult))); + } + + @Test + void shouldReturnCorrectPersonByIdInPath() throws Exception { + Person person = new Person(1, "Person1"); + given(repository.findById(1L)).willReturn(Optional.of(person)); + PersonDto expectedResult = PersonDto.toDto(person); + + mvc.perform(get("/persons/1")) + .andExpect(status().isOk()) + .andExpect(content().json(mapper.writeValueAsString(expectedResult))); + } + + @Test + void shouldReturnExpectedErrorWhenPersonNotFound() throws Exception { + given(repository.findById(1L)).willReturn(Optional.empty()); + + mvc.perform(get("/persons").param("name", "Person1")) + .andExpect(status().isBadRequest()) + .andExpect(content().string(ERROR_STRING)); + + mvc.perform(get("/persons/1")) + .andExpect(status().isBadRequest()) + .andExpect(content().string(ERROR_STRING)); + } +} \ No newline at end of file