From fe5308a283657e62f7304ac14ae2e1ab40ddfac5 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Thu, 30 Nov 2023 11:36:00 +0300 Subject: [PATCH 1/6] Spring boot template --- pom.xml | 46 +++++++++++++++++++ .../filmorate/FilmorateApplication.java | 12 +++++ .../filmorate/controller/FilmController.java | 7 +++ .../practicum/filmorate/model/Film.java | 12 +++++ src/main/resources/application.properties | 1 + .../filmorate/FilmorateApplicationTests.java | 13 ++++++ 6 files changed, 91 insertions(+) create mode 100644 pom.xml create mode 100644 src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/model/Film.java create mode 100644 src/main/resources/application.properties create mode 100644 src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..371c29c8 --- /dev/null +++ b/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.7.18 + + + ru.yandex.practicum + filmorate + 0.0.1-SNAPSHOT + filmorate + filmorate + + 11 + + + + org.springframework.boot + spring-boot-starter-web + + + + org.projectlombok + lombok + provided + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java b/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java new file mode 100644 index 00000000..dca451bc --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java @@ -0,0 +1,12 @@ +package ru.yandex.practicum.filmorate; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class FilmorateApplication { + public static void main(String[] args) { + SpringApplication.run(FilmorateApplication.class, args); + } + +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java new file mode 100644 index 00000000..08cf0a18 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -0,0 +1,7 @@ +package ru.yandex.practicum.filmorate.controller; + +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class FilmController { +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java new file mode 100644 index 00000000..3614a44b --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -0,0 +1,12 @@ +package ru.yandex.practicum.filmorate.model; + +import lombok.Getter; +import lombok.Setter; + +/** + * Film. + */ +@Getter +@Setter +public class Film { +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java new file mode 100644 index 00000000..660412e8 --- /dev/null +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java @@ -0,0 +1,13 @@ +package ru.yandex.practicum.filmorate; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class FilmorateApplicationTests { + + @Test + void contextLoads() { + } + +} From c9016a0be932a62ab2933f695bf1b304c123b244 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov Date: Fri, 12 Apr 2024 13:40:20 +0300 Subject: [PATCH 2/6] JDK 21 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 371c29c8..0cad0315 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 2.7.18 + 3.2.4 ru.yandex.practicum @@ -14,7 +14,7 @@ filmorate filmorate - 11 + 21 From 8d9d935693fb9575afebd5b33e7ec77459e0cf6a Mon Sep 17 00:00:00 2001 From: Aidar Date: Sat, 31 Aug 2024 13:57:42 +0500 Subject: [PATCH 3/6] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D1=8B=D0=B9=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=20=D1=81?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0=2010?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 41 +++++++- .../filmorate/FilmorateApplication.java | 4 +- .../filmorate/controller/FilmController.java | 75 ++++++++++++++- .../filmorate/controller/UserController.java | 82 ++++++++++++++++ .../ecxeption/ValidationException.java | 7 ++ .../practicum/filmorate/model/Film.java | 16 ++-- .../practicum/filmorate/model/User.java | 15 +++ .../filmorate/FilmorateApplicationTests.java | 95 ++++++++++++++++++- 8 files changed, 320 insertions(+), 15 deletions(-) create mode 100644 src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/ecxeption/ValidationException.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/model/User.java diff --git a/pom.xml b/pom.xml index 0cad0315..63951140 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,10 @@ org.springframework.boot spring-boot-starter-web - + + org.slf4j + slf4j-api + org.projectlombok lombok @@ -32,14 +35,50 @@ spring-boot-starter-test test + + ch.qos.logback + logback-classic + + + junit + junit + test + + + org.springframework.boot + spring-boot-starter-validation + + + org.apache.maven.plugins + maven-compiler-plugin + org.springframework.boot spring-boot-maven-plugin + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.3.1 + + checkstyle.xml + true + true + true + + + + + check + + compile + + + diff --git a/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java b/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java index dca451bc..eb0225c0 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java +++ b/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java @@ -1,12 +1,14 @@ package ru.yandex.practicum.filmorate; +import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +@Slf4j @SpringBootApplication public class FilmorateApplication { public static void main(String[] args) { SpringApplication.run(FilmorateApplication.class, args); + log.info("Приложение запущено"); } - } diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java index 08cf0a18..9a1cd1f3 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -1,7 +1,78 @@ package ru.yandex.practicum.filmorate.controller; -import org.springframework.web.bind.annotation.RestController; +import jakarta.validation.Valid; +import lombok.extern.slf4j.Slf4j; +import ru.yandex.practicum.filmorate.ecxeption.ValidationException; +import ru.yandex.practicum.filmorate.model.Film; +import org.springframework.web.bind.annotation.*; +import java.time.LocalDate; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +@Slf4j @RestController +@RequestMapping("/films") public class FilmController { -} + private final Map films = new HashMap<>(); + + @GetMapping + public Collection getAllFilms() { + return films.values(); + } + + @PostMapping + public Film createFilm(@Valid @RequestBody Film film) { + if (validateFilm(film) == null) { + throw new ValidationException("Валидация не пройдена."); + } + film.setId(getNextId()); + log.debug("Валидация пройдена."); + films.put(film.getId(), film); + log.debug("Фильм добавлен в список."); + return film; + } + + @PutMapping + public Film ubdateFilm(@Valid @RequestBody Film film) { + if (film.getId() == null) { + throw new ValidationException("Id должен быть указан!"); + } + if (films.containsKey(film.getId())) { + if (validateFilm(film) == null) { + throw new ValidationException("Валидация не пройдена."); + } + film.setDescription(film.getDescription()); + film.setName(film.getName()); + film.setReleaseDate(film.getReleaseDate()); + film.setDuration(film.getDuration()); + return film; + } else throw new ValidationException("Такого фильма нет в списке!"); + } + + private Film validateFilm(Film film) { + if (film.getName() == null || film.getName().isBlank()) { + throw new ValidationException("Название не может быть пустым!"); + } + if (film.getDescription().length() > 200) { + throw new ValidationException("Максимальная длина описания — 200 символов!"); + } + if (film.getReleaseDate().isBefore(LocalDate.of(1895, 12, 28))) { + throw new ValidationException("Дата релиза — не раньше 28 декабря 1895 года!"); + } + if (film.getDuration() <= 0) { + throw new ValidationException("Продолжительность фильма должна быть положительным числом!"); + } + return film; + } + + private Long getNextId() { + long currentMaxId = films.keySet() + .stream() + .mapToLong(id -> id) + .max() + .orElse(0); + return ++currentMaxId; + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java new file mode 100644 index 00000000..604915e1 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -0,0 +1,82 @@ +package ru.yandex.practicum.filmorate.controller; + +import jakarta.validation.Valid; +import lombok.extern.slf4j.Slf4j; +import ru.yandex.practicum.filmorate.ecxeption.ValidationException; +import ru.yandex.practicum.filmorate.model.User; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDate; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@RestController +@RequestMapping("/users") +public class UserController { + private final Map users = new HashMap<>(); + + @GetMapping + public Collection getAllUsers() { + return users.values(); + } + + @PostMapping + public User createUser(@Valid @RequestBody User user) { + if (validateUser(user) == null) { + throw new ValidationException("Валидация не пройдена."); + } + user.setId(getNextId()); + if (user.getName() == null) { + user.setName(user.getLogin()); + } + users.put(user.getId(), user); + return user; + } + + @PutMapping + public User updateUser(@Valid @RequestBody User user) { + if (user.getId() == null) { + throw new ValidationException("Id должен быть указан!"); + } + if (users.containsKey(user.getId())) { + if (validateUser(user) == null) { + throw new ValidationException("Валидация не пройдена."); + } + log.debug("Валидация пройдена."); + user.setBirthday(user.getBirthday()); + user.setLogin(user.getLogin()); + user.setEmail(user.getEmail()); + if (user.getName() == null) { + user.setName(user.getLogin()); + log.debug("Заменили имя на логин."); + } else { + user.setName(user.getName()); + } + return user; + } else throw new ValidationException("Такого пользователя нет в списке!"); + } + + private User validateUser(User user) { + if (user.getEmail() == null || user.getEmail().isBlank() || !user.getEmail().contains(String.valueOf('@'))) { + throw new ValidationException("Электронная почта не может быть пустой и должна содержать символ @!"); + } + if (user.getLogin().isBlank() || user.getLogin().contains(String.valueOf(' '))) { + throw new ValidationException("Логин не может быть пустым и содержать пробелы!"); + } + if (user.getBirthday().isAfter(LocalDate.now())) { + throw new ValidationException("Дата рождения не может быть в будущем!"); + } + return user; + } + + private Long getNextId() { + long currentMaxId = users.keySet() + .stream() + .mapToLong(id -> id) + .max() + .orElse(0); + return ++currentMaxId; + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/ecxeption/ValidationException.java b/src/main/java/ru/yandex/practicum/filmorate/ecxeption/ValidationException.java new file mode 100644 index 00000000..4f13aa60 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/ecxeption/ValidationException.java @@ -0,0 +1,7 @@ +package ru.yandex.practicum.filmorate.ecxeption; + +public class ValidationException extends RuntimeException { + public ValidationException(String string) { + super(string); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java index 3614a44b..4f049bf5 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -1,12 +1,14 @@ package ru.yandex.practicum.filmorate.model; -import lombok.Getter; -import lombok.Setter; +import lombok.Data; -/** - * Film. - */ -@Getter -@Setter +import java.time.LocalDate; + +@Data public class Film { + Long id; + String name; + String description; + LocalDate releaseDate; + int duration; } diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/User.java b/src/main/java/ru/yandex/practicum/filmorate/model/User.java new file mode 100644 index 00000000..2a836db4 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -0,0 +1,15 @@ +package ru.yandex.practicum.filmorate.model; +import jakarta.validation.constraints.Email; +import lombok.Data; + +import java.time.LocalDate; + +@Data +public class User { + Long id; + @Email + String email; + String login; + String name; + LocalDate birthday; +} diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java index 660412e8..4227ab63 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java @@ -1,13 +1,100 @@ package ru.yandex.practicum.filmorate; -import org.junit.jupiter.api.Test; +import org.junit.Test; import org.springframework.boot.test.context.SpringBootTest; +import ru.yandex.practicum.filmorate.ecxeption.ValidationException; +import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.model.User; +import ru.yandex.practicum.filmorate.controller.FilmController; +import ru.yandex.practicum.filmorate.controller.UserController; + +import java.io.IOException; +import java.time.LocalDate; @SpringBootTest -class FilmorateApplicationTests { +public class FilmorateApplicationTests { + + @Test(expected = ValidationException.class) + public void testValidateEmailUser() throws IOException { + + User user = new User(); + user.setId(1L); + user.setEmail("exampleexample.com"); + user.setLogin("exampleLogin"); + user.setName("Example"); + user.setBirthday(LocalDate.of(2000, 1, 1)); + UserController userController = new UserController(); + userController.createUser(user); + } + + @Test(expected = ValidationException.class) + public void testValidateLoginUser() throws IOException { + + User user = new User(); + user.setId(1L); + user.setEmail("example@example.com"); + user.setLogin(""); + user.setName("Example"); + user.setBirthday(LocalDate.of(2000, 1, 1)); + UserController userController = new UserController(); + userController.createUser(user); + } + + @Test(expected = ValidationException.class) + public void testValidateDateUser() throws IOException { + + User user = new User(); + user.setId(1L); + user.setEmail("example@example.com"); + user.setLogin("exampleLogin"); + user.setName("Example"); + user.setBirthday(LocalDate.of(2050, 1, 1)); + UserController userController = new UserController(); + userController.createUser(user); + } + + @Test(expected = ValidationException.class) + public void testValidateFilmName() throws IOException { + Film film = new Film(); + film.setName(""); + film.setDescription("exampleFilm"); + film.setReleaseDate(LocalDate.of(2000, 1, 1)); + film.setDuration(100); + FilmController filmController = new FilmController(); + filmController.createFilm(film); + } + + @Test(expected = ValidationException.class) + public void testValidateFilmDescription() throws IOException { + Film film = new Film(); + film.setName("Example"); + film.setDescription("exampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmFilmexampleFilmFilmexampleFilmFilmexampleFilmFilmexampleFilmFilmexampleFilmFilmexampleFilm"); + film.setReleaseDate(LocalDate.of(2000, 1, 1)); + film.setDuration(100); + FilmController filmController = new FilmController(); + filmController.createFilm(film); + } + + @Test(expected = ValidationException.class) + public void testValidateFilmRelease() throws IOException { + Film film = new Film(); + film.setName("Example"); + film.setDescription("exampleFilm"); + film.setReleaseDate(LocalDate.of(1895, 12, 27)); + film.setDuration(100); + FilmController filmController = new FilmController(); + filmController.createFilm(film); + } - @Test - void contextLoads() { + @Test(expected = ValidationException.class) + public void testValidateFilmDuration() throws IOException { + Film film = new Film(); + film.setName("Example"); + film.setDescription("exampleFilm"); + film.setReleaseDate(LocalDate.of(2000, 1, 1)); + film.setDuration(0); + FilmController filmController = new FilmController(); + filmController.createFilm(film); } } From 749876b5dcd9b02faf40a2fa52db91b70bf31f19 Mon Sep 17 00:00:00 2001 From: Aidar Date: Sun, 1 Sep 2024 15:32:28 +0500 Subject: [PATCH 4/6] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D1=8B=D0=B9=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=20=D1=81?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0=2010(=D0=B2=D0=B0=D1=801)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 5 ++ .../filmorate/controller/FilmController.java | 24 ++------- .../filmorate/controller/UserController.java | 22 +------- .../practicum/filmorate/model/Film.java | 10 ++++ .../practicum/filmorate/model/User.java | 11 +++- .../filmorate/FilmorateApplicationTests.java | 54 ++++++++++--------- 6 files changed, 58 insertions(+), 68 deletions(-) diff --git a/pom.xml b/pom.xml index 63951140..3a2178a0 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,11 @@ 21 + + jakarta.validation + jakarta.validation-api + 3.0.2 + org.springframework.boot spring-boot-starter-web diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java index 9a1cd1f3..8fa2e9f1 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -24,8 +24,8 @@ public Collection getAllFilms() { @PostMapping public Film createFilm(@Valid @RequestBody Film film) { - if (validateFilm(film) == null) { - throw new ValidationException("Валидация не пройдена."); + if (film.getReleaseDate().isBefore(LocalDate.of(1895, 12, 28))) { + throw new ValidationException("Дата релиза — не раньше 28 декабря 1895 года!"); } film.setId(getNextId()); log.debug("Валидация пройдена."); @@ -40,8 +40,8 @@ public Film ubdateFilm(@Valid @RequestBody Film film) { throw new ValidationException("Id должен быть указан!"); } if (films.containsKey(film.getId())) { - if (validateFilm(film) == null) { - throw new ValidationException("Валидация не пройдена."); + if (film.getReleaseDate().isBefore(LocalDate.of(1895, 12, 28))) { + throw new ValidationException("Дата релиза — не раньше 28 декабря 1895 года!"); } film.setDescription(film.getDescription()); film.setName(film.getName()); @@ -51,22 +51,6 @@ public Film ubdateFilm(@Valid @RequestBody Film film) { } else throw new ValidationException("Такого фильма нет в списке!"); } - private Film validateFilm(Film film) { - if (film.getName() == null || film.getName().isBlank()) { - throw new ValidationException("Название не может быть пустым!"); - } - if (film.getDescription().length() > 200) { - throw new ValidationException("Максимальная длина описания — 200 символов!"); - } - if (film.getReleaseDate().isBefore(LocalDate.of(1895, 12, 28))) { - throw new ValidationException("Дата релиза — не раньше 28 декабря 1895 года!"); - } - if (film.getDuration() <= 0) { - throw new ValidationException("Продолжительность фильма должна быть положительным числом!"); - } - return film; - } - private Long getNextId() { long currentMaxId = films.keySet() .stream() diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java index 604915e1..0eaa09f7 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -6,7 +6,6 @@ import ru.yandex.practicum.filmorate.model.User; import org.springframework.web.bind.annotation.*; -import java.time.LocalDate; import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -24,10 +23,8 @@ public Collection getAllUsers() { @PostMapping public User createUser(@Valid @RequestBody User user) { - if (validateUser(user) == null) { - throw new ValidationException("Валидация не пройдена."); - } user.setId(getNextId()); + log.debug("Валидация пройдена."); if (user.getName() == null) { user.setName(user.getLogin()); } @@ -41,10 +38,6 @@ public User updateUser(@Valid @RequestBody User user) { throw new ValidationException("Id должен быть указан!"); } if (users.containsKey(user.getId())) { - if (validateUser(user) == null) { - throw new ValidationException("Валидация не пройдена."); - } - log.debug("Валидация пройдена."); user.setBirthday(user.getBirthday()); user.setLogin(user.getLogin()); user.setEmail(user.getEmail()); @@ -58,19 +51,6 @@ public User updateUser(@Valid @RequestBody User user) { } else throw new ValidationException("Такого пользователя нет в списке!"); } - private User validateUser(User user) { - if (user.getEmail() == null || user.getEmail().isBlank() || !user.getEmail().contains(String.valueOf('@'))) { - throw new ValidationException("Электронная почта не может быть пустой и должна содержать символ @!"); - } - if (user.getLogin().isBlank() || user.getLogin().contains(String.valueOf(' '))) { - throw new ValidationException("Логин не может быть пустым и содержать пробелы!"); - } - if (user.getBirthday().isAfter(LocalDate.now())) { - throw new ValidationException("Дата рождения не может быть в будущем!"); - } - return user; - } - private Long getNextId() { long currentMaxId = users.keySet() .stream() diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java index 4f049bf5..00675a29 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -1,14 +1,24 @@ package ru.yandex.practicum.filmorate.model; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Positive; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; import java.time.LocalDate; @Data +@AllArgsConstructor +@NoArgsConstructor public class Film { Long id; + @NotBlank(message = "Название не может быть пустым!") String name; + @Size(max = 200, message = "Максимальная длина описания — 200 символов!") String description; LocalDate releaseDate; + @Positive(message = "Продолжительность фильма должна быть положительным числом!") int duration; } diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/User.java b/src/main/java/ru/yandex/practicum/filmorate/model/User.java index 2a836db4..75a46169 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/User.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -1,15 +1,24 @@ package ru.yandex.practicum.filmorate.model; + import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Past; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; import java.time.LocalDate; @Data +@AllArgsConstructor +@NoArgsConstructor public class User { Long id; - @Email + @Email(message = "Введенный email не соответствует формату email-адресов!") String email; + @NotBlank(message = "Логин не может быть пустым и содержать пробелы!") String login; String name; + @Past(message = "Дата рождения не может быть в будущем!") LocalDate birthday; } diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java index 4227ab63..0f9320c7 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java @@ -1,78 +1,80 @@ package ru.yandex.practicum.filmorate; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; import org.junit.Test; +import org.junit.jupiter.api.Assertions; import org.springframework.boot.test.context.SpringBootTest; import ru.yandex.practicum.filmorate.ecxeption.ValidationException; import ru.yandex.practicum.filmorate.model.Film; import ru.yandex.practicum.filmorate.model.User; import ru.yandex.practicum.filmorate.controller.FilmController; -import ru.yandex.practicum.filmorate.controller.UserController; import java.io.IOException; import java.time.LocalDate; +import java.util.Set; @SpringBootTest public class FilmorateApplicationTests { - @Test(expected = ValidationException.class) - public void testValidateEmailUser() throws IOException { + private final ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + private final Validator validator = factory.getValidator(); + @Test + public void testValidateEmailUser() throws IOException { User user = new User(); - user.setId(1L); - user.setEmail("exampleexample.com"); + user.setEmail("@exampleexample.com"); user.setLogin("exampleLogin"); user.setName("Example"); user.setBirthday(LocalDate.of(2000, 1, 1)); - UserController userController = new UserController(); - userController.createUser(user); + Set> violations = validator.validate(user); + Assertions.assertFalse(violations.isEmpty(), "Пользователь с неправильным емейлом не должен создаваться"); } - @Test(expected = ValidationException.class) + @Test public void testValidateLoginUser() throws IOException { - User user = new User(); - user.setId(1L); user.setEmail("example@example.com"); user.setLogin(""); user.setName("Example"); user.setBirthday(LocalDate.of(2000, 1, 1)); - UserController userController = new UserController(); - userController.createUser(user); + Set> violations = validator.validate(user); + Assertions.assertFalse(violations.isEmpty(), "Пользователь с пустым логином не должен создаваться"); } - @Test(expected = ValidationException.class) + @Test public void testValidateDateUser() throws IOException { - User user = new User(); - user.setId(1L); user.setEmail("example@example.com"); user.setLogin("exampleLogin"); user.setName("Example"); user.setBirthday(LocalDate.of(2050, 1, 1)); - UserController userController = new UserController(); - userController.createUser(user); + Set> violations = validator.validate(user); + Assertions.assertFalse(violations.isEmpty(), "Пользователь с датой др в будущем не должен создаваться"); } - @Test(expected = ValidationException.class) + @Test public void testValidateFilmName() throws IOException { Film film = new Film(); film.setName(""); film.setDescription("exampleFilm"); film.setReleaseDate(LocalDate.of(2000, 1, 1)); film.setDuration(100); - FilmController filmController = new FilmController(); - filmController.createFilm(film); + Set> violations = validator.validate(film); + Assertions.assertFalse(violations.isEmpty(), "Фильм с пустым именем не должен создаваться"); } - @Test(expected = ValidationException.class) + @Test public void testValidateFilmDescription() throws IOException { Film film = new Film(); film.setName("Example"); film.setDescription("exampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmexampleFilmFilmexampleFilmFilmexampleFilmFilmexampleFilmFilmexampleFilmFilmexampleFilmFilmexampleFilm"); film.setReleaseDate(LocalDate.of(2000, 1, 1)); film.setDuration(100); - FilmController filmController = new FilmController(); - filmController.createFilm(film); + Set> violations = validator.validate(film); + Assertions.assertFalse(violations.isEmpty(), "Фильм с описанием более 200 смволов не должен создаваться"); } @Test(expected = ValidationException.class) @@ -86,15 +88,15 @@ public void testValidateFilmRelease() throws IOException { filmController.createFilm(film); } - @Test(expected = ValidationException.class) + @Test public void testValidateFilmDuration() throws IOException { Film film = new Film(); film.setName("Example"); film.setDescription("exampleFilm"); film.setReleaseDate(LocalDate.of(2000, 1, 1)); film.setDuration(0); - FilmController filmController = new FilmController(); - filmController.createFilm(film); + Set> violations = validator.validate(film); + Assertions.assertFalse(violations.isEmpty(), "Фильм с продолжительностью 0 не должен создаваться"); } } From 7f6c640d1d2ebca514117833139ab938e7db323b Mon Sep 17 00:00:00 2001 From: Aidar Date: Mon, 16 Sep 2024 16:49:59 +0500 Subject: [PATCH 5/6] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D1=8B=D0=B9=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=20=D1=81?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0=2011?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 5 ++ .../filmorate/controller/ErrorHandler.java | 31 +++++++ .../filmorate/controller/FilmController.java | 71 +++++++-------- .../filmorate/controller/UserController.java | 74 ++++++++-------- .../ecxeption/NotFoundException.java | 7 ++ .../ecxeption/OccurredException.java | 7 ++ .../filmorate/model/ErrorResponse.java | 11 +++ .../practicum/filmorate/model/Film.java | 3 + .../practicum/filmorate/model/User.java | 3 + .../filmorate/service/FilmService.java | 79 +++++++++++++++++ .../filmorate/service/UserService.java | 87 +++++++++++++++++++ .../filmorate/storage/film/FilmStorage.java | 16 ++++ .../storage/film/InMemoryFilmStorage.java | 83 ++++++++++++++++++ .../storage/user/InMemoryUserStorage.java | 82 +++++++++++++++++ .../filmorate/storage/user/UserStorage.java | 16 ++++ src/main/resources/application.properties | 2 +- .../filmorate/FilmorateApplicationTests.java | 26 +++--- 17 files changed, 513 insertions(+), 90 deletions(-) create mode 100644 src/main/java/ru/yandex/practicum/filmorate/controller/ErrorHandler.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/ecxeption/NotFoundException.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/ecxeption/OccurredException.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/model/ErrorResponse.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/service/UserService.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/film/FilmStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/film/InMemoryFilmStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/user/InMemoryUserStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/user/UserStorage.java diff --git a/pom.xml b/pom.xml index 3a2178a0..c5236f5e 100644 --- a/pom.xml +++ b/pom.xml @@ -53,6 +53,11 @@ org.springframework.boot spring-boot-starter-validation + + org.zalando + logbook-spring-boot-starter + 3.7.2 + diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/ErrorHandler.java b/src/main/java/ru/yandex/practicum/filmorate/controller/ErrorHandler.java new file mode 100644 index 00000000..750cdb26 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/ErrorHandler.java @@ -0,0 +1,31 @@ +package ru.yandex.practicum.filmorate.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import ru.yandex.practicum.filmorate.ecxeption.NotFoundException; +import ru.yandex.practicum.filmorate.ecxeption.OccurredException; +import ru.yandex.practicum.filmorate.ecxeption.ValidationException; +import ru.yandex.practicum.filmorate.model.ErrorResponse; + +@RestControllerAdvice +public class ErrorHandler { + @ExceptionHandler + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ErrorResponse validationException(final ValidationException e) { + return new ErrorResponse(e.getMessage()); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public ErrorResponse occurredException(final OccurredException e) { + return new ErrorResponse(e.getMessage()); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.NOT_FOUND) + public ErrorResponse notFoundException(final NotFoundException e) { + return new ErrorResponse(e.getMessage()); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java index 8fa2e9f1..9ca183ff 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -1,62 +1,55 @@ package ru.yandex.practicum.filmorate.controller; import jakarta.validation.Valid; -import lombok.extern.slf4j.Slf4j; -import ru.yandex.practicum.filmorate.ecxeption.ValidationException; import ru.yandex.practicum.filmorate.model.Film; import org.springframework.web.bind.annotation.*; +import ru.yandex.practicum.filmorate.service.FilmService; -import java.time.LocalDate; import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -@Slf4j @RestController +//@RequiredArgsConstructor @RequestMapping("/films") public class FilmController { - private final Map films = new HashMap<>(); + private final FilmService filmService; + + public FilmController(FilmService filmService) { + this.filmService = filmService; + } @GetMapping public Collection getAllFilms() { - return films.values(); + return filmService.getAllFilms(); + } + + @GetMapping("/{id}") + public Film getFilmById(@PathVariable("id") long id) { + return filmService.getFilmById(id); } @PostMapping public Film createFilm(@Valid @RequestBody Film film) { - if (film.getReleaseDate().isBefore(LocalDate.of(1895, 12, 28))) { - throw new ValidationException("Дата релиза — не раньше 28 декабря 1895 года!"); - } - film.setId(getNextId()); - log.debug("Валидация пройдена."); - films.put(film.getId(), film); - log.debug("Фильм добавлен в список."); - return film; + return filmService.createFilm(film); } @PutMapping - public Film ubdateFilm(@Valid @RequestBody Film film) { - if (film.getId() == null) { - throw new ValidationException("Id должен быть указан!"); - } - if (films.containsKey(film.getId())) { - if (film.getReleaseDate().isBefore(LocalDate.of(1895, 12, 28))) { - throw new ValidationException("Дата релиза — не раньше 28 декабря 1895 года!"); - } - film.setDescription(film.getDescription()); - film.setName(film.getName()); - film.setReleaseDate(film.getReleaseDate()); - film.setDuration(film.getDuration()); - return film; - } else throw new ValidationException("Такого фильма нет в списке!"); - } - - private Long getNextId() { - long currentMaxId = films.keySet() - .stream() - .mapToLong(id -> id) - .max() - .orElse(0); - return ++currentMaxId; + public Film updateFilm(@Valid @RequestBody Film film) { + return filmService.updateFilm(film); + } + + @PutMapping("/{id}/like/{userId}") + public Film userLikesFilm(@PathVariable("id") Long id, @PathVariable("userId") Long userId) { + return filmService.userLikesFilm(id, userId); } + + @DeleteMapping("/{id}/like/{userId}") + public Film deleteLikesFilm(@PathVariable("id") Long id, @PathVariable("userId") Long userId) { + return filmService.deleteLikesFilm(id, userId); + } + + @GetMapping("/popular") + public Collection listFirstCountFilm(@RequestParam(defaultValue = "10") int count) { + return filmService.listFirstCountFilm(count); + } + } \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java index 0eaa09f7..a0b8b830 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -1,62 +1,60 @@ package ru.yandex.practicum.filmorate.controller; import jakarta.validation.Valid; -import lombok.extern.slf4j.Slf4j; -import ru.yandex.practicum.filmorate.ecxeption.ValidationException; import ru.yandex.practicum.filmorate.model.User; import org.springframework.web.bind.annotation.*; +import ru.yandex.practicum.filmorate.service.UserService; import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -@Slf4j @RestController @RequestMapping("/users") public class UserController { - private final Map users = new HashMap<>(); + + private UserService userService; + + UserController(UserService userService) { + this.userService = userService; + } @GetMapping public Collection getAllUsers() { - return users.values(); + return userService.getAllUsers(); + } + + @GetMapping("/{id}") + public User getUserById(@PathVariable("id") long id) { + return userService.getUserById(id); } @PostMapping public User createUser(@Valid @RequestBody User user) { - user.setId(getNextId()); - log.debug("Валидация пройдена."); - if (user.getName() == null) { - user.setName(user.getLogin()); - } - users.put(user.getId(), user); - return user; + return userService.createUser(user); } @PutMapping public User updateUser(@Valid @RequestBody User user) { - if (user.getId() == null) { - throw new ValidationException("Id должен быть указан!"); - } - if (users.containsKey(user.getId())) { - user.setBirthday(user.getBirthday()); - user.setLogin(user.getLogin()); - user.setEmail(user.getEmail()); - if (user.getName() == null) { - user.setName(user.getLogin()); - log.debug("Заменили имя на логин."); - } else { - user.setName(user.getName()); - } - return user; - } else throw new ValidationException("Такого пользователя нет в списке!"); - } - - private Long getNextId() { - long currentMaxId = users.keySet() - .stream() - .mapToLong(id -> id) - .max() - .orElse(0); - return ++currentMaxId; + return userService.updateUser(user); + } + + @PutMapping("/{id}/friends/{friendId}") + public User putFriends(@PathVariable("id") long id, @PathVariable("friendId") long friendId) { + return userService.makeFriendship(id, friendId); } + + @DeleteMapping("/{id}/friends/{friendId}") + public User deleteFriends(@PathVariable("id") long id, @PathVariable("friendId") long friendId) { + return userService.deleteFriendship(id, friendId); + } + + @GetMapping("/{id}/friends") + public Collection listFriends(@PathVariable("id") long id) { + return userService.listOfFriends(id); + } + + @GetMapping("/{id}/friends/common/{otherId}") + public Collection commonFriends(@PathVariable("id") long id, @PathVariable("otherId") long otherId) { + return userService.listOfCommonFriends(id, otherId); + } + } diff --git a/src/main/java/ru/yandex/practicum/filmorate/ecxeption/NotFoundException.java b/src/main/java/ru/yandex/practicum/filmorate/ecxeption/NotFoundException.java new file mode 100644 index 00000000..db265b31 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/ecxeption/NotFoundException.java @@ -0,0 +1,7 @@ +package ru.yandex.practicum.filmorate.ecxeption; + +public class NotFoundException extends RuntimeException { + public NotFoundException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/ecxeption/OccurredException.java b/src/main/java/ru/yandex/practicum/filmorate/ecxeption/OccurredException.java new file mode 100644 index 00000000..7b774095 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/ecxeption/OccurredException.java @@ -0,0 +1,7 @@ +package ru.yandex.practicum.filmorate.ecxeption; + +public class OccurredException extends RuntimeException { + public OccurredException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/ErrorResponse.java b/src/main/java/ru/yandex/practicum/filmorate/model/ErrorResponse.java new file mode 100644 index 00000000..756207ee --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/model/ErrorResponse.java @@ -0,0 +1,11 @@ +package ru.yandex.practicum.filmorate.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class ErrorResponse { + String error; +} + diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java index 00675a29..1241d0f2 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -8,6 +8,8 @@ import lombok.NoArgsConstructor; import java.time.LocalDate; +import java.util.HashSet; +import java.util.Set; @Data @AllArgsConstructor @@ -21,4 +23,5 @@ public class Film { LocalDate releaseDate; @Positive(message = "Продолжительность фильма должна быть положительным числом!") int duration; + Set likes = new HashSet<>(); } diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/User.java b/src/main/java/ru/yandex/practicum/filmorate/model/User.java index 75a46169..e7d84235 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/User.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -8,6 +8,8 @@ import lombok.NoArgsConstructor; import java.time.LocalDate; +import java.util.HashSet; +import java.util.Set; @Data @AllArgsConstructor @@ -21,4 +23,5 @@ public class User { String name; @Past(message = "Дата рождения не может быть в будущем!") LocalDate birthday; + Set friends = new HashSet<>(); } diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java new file mode 100644 index 00000000..29f8787a --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java @@ -0,0 +1,79 @@ +package ru.yandex.practicum.filmorate.service; + +import org.springframework.stereotype.Service; +import ru.yandex.practicum.filmorate.ecxeption.NotFoundException; +import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.storage.film.FilmStorage; +import ru.yandex.practicum.filmorate.storage.user.UserStorage; + +import java.util.*; + +@Service +public class FilmService { + FilmStorage filmStorage; + UserStorage userStorage; + + public FilmService(FilmStorage filmStorage, UserStorage userStorage) { + this.filmStorage = filmStorage; + this.userStorage = userStorage; + } + + public Film getFilmById(Long id) { + if (filmStorage.getFilmById(id) == null) { + throw new NotFoundException("Такого фильма нет в списке!"); + } + return filmStorage.getFilmById(id); + } + + public Film userLikesFilm(Long id, Long userId) { + Film film = filmStorage.getFilmById(id); + if (userStorage.getUserById(userId) == null) { + throw new NotFoundException("Такого юзера нет в списке!"); + } + if (film == null) { + throw new NotFoundException("Такого фильма нет в списке!"); + } + film.getLikes().add(userId); + return film; + } + + public Film deleteLikesFilm(Long id, Long userId) { + if (userStorage.getUserById(userId) == null) { + throw new NotFoundException("Такого юзера нет!"); + } + Film film = filmStorage.getFilmById(id); + if (film == null) { + throw new NotFoundException("Такого фильма нет в списке!"); + } + film.getLikes().remove(userId); + return film; + } + + public Collection listFirstCountFilm(int count) { + Collection films; + films = sortingToDown().stream() + .limit(count) + .toList(); + return films; + } + + public List sortingToDown() { + ArrayList listFilms = new ArrayList<>(filmStorage.getAllFilms()); + listFilms.sort((Film film1, Film film2) -> + Integer.compare(film2.getLikes().size(), film1.getLikes().size()) + ); + return listFilms; + } + + public Collection getAllFilms() { + return filmStorage.getAllFilms(); + } + + public Film createFilm(Film film) { + return filmStorage.createFilm(film); + } + + public Film updateFilm(Film film) { + return filmStorage.ubdateFilm(film); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java new file mode 100644 index 00000000..b9496256 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java @@ -0,0 +1,87 @@ +package ru.yandex.practicum.filmorate.service; + +import org.springframework.stereotype.Service; +import ru.yandex.practicum.filmorate.ecxeption.NotFoundException; +import ru.yandex.practicum.filmorate.model.User; +import ru.yandex.practicum.filmorate.storage.user.UserStorage; + +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class UserService { + + UserStorage userStorage; + + public UserService(UserStorage userStorage) { + this.userStorage = userStorage; + } + + public User getUserById(Long id) { + if (userStorage.getUserById(id) == null) { + throw new NotFoundException("Такого юзера нет в списке!"); + } + return userStorage.getUserById(id); + } + + public User makeFriendship(long id, long friendId) { + if (userStorage.getUserById(id) == null) { + throw new NotFoundException("Такого юзера нет в списке!"); + } + if (userStorage.getUserById(friendId) == null) { + throw new NotFoundException("Невозможно добавить в друзья несуществующего юзера!"); + } + userStorage.getUserById(id).getFriends().add(friendId); + userStorage.getUserById(friendId).getFriends().add(id); + return userStorage.getUserById(id); + } + + public User deleteFriendship(long id, long friendId) { + if (userStorage.getUserById(id) == null) { + throw new NotFoundException("Такого юзера нет в списке!"); + } + if (userStorage.getUserById(friendId) == null) { + throw new NotFoundException("Добавляемого в друзья юзера нет в списке!"); + } + userStorage.getUserById(id).getFriends().remove(friendId); + userStorage.getUserById(friendId).getFriends().remove(id); + return userStorage.getUserById(id); + } + + public Collection listOfFriends(long id) { + if (userStorage.getUserById(id) == null) { + throw new NotFoundException("Такого юзера нет в списке!"); + } + if (userStorage.getUserById(id).getFriends() == null) { + throw new NotFoundException("Список друзей пуст!"); + } + return userStorage.getUserById(id).getFriends().stream() + .map(friends -> userStorage.getUserById(friends)) + .collect(Collectors.toList()); + } + + public Collection listOfCommonFriends(Long id, Long otherId) { + if (userStorage.getUserById(id) == null || userStorage.getUserById(otherId) == null) { + throw new NotFoundException("Одного из юзеров нет в списке!"); + } + if (userStorage.getUserById(id).getFriends() == null || userStorage.getUserById(otherId).getFriends() == null) { + throw new NotFoundException("Один из списков друзей пуст!"); + } + userStorage.getUserById(id).getFriends().retainAll(userStorage.getUserById(otherId).getFriends()); + return userStorage.getUserById(id).getFriends().stream() + .map(friends -> userStorage.getUserById(friends)) + .collect(Collectors.toList()); + } + + public Collection getAllUsers() { + return userStorage.getAllUsers(); + } + + public User createUser(User user) { + return userStorage.createUser(user); + } + + public User updateUser(User user) { + return userStorage.updateUser(user); + } +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/film/FilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/film/FilmStorage.java new file mode 100644 index 00000000..4d22cd88 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/film/FilmStorage.java @@ -0,0 +1,16 @@ +package ru.yandex.practicum.filmorate.storage.film; + +import ru.yandex.practicum.filmorate.model.Film; + +import java.util.Collection; + +public interface FilmStorage { + + Film getFilmById(Long id); + + Collection getAllFilms(); + + Film createFilm(Film film); + + Film ubdateFilm(Film film); +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/film/InMemoryFilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/film/InMemoryFilmStorage.java new file mode 100644 index 00000000..e8568991 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/film/InMemoryFilmStorage.java @@ -0,0 +1,83 @@ +package ru.yandex.practicum.filmorate.storage.film; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.ecxeption.NotFoundException; +import ru.yandex.practicum.filmorate.ecxeption.OccurredException; +import ru.yandex.practicum.filmorate.ecxeption.ValidationException; +import ru.yandex.practicum.filmorate.model.Film; + +import java.time.LocalDate; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +@Slf4j +@Component +public class InMemoryFilmStorage implements FilmStorage { + + private final Map films = new HashMap<>(); + + @Override + public Film getFilmById(Long id) { + return films.get(id); + } + + @Override + public Collection getAllFilms() { + return films.values(); + } + + @Override + public Film createFilm(Film film) { + validateFilm(film); + if (film.getReleaseDate().isBefore(LocalDate.of(1895, 12, 28))) { + throw new ValidationException("Дата релиза — не раньше 28 декабря 1895 года!"); + } + film.setId(getNextId()); + log.debug("Валидация пройдена."); + films.put(film.getId(), film); + log.debug("Фильм добавлен в список."); + return film; + } + + @Override + public Film ubdateFilm(Film film) { + validateFilm(film); + if (film.getId() == null) { + throw new ValidationException("Id должен быть указан!"); + } + validateFilm(film); + if (films.containsKey(film.getId())) { + if (film.getReleaseDate().isBefore(LocalDate.of(1895, 12, 28))) { + throw new ValidationException("Дата релиза — не раньше 28 декабря 1895 года!"); + } + film.setDescription(film.getDescription()); + film.setName(film.getName()); + film.setReleaseDate(film.getReleaseDate()); + film.setDuration(film.getDuration()); + return film; + } else throw new NotFoundException("Такого фильма нет в списке!"); + } + + private Long getNextId() { + long currentMaxId = films.keySet() + .stream() + .mapToLong(id -> id) + .max() + .orElse(0); + return ++currentMaxId; + } + + private void validateFilm(Film film) { + if (film.getName() == null || film.getName().isBlank()) { + throw new OccurredException("Название не может быть пустым!"); + } + if (film.getDescription().length() > 200) { + throw new OccurredException("Максимальная длина описания — 200 символов!"); + } + if (film.getDuration() <= 0) { + throw new OccurredException("Продолжительность фильма должна быть положительным числом!"); + } + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/user/InMemoryUserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/user/InMemoryUserStorage.java new file mode 100644 index 00000000..b45966ed --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/user/InMemoryUserStorage.java @@ -0,0 +1,82 @@ +package ru.yandex.practicum.filmorate.storage.user; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.ecxeption.NotFoundException; +import ru.yandex.practicum.filmorate.ecxeption.OccurredException; +import ru.yandex.practicum.filmorate.ecxeption.ValidationException; +import ru.yandex.practicum.filmorate.model.User; + +import java.time.LocalDate; + +import java.util.*; + +@Slf4j +@Component +public class InMemoryUserStorage implements UserStorage { + + private final Map users = new HashMap<>(); + + @Override + public Collection getAllUsers() { + return users.values(); + } + + @Override + public User getUserById(Long id) { + return users.get(id); + } + + @Override + public User createUser(User user) { + validateUser(user); + user.setId(getNextId()); + log.debug("Валидация пройдена."); + if (user.getName() == null) { + user.setName(user.getLogin()); + } + users.put(user.getId(), user); + return user; + } + + @Override + public User updateUser(User user) { + if (user.getId() == null) { + throw new ValidationException("Id должен быть указан!"); + } + validateUser(user); + if (users.containsKey(user.getId())) { + user.setBirthday(user.getBirthday()); + user.setLogin(user.getLogin()); + user.setEmail(user.getEmail()); + if (user.getName() == null) { + user.setName(user.getLogin()); + log.debug("Заменили имя на логин."); + } else { + user.setName(user.getName()); + } + return user; + } else throw new NotFoundException("Такого пользователя нет в списке!"); + } + + private Long getNextId() { + long currentMaxId = users.keySet() + .stream() + .mapToLong(id -> id) + .max() + .orElse(0); + return ++currentMaxId; + } + + private void validateUser(User user) { + if (user.getEmail() == null || user.getEmail().isBlank() || !user.getEmail().contains(String.valueOf('@'))) { + throw new OccurredException("Электронная почта не может быть пустой и должна содержать символ @!"); + } + if (user.getLogin().isBlank() || user.getLogin().contains(String.valueOf(' '))) { + throw new OccurredException("Логин не может быть пустым и содержать пробелы!"); + } + if (user.getBirthday().isAfter(LocalDate.now())) { + throw new OccurredException("Дата рождения не может быть в будущем!"); + } + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/user/UserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/user/UserStorage.java new file mode 100644 index 00000000..8d013fd4 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/user/UserStorage.java @@ -0,0 +1,16 @@ +package ru.yandex.practicum.filmorate.storage.user; + +import ru.yandex.practicum.filmorate.model.User; + +import java.util.Collection; + +public interface UserStorage { + + User getUserById(Long id); + + Collection getAllUsers(); + + User createUser(User user); + + User updateUser(User user); +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8b137891..21af5c78 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1 @@ - +logging.level.org.zalando.logbook=TRACE diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java index 0f9320c7..00b99fcb 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java @@ -7,10 +7,12 @@ import org.junit.Test; import org.junit.jupiter.api.Assertions; import org.springframework.boot.test.context.SpringBootTest; -import ru.yandex.practicum.filmorate.ecxeption.ValidationException; +//import ru.yandex.practicum.filmorate.ecxeption.ValidationException; import ru.yandex.practicum.filmorate.model.Film; import ru.yandex.practicum.filmorate.model.User; -import ru.yandex.practicum.filmorate.controller.FilmController; +//import ru.yandex.practicum.filmorate.controller.FilmController; +//import ru.yandex.practicum.filmorate.service.FilmService; +//import ru.yandex.practicum.filmorate.storage.film.InMemoryFilmStorage; import java.io.IOException; import java.time.LocalDate; @@ -77,16 +79,16 @@ public void testValidateFilmDescription() throws IOException { Assertions.assertFalse(violations.isEmpty(), "Фильм с описанием более 200 смволов не должен создаваться"); } - @Test(expected = ValidationException.class) - public void testValidateFilmRelease() throws IOException { - Film film = new Film(); - film.setName("Example"); - film.setDescription("exampleFilm"); - film.setReleaseDate(LocalDate.of(1895, 12, 27)); - film.setDuration(100); - FilmController filmController = new FilmController(); - filmController.createFilm(film); - } +// @Test(expected = ValidationException.class) +// public void testValidateFilmRelease() throws IOException { +// Film film = new Film(); +// film.setName("Example"); +// film.setDescription("exampleFilm"); +// film.setReleaseDate(LocalDate.of(1895, 12, 27)); +// film.setDuration(100); +// FilmController filmController = new FilmController(new FilmService()); +// filmController.createFilm(film); +// } @Test public void testValidateFilmDuration() throws IOException { From 33b4eb2890fb807365a525f0c3f154f9d799c686 Mon Sep 17 00:00:00 2001 From: Aidar Date: Tue, 17 Sep 2024 12:08:43 +0500 Subject: [PATCH 6/6] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D1=8B=D0=B9=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=20=D1=81?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0=2011=20(=D0=B2=D0=B0=D1=80?= =?UTF-8?q?2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filmorate/controller/FilmController.java | 1 - .../filmorate/controller/UserController.java | 2 +- .../filmorate/service/FilmService.java | 13 ++++------ .../filmorate/service/UserService.java | 8 +++---- .../filmorate/storage/film/FilmStorage.java | 2 +- .../storage/film/InMemoryFilmStorage.java | 24 +++---------------- .../storage/user/InMemoryUserStorage.java | 17 ------------- 7 files changed, 13 insertions(+), 54 deletions(-) diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java index 9ca183ff..8d422bf6 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -8,7 +8,6 @@ import java.util.Collection; @RestController -//@RequiredArgsConstructor @RequestMapping("/films") public class FilmController { private final FilmService filmService; diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java index a0b8b830..badda64a 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -11,7 +11,7 @@ @RequestMapping("/users") public class UserController { - private UserService userService; + private final UserService userService; UserController(UserService userService) { this.userService = userService; diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java index 29f8787a..41e572ab 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java @@ -1,5 +1,6 @@ package ru.yandex.practicum.filmorate.service; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import ru.yandex.practicum.filmorate.ecxeption.NotFoundException; import ru.yandex.practicum.filmorate.model.Film; @@ -9,14 +10,10 @@ import java.util.*; @Service +@RequiredArgsConstructor public class FilmService { - FilmStorage filmStorage; - UserStorage userStorage; - - public FilmService(FilmStorage filmStorage, UserStorage userStorage) { - this.filmStorage = filmStorage; - this.userStorage = userStorage; - } + private final FilmStorage filmStorage; + private final UserStorage userStorage; public Film getFilmById(Long id) { if (filmStorage.getFilmById(id) == null) { @@ -74,6 +71,6 @@ public Film createFilm(Film film) { } public Film updateFilm(Film film) { - return filmStorage.ubdateFilm(film); + return filmStorage.updateFilm(film); } } diff --git a/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java index b9496256..3813fd68 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java @@ -1,5 +1,6 @@ package ru.yandex.practicum.filmorate.service; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import ru.yandex.practicum.filmorate.ecxeption.NotFoundException; import ru.yandex.practicum.filmorate.model.User; @@ -9,13 +10,10 @@ import java.util.stream.Collectors; @Service +@RequiredArgsConstructor public class UserService { - UserStorage userStorage; - - public UserService(UserStorage userStorage) { - this.userStorage = userStorage; - } + private final UserStorage userStorage; public User getUserById(Long id) { if (userStorage.getUserById(id) == null) { diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/film/FilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/film/FilmStorage.java index 4d22cd88..6e5b828a 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/film/FilmStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/film/FilmStorage.java @@ -12,5 +12,5 @@ public interface FilmStorage { Film createFilm(Film film); - Film ubdateFilm(Film film); + Film updateFilm(Film film); } diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/film/InMemoryFilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/film/InMemoryFilmStorage.java index e8568991..728311f2 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/film/InMemoryFilmStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/film/InMemoryFilmStorage.java @@ -3,7 +3,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import ru.yandex.practicum.filmorate.ecxeption.NotFoundException; -import ru.yandex.practicum.filmorate.ecxeption.OccurredException; import ru.yandex.practicum.filmorate.ecxeption.ValidationException; import ru.yandex.practicum.filmorate.model.Film; @@ -30,7 +29,6 @@ public Collection getAllFilms() { @Override public Film createFilm(Film film) { - validateFilm(film); if (film.getReleaseDate().isBefore(LocalDate.of(1895, 12, 28))) { throw new ValidationException("Дата релиза — не раньше 28 декабря 1895 года!"); } @@ -42,20 +40,16 @@ public Film createFilm(Film film) { } @Override - public Film ubdateFilm(Film film) { - validateFilm(film); + public Film updateFilm(Film film) { + // validateFilm(film); if (film.getId() == null) { throw new ValidationException("Id должен быть указан!"); } - validateFilm(film); if (films.containsKey(film.getId())) { if (film.getReleaseDate().isBefore(LocalDate.of(1895, 12, 28))) { throw new ValidationException("Дата релиза — не раньше 28 декабря 1895 года!"); } - film.setDescription(film.getDescription()); - film.setName(film.getName()); - film.setReleaseDate(film.getReleaseDate()); - film.setDuration(film.getDuration()); + films.put(film.getId(), film); return film; } else throw new NotFoundException("Такого фильма нет в списке!"); } @@ -68,16 +62,4 @@ private Long getNextId() { .orElse(0); return ++currentMaxId; } - - private void validateFilm(Film film) { - if (film.getName() == null || film.getName().isBlank()) { - throw new OccurredException("Название не может быть пустым!"); - } - if (film.getDescription().length() > 200) { - throw new OccurredException("Максимальная длина описания — 200 символов!"); - } - if (film.getDuration() <= 0) { - throw new OccurredException("Продолжительность фильма должна быть положительным числом!"); - } - } } diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/user/InMemoryUserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/user/InMemoryUserStorage.java index b45966ed..02d314bb 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/user/InMemoryUserStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/user/InMemoryUserStorage.java @@ -3,12 +3,9 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import ru.yandex.practicum.filmorate.ecxeption.NotFoundException; -import ru.yandex.practicum.filmorate.ecxeption.OccurredException; import ru.yandex.practicum.filmorate.ecxeption.ValidationException; import ru.yandex.practicum.filmorate.model.User; -import java.time.LocalDate; - import java.util.*; @Slf4j @@ -29,7 +26,6 @@ public User getUserById(Long id) { @Override public User createUser(User user) { - validateUser(user); user.setId(getNextId()); log.debug("Валидация пройдена."); if (user.getName() == null) { @@ -44,7 +40,6 @@ public User updateUser(User user) { if (user.getId() == null) { throw new ValidationException("Id должен быть указан!"); } - validateUser(user); if (users.containsKey(user.getId())) { user.setBirthday(user.getBirthday()); user.setLogin(user.getLogin()); @@ -67,16 +62,4 @@ private Long getNextId() { .orElse(0); return ++currentMaxId; } - - private void validateUser(User user) { - if (user.getEmail() == null || user.getEmail().isBlank() || !user.getEmail().contains(String.valueOf('@'))) { - throw new OccurredException("Электронная почта не может быть пустой и должна содержать символ @!"); - } - if (user.getLogin().isBlank() || user.getLogin().contains(String.valueOf(' '))) { - throw new OccurredException("Логин не может быть пустым и содержать пробелы!"); - } - if (user.getBirthday().isAfter(LocalDate.now())) { - throw new OccurredException("Дата рождения не может быть в будущем!"); - } - } }