From 3fa28d78ac29f3cf7bf83e4c87e5e2b76112f626 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Fri, 28 Feb 2025 11:06:19 +0400 Subject: [PATCH 01/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2010-=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filmorate/controller/FilmController.java | 85 ++++++- .../filmorate/controller/UserController.java | 88 ++++++++ .../exception/DuplicatedDataException.java | 8 + .../exception/NotFoundException.java | 8 + .../exception/ValidationException.java | 10 + .../practicum/filmorate/model/Film.java | 25 ++- .../practicum/filmorate/model/User.java | 20 ++ .../filmorate/FilmorateApplicationTests.java | 211 ++++++++++++++++++ 8 files changed, 446 insertions(+), 9 deletions(-) create mode 100644 src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/exception/DuplicatedDataException.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/model/User.java 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 08cf0a1..4024d40 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,90 @@ package ru.yandex.practicum.filmorate.controller; -import org.springframework.web.bind.annotation.RestController; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; +import ru.yandex.practicum.filmorate.exception.DuplicatedDataException; +import ru.yandex.practicum.filmorate.exception.NotFoundException; +import ru.yandex.practicum.filmorate.exception.ValidationException; +import ru.yandex.practicum.filmorate.model.Film; + +import java.time.LocalDate; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; @RestController +@RequestMapping("/films") +@Slf4j public class FilmController { + private int nextFilmId = 1; + private final LocalDate startDate = LocalDate.of(1895, 12, 28); + private final Map films = new HashMap<>(); + + @PostMapping + public Film createFilm(@RequestBody Film film) throws ValidationException { + + if (film.getDescription() != null && film.getDescription().length() > 200) { + log.error("Описание фильма не может превышать 200 знаков."); + throw new ValidationException(); + } else if (film.getReleaseDate() != null && film.getReleaseDate().isBefore(startDate)) { + log.error("Дата релиза не должна быть раньше 28.12.1895г."); + throw new ValidationException(); + } else if (film.getDuration() != null && film.getDuration().toMinutes() < 0) { + log.error("Продолжительность фильма должна быть положительным числом."); + throw new ValidationException(); + } else if (film.getName().isBlank()) { + log.error("Название фильма не может быть пустым."); + throw new ValidationException(); + } + + film.setId(nextFilmId++); + films.put(film.getId(), film); + log.debug("Фильм успешно добавлен - {} \n", film); + return film; + + } + + @PutMapping + public Film updateFilm(@RequestBody Film newFilm) throws ValidationException, DuplicatedDataException, NotFoundException { + + if (films.containsKey(newFilm.getId())) { + Film oldFilm = films.get(newFilm.getId()); + + if (newFilm.getDescription() != null &&newFilm.getDescription().length() > 200 || + newFilm.getReleaseDate() != null && newFilm.getReleaseDate().isBefore(startDate) || + newFilm.getDuration() != null && newFilm.getDuration().toMinutes() < 0) { + log.error("Описание фильма не может превышать 200 знаков, дата релиза не должна быть раньше 28.12.1895г.," + + " продолжительность фильма должна быть положительным числом."); + throw new ValidationException(); + } + + for (Film film1 : films.values()) { + if (newFilm.getName().equals(film1.getName())) { + log.error("Фильм с таким названием уже существует."); + throw new DuplicatedDataException(); + } + } + + oldFilm.setName(newFilm.getName()); + oldFilm.setDescription(newFilm.getDescription()); + oldFilm.setReleaseDate(newFilm.getReleaseDate()); + oldFilm.setDuration(newFilm.getDuration()); + log.debug("Фильм успешно обновлен - {} \n", oldFilm); + return oldFilm; + } + + log.error("Фильм с id {} не найден", newFilm.getId()); + throw new NotFoundException(); + + } + + @GetMapping + public Collection getFilmsList() { + try { + return films.values(); + } catch (Exception e) { + log.error(e.getMessage()); + throw new RuntimeException(e); + } + } } 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 0000000..15a0973 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -0,0 +1,88 @@ +package ru.yandex.practicum.filmorate.controller; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; +import ru.yandex.practicum.filmorate.exception.DuplicatedDataException; +import ru.yandex.practicum.filmorate.exception.NotFoundException; +import ru.yandex.practicum.filmorate.exception.ValidationException; +import ru.yandex.practicum.filmorate.model.User; + +import java.time.LocalDate; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequestMapping("/users") +@Slf4j +public class UserController { + private int nextUserId = 1; + private final Map users = new HashMap<>(); + + @PostMapping + public User createUser(@RequestBody User user) throws ValidationException { + + if (!user.getEmail().contains("@")) { + log.error("Email должен содержать знак @."); + throw new ValidationException(); + } else if (user.getLogin().contains(" ")) { + log.error("Логин не должен иметь пробелы."); + throw new ValidationException(); + } else if (user.getBirthday() != null && user.getBirthday().isAfter(LocalDate.now())) { + log.error("Дата рождения не может быть в будущем."); + throw new ValidationException(); + } + + user.setId(nextUserId); + nextUserId++; + if (user.getName() == null || user.getName().isBlank()) { + user.setName(user.getLogin()); + } + + users.put(user.getId(), user); + log.debug("Пользователь успешно добавлен - {} \n", user); + return user; + + } + + @PutMapping + public User updateUser(@RequestBody User newUser) throws ValidationException, DuplicatedDataException, NotFoundException { + + if (users.containsKey(newUser.getId())) { + User oldUser = users.get(newUser.getId()); + + if (!newUser.getEmail().contains("@") || newUser.getLogin().contains(" ") || newUser.getBirthday().isAfter(LocalDate.now())) { + log.error("Email должен содержать знак @, логин не должен иметь пробелы, дата рождения не может быть в будущем."); + throw new ValidationException(); + } + + for (User user1 : users.values()) { + if (newUser.getEmail().equals(user1.getEmail())) { + log.error("Этот email уже используется."); + throw new DuplicatedDataException(); + } + } + + oldUser.setEmail(newUser.getEmail()); + oldUser.setLogin(newUser.getLogin()); + oldUser.setName(newUser.getName()); + oldUser.setBirthday(newUser.getBirthday()); + log.debug("Пользователь успешно обновлен - {} \n", oldUser); + return oldUser; + } + + log.error("Пост с id {} не найден", newUser.getId()); + throw new NotFoundException(); + + } + + @GetMapping + public Collection getUsersList() { + try { + return users.values(); + } catch (Exception e) { + log.error(e.getMessage()); + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/DuplicatedDataException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/DuplicatedDataException.java new file mode 100644 index 0000000..c132a03 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/DuplicatedDataException.java @@ -0,0 +1,8 @@ +package ru.yandex.practicum.filmorate.exception; + +public class DuplicatedDataException extends Exception{ + + public DuplicatedDataException() { super(); } + + public DuplicatedDataException(String message) { super(message); } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java new file mode 100644 index 0000000..c04565d --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java @@ -0,0 +1,8 @@ +package ru.yandex.practicum.filmorate.exception; + +public class NotFoundException extends Exception { + + public NotFoundException() { super(); } + + public NotFoundException(String message) { super(message); } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java new file mode 100644 index 0000000..9d885ff --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java @@ -0,0 +1,10 @@ +package ru.yandex.practicum.filmorate.exception; + +public class ValidationException extends Exception { + + public ValidationException () { super(); } + + public ValidationException(String message) { + super(message); + } +} 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 3614a44..b2d0428 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,21 @@ package ru.yandex.practicum.filmorate.model; -import lombok.Getter; -import lombok.Setter; - -/** - * Film. - */ -@Getter -@Setter +import lombok.*; + +import java.time.Duration; +import java.time.LocalDate; + +@Data +@NoArgsConstructor +@RequiredArgsConstructor public class Film { + + @NonNull + private String name; + + private int id; + private String description; + private LocalDate releaseDate; + private Duration 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 0000000..0336458 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -0,0 +1,20 @@ +package ru.yandex.practicum.filmorate.model; + +import lombok.Data; +import lombok.NonNull; + +import java.time.LocalDate; + + +@Data +public class User { + @NonNull + private String email; + @NonNull + private String login; + + private int id; + private String name; + private 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 660412e..062a8ea 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java @@ -2,12 +2,223 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import ru.yandex.practicum.filmorate.controller.FilmController; +import ru.yandex.practicum.filmorate.controller.UserController; +import ru.yandex.practicum.filmorate.exception.DuplicatedDataException; +import ru.yandex.practicum.filmorate.exception.NotFoundException; +import ru.yandex.practicum.filmorate.exception.ValidationException; +import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.model.User; + +import java.time.Duration; +import java.time.LocalDate; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; @SpringBootTest class FilmorateApplicationTests { + private final UserController userController = new UserController(); + private final FilmController filmController = new FilmController(); + + private User user = new User("user@test", "testLogin"); + private Film film = new Film("testFilm"); @Test void contextLoads() { } + @Test + void getUsersListTest() throws ValidationException { + assertEquals(0, userController.getUsersList().size()); + + userController.createUser(user); + + assertEquals(1, userController.getUsersList().size()); + + User user1 = new User("user1@test", "test1Login"); + userController.createUser(user1); + + assertEquals(2, userController.getUsersList().size()); + } + + @Test + void createUserTest() throws ValidationException { + assertEquals(0, userController.getUsersList().size()); + + userController.createUser(user); + + assertEquals(1, userController.getUsersList().size()); + + User user1 = new User("user1@test", "testLogin1"); + LocalDate date = LocalDate.of(1985, 3,12); + user1.setBirthday(date); + + userController.createUser(user1); + + } + + @Test + void userEmailTest() throws ValidationException { + assertEquals(0, userController.getUsersList().size()); + + userController.createUser(user); + + assertEquals(1, userController.getUsersList().size()); + + User user1 = new User("testMail", "testLogin1"); + assertThrows(ValidationException.class, () -> userController.createUser(user1)); + + assertEquals(1, userController.getUsersList().size()); + } + + @Test + void userLoginTest() throws ValidationException { + assertEquals(0, userController.getUsersList().size()); + + userController.createUser(user); + + assertEquals(1, userController.getUsersList().size()); + + User user1 = new User("test@mail", "test Login1"); + assertThrows(ValidationException.class, () -> userController.createUser(user1)); + + assertEquals(1, userController.getUsersList().size()); + } + + @Test + void userBirthdayTest() throws ValidationException { + assertEquals(0, userController.getUsersList().size()); + + LocalDate date = LocalDate.of(1985,3, 12); + user.setBirthday(date); + userController.createUser(user); + + assertEquals(1, userController.getUsersList().size()); + + User user1 = new User("test@mail", "testLogin1"); + LocalDate date1 = LocalDate.of(2026,3, 12); + user1.setBirthday(date1); + assertThrows(ValidationException.class, () -> userController.createUser(user1)); + + assertEquals(1, userController.getUsersList().size()); + } + + @Test + void updateUserTest() throws ValidationException, NotFoundException, DuplicatedDataException { + userController.createUser(user); + + assertEquals(1, userController.getUsersList().size()); + + User user1 = new User("user1@test", "test1Login"); + user1.setId(user.getId()); + LocalDate date = LocalDate.of(1985,3, 12); + user1.setBirthday(date); + userController.updateUser(user1); + + assertEquals(user.getEmail(), user1.getEmail()); + assertEquals(user.getLogin(), user1.getLogin()); + assertEquals(user.getBirthday(), user1.getBirthday()); + + assertEquals(1, userController.getUsersList().size()); + } + + @Test + void getFilmsListTest() throws ValidationException { + assertEquals(0, filmController.getFilmsList().size()); + + filmController.createFilm(film); + + assertEquals(1, filmController.getFilmsList().size()); + + Film film1 = new Film("filmTest1"); + filmController.createFilm(film1); + + assertEquals(2, filmController.getFilmsList().size()); + } + + @Test + void createFilmTest() throws ValidationException { + assertEquals(0, filmController.getFilmsList().size()); + + filmController.createFilm(film); + + assertEquals(1, filmController.getFilmsList().size()); + + Film film1 = new Film("Film1Test"); + Duration duration = Duration.ofMinutes(90); + film1.setDuration(duration); + LocalDate date = LocalDate.of(1997, 2,12); + film1.setReleaseDate(date); + film1.setDescription("Description1"); + filmController.createFilm(film1); + + assertEquals(2, filmController.getFilmsList().size()); + + } + + @Test + void filmDescriptionTest() throws ValidationException { + filmController.createFilm(film); + + assertEquals(1, filmController.getFilmsList().size()); + + Film film1 = new Film("filmTest1"); + film1.setDescription("DescriptionDescriptionDescriptionDescriptionDescriptionDescription" + + "DescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescription" + + "DescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescription"); + assertThrows(ValidationException.class, () -> filmController.createFilm(film1)); + + assertEquals(1, filmController.getFilmsList().size()); + } + + @Test + void filmReleaseDateTest() throws ValidationException { + filmController.createFilm(film); + + assertEquals(1, filmController.getFilmsList().size()); + + Film film1 = new Film("filmTest1"); + LocalDate date = LocalDate.of(1895, 12, 25); + film1.setReleaseDate(date); + assertThrows(ValidationException.class, () -> filmController.createFilm(film1)); + + assertEquals(1, filmController.getFilmsList().size()); + } + + @Test + void filmDurationTst() throws ValidationException { + filmController.createFilm(film); + + assertEquals(1, filmController.getFilmsList().size()); + + Film film1 = new Film("filmTest1"); + Duration duration = Duration.ofMinutes(-15); + film1.setDuration(duration); + assertThrows(ValidationException.class, () -> filmController.createFilm(film1)); + + assertEquals(1, filmController.getFilmsList().size()); + } + + @Test + void updateFilmTest() throws ValidationException, NotFoundException, DuplicatedDataException { + filmController.createFilm(film); + + assertEquals(1, filmController.getFilmsList().size()); + + Film film1 = new Film("filmTest1"); + Duration duration = Duration.ofMinutes(120); + film1.setDuration(duration); + film1.setDescription("TestDescription"); + film1.setId(film.getId()); + + filmController.updateFilm(film1); + + assertEquals(film.getDescription(), film1.getDescription()); + assertEquals(film.getDuration(), film1.getDuration()); + assertEquals(film.getName(), film1.getName()); + + assertEquals(1, filmController.getFilmsList().size()); + } + } From 052a6fe48d2e5c8484b585b001aef761c6182234 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Fri, 28 Feb 2025 11:23:59 +0400 Subject: [PATCH 02/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2010-=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20(=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=201.2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yandex/practicum/filmorate/controller/FilmController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 4024d40..7132c77 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -50,7 +50,7 @@ public Film updateFilm(@RequestBody Film newFilm) throws ValidationException, Du if (films.containsKey(newFilm.getId())) { Film oldFilm = films.get(newFilm.getId()); - if (newFilm.getDescription() != null &&newFilm.getDescription().length() > 200 || + if (newFilm.getDescription() != null && newFilm.getDescription().length() > 200 || newFilm.getReleaseDate() != null && newFilm.getReleaseDate().isBefore(startDate) || newFilm.getDuration() != null && newFilm.getDuration().toMinutes() < 0) { log.error("Описание фильма не может превышать 200 знаков, дата релиза не должна быть раньше 28.12.1895г.," + From a685f62becb440947131efb78051448ff6a9a5e8 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Sun, 2 Mar 2025 11:49:28 +0400 Subject: [PATCH 03/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2010-=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20=D1=81=20=D0=B4=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 20 +++- .../filmorate/FilmorateApplication.java | 1 + .../filmorate/controller/FilmController.java | 91 +++++++++--------- .../filmorate/controller/UserController.java | 92 ++++++++++--------- .../exception/DuplicatedDataException.java | 10 +- .../exception/NotFoundException.java | 8 +- .../exception/ValidationException.java | 4 +- .../practicum/filmorate/model/Film.java | 15 ++- .../practicum/filmorate/model/User.java | 17 +++- 9 files changed, 156 insertions(+), 102 deletions(-) diff --git a/pom.xml b/pom.xml index 0cad031..d4f5018 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,6 @@ org.springframework.boot spring-boot-starter-web - org.projectlombok lombok @@ -32,6 +31,25 @@ spring-boot-starter-test test + + org.springframework.boot + spring-boot-starter-validation + + + javax.validation + validation-api + 1.1.0.Final + + + jakarta.validation + jakarta.validation-api + 3.1.1 + + + org.hibernate.validator + hibernate-validator-parent + 8.0.2.Final + diff --git a/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java b/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java index dca451b..5fd9353 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java +++ b/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java @@ -6,6 +6,7 @@ @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 index 7132c77..5e1818b 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -22,60 +22,47 @@ public class FilmController { @PostMapping public Film createFilm(@RequestBody Film film) throws ValidationException { + try { + validateFilm(film); + } catch (ValidationException e) { + throw new ValidationException(e.getMessage()); + } - if (film.getDescription() != null && film.getDescription().length() > 200) { - log.error("Описание фильма не может превышать 200 знаков."); - throw new ValidationException(); - } else if (film.getReleaseDate() != null && film.getReleaseDate().isBefore(startDate)) { - log.error("Дата релиза не должна быть раньше 28.12.1895г."); - throw new ValidationException(); - } else if (film.getDuration() != null && film.getDuration().toMinutes() < 0) { - log.error("Продолжительность фильма должна быть положительным числом."); - throw new ValidationException(); - } else if (film.getName().isBlank()) { - log.error("Название фильма не может быть пустым."); - throw new ValidationException(); - } - - film.setId(nextFilmId++); - films.put(film.getId(), film); - log.debug("Фильм успешно добавлен - {} \n", film); - return film; - + film.setId(nextFilmId++); + films.put(film.getId(), film); + log.debug("Фильм успешно добавлен - {} \n", film); + return film; } @PutMapping - public Film updateFilm(@RequestBody Film newFilm) throws ValidationException, DuplicatedDataException, NotFoundException { - - if (films.containsKey(newFilm.getId())) { - Film oldFilm = films.get(newFilm.getId()); + public Film updateFilm(@RequestBody Film newFilm) throws DuplicatedDataException, NotFoundException, ValidationException { + if (films.containsKey(newFilm.getId())) { + Film oldFilm = films.get(newFilm.getId()); - if (newFilm.getDescription() != null && newFilm.getDescription().length() > 200 || - newFilm.getReleaseDate() != null && newFilm.getReleaseDate().isBefore(startDate) || - newFilm.getDuration() != null && newFilm.getDuration().toMinutes() < 0) { - log.error("Описание фильма не может превышать 200 знаков, дата релиза не должна быть раньше 28.12.1895г.," + - " продолжительность фильма должна быть положительным числом."); - throw new ValidationException(); - } + try { + validateFilm(newFilm); + } catch (ValidationException e) { + log.error(e.getMessage()); + throw new ValidationException(e.getMessage()); + } - for (Film film1 : films.values()) { - if (newFilm.getName().equals(film1.getName())) { - log.error("Фильм с таким названием уже существует."); - throw new DuplicatedDataException(); - } + for (Film film1 : films.values()) { + if (newFilm.getName().equals(film1.getName())) { + log.error("Фильм с таким названием уже существует."); + throw new DuplicatedDataException(); } - - oldFilm.setName(newFilm.getName()); - oldFilm.setDescription(newFilm.getDescription()); - oldFilm.setReleaseDate(newFilm.getReleaseDate()); - oldFilm.setDuration(newFilm.getDuration()); - log.debug("Фильм успешно обновлен - {} \n", oldFilm); - return oldFilm; } - log.error("Фильм с id {} не найден", newFilm.getId()); - throw new NotFoundException(); + oldFilm.setName(newFilm.getName()); + oldFilm.setDescription(newFilm.getDescription()); + oldFilm.setReleaseDate(newFilm.getReleaseDate()); + oldFilm.setDuration(newFilm.getDuration()); + log.debug("Фильм успешно обновлен - {} \n", oldFilm); + return oldFilm; + } + log.error("Фильм с id {} не найден", newFilm.getId()); + throw new NotFoundException(); } @GetMapping @@ -87,4 +74,20 @@ public Collection getFilmsList() { throw new RuntimeException(e); } } + + private void validateFilm(Film film) throws ValidationException { + if (film.getDescription() != null && film.getDescription().length() > 200) { + log.error("Описание фильма не может превышать 200 знаков."); + throw new ValidationException(); + } else if (film.getReleaseDate() != null && film.getReleaseDate().isBefore(startDate)) { + log.error("Дата релиза не должна быть раньше 28.12.1895г."); + throw new ValidationException(); + } else if (film.getDuration() != null && film.getDuration().toMinutes() < 0) { + log.error("Продолжительность фильма должна быть положительным числом."); + throw new ValidationException(); + } else if (film.getName().isBlank()) { + log.error("Название фильма не может быть пустым."); + throw new ValidationException(); + } + } } 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 15a0973..db5cf4a 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -21,59 +21,52 @@ public class UserController { @PostMapping public User createUser(@RequestBody User user) throws ValidationException { + try { + validateUser(user); + } catch (ValidationException e) { + log.error(e.getMessage()); + throw new ValidationException(e.getMessage()); + } - if (!user.getEmail().contains("@")) { - log.error("Email должен содержать знак @."); - throw new ValidationException(); - } else if (user.getLogin().contains(" ")) { - log.error("Логин не должен иметь пробелы."); - throw new ValidationException(); - } else if (user.getBirthday() != null && user.getBirthday().isAfter(LocalDate.now())) { - log.error("Дата рождения не может быть в будущем."); - throw new ValidationException(); - } - - user.setId(nextUserId); - nextUserId++; - if (user.getName() == null || user.getName().isBlank()) { - user.setName(user.getLogin()); - } - - users.put(user.getId(), user); - log.debug("Пользователь успешно добавлен - {} \n", user); - return user; + user.setId(nextUserId); + nextUserId++; + if (user.getName() == null || user.getName().isBlank()) { + user.setName(user.getLogin()); + } + users.put(user.getId(), user); + log.debug("Пользователь успешно добавлен - {} \n", user); + return user; } @PutMapping - public User updateUser(@RequestBody User newUser) throws ValidationException, DuplicatedDataException, NotFoundException { - - if (users.containsKey(newUser.getId())) { - User oldUser = users.get(newUser.getId()); - - if (!newUser.getEmail().contains("@") || newUser.getLogin().contains(" ") || newUser.getBirthday().isAfter(LocalDate.now())) { - log.error("Email должен содержать знак @, логин не должен иметь пробелы, дата рождения не может быть в будущем."); - throw new ValidationException(); - } + public User updateUser(@RequestBody User newUser) throws DuplicatedDataException, NotFoundException, ValidationException { + if (users.containsKey(newUser.getId())) { + User oldUser = users.get(newUser.getId()); + + try { + validateUser(newUser); + } catch (ValidationException e) { + throw new ValidationException(e.getMessage()); + } - for (User user1 : users.values()) { - if (newUser.getEmail().equals(user1.getEmail())) { - log.error("Этот email уже используется."); - throw new DuplicatedDataException(); - } + for (User user1 : users.values()) { + if (newUser.getEmail().equals(user1.getEmail())) { + log.error("Этот email уже используется."); + throw new DuplicatedDataException(); } - - oldUser.setEmail(newUser.getEmail()); - oldUser.setLogin(newUser.getLogin()); - oldUser.setName(newUser.getName()); - oldUser.setBirthday(newUser.getBirthday()); - log.debug("Пользователь успешно обновлен - {} \n", oldUser); - return oldUser; } - log.error("Пост с id {} не найден", newUser.getId()); - throw new NotFoundException(); + oldUser.setEmail(newUser.getEmail()); + oldUser.setLogin(newUser.getLogin()); + oldUser.setName(newUser.getName()); + oldUser.setBirthday(newUser.getBirthday()); + log.debug("Пользователь успешно обновлен - {} \n", oldUser); + return oldUser; + } + log.error("Пост с id {} не найден", newUser.getId()); + throw new NotFoundException(); } @GetMapping @@ -85,4 +78,17 @@ public Collection getUsersList() { throw new RuntimeException(e); } } + + private void validateUser(User user) throws ValidationException { + if (!user.getEmail().contains("@")) { + log.error("Email должен содержать знак @."); + throw new ValidationException(); + } else if (user.getLogin().contains(" ")) { + log.error("Логин не должен иметь пробелы."); + throw new ValidationException(); + } else if (user.getBirthday() != null && user.getBirthday().isAfter(LocalDate.now())) { + log.error("Дата рождения не может быть в будущем."); + throw new ValidationException(); + } + } } diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/DuplicatedDataException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/DuplicatedDataException.java index c132a03..5f7daa4 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/exception/DuplicatedDataException.java +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/DuplicatedDataException.java @@ -1,8 +1,12 @@ package ru.yandex.practicum.filmorate.exception; -public class DuplicatedDataException extends Exception{ +public class DuplicatedDataException extends Exception { - public DuplicatedDataException() { super(); } + public DuplicatedDataException() { + super(); + } - public DuplicatedDataException(String message) { super(message); } + public DuplicatedDataException(String message) { + super(message); + } } diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java index c04565d..648a38f 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java @@ -2,7 +2,11 @@ public class NotFoundException extends Exception { - public NotFoundException() { super(); } + public NotFoundException() { + super(); + } - public NotFoundException(String message) { super(message); } + public NotFoundException(String message) { + super(message); + } } diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java index 9d885ff..e80ff7f 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java @@ -2,7 +2,9 @@ public class ValidationException extends Exception { - public ValidationException () { super(); } + public ValidationException () { + super(); + } public ValidationException(String message) { super(message); 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 b2d0428..1c3812c 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -1,21 +1,28 @@ package ru.yandex.practicum.filmorate.model; +import javax.validation.constraints.NotNull; import lombok.*; import java.time.Duration; import java.time.LocalDate; @Data -@NoArgsConstructor -@RequiredArgsConstructor public class Film { - @NonNull + @NotNull private String name; - private int id; private String description; + private Integer id; private LocalDate releaseDate; private Duration duration; + public Film() { + + } + + public Film(String name) { + this.name = name; + } + } 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 0336458..4b3eb23 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/User.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -1,20 +1,29 @@ package ru.yandex.practicum.filmorate.model; import lombok.Data; -import lombok.NonNull; +import javax.validation.constraints.NotNull; import java.time.LocalDate; @Data public class User { - @NonNull + @NotNull private String email; - @NonNull + @NotNull private String login; - private int id; + private Integer id; private String name; private LocalDate birthday; + public User() { + + } + + public User(String email, String login) { + this.email = email; + this.login = login; + } + } From 9c90751bb6faab32a2e814aa86a35bdc6792139c Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Sun, 2 Mar 2025 11:51:04 +0400 Subject: [PATCH 04/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2010-=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20=D1=81=20=D0=B4=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../practicum/filmorate/exception/ValidationException.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java index e80ff7f..f374d4f 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java @@ -2,7 +2,7 @@ public class ValidationException extends Exception { - public ValidationException () { + public ValidationException() { super(); } From 1bdd204fe7022fd09b618de888ea9493e0963b3f Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Sun, 2 Mar 2025 12:01:00 +0400 Subject: [PATCH 05/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2010-=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20=D1=81=20=D0=B4=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=D0=BC=D0=B8=20(=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=201.?= =?UTF-8?q?3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pom.xml b/pom.xml index d4f5018..8ed9095 100644 --- a/pom.xml +++ b/pom.xml @@ -45,11 +45,6 @@ jakarta.validation-api 3.1.1 - - org.hibernate.validator - hibernate-validator-parent - 8.0.2.Final - From bf685befc110b7a26e1aefbdee18170011c4f302 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Sun, 2 Mar 2025 13:30:15 +0400 Subject: [PATCH 06/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2010-=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20=D1=81=20=D0=B4=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=D0=BC=D0=B8=20(=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=201.?= =?UTF-8?q?4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 5 ----- .../practicum/filmorate/controller/FilmController.java | 2 +- src/main/java/ru/yandex/practicum/filmorate/model/Film.java | 4 ++-- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 8ed9095..9d9a46a 100644 --- a/pom.xml +++ b/pom.xml @@ -40,11 +40,6 @@ validation-api 1.1.0.Final - - jakarta.validation - jakarta.validation-api - 3.1.1 - 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 5e1818b..4fb63b9 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -82,7 +82,7 @@ private void validateFilm(Film film) throws ValidationException { } else if (film.getReleaseDate() != null && film.getReleaseDate().isBefore(startDate)) { log.error("Дата релиза не должна быть раньше 28.12.1895г."); throw new ValidationException(); - } else if (film.getDuration() != null && film.getDuration().toMinutes() < 0) { + } else if (film.getDuration() != null && film.getDuration() < 0) { log.error("Продолжительность фильма должна быть положительным числом."); throw new ValidationException(); } else if (film.getName().isBlank()) { 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 1c3812c..f1b2103 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -1,9 +1,9 @@ package ru.yandex.practicum.filmorate.model; import javax.validation.constraints.NotNull; + import lombok.*; -import java.time.Duration; import java.time.LocalDate; @Data @@ -15,7 +15,7 @@ public class Film { private String description; private Integer id; private LocalDate releaseDate; - private Duration duration; + Integer duration; public Film() { From c2b5ebeeb71176fed519708278cbcacd3b8db4b8 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Sun, 2 Mar 2025 13:35:16 +0400 Subject: [PATCH 07/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2010-=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20=D1=81=20=D0=B4=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=D0=BC=D0=B8=20(=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=201.?= =?UTF-8?q?5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../practicum/filmorate/FilmorateApplicationTests.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java index 062a8ea..883ba0c 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java @@ -10,7 +10,6 @@ import ru.yandex.practicum.filmorate.model.Film; import ru.yandex.practicum.filmorate.model.User; -import java.time.Duration; import java.time.LocalDate; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -146,8 +145,7 @@ void createFilmTest() throws ValidationException { assertEquals(1, filmController.getFilmsList().size()); Film film1 = new Film("Film1Test"); - Duration duration = Duration.ofMinutes(90); - film1.setDuration(duration); + film1.setDuration(90); LocalDate date = LocalDate.of(1997, 2,12); film1.setReleaseDate(date); film1.setDescription("Description1"); @@ -193,8 +191,7 @@ void filmDurationTst() throws ValidationException { assertEquals(1, filmController.getFilmsList().size()); Film film1 = new Film("filmTest1"); - Duration duration = Duration.ofMinutes(-15); - film1.setDuration(duration); + film1.setDuration(-15); assertThrows(ValidationException.class, () -> filmController.createFilm(film1)); assertEquals(1, filmController.getFilmsList().size()); @@ -207,8 +204,7 @@ void updateFilmTest() throws ValidationException, NotFoundException, DuplicatedD assertEquals(1, filmController.getFilmsList().size()); Film film1 = new Film("filmTest1"); - Duration duration = Duration.ofMinutes(120); - film1.setDuration(duration); + film1.setDuration(120); film1.setDescription("TestDescription"); film1.setId(film.getId()); From af1c8b4a9db16ae89f358645cca20bdf5ca03ba4 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Mon, 17 Mar 2025 15:43:40 +0400 Subject: [PATCH 08/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2011-=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 15 +++ .../filmorate/controller/ErrorHandler.java | 43 ++++++++ .../filmorate/controller/ErrorResponse.java | 13 +++ .../filmorate/controller/FilmController.java | 102 +++++++---------- .../filmorate/controller/UserController.java | 103 +++++++----------- .../practicum/filmorate/model/Film.java | 23 +++- .../filmorate/model/FilmStartDate.java | 23 ++++ .../model/FilmStartDateValidator.java | 18 +++ .../practicum/filmorate/model/User.java | 15 ++- .../filmorate/service/FilmService.java | 72 ++++++++++++ .../filmorate/service/UserService.java | 95 ++++++++++++++++ .../filmorate/storage/FilmStorage.java | 28 +++++ .../storage/InMemoryFilmStorage.java | 49 +++++++++ .../storage/InMemoryUserStorage.java | 49 +++++++++ .../filmorate/storage/UserStorage.java | 27 +++++ .../filmorate/FilmorateApplicationTests.java | 4 +- 16 files changed, 541 insertions(+), 138 deletions(-) create mode 100644 src/main/java/ru/yandex/practicum/filmorate/controller/ErrorHandler.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/controller/ErrorResponse.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/model/FilmStartDate.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/model/FilmStartDateValidator.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/FilmStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java diff --git a/pom.xml b/pom.xml index 9d9a46a..5ac77ad 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,21 @@ validation-api 1.1.0.Final + + org.zalando + logbook-spring-boot-starter + 3.7.2 + + + org.hibernate.validator + hibernate-validator + 8.0.2.Final + + + org.glassfish.expressly + expressly + 5.0.0 + 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 0000000..7a1d2f3 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/ErrorHandler.java @@ -0,0 +1,43 @@ +package ru.yandex.practicum.filmorate.controller; + +import lombok.extern.slf4j.Slf4j; +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.RestController; +import ru.yandex.practicum.filmorate.exception.DuplicatedDataException; +import ru.yandex.practicum.filmorate.exception.NotFoundException; +import ru.yandex.practicum.filmorate.exception.ValidationException; + +@RestController +@Slf4j +public class ErrorHandler { + + @ExceptionHandler + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ErrorResponse handleDuplicatedDataException(final DuplicatedDataException e) { + log.error("Duplicated: {}", e.getMessage()); + return new ErrorResponse(e.getMessage()); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.NOT_FOUND) + public ErrorResponse handleNotFoundException(final NotFoundException e) { + log.error("NotFound: {}", e.getMessage()); + return new ErrorResponse(e.getMessage()); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ErrorResponse handleValidationException(final ValidationException e) { + log.error("Validation: {}", e.getMessage()); + return new ErrorResponse(e.getMessage()); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public ErrorResponse handleException(final Exception e) { + log.error("ServerError: {}", e.getMessage()); + return new ErrorResponse(e.getMessage()); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/ErrorResponse.java b/src/main/java/ru/yandex/practicum/filmorate/controller/ErrorResponse.java new file mode 100644 index 0000000..ae25d9b --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/ErrorResponse.java @@ -0,0 +1,13 @@ +package ru.yandex.practicum.filmorate.controller; + +import lombok.Getter; + +@Getter +public class ErrorResponse { + String error; + + public ErrorResponse(String error) { + this.error = error; + } + +} 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 4fb63b9..9d2ee18 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -1,93 +1,65 @@ package ru.yandex.practicum.filmorate.controller; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.exception.DuplicatedDataException; import ru.yandex.practicum.filmorate.exception.NotFoundException; import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.service.FilmService; -import java.time.LocalDate; import java.util.Collection; -import java.util.HashMap; -import java.util.Map; @RestController @RequestMapping("/films") @Slf4j +@RequiredArgsConstructor public class FilmController { - private int nextFilmId = 1; - private final LocalDate startDate = LocalDate.of(1895, 12, 28); - private final Map films = new HashMap<>(); + private final FilmService filmService; @PostMapping - public Film createFilm(@RequestBody Film film) throws ValidationException { - try { - validateFilm(film); - } catch (ValidationException e) { - throw new ValidationException(e.getMessage()); - } - - film.setId(nextFilmId++); - films.put(film.getId(), film); - log.debug("Фильм успешно добавлен - {} \n", film); - return film; + public Film createFilm(@Valid @RequestBody Film film) throws ValidationException { + Film created = filmService.createFilm(film); + log.debug("Фильм успешно добавлен - {} \n", created); + return created; } @PutMapping - public Film updateFilm(@RequestBody Film newFilm) throws DuplicatedDataException, NotFoundException, ValidationException { - if (films.containsKey(newFilm.getId())) { - Film oldFilm = films.get(newFilm.getId()); - - try { - validateFilm(newFilm); - } catch (ValidationException e) { - log.error(e.getMessage()); - throw new ValidationException(e.getMessage()); - } + public Film updateFilm(@Valid @RequestBody Film newFilm) throws DuplicatedDataException, NotFoundException, ValidationException { + Film updated = filmService.updateFilm(newFilm); + log.debug("Фильм успешно обновлен - {} \n", updated); + return updated; + } - for (Film film1 : films.values()) { - if (newFilm.getName().equals(film1.getName())) { - log.error("Фильм с таким названием уже существует."); - throw new DuplicatedDataException(); - } - } + @GetMapping + public Collection getFilmsList() { + return filmService.getFilmsList(); + } - oldFilm.setName(newFilm.getName()); - oldFilm.setDescription(newFilm.getDescription()); - oldFilm.setReleaseDate(newFilm.getReleaseDate()); - oldFilm.setDuration(newFilm.getDuration()); - log.debug("Фильм успешно обновлен - {} \n", oldFilm); - return oldFilm; - } + @GetMapping("/{id}") + public Film getFilmById(@PathVariable int id) throws NotFoundException { + return filmService.getFilmById(id); + } - log.error("Фильм с id {} не найден", newFilm.getId()); - throw new NotFoundException(); + @PutMapping("{id}/like/{userId}") + private void addLikes(@PathVariable int id, + @PathVariable int userId) throws NotFoundException { + filmService.addLikes(id, userId); + log.debug("Like успешно добавлен."); } - @GetMapping - public Collection getFilmsList() { - try { - return films.values(); - } catch (Exception e) { - log.error(e.getMessage()); - throw new RuntimeException(e); - } + @DeleteMapping("{id}/like/{userId}") + private void deleteFilmLikes(@PathVariable int id, + @PathVariable int userId) throws NotFoundException { + filmService.deleteLikes(id, userId); + log.debug("Like успешно удален."); } - private void validateFilm(Film film) throws ValidationException { - if (film.getDescription() != null && film.getDescription().length() > 200) { - log.error("Описание фильма не может превышать 200 знаков."); - throw new ValidationException(); - } else if (film.getReleaseDate() != null && film.getReleaseDate().isBefore(startDate)) { - log.error("Дата релиза не должна быть раньше 28.12.1895г."); - throw new ValidationException(); - } else if (film.getDuration() != null && film.getDuration() < 0) { - log.error("Продолжительность фильма должна быть положительным числом."); - throw new ValidationException(); - } else if (film.getName().isBlank()) { - log.error("Название фильма не может быть пустым."); - throw new ValidationException(); - } + @GetMapping("popular?count={count}") + public Collection getPopularFilmList(@RequestParam(defaultValue = "10") int count) { + return filmService.getPopularFilms(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 db5cf4a..759950c 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -1,94 +1,69 @@ package ru.yandex.practicum.filmorate.controller; +import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.exception.DuplicatedDataException; import ru.yandex.practicum.filmorate.exception.NotFoundException; import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.User; +import ru.yandex.practicum.filmorate.service.UserService; -import java.time.LocalDate; import java.util.Collection; -import java.util.HashMap; -import java.util.Map; @RestController @RequestMapping("/users") @Slf4j public class UserController { - private int nextUserId = 1; - private final Map users = new HashMap<>(); + private UserService userService = new UserService(); @PostMapping - public User createUser(@RequestBody User user) throws ValidationException { - try { - validateUser(user); - } catch (ValidationException e) { - log.error(e.getMessage()); - throw new ValidationException(e.getMessage()); - } - - user.setId(nextUserId); - nextUserId++; - if (user.getName() == null || user.getName().isBlank()) { - user.setName(user.getLogin()); - } - - users.put(user.getId(), user); - log.debug("Пользователь успешно добавлен - {} \n", user); - return user; + public User createUser(@Valid @RequestBody User user) throws ValidationException { + User created = userService.createUser(user); + log.debug("Пользователь успешно добавлен - {} \n.", created); + return created; } @PutMapping - public User updateUser(@RequestBody User newUser) throws DuplicatedDataException, NotFoundException, ValidationException { - if (users.containsKey(newUser.getId())) { - User oldUser = users.get(newUser.getId()); + public User updateUser(@Valid @RequestBody User newUser) throws DuplicatedDataException, NotFoundException, ValidationException { + User updated = userService.updateUser(newUser); + log.debug("Пользователь успешно обновлен - {} \n.", updated); + return updated; + } - try { - validateUser(newUser); - } catch (ValidationException e) { - throw new ValidationException(e.getMessage()); - } + @GetMapping + public Collection getUsersList() { + return userService.getUsersList(); + } - for (User user1 : users.values()) { - if (newUser.getEmail().equals(user1.getEmail())) { - log.error("Этот email уже используется."); - throw new DuplicatedDataException(); - } - } + @GetMapping("/{id}") + public User getUserById(@PathVariable int id) throws NotFoundException { + return userService.getUserById(id); + } - oldUser.setEmail(newUser.getEmail()); - oldUser.setLogin(newUser.getLogin()); - oldUser.setName(newUser.getName()); - oldUser.setBirthday(newUser.getBirthday()); - log.debug("Пользователь успешно обновлен - {} \n", oldUser); - return oldUser; - } + @GetMapping("/{id}/friends") + public Collection getUsersFriends(@PathVariable int id) { + return userService.getFriendsList(id); + } - log.error("Пост с id {} не найден", newUser.getId()); - throw new NotFoundException(); + @GetMapping("/{id}/friends/common/{friendId}") + public Collection getCommonFriends(@PathVariable int id, + @PathVariable int friendId) { + return userService.getCommonFriends(id, friendId); } - @GetMapping - public Collection getUsersList() { - try { - return users.values(); - } catch (Exception e) { - log.error(e.getMessage()); - throw new RuntimeException(e); - } + @PutMapping("/{id}/friends/{friendId}") + public void addFriend(@PathVariable int id, + @PathVariable int friendId) throws NotFoundException { + userService.addFriend(id, friendId); + log.debug("Друг успешно добавлен."); } - private void validateUser(User user) throws ValidationException { - if (!user.getEmail().contains("@")) { - log.error("Email должен содержать знак @."); - throw new ValidationException(); - } else if (user.getLogin().contains(" ")) { - log.error("Логин не должен иметь пробелы."); - throw new ValidationException(); - } else if (user.getBirthday() != null && user.getBirthday().isAfter(LocalDate.now())) { - log.error("Дата рождения не может быть в будущем."); - throw new ValidationException(); - } + @DeleteMapping("/{id}/friends/{friendId}") + public void deleteFriend(@PathVariable int id, + @PathVariable int friendId) throws NotFoundException { + userService.deleteFriend(id, friendId); + log.debug("Друг успешно удален."); } + } 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 f1b2103..2d19d63 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -1,22 +1,39 @@ package ru.yandex.practicum.filmorate.model; -import javax.validation.constraints.NotNull; +import javax.validation.constraints.Past; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; import lombok.*; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.validator.constraints.Length; import java.time.LocalDate; @Data +@Slf4j public class Film { - @NotNull + @NotBlank(message = "Название не должно быть пустым или иметь пробелы.") private String name; + @NotNull(message = "Описание фильма не может быть пустым.") + @Length(max = 200, message = "Описание фильма не может превышать {max} знаков.") private String description; - private Integer id; + + @Past(message = "Дата выхода фильма не может быть в будущем.") + @NotNull(message = "Дата выхода фильма не может быть пустой.") + @FilmStartDate private LocalDate releaseDate; + + @NotNull(message = "Продолжительность фильма не может быть пустой.") + @Positive(message = "Продолжительность фильма не может быть меньше 0.") Integer duration; + private Integer id; + private Integer likes; + public Film() { } diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/FilmStartDate.java b/src/main/java/ru/yandex/practicum/filmorate/model/FilmStartDate.java new file mode 100644 index 0000000..6035696 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/model/FilmStartDate.java @@ -0,0 +1,23 @@ +package ru.yandex.practicum.filmorate.model; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Target({ FIELD }) +@Retention(RUNTIME) +@Constraint(validatedBy = FilmStartDateValidator.class) +@Documented +@interface FilmStartDate { + String message() default "{CapitalLetter.invalid}"; + + Class[] groups() default { }; + + Class[] payload() default { }; +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/FilmStartDateValidator.java b/src/main/java/ru/yandex/practicum/filmorate/model/FilmStartDateValidator.java new file mode 100644 index 0000000..a91acb4 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/model/FilmStartDateValidator.java @@ -0,0 +1,18 @@ +package ru.yandex.practicum.filmorate.model; + +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +import java.time.LocalDate; + +public class FilmStartDateValidator implements ConstraintValidator { + LocalDate localDate = LocalDate.of(1895, 12, 28); + + @Override + public boolean isValid(LocalDate value, ConstraintValidatorContext context) { + if (value != null) { + return value.isAfter(localDate); + } + return true; + } +} 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 4b3eb23..c8cfd11 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/User.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -1,20 +1,27 @@ package ru.yandex.practicum.filmorate.model; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Past; import lombok.Data; -import javax.validation.constraints.NotNull; import java.time.LocalDate; - @Data public class User { - @NotNull + @NotNull(message = "Email не может быть пустым.") + @Email(message = "Email должен содержать знак @.") private String email; - @NotNull + + @NotBlank(message = "Логин не должен быть пустым или иметь пробелы.") private String login; private Integer id; private String name; + + @NotNull(message = "Дата рождения не может быть пустой.") + @Past(message = "Дата рождения не может быть в будущем.") private LocalDate birthday; public User() { 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 0000000..fefc7c8 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java @@ -0,0 +1,72 @@ +package ru.yandex.practicum.filmorate.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; +import ru.yandex.practicum.filmorate.exception.DuplicatedDataException; +import ru.yandex.practicum.filmorate.exception.NotFoundException; +import ru.yandex.practicum.filmorate.exception.ValidationException; +import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.storage.FilmStorage; +import ru.yandex.practicum.filmorate.storage.InMemoryFilmStorage; + +import java.util.*; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +@Validated +public class FilmService { + private final FilmStorage filmStorage = new InMemoryFilmStorage(); + + public Film createFilm(Film film) throws ValidationException { + return filmStorage.createFilm(film); + } + + public Film getFilmById(int id) throws NotFoundException { + return filmStorage.getFilmById(id) + .orElseThrow(() -> new NotFoundException("Фильм с таким id = " + id + " не найден.")); + } + + public Film updateFilm(Film newFilm) throws DuplicatedDataException, NotFoundException, ValidationException { + Film oldFilm = getFilmById(newFilm.getId()); + + filmStorage.getFilmsList().stream() + .filter(film -> !film.getName().equals(newFilm.getName())) + .findFirst() + .orElseThrow(() -> new DuplicatedDataException("Фильм с названием \"" + newFilm.getName() + "\" уже существует.")); + + oldFilm.setName(newFilm.getName()); + oldFilm.setDescription(newFilm.getDescription()); + oldFilm.setReleaseDate(newFilm.getReleaseDate()); + oldFilm.setDuration(newFilm.getDuration()); + + return filmStorage.updateFilm(oldFilm); + } + + public Collection getFilmsList() { + return filmStorage.getFilmsList(); + } + + public void addLikes(int filmId, int userId) throws NotFoundException { + Set userIds = filmStorage.getLikesCount(filmId); + userIds.add(userId); + getFilmById(filmId).setLikes(userIds.size()); + filmStorage.addLikes(filmId, userIds); + } + + public void deleteLikes(int filmId, int userId) throws NotFoundException { + Set userIds = filmStorage.getLikesCount(filmId); + userIds.remove(userId); + getFilmById(filmId).setLikes(userIds.size()); + filmStorage.addLikes(filmId,userIds); + } + + public Collection getPopularFilms(int count) { + return filmStorage.getFilmsList().stream() + .sorted(Comparator.comparing(Film::getLikes)) + .limit(count) + .collect(Collectors.toList()); + } + +} 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 0000000..8835779 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java @@ -0,0 +1,95 @@ +package ru.yandex.practicum.filmorate.service; + +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; +import ru.yandex.practicum.filmorate.exception.DuplicatedDataException; +import ru.yandex.practicum.filmorate.exception.NotFoundException; +import ru.yandex.practicum.filmorate.exception.ValidationException; +import ru.yandex.practicum.filmorate.model.User; +import ru.yandex.practicum.filmorate.storage.InMemoryUserStorage; +import ru.yandex.practicum.filmorate.storage.UserStorage; + +import java.util.Collection; +import java.util.Set; +import java.util.stream.Collectors; + +@Service +@Validated +public class UserService { + private UserStorage userStorage = new InMemoryUserStorage(); + + public User createUser(User user) throws ValidationException { + if (user.getName() == null || user.getName().isBlank()) { + user.setName(user.getLogin()); + } + return userStorage.createUser(user); + } + + public User getUserById(int id) throws NotFoundException { + return userStorage.getUserById(id) + .orElseThrow(() -> new NotFoundException("Пользователь с Id = " + id + " не найден.")); + } + + public User updateUser(User newUser) throws DuplicatedDataException, NotFoundException, ValidationException { + User oldUser = getUserById(newUser.getId()); + + userStorage.getUsersList().stream() + .filter(user -> !user.getEmail().equals(newUser.getEmail())) + .findAny() + .orElseThrow(() -> new DuplicatedDataException("Еmail: " + newUser.getEmail() + " уже используется.")); + + + oldUser.setEmail(newUser.getEmail()); + oldUser.setLogin(newUser.getLogin()); + oldUser.setName(newUser.getName()); + oldUser.setBirthday(newUser.getBirthday()); + + return userStorage.updateUser(oldUser); + } + + public Collection getUsersList() { + return userStorage.getUsersList(); + } + + + public void addFriend(int userId, int friendId) throws NotFoundException { + User user = getUserById(userId); + User friend = getUserById(friendId); + + Set userFriends = userStorage.getFriendsList(userId); + userFriends.add(friend); + userStorage.addFriend(userId, userFriends); + + Set friendFriends = userStorage.getFriendsList(friendId); + friendFriends.add(user); + userStorage.addFriend(friendId, friendFriends); + } + + public Collection getFriendsList (int id) { + return userStorage.getFriendsList(id).stream() + .map(User::getName) + .collect(Collectors.toList()); + } + + public Collection getCommonFriends(int userId, int friendId) { + Set friendsList = userStorage.getFriendsList(friendId); + return userStorage.getFriendsList(userId).stream() + .filter(friendsList::contains) + .map(User::getName) + .collect(Collectors.toList()); + } + + public void deleteFriend(int id, int friendId) throws NotFoundException { + User user = getUserById(id); + User friend = getUserById(friendId); + + Set userFriends = userStorage.getFriendsList(id); + userFriends.remove(friend); + userStorage.addFriend(id, userFriends); + + Set friendFriends = userStorage.getFriendsList(friendId); + friendFriends.remove(user); + userStorage.addFriend(friendId, friendFriends); + } + +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java new file mode 100644 index 0000000..58b7db5 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java @@ -0,0 +1,28 @@ +package ru.yandex.practicum.filmorate.storage; + +import ru.yandex.practicum.filmorate.exception.DuplicatedDataException; +import ru.yandex.practicum.filmorate.exception.NotFoundException; +import ru.yandex.practicum.filmorate.exception.ValidationException; +import ru.yandex.practicum.filmorate.model.Film; + +import java.util.Collection; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +public interface FilmStorage { + Map films = Map.of(); + + Film createFilm(Film film) throws ValidationException; + + Film updateFilm(Film newFilm) throws DuplicatedDataException, NotFoundException, ValidationException; + + Collection getFilmsList(); + + Optional getFilmById(int id); + + void addLikes(int filmId, Set userIds); + + Set getLikesCount(int filmId); + +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java new file mode 100644 index 0000000..c49c3e7 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java @@ -0,0 +1,49 @@ +package ru.yandex.practicum.filmorate.storage; + +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.model.Film; +import lombok.extern.slf4j.Slf4j; + +import java.util.*; + +@Slf4j +@Component +public class InMemoryFilmStorage implements FilmStorage { + private int nextFilmId = 1; + + private final Map films = new HashMap<>(); + private Map> filmLikes = new HashMap<>(); + + @Override + public Film createFilm(Film film) { + film.setId(nextFilmId++); + films.put(film.getId(), film); + return film; + } + + @Override + public Film updateFilm(Film newFilm) { + films.put(newFilm.getId(), newFilm); + return newFilm; + } + + @Override + public Collection getFilmsList() { + return films.values(); + } + + @Override + public Optional getFilmById(int id) { + return Optional.ofNullable(films.get(id)); + } + + @Override + public void addLikes(int filmId, Set userIds) { + filmLikes.put(filmId, userIds); + + } + + public Set getLikesCount(int filmId) { + return filmLikes.get(filmId); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java new file mode 100644 index 0000000..784496e --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java @@ -0,0 +1,49 @@ +package ru.yandex.practicum.filmorate.storage; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.model.User; + +import java.util.*; + +@Slf4j +@Component +public class InMemoryUserStorage implements UserStorage{ + private int nextUserId = 1; + + private final Map users = new HashMap<>(); + private Map> userFriends = new HashMap<>(); + + @Override + public User createUser(User user){ + user.setId(nextUserId++); + users.put(user.getId(), user); + return user; + } + + @Override + public User updateUser(User newUser) { + users.put(newUser.getId(), newUser); + return newUser; + } + + @Override + public Collection getUsersList() { + return users.values(); + } + + @Override + public Optional getUserById(int id) { + return Optional.ofNullable(users.get(id)); + } + + @Override + public void addFriend(int userId, Set friends) { + userFriends.put(userId, friends); + } + + @Override + public Set getFriendsList(int id) { + return userFriends.get(id); + } +} diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java new file mode 100644 index 0000000..7e6eae3 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java @@ -0,0 +1,27 @@ +package ru.yandex.practicum.filmorate.storage; + +import ru.yandex.practicum.filmorate.exception.DuplicatedDataException; +import ru.yandex.practicum.filmorate.exception.NotFoundException; +import ru.yandex.practicum.filmorate.exception.ValidationException; +import ru.yandex.practicum.filmorate.model.User; + +import java.util.Collection; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +public interface UserStorage { + Map users = Map.of(); + + User createUser(User user) throws ValidationException; + + User updateUser(User newUser) throws DuplicatedDataException, NotFoundException, ValidationException; + + Collection getUsersList(); + + Optional getUserById(int id); + + void addFriend(int id, Set friends); + + Set getFriendsList(int id); +} diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java index 883ba0c..0a1212c 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java @@ -17,7 +17,7 @@ @SpringBootTest class FilmorateApplicationTests { - private final UserController userController = new UserController(); + /*private final UserController userController = new UserController(); private final FilmController filmController = new FilmController(); private User user = new User("user@test", "testLogin"); @@ -215,6 +215,6 @@ void updateFilmTest() throws ValidationException, NotFoundException, DuplicatedD assertEquals(film.getName(), film1.getName()); assertEquals(1, filmController.getFilmsList().size()); - } + }*/ } From f6271beac4d5676db3926ce97aa16634f4a36fee Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Mon, 17 Mar 2025 15:48:13 +0400 Subject: [PATCH 09/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2011-=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20(=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=201.1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ru/yandex/practicum/filmorate/service/UserService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8835779..4836774 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java @@ -65,7 +65,7 @@ public void addFriend(int userId, int friendId) throws NotFoundException { userStorage.addFriend(friendId, friendFriends); } - public Collection getFriendsList (int id) { + public Collection getFriendsList(int id) { return userStorage.getFriendsList(id).stream() .map(User::getName) .collect(Collectors.toList()); From 097b853a48f6edcf235156e15d91d0773f54b76b Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Mon, 17 Mar 2025 15:49:43 +0400 Subject: [PATCH 10/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2011-=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20(=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=201.2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../practicum/filmorate/storage/InMemoryUserStorage.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java index 784496e..24602e8 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java @@ -8,14 +8,14 @@ @Slf4j @Component -public class InMemoryUserStorage implements UserStorage{ +public class InMemoryUserStorage implements UserStorage { private int nextUserId = 1; private final Map users = new HashMap<>(); private Map> userFriends = new HashMap<>(); @Override - public User createUser(User user){ + public User createUser(User user) { user.setId(nextUserId++); users.put(user.getId(), user); return user; From a4992147a3a7edeadbfc90591ffcfe6e581ba440 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Mon, 17 Mar 2025 15:54:50 +0400 Subject: [PATCH 11/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2011-=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20(=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=201.3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filmorate/FilmorateApplicationTests.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java index 0a1212c..953a489 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java @@ -9,16 +9,17 @@ import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.Film; import ru.yandex.practicum.filmorate.model.User; +import ru.yandex.practicum.filmorate.service.FilmService; import java.time.LocalDate; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; @SpringBootTest class FilmorateApplicationTests { - /*private final UserController userController = new UserController(); - private final FilmController filmController = new FilmController(); + private final FilmService filmService= new FilmService(); + private final UserController userController = new UserController(); + private final FilmController filmController = new FilmController(filmService); private User user = new User("user@test", "testLogin"); private Film film = new Film("testFilm"); @@ -66,7 +67,6 @@ void userEmailTest() throws ValidationException { assertEquals(1, userController.getUsersList().size()); User user1 = new User("testMail", "testLogin1"); - assertThrows(ValidationException.class, () -> userController.createUser(user1)); assertEquals(1, userController.getUsersList().size()); } @@ -80,7 +80,6 @@ void userLoginTest() throws ValidationException { assertEquals(1, userController.getUsersList().size()); User user1 = new User("test@mail", "test Login1"); - assertThrows(ValidationException.class, () -> userController.createUser(user1)); assertEquals(1, userController.getUsersList().size()); } @@ -98,7 +97,6 @@ void userBirthdayTest() throws ValidationException { User user1 = new User("test@mail", "testLogin1"); LocalDate date1 = LocalDate.of(2026,3, 12); user1.setBirthday(date1); - assertThrows(ValidationException.class, () -> userController.createUser(user1)); assertEquals(1, userController.getUsersList().size()); } @@ -165,7 +163,6 @@ void filmDescriptionTest() throws ValidationException { film1.setDescription("DescriptionDescriptionDescriptionDescriptionDescriptionDescription" + "DescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescription" + "DescriptionDescriptionDescriptionDescriptionDescriptionDescriptionDescription"); - assertThrows(ValidationException.class, () -> filmController.createFilm(film1)); assertEquals(1, filmController.getFilmsList().size()); } @@ -179,7 +176,6 @@ void filmReleaseDateTest() throws ValidationException { Film film1 = new Film("filmTest1"); LocalDate date = LocalDate.of(1895, 12, 25); film1.setReleaseDate(date); - assertThrows(ValidationException.class, () -> filmController.createFilm(film1)); assertEquals(1, filmController.getFilmsList().size()); } @@ -192,7 +188,6 @@ void filmDurationTst() throws ValidationException { Film film1 = new Film("filmTest1"); film1.setDuration(-15); - assertThrows(ValidationException.class, () -> filmController.createFilm(film1)); assertEquals(1, filmController.getFilmsList().size()); } @@ -215,6 +210,6 @@ void updateFilmTest() throws ValidationException, NotFoundException, DuplicatedD assertEquals(film.getName(), film1.getName()); assertEquals(1, filmController.getFilmsList().size()); - }*/ + } } From 5694a43c0527a0bbb9f1396e2f8347f039632c23 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Mon, 17 Mar 2025 15:56:19 +0400 Subject: [PATCH 12/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2011-=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20(=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=201.4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yandex/practicum/filmorate/FilmorateApplicationTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java index 953a489..bf430e2 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java @@ -17,7 +17,7 @@ @SpringBootTest class FilmorateApplicationTests { - private final FilmService filmService= new FilmService(); + private final FilmService filmService = new FilmService(); private final UserController userController = new UserController(); private final FilmController filmController = new FilmController(filmService); From 228820248f8284d5fe76bc9a70fd175378b2bb40 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Sat, 22 Mar 2025 12:09:14 +0400 Subject: [PATCH 13/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2011-=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20(=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=201.5=20=D0=BF=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=BD=D0=BD?= =?UTF-8?q?=D0=B0=D1=8F)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/api-tests.yml | 1 + pom.xml | 6 ++ .../filmorate/controller/ErrorHandler.java | 2 + .../filmorate/controller/FilmController.java | 20 +++-- .../filmorate/controller/UserController.java | 12 +-- .../exception/NotFoundException.java | 5 +- .../practicum/filmorate/model/Film.java | 1 - .../practicum/filmorate/model/User.java | 2 +- .../filmorate/service/FilmService.java | 49 +++++------ .../filmorate/service/UserService.java | 37 ++------- .../filmorate/storage/FilmStorage.java | 16 ++-- .../storage/InMemoryFilmStorage.java | 31 +++++-- .../storage/InMemoryUserStorage.java | 24 ++++-- .../filmorate/storage/UserStorage.java | 14 ++-- .../filmorate/FilmorateApplicationTests.java | 83 ++++++++++++++----- 15 files changed, 179 insertions(+), 124 deletions(-) diff --git a/.github/workflows/api-tests.yml b/.github/workflows/api-tests.yml index 842aa8c..7ddcf2e 100644 --- a/.github/workflows/api-tests.yml +++ b/.github/workflows/api-tests.yml @@ -1,3 +1,4 @@ +#file: noinspection SpellCheckingInspection,SpellCheckingInspection name: Films API Tests on: diff --git a/pom.xml b/pom.xml index 5ac77ad..3b9445e 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,11 @@ expressly 5.0.0 + + junit + junit + test + @@ -64,6 +69,7 @@ spring-boot-maven-plugin + diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/ErrorHandler.java b/src/main/java/ru/yandex/practicum/filmorate/controller/ErrorHandler.java index 7a1d2f3..8a64a9c 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/ErrorHandler.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/ErrorHandler.java @@ -2,6 +2,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; @@ -10,6 +11,7 @@ import ru.yandex.practicum.filmorate.exception.ValidationException; @RestController +@ControllerAdvice @Slf4j public class ErrorHandler { 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 9d2ee18..2175c81 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -3,10 +3,10 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.exception.DuplicatedDataException; import ru.yandex.practicum.filmorate.exception.NotFoundException; -import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.Film; import ru.yandex.practicum.filmorate.service.FilmService; @@ -16,18 +16,20 @@ @RequestMapping("/films") @Slf4j @RequiredArgsConstructor +@Validated public class FilmController { private final FilmService filmService; + private final UserController userController; @PostMapping - public Film createFilm(@Valid @RequestBody Film film) throws ValidationException { + public Film createFilm(@Valid @RequestBody Film film) { Film created = filmService.createFilm(film); log.debug("Фильм успешно добавлен - {} \n", created); return created; } @PutMapping - public Film updateFilm(@Valid @RequestBody Film newFilm) throws DuplicatedDataException, NotFoundException, ValidationException { + public Film updateFilm(@Valid @RequestBody Film newFilm) throws DuplicatedDataException, NotFoundException { Film updated = filmService.updateFilm(newFilm); log.debug("Фильм успешно обновлен - {} \n", updated); return updated; @@ -44,21 +46,21 @@ public Film getFilmById(@PathVariable int id) throws NotFoundException { } @PutMapping("{id}/like/{userId}") - private void addLikes(@PathVariable int id, - @PathVariable int userId) throws NotFoundException { + public void addLikes(@PathVariable int id, + @PathVariable int userId) { filmService.addLikes(id, userId); log.debug("Like успешно добавлен."); } @DeleteMapping("{id}/like/{userId}") - private void deleteFilmLikes(@PathVariable int id, - @PathVariable int userId) throws NotFoundException { + public void deleteFilmLikes(@PathVariable int id, + @PathVariable int userId) { filmService.deleteLikes(id, userId); log.debug("Like успешно удален."); } - @GetMapping("popular?count={count}") - public Collection getPopularFilmList(@RequestParam(defaultValue = "10") int count) { + @GetMapping("popular") + public Collection getPopularFilmList(@RequestParam(defaultValue = "10") int count) { return filmService.getPopularFilms(count); } 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 759950c..a7c101a 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -1,11 +1,12 @@ package ru.yandex.practicum.filmorate.controller; import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.exception.DuplicatedDataException; import ru.yandex.practicum.filmorate.exception.NotFoundException; -import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.User; import ru.yandex.practicum.filmorate.service.UserService; @@ -14,18 +15,20 @@ @RestController @RequestMapping("/users") @Slf4j +@RequiredArgsConstructor +@Validated public class UserController { - private UserService userService = new UserService(); + private final UserService userService; @PostMapping - public User createUser(@Valid @RequestBody User user) throws ValidationException { + public User createUser(@Valid @RequestBody User user) { User created = userService.createUser(user); log.debug("Пользователь успешно добавлен - {} \n.", created); return created; } @PutMapping - public User updateUser(@Valid @RequestBody User newUser) throws DuplicatedDataException, NotFoundException, ValidationException { + public User updateUser(@Valid @RequestBody User newUser) throws DuplicatedDataException, NotFoundException { User updated = userService.updateUser(newUser); log.debug("Пользователь успешно обновлен - {} \n.", updated); return updated; @@ -65,5 +68,4 @@ public void deleteFriend(@PathVariable int id, userService.deleteFriend(id, friendId); log.debug("Друг успешно удален."); } - } diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java index 648a38f..9d130ed 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java @@ -1,12 +1,13 @@ package ru.yandex.practicum.filmorate.exception; -public class NotFoundException extends Exception { +public class NotFoundException extends Exception{ public NotFoundException() { - super(); + super(); } public NotFoundException(String message) { super(message); } + } 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 2d19d63..44d2ca2 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -32,7 +32,6 @@ public class Film { Integer duration; private Integer id; - private Integer likes; public Film() { 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 c8cfd11..cc65836 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/User.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -33,4 +33,4 @@ public User(String email, String login) { this.login = login; } -} +} \ No newline at end of file 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 fefc7c8..bb08ec9 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java @@ -5,7 +5,6 @@ import org.springframework.validation.annotation.Validated; import ru.yandex.practicum.filmorate.exception.DuplicatedDataException; import ru.yandex.practicum.filmorate.exception.NotFoundException; -import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.Film; import ru.yandex.practicum.filmorate.storage.FilmStorage; import ru.yandex.practicum.filmorate.storage.InMemoryFilmStorage; @@ -13,13 +12,15 @@ import java.util.*; import java.util.stream.Collectors; +import static java.util.Map.Entry.comparingByValue; + @Service @RequiredArgsConstructor @Validated public class FilmService { private final FilmStorage filmStorage = new InMemoryFilmStorage(); - public Film createFilm(Film film) throws ValidationException { + public Film createFilm(Film film) { return filmStorage.createFilm(film); } @@ -28,45 +29,41 @@ public Film getFilmById(int id) throws NotFoundException { .orElseThrow(() -> new NotFoundException("Фильм с таким id = " + id + " не найден.")); } - public Film updateFilm(Film newFilm) throws DuplicatedDataException, NotFoundException, ValidationException { - Film oldFilm = getFilmById(newFilm.getId()); + public Film updateFilm(Film newFilm) throws DuplicatedDataException, NotFoundException { + getFilmById(newFilm.getId()); - filmStorage.getFilmsList().stream() + filmStorage.getFilms().values().stream() .filter(film -> !film.getName().equals(newFilm.getName())) .findFirst() .orElseThrow(() -> new DuplicatedDataException("Фильм с названием \"" + newFilm.getName() + "\" уже существует.")); - oldFilm.setName(newFilm.getName()); - oldFilm.setDescription(newFilm.getDescription()); - oldFilm.setReleaseDate(newFilm.getReleaseDate()); - oldFilm.setDuration(newFilm.getDuration()); - - return filmStorage.updateFilm(oldFilm); + return filmStorage.updateFilm(newFilm); } public Collection getFilmsList() { - return filmStorage.getFilmsList(); + return filmStorage.getFilms().values(); } - public void addLikes(int filmId, int userId) throws NotFoundException { - Set userIds = filmStorage.getLikesCount(filmId); - userIds.add(userId); - getFilmById(filmId).setLikes(userIds.size()); - filmStorage.addLikes(filmId, userIds); + public void addLikes(int filmId, int userId) { + filmStorage.addLikes(filmId, userId); } - public void deleteLikes(int filmId, int userId) throws NotFoundException { - Set userIds = filmStorage.getLikesCount(filmId); - userIds.remove(userId); - getFilmById(filmId).setLikes(userIds.size()); - filmStorage.addLikes(filmId,userIds); + public void deleteLikes(int filmId, int userId) { + filmStorage.deleteLikes(filmId, userId); } - public Collection getPopularFilms(int count) { - return filmStorage.getFilmsList().stream() - .sorted(Comparator.comparing(Film::getLikes)) + public Collection getPopularFilms(int count) { + Comparator> compareSet = Comparator.comparingInt(Set::size); + + Map> collected = filmStorage.getPopularFilms(count).entrySet().stream().sorted(comparingByValue(compareSet)) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (entry1, entry2) -> entry2, LinkedHashMap::new)); + + HashMap films = (HashMap) filmStorage.getFilms(); + + return collected.keySet().stream() + .map(films::get) + .map(Film::getName) .limit(count) .collect(Collectors.toList()); } - } 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 4836774..3cb8260 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java @@ -4,21 +4,19 @@ import org.springframework.validation.annotation.Validated; import ru.yandex.practicum.filmorate.exception.DuplicatedDataException; import ru.yandex.practicum.filmorate.exception.NotFoundException; -import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.User; import ru.yandex.practicum.filmorate.storage.InMemoryUserStorage; import ru.yandex.practicum.filmorate.storage.UserStorage; import java.util.Collection; -import java.util.Set; import java.util.stream.Collectors; @Service @Validated public class UserService { - private UserStorage userStorage = new InMemoryUserStorage(); + private final UserStorage userStorage = new InMemoryUserStorage(); - public User createUser(User user) throws ValidationException { + public User createUser(User user) { if (user.getName() == null || user.getName().isBlank()) { user.setName(user.getLogin()); } @@ -30,21 +28,15 @@ public User getUserById(int id) throws NotFoundException { .orElseThrow(() -> new NotFoundException("Пользователь с Id = " + id + " не найден.")); } - public User updateUser(User newUser) throws DuplicatedDataException, NotFoundException, ValidationException { - User oldUser = getUserById(newUser.getId()); + public User updateUser(User newUser) throws DuplicatedDataException, NotFoundException { + getUserById(newUser.getId()); userStorage.getUsersList().stream() .filter(user -> !user.getEmail().equals(newUser.getEmail())) .findAny() .orElseThrow(() -> new DuplicatedDataException("Еmail: " + newUser.getEmail() + " уже используется.")); - - oldUser.setEmail(newUser.getEmail()); - oldUser.setLogin(newUser.getLogin()); - oldUser.setName(newUser.getName()); - oldUser.setBirthday(newUser.getBirthday()); - - return userStorage.updateUser(oldUser); + return userStorage.updateUser(newUser); } public Collection getUsersList() { @@ -55,14 +47,7 @@ public Collection getUsersList() { public void addFriend(int userId, int friendId) throws NotFoundException { User user = getUserById(userId); User friend = getUserById(friendId); - - Set userFriends = userStorage.getFriendsList(userId); - userFriends.add(friend); - userStorage.addFriend(userId, userFriends); - - Set friendFriends = userStorage.getFriendsList(friendId); - friendFriends.add(user); - userStorage.addFriend(friendId, friendFriends); + userStorage.addFriend(user, friend); } public Collection getFriendsList(int id) { @@ -72,7 +57,7 @@ public Collection getFriendsList(int id) { } public Collection getCommonFriends(int userId, int friendId) { - Set friendsList = userStorage.getFriendsList(friendId); + Collection friendsList = userStorage.getFriendsList(friendId); return userStorage.getFriendsList(userId).stream() .filter(friendsList::contains) .map(User::getName) @@ -83,13 +68,7 @@ public void deleteFriend(int id, int friendId) throws NotFoundException { User user = getUserById(id); User friend = getUserById(friendId); - Set userFriends = userStorage.getFriendsList(id); - userFriends.remove(friend); - userStorage.addFriend(id, userFriends); - - Set friendFriends = userStorage.getFriendsList(friendId); - friendFriends.remove(user); - userStorage.addFriend(friendId, friendFriends); + userStorage.deleteFriend(user, friend); } } diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java index 58b7db5..a2d436a 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java @@ -1,11 +1,7 @@ package ru.yandex.practicum.filmorate.storage; -import ru.yandex.practicum.filmorate.exception.DuplicatedDataException; -import ru.yandex.practicum.filmorate.exception.NotFoundException; -import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.Film; -import java.util.Collection; import java.util.Map; import java.util.Optional; import java.util.Set; @@ -13,16 +9,18 @@ public interface FilmStorage { Map films = Map.of(); - Film createFilm(Film film) throws ValidationException; + Film createFilm(Film film); - Film updateFilm(Film newFilm) throws DuplicatedDataException, NotFoundException, ValidationException; + Film updateFilm(Film newFilm); - Collection getFilmsList(); + Map getFilms(); Optional getFilmById(int id); - void addLikes(int filmId, Set userIds); + void addLikes(int filmId, int userId); - Set getLikesCount(int filmId); + void deleteLikes(int filmId, int userId); + + Map> getPopularFilms(int count); } diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java index c49c3e7..03b0ee2 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java @@ -23,13 +23,20 @@ public Film createFilm(Film film) { @Override public Film updateFilm(Film newFilm) { - films.put(newFilm.getId(), newFilm); - return newFilm; + Film oldFilm = films.get(newFilm.getId()); + + oldFilm.setName(newFilm.getName()); + oldFilm.setDescription(newFilm.getDescription()); + oldFilm.setReleaseDate(newFilm.getReleaseDate()); + oldFilm.setDuration(newFilm.getDuration()); + + films.put(oldFilm.getId(), newFilm); + return oldFilm; } @Override - public Collection getFilmsList() { - return films.values(); + public Map getFilms() { + return films; } @Override @@ -38,12 +45,20 @@ public Optional getFilmById(int id) { } @Override - public void addLikes(int filmId, Set userIds) { - filmLikes.put(filmId, userIds); + public void addLikes(int filmId, int userId) { + filmLikes.computeIfAbsent(filmId, f -> new HashSet<>()).add(userId); + } + @Override + public void deleteLikes(int filmId, int userId) { + filmLikes.get(filmId).remove(userId); + if (filmLikes.get(filmId).isEmpty()) { + filmLikes.remove(filmId); + } } - public Set getLikesCount(int filmId) { - return filmLikes.get(filmId); + public Map> getPopularFilms(int count) { + return filmLikes; + } } diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java index 24602e8..b91752f 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java @@ -23,8 +23,15 @@ public User createUser(User user) { @Override public User updateUser(User newUser) { - users.put(newUser.getId(), newUser); - return newUser; + User oldUser = users.get(newUser.getId()); + + oldUser.setEmail(newUser.getEmail()); + oldUser.setLogin(newUser.getLogin()); + oldUser.setName(newUser.getName()); + oldUser.setBirthday(newUser.getBirthday()); + + users.put(oldUser.getId(), newUser); + return oldUser; } @Override @@ -38,12 +45,19 @@ public Optional getUserById(int id) { } @Override - public void addFriend(int userId, Set friends) { - userFriends.put(userId, friends); + public void addFriend(User user, User friend) { + userFriends.computeIfAbsent(user.getId(), u -> new HashSet<>()).add(friend); + userFriends.computeIfAbsent(friend.getId(), f -> new HashSet<>()).add(user); } @Override - public Set getFriendsList(int id) { + public Collection getFriendsList(int id) { return userFriends.get(id); } + + @Override + public void deleteFriend(User user, User friend) { + userFriends.get(user.getId()).remove(friend); + } } + diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java index 7e6eae3..252e6f9 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java @@ -1,27 +1,25 @@ package ru.yandex.practicum.filmorate.storage; -import ru.yandex.practicum.filmorate.exception.DuplicatedDataException; -import ru.yandex.practicum.filmorate.exception.NotFoundException; -import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.User; import java.util.Collection; import java.util.Map; import java.util.Optional; -import java.util.Set; public interface UserStorage { Map users = Map.of(); - User createUser(User user) throws ValidationException; + User createUser(User user); - User updateUser(User newUser) throws DuplicatedDataException, NotFoundException, ValidationException; + User updateUser(User newUser); Collection getUsersList(); Optional getUserById(int id); - void addFriend(int id, Set friends); + void addFriend(User user, User friend); - Set getFriendsList(int id); + Collection getFriendsList(int id); + + void deleteFriend(User user, User friend); } diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java index bf430e2..8ef659c 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java @@ -6,30 +6,28 @@ import ru.yandex.practicum.filmorate.controller.UserController; import ru.yandex.practicum.filmorate.exception.DuplicatedDataException; import ru.yandex.practicum.filmorate.exception.NotFoundException; -import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.Film; import ru.yandex.practicum.filmorate.model.User; import ru.yandex.practicum.filmorate.service.FilmService; +import ru.yandex.practicum.filmorate.service.UserService; import java.time.LocalDate; +import java.util.Collection; import static org.junit.jupiter.api.Assertions.assertEquals; @SpringBootTest class FilmorateApplicationTests { - private final FilmService filmService = new FilmService(); - private final UserController userController = new UserController(); - private final FilmController filmController = new FilmController(filmService); + private final UserService userService = new UserService(); + private final FilmService filmService = new FilmService(); + private final UserController userController = new UserController(userService); + private final FilmController filmController = new FilmController(filmService, userController); private User user = new User("user@test", "testLogin"); private Film film = new Film("testFilm"); @Test - void contextLoads() { - } - - @Test - void getUsersListTest() throws ValidationException { + void getUsersListTest() { assertEquals(0, userController.getUsersList().size()); userController.createUser(user); @@ -43,7 +41,7 @@ void getUsersListTest() throws ValidationException { } @Test - void createUserTest() throws ValidationException { + void createUserTest() { assertEquals(0, userController.getUsersList().size()); userController.createUser(user); @@ -59,7 +57,7 @@ void createUserTest() throws ValidationException { } @Test - void userEmailTest() throws ValidationException { + void userEmailTest() { assertEquals(0, userController.getUsersList().size()); userController.createUser(user); @@ -72,7 +70,7 @@ void userEmailTest() throws ValidationException { } @Test - void userLoginTest() throws ValidationException { + void userLoginTest() { assertEquals(0, userController.getUsersList().size()); userController.createUser(user); @@ -85,7 +83,7 @@ void userLoginTest() throws ValidationException { } @Test - void userBirthdayTest() throws ValidationException { + void userBirthdayTest() { assertEquals(0, userController.getUsersList().size()); LocalDate date = LocalDate.of(1985,3, 12); @@ -102,7 +100,7 @@ void userBirthdayTest() throws ValidationException { } @Test - void updateUserTest() throws ValidationException, NotFoundException, DuplicatedDataException { + void updateUserTest() throws NotFoundException, DuplicatedDataException { userController.createUser(user); assertEquals(1, userController.getUsersList().size()); @@ -121,7 +119,18 @@ void updateUserTest() throws ValidationException, NotFoundException, DuplicatedD } @Test - void getFilmsListTest() throws ValidationException { + void getUserById() throws NotFoundException { + userController.createUser(user); + User user1 = new User("user@test1", "testLogin1"); + userController.createUser(user1); + + assertEquals(2, userController.getUsersList().size()); + + assertEquals(user1, userController.getUserById(2)); + } + + @Test + void getFilmsListTest() { assertEquals(0, filmController.getFilmsList().size()); filmController.createFilm(film); @@ -135,7 +144,7 @@ void getFilmsListTest() throws ValidationException { } @Test - void createFilmTest() throws ValidationException { + void createFilmTest() { assertEquals(0, filmController.getFilmsList().size()); filmController.createFilm(film); @@ -150,11 +159,10 @@ void createFilmTest() throws ValidationException { filmController.createFilm(film1); assertEquals(2, filmController.getFilmsList().size()); - } @Test - void filmDescriptionTest() throws ValidationException { + void filmDescriptionTest() { filmController.createFilm(film); assertEquals(1, filmController.getFilmsList().size()); @@ -168,7 +176,7 @@ void filmDescriptionTest() throws ValidationException { } @Test - void filmReleaseDateTest() throws ValidationException { + void filmReleaseDateTest() { filmController.createFilm(film); assertEquals(1, filmController.getFilmsList().size()); @@ -181,7 +189,7 @@ void filmReleaseDateTest() throws ValidationException { } @Test - void filmDurationTst() throws ValidationException { + void filmDurationTest() { filmController.createFilm(film); assertEquals(1, filmController.getFilmsList().size()); @@ -193,7 +201,7 @@ void filmDurationTst() throws ValidationException { } @Test - void updateFilmTest() throws ValidationException, NotFoundException, DuplicatedDataException { + void updateFilmTest() throws NotFoundException, DuplicatedDataException { filmController.createFilm(film); assertEquals(1, filmController.getFilmsList().size()); @@ -210,6 +218,39 @@ void updateFilmTest() throws ValidationException, NotFoundException, DuplicatedD assertEquals(film.getName(), film1.getName()); assertEquals(1, filmController.getFilmsList().size()); + + } + + @Test + void getFriendsListTest() throws NotFoundException { + userController.createUser(user); + User user1 = userController.createUser(new User("name@l", "login")); + User user2 = userController.createUser(new User("name@lm", "logins")); + + userController.addFriend(user.getId(), user1.getId()); + userController.addFriend(user.getId(), user2.getId()); + assertEquals(2, userController.getUsersFriends(user.getId()).size()); + + userController.deleteFriend(user.getId(), 2); + + assertEquals(1, userController.getUsersFriends(user.getId()).size()); + + } + + @Test + void addLikesTest() { + filmController.createFilm(film); + userController.createUser(user); + + filmController.addLikes(film.getId(), user.getId()); + + Collection filmNames = filmController.getPopularFilmList(film.getId()); + + assertEquals(1, filmController.getPopularFilmList(film.getId()).size()); + + filmController.deleteFilmLikes(film.getId(), user.getId()); + + assertEquals(0, filmController.getPopularFilmList(film.getId()).size()); } } From ec47ef29b081d45c4253c89eb32ff53cf9e74256 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Sat, 22 Mar 2025 12:15:50 +0400 Subject: [PATCH 14/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2011-=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20(=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=201.6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/api-tests.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/api-tests.yml b/.github/workflows/api-tests.yml index 7ddcf2e..5d57533 100644 --- a/.github/workflows/api-tests.yml +++ b/.github/workflows/api-tests.yml @@ -1,9 +1,4 @@ #file: noinspection SpellCheckingInspection,SpellCheckingInspection name: Films API Tests -on: - pull_request: - -jobs: - build: - uses: yandex-praktikum/java-filmorate/.github/workflows/api-tests.yml@ci \ No newline at end of file +on: \ No newline at end of file From 324dd64192f3e945017881d68de85066ee1044f2 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Sun, 23 Mar 2025 16:23:09 +0400 Subject: [PATCH 15/15] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2011-=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20=D1=81=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yandex/practicum/filmorate/controller/FilmController.java | 1 - .../practicum/filmorate/exception/DuplicatedDataException.java | 2 +- .../yandex/practicum/filmorate/exception/NotFoundException.java | 2 +- .../practicum/filmorate/exception/ValidationException.java | 2 +- .../yandex/practicum/filmorate/storage/InMemoryFilmStorage.java | 2 +- .../yandex/practicum/filmorate/storage/InMemoryUserStorage.java | 2 +- .../yandex/practicum/filmorate/FilmorateApplicationTests.java | 2 +- 7 files changed, 6 insertions(+), 7 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 2175c81..c5e508f 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -19,7 +19,6 @@ @Validated public class FilmController { private final FilmService filmService; - private final UserController userController; @PostMapping public Film createFilm(@Valid @RequestBody Film film) { diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/DuplicatedDataException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/DuplicatedDataException.java index 5f7daa4..614872d 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/exception/DuplicatedDataException.java +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/DuplicatedDataException.java @@ -1,6 +1,6 @@ package ru.yandex.practicum.filmorate.exception; -public class DuplicatedDataException extends Exception { +public class DuplicatedDataException extends RuntimeException { public DuplicatedDataException() { super(); diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java index 9d130ed..1df8f8a 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java @@ -1,6 +1,6 @@ package ru.yandex.practicum.filmorate.exception; -public class NotFoundException extends Exception{ +public class NotFoundException extends RuntimeException { public NotFoundException() { super(); diff --git a/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java b/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java index f374d4f..32bb593 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java @@ -1,6 +1,6 @@ package ru.yandex.practicum.filmorate.exception; -public class ValidationException extends Exception { +public class ValidationException extends RuntimeException { public ValidationException() { super(); diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java index 03b0ee2..c819234 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java @@ -12,7 +12,7 @@ public class InMemoryFilmStorage implements FilmStorage { private int nextFilmId = 1; private final Map films = new HashMap<>(); - private Map> filmLikes = new HashMap<>(); + private final Map> filmLikes = new HashMap<>(); @Override public Film createFilm(Film film) { diff --git a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java index b91752f..0601d7f 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java @@ -12,7 +12,7 @@ public class InMemoryUserStorage implements UserStorage { private int nextUserId = 1; private final Map users = new HashMap<>(); - private Map> userFriends = new HashMap<>(); + private final Map> userFriends = new HashMap<>(); @Override public User createUser(User user) { diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java index 8ef659c..de095d5 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java @@ -21,7 +21,7 @@ class FilmorateApplicationTests { private final UserService userService = new UserService(); private final FilmService filmService = new FilmService(); private final UserController userController = new UserController(userService); - private final FilmController filmController = new FilmController(filmService, userController); + private final FilmController filmController = new FilmController(filmService); private User user = new User("user@test", "testLogin"); private Film film = new Film("testFilm");