diff --git a/pom.xml b/pom.xml
index 0cad031..f81fee6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.boot
spring-boot-starter-parent
- 3.2.4
+ 3.5.8
ru.yandex.practicum
@@ -25,6 +25,7 @@
org.projectlombok
lombok
+ 1.18.38
provided
@@ -32,6 +33,10 @@
spring-boot-starter-test
test
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
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..8c62826 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,124 @@
package ru.yandex.practicum.filmorate.controller;
-import org.springframework.web.bind.annotation.RestController;
+import jakarta.validation.Valid;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import ru.yandex.practicum.filmorate.exception.ValidationException;
+import ru.yandex.practicum.filmorate.model.Film;
+
+import java.time.LocalDate;
+import java.time.Month;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
@RestController
+@RequestMapping("/films")
public class FilmController {
-}
+ private static final int FILM_DESCRIPTION_LENGTH = 200;
+ private static final LocalDate EARLIEST_RELEASE_DATE = LocalDate.of(1895, Month.DECEMBER, 28);
+ private static final Logger log = LoggerFactory.getLogger(FilmController.class);
+ private final HashMap films = new HashMap<>();
+
+ /**
+ * Возвращает все фильмы в виде списка
+ */
+ @GetMapping
+ public ResponseEntity> getFilms() {
+ return ResponseEntity.ok(new ArrayList<>(films.values()));
+ }
+
+ /**
+ * Добавляет новый фильм.
+ * Проверяет поля фильма на соответствие.
+ * Если всё хорошо, то создаёт копию переданного фильма, присваивает уникальный ID и сохраняет в контроллер.
+ *
+ * @param newFilm объект фильма, который нужно добавить
+ * @return копия созданного фильма с присвоенным ID
+ */
+ @PostMapping
+ public ResponseEntity addFilm(@Valid @RequestBody Film newFilm) {
+ try {
+ checkIsValidFilm(newFilm);
+ } catch (ValidationException exception) {
+ log.error("Ошибка валидации данных фильма {} при добавлении: {}", newFilm.getId(), exception.getMessage());
+ throw exception;
+ }
+ log.trace("Данные фильма {} прошли валидацию при добавлении", newFilm.getId());
+
+ newFilm.setId(getNextId());
+ films.put(newFilm.getId(), newFilm);
+ log.info("Фильм {} добавлен", newFilm.getId());
+
+ return ResponseEntity.status(HttpStatus.CREATED).body(newFilm);
+ }
+
+ /**
+ * Обновляет фильм.
+ * Проверяет поля переданного фильма на соответствие.
+ * Если всё хорошо и переданный фильм существует в контроллере, то создаёт копию и сохраняет в контроллер.
+ *
+ * @param updatedFilm объект фильма, который нужно обновить
+ * @return копия обновлённого фильма
+ */
+ @PutMapping
+ public ResponseEntity updateFilm(@Valid @RequestBody Film updatedFilm) {
+ try {
+ checkIsValidFilm(updatedFilm);
+ } catch (ValidationException exception) {
+ log.error("Ошибка валидации данных фильма {} при обновлении: {}", updatedFilm.getId(),
+ exception.getMessage());
+ throw exception;
+ }
+
+ log.trace("Фильм {} прошёл валидацию для обновления", updatedFilm.getId());
+ if (!films.containsKey(updatedFilm.getId())) {
+ String filmNotFound = "Фильм " + updatedFilm.getId() + " для обновления не найден";
+ log.error(filmNotFound);
+ throw new ValidationException(filmNotFound);
+ }
+
+ films.put(updatedFilm.getId(), updatedFilm);
+ log.info("Фильм {} обновлён", updatedFilm.getId());
+
+ return ResponseEntity.ok(updatedFilm);
+ }
+
+ /**
+ * Генерирует следующий Id.
+ * Находит максимальный текущй Id и увеличивает его.
+ */
+ private int getNextId() {
+ int currentMaxId = films.keySet()
+ .stream()
+ .mapToInt(id -> id)
+ .max()
+ .orElse(0);
+ return ++currentMaxId;
+ }
+
+ /**
+ * Проверяет переданный фильм на соответствие условиям.
+ * Если не удовлетворяет какой-то проверке, то выбрасывается ошибка
+ */
+ private void checkIsValidFilm(Film film) throws ValidationException {
+ if (film == null) {
+ throw new ValidationException("Фильм не найден");
+ }
+
+ if (film.getDescription().length() > FILM_DESCRIPTION_LENGTH) {
+ throw new ValidationException("Описание фильма не может быть больше 200 символов");
+ }
+
+ if (film.getReleaseDate().isBefore(EARLIEST_RELEASE_DATE)) {
+ throw new ValidationException("Дата релиза фильма не может быть раньше 28 декабря 1895 года");
+ }
+
+ if (film.getDuration() <= 0) {
+ throw new ValidationException("Продолжительность фильма должна быть положительным числом");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java
new file mode 100644
index 0000000..a742286
--- /dev/null
+++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java
@@ -0,0 +1,122 @@
+package ru.yandex.practicum.filmorate.controller;
+
+import jakarta.validation.Valid;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import ru.yandex.practicum.filmorate.exception.ValidationException;
+import ru.yandex.practicum.filmorate.model.User;
+
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+@RestController
+@RequestMapping("/users")
+public class UserController {
+ private static final Logger log = LoggerFactory.getLogger(UserController.class);
+ private final HashMap users = new HashMap<>();
+
+ /**
+ * Возвращает всех пользователей в виде списка
+ */
+ @GetMapping
+ public ResponseEntity> getUsers() {
+ return ResponseEntity.ok(new ArrayList<>(users.values()));
+ }
+
+ /**
+ * Добавляет нового пользователя.
+ * Проверяет поля пользователя на соответствие.
+ * Если всё хорошо, то создаёт копию переданного пользователя, присваивает уникальный ID и сохраняет в контроллер.
+ *
+ * @param newUser объект пользователя, который нужно добавить
+ * @return копия созданного пользователя с присвоенным ID
+ */
+ @PostMapping
+ public ResponseEntity addUser(@Valid @RequestBody User newUser) {
+ try {
+ checkIsValidUser(newUser);
+ } catch (ValidationException exception) {
+ log.error("Ошибка валидации данных пользователя при добавлении: {}",
+ exception.getMessage());
+ throw exception;
+ }
+ log.info("Данные пользователя прошли валидацию при добавлении");
+
+ newUser.setId(getNextId());
+ users.put(newUser.getId(), newUser);
+ log.info("Пользователь {} добавлен", newUser.getId());
+
+ return ResponseEntity.status(HttpStatus.CREATED).body(newUser);
+ }
+
+ /**
+ * Обновляет пользователя.
+ * Проверяет поля переданного пользователя на соответствие.
+ * Если всё хорошо и переданный пользователь существует в контроллере, то создаёт копию и сохраняет в контроллер.
+ *
+ * @param updatedUser объект пользователя, который нужно обновить
+ * @return копия обновлённого пользователя
+ */
+ @PutMapping
+ public ResponseEntity updateUser(@Valid @RequestBody User updatedUser) {
+ try {
+ checkIsValidUser(updatedUser);
+ } catch (ValidationException exception) {
+ log.error("Ошибка валидации данных пользователя {} при обновлении: {}", updatedUser.getId(),
+ exception.getMessage());
+ throw exception;
+ }
+ log.info("Данные пользователя {} прошли валидацию при обновлении", updatedUser.getId());
+
+ if (!users.containsKey(updatedUser.getId())) {
+ String userNotFound = "Пользователь " + updatedUser.getId() + " для обновления не найден";
+ log.error(userNotFound);
+ throw new ValidationException(userNotFound);
+ }
+
+ users.put(updatedUser.getId(), updatedUser);
+ log.info("Пользователь {} обновлён", updatedUser.getId());
+
+ return ResponseEntity.ok(updatedUser);
+ }
+
+ /**
+ * Генерирует следующий Id.
+ * Находит максимальный текущй Id и увеличивает его.
+ */
+ private int getNextId() {
+ int currentMaxId = users.keySet()
+ .stream()
+ .mapToInt(id -> id)
+ .max()
+ .orElse(0);
+ return ++currentMaxId;
+ }
+
+ /**
+ * Проверяет переданного пользователя на соответствие условиям.
+ * Если не удовлетворяет какой-то проверке, то выбрасывается ошибка
+ */
+ private void checkIsValidUser(User user) throws ValidationException {
+ if (user == null) {
+ throw new ValidationException("Пользователь не найден");
+ }
+
+ if (user.getLogin().contains(" ")) {
+ throw new ValidationException("Логин пользователя не может содержать пробел");
+ }
+
+ if (user.getBirthday() != null && user.getBirthday().isAfter(LocalDate.now())) {
+ throw new ValidationException("Дата рождения не может быть в будущем");
+ }
+
+ if (user.getName() == null || user.getName().isEmpty()) {
+ user.setName(user.getLogin());
+ }
+ }
+}
\ No newline at end of file
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..52dc49c
--- /dev/null
+++ b/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java
@@ -0,0 +1,7 @@
+package ru.yandex.practicum.filmorate.exception;
+
+public class ValidationException extends RuntimeException {
+ 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..a80bbf0 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,29 @@
package ru.yandex.practicum.filmorate.model;
-import lombok.Getter;
-import lombok.Setter;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.*;
+
+import java.time.LocalDate;
/**
* Film.
*/
-@Getter
-@Setter
+@Data
+@Builder(toBuilder = true)
+@EqualsAndHashCode(of = { "id" })
+@AllArgsConstructor
public class Film {
-}
+ private int id;
+
+ @NotBlank
+ private String name;
+
+ private String description;
+
+ @NotNull
+ private LocalDate releaseDate;
+
+ @NotNull
+ private Integer duration;
+}
\ No newline at end of file
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..3f13eab
--- /dev/null
+++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java
@@ -0,0 +1,28 @@
+package ru.yandex.practicum.filmorate.model;
+
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.time.LocalDate;
+
+@Data
+@Builder(toBuilder = true)
+@EqualsAndHashCode(of = { "id" })
+@AllArgsConstructor
+public class User {
+ private int id;
+ private String name;
+
+ @Email
+ @NotBlank
+ private String email;
+
+ @NotBlank
+ private String login;
+
+ private LocalDate birthday;
+}
\ No newline at end of file
diff --git a/src/test/java/ru/yandex/practicum/filmorate/controller/FilmControllerTest.java b/src/test/java/ru/yandex/practicum/filmorate/controller/FilmControllerTest.java
new file mode 100644
index 0000000..6ec6c48
--- /dev/null
+++ b/src/test/java/ru/yandex/practicum/filmorate/controller/FilmControllerTest.java
@@ -0,0 +1,190 @@
+package ru.yandex.practicum.filmorate.controller;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import ru.yandex.practicum.filmorate.exception.ValidationException;
+import ru.yandex.practicum.filmorate.model.Film;
+
+import java.time.LocalDate;
+import java.time.Month;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class FilmControllerTest {
+ private static final String FILM_NAME = "Фильм";
+ private static final String FILM_NAME_2 = "Второй фильм";
+
+ private static final String FILM_DESCRIPTION = "Описание фильма";
+ private static final String FILM_DESCRIPTION_2 = "Описание второго фильма";
+ private static final String FILM_DESCRIPTION_INCORRECT = "Очень " + "очень".repeat(199) + "длинное описание";
+
+ private static final LocalDate FILM_RELEASE_DATE = LocalDate.of(1992, Month.DECEMBER, 12);
+ private static final LocalDate FILM_RELEASE_DATE_2 = LocalDate.of(2005, Month.APRIL, 28);
+ private static final LocalDate FILM_RELEASE_DATE_INCORRECT = LocalDate.of(1600, Month.DECEMBER, 5);
+
+ private static final int FILM_DURATION = 100;
+ private static final int FILM_DURATION_2 = 200;
+ private static final int FILM_DURATION_INCORRECT = -100;
+
+ FilmController filmController;
+
+ @BeforeEach
+ @DisplayName("Инициализирует контроллер")
+ void setUp() {
+ filmController = new FilmController();
+ }
+
+ @Test
+ @DisplayName("При добавлении двух фильмов контроллер должен возвращать их")
+ void test_getFilms_WhenAddedFilms_ShouldReturnAll() {
+ //given
+ Film film = Film.builder().name(FILM_NAME).description(FILM_DESCRIPTION).releaseDate(FILM_RELEASE_DATE)
+ .duration(FILM_DURATION).build();
+ Film film2 = Film.builder().name(FILM_NAME_2).description(FILM_DESCRIPTION_2).releaseDate(FILM_RELEASE_DATE_2)
+ .duration(FILM_DURATION_2).build();
+
+ //when
+ filmController.addFilm(film);
+ filmController.addFilm(film2);
+ List filmsByController = filmController.getFilms().getBody();
+
+ //then
+ assertNotNull(filmsByController, "В контроллере нет фильмов");
+ assertEquals(2, filmsByController.size(), "В контроллере не верное количество фильмов");
+ assertEquals(FILM_NAME, filmsByController.get(0).getName(), "В контроллере не корректный 1-ый фильм");
+ assertEquals(FILM_NAME_2, filmsByController.get(1).getName(), "В контроллере не корректный 2-ой фильм");
+ }
+
+ @Test
+ @DisplayName("При добавлении фильма с корректными полями контроллер должен добавить его")
+ void test_addFilm_WhenCorrectFields_ShouldAddToController() {
+ //given
+ Film film = Film.builder().name(FILM_NAME).description(FILM_DESCRIPTION)
+ .releaseDate(FILM_RELEASE_DATE)
+ .duration(FILM_DURATION).build();
+
+ //when
+ filmController.addFilm(film);
+ List filmsByController = filmController.getFilms().getBody();
+
+ //then
+ assertNotNull(filmsByController, "В контроллере нет фильмов");
+ assertEquals(1, filmsByController.size(), "В контроллере не верное количество фильмов");
+ assertEquals(FILM_NAME, filmsByController.get(0).getName(), "В контроллере некорректный фильм");
+ }
+
+ @Test
+ @DisplayName("При добавлении фильма с некорректным описанием контроллер должен выбросить ошибку")
+ void test_addFilm_WhenIncorrectDescription_ShouldThrowsError() {
+ //given && when
+ Film film = Film.builder().name(FILM_NAME).description(FILM_DESCRIPTION_INCORRECT)
+ .releaseDate(FILM_RELEASE_DATE)
+ .duration(FILM_DURATION).build();
+
+ //then
+ assertThrows(ValidationException.class,
+ () -> filmController.addFilm(film),
+ "Фильм может быть добавлен с некорректным описанием");
+ }
+
+ @Test
+ @DisplayName("При добавлении фильма с некорректной длительностью контроллер должен выбросить ошибку")
+ void test_addFilm_WhenIncorrectDuration_ShouldThrowsError() {
+ //given && when
+ Film film = Film.builder().name(FILM_NAME).description(FILM_DESCRIPTION)
+ .releaseDate(FILM_RELEASE_DATE)
+ .duration(FILM_DURATION_INCORRECT).build();
+
+ //then
+ assertThrows(ValidationException.class,
+ () -> filmController.addFilm(film),
+ "Фильм может быть добавлен с некорректной длительностью");
+ }
+
+ @Test
+ @DisplayName("При добавлении фильма с некорректной датой релиза контроллер должен выбросить ошибку")
+ void test_addFilm_WhenIncorrectReleaseDate_ShouldThrowsError() {
+ //given && when
+ Film film = Film.builder().name(FILM_NAME).description(FILM_DESCRIPTION)
+ .releaseDate(FILM_RELEASE_DATE_INCORRECT)
+ .duration(FILM_DURATION).build();
+
+ //then
+ assertThrows(ValidationException.class,
+ () -> filmController.addFilm(film),
+ "Фильм может быть добавлен с некорректной датой релиза");
+ }
+
+ @Test
+ @DisplayName("При обновлении фильма с корректными данными контроллер должен обновить его")
+ void test_updateFilm_WhenCorrectFields_ShouldUpdateInController() {
+ //given
+ Film film = Film.builder().name(FILM_NAME).description(FILM_DESCRIPTION).releaseDate(FILM_RELEASE_DATE)
+ .duration(FILM_DURATION).build();
+ filmController.addFilm(film);
+
+ //when
+ Film updatedFilm = film.toBuilder().name(FILM_NAME_2).build();
+ filmController.updateFilm(updatedFilm);
+ List filmsByController = filmController.getFilms().getBody();
+
+ //then
+ assertNotNull(filmsByController, "В контроллере нет фильмов");
+ assertEquals(1, filmsByController.size(), "В контроллере не верное количество фильмов");
+ assertEquals(FILM_NAME_2, filmsByController.get(0).getName(), "В контроллере некорректный фильм");
+ }
+
+ @Test
+ @DisplayName("При обновлении фильма с некорректным описанием контроллер должен выбросить ошибку")
+ void test_updateFilm_WhenIncorrectDescription_ShouldThrowsError() {
+ //given
+ Film film = Film.builder().name(FILM_NAME).description(FILM_DESCRIPTION).releaseDate(FILM_RELEASE_DATE)
+ .duration(FILM_DURATION).build();
+ filmController.addFilm(film);
+
+ //when
+ Film updatedFilm = film.toBuilder().description(FILM_DESCRIPTION_INCORRECT).build();
+
+ //then
+ assertThrows(ValidationException.class,
+ () -> filmController.updateFilm(updatedFilm),
+ "Фильм может быть обновлён с некорректным описанием");
+ }
+
+ @Test
+ @DisplayName("При обновлении фильма с некорректной длительностью контроллер должен выбросить ошибку")
+ void test_updateFilm_WhenIncorrectDuration_ShouldThrowsError() {
+ //given
+ Film film = Film.builder().name(FILM_NAME).description(FILM_DESCRIPTION).releaseDate(FILM_RELEASE_DATE)
+ .duration(FILM_DURATION).build();
+ filmController.addFilm(film);
+
+ //when
+ Film updatedFilm = film.toBuilder().duration(FILM_DURATION_INCORRECT).build();
+
+ //then
+ assertThrows(ValidationException.class,
+ () -> filmController.updateFilm(updatedFilm),
+ "Фильм может быть обновлён с некорректной длительностью");
+ }
+
+ @Test
+ @DisplayName("При добавлении фильма с некорректной датой релиза контроллер должен выбросить ошибку")
+ void test_updateFilm_WhenIncorrectReleaseDate_ShouldThrowsError() {
+ //given
+ Film film = Film.builder().name(FILM_NAME).description(FILM_DESCRIPTION).releaseDate(FILM_RELEASE_DATE)
+ .duration(FILM_DURATION).build();
+ filmController.addFilm(film);
+
+ //when
+ Film updatedFilm = film.toBuilder().releaseDate(FILM_RELEASE_DATE_INCORRECT).build();
+
+ //then
+ assertThrows(ValidationException.class,
+ () -> filmController.updateFilm(updatedFilm),
+ "Фильм может быть обновлён с некорректной датой релиза");
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/ru/yandex/practicum/filmorate/controller/UserControllerTest.java b/src/test/java/ru/yandex/practicum/filmorate/controller/UserControllerTest.java
new file mode 100644
index 0000000..7666f1b
--- /dev/null
+++ b/src/test/java/ru/yandex/practicum/filmorate/controller/UserControllerTest.java
@@ -0,0 +1,186 @@
+package ru.yandex.practicum.filmorate.controller;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import ru.yandex.practicum.filmorate.exception.ValidationException;
+import ru.yandex.practicum.filmorate.model.User;
+
+import java.time.LocalDate;
+import java.time.Month;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class UserControllerTest {
+ private static final String USER_NAME = "Вася";
+ private static final String USER_NAME_2 = "Петя";
+
+ private static final String USER_EMAIL = "mail@mail.ru";
+ private static final String USER_EMAIL_2 = "newMail@mail.ru";
+
+ private static final String USER_LOGIN = "user";
+ private static final String USER_LOGIN_2 = "newUser";
+ private static final String USER_LOGIN_INCORRECT = "new User";
+
+ private static final LocalDate USER_BIRTHDAY = LocalDate.of(1992, Month.DECEMBER, 12);
+ private static final LocalDate USER_BIRTHDAY_2 = LocalDate.of(1982, Month.OCTOBER, 22);
+ private static final LocalDate USER_BIRTHDAY_INCORRECT = LocalDate.of(3035, Month.DECEMBER, 12);
+
+ UserController userController;
+
+ @BeforeEach
+ @DisplayName("Инициализирует контроллер")
+ void setUp() {
+ userController = new UserController();
+ }
+
+ @Test
+ @DisplayName("При добавлении двух пользователей контроллер должен возвращать их")
+ void test_getUsers_WhenAddedUsers_ShouldReturnAll() {
+ //given
+ User user = User.builder().name(USER_NAME).email(USER_EMAIL).login(USER_LOGIN).birthday(USER_BIRTHDAY).build();
+ User user2 = User.builder().name(USER_NAME_2).email(USER_EMAIL_2).login(USER_LOGIN_2).birthday(USER_BIRTHDAY_2)
+ .build();
+
+ //when
+ userController.addUser(user);
+ userController.addUser(user2);
+ List usersByController = userController.getUsers().getBody();
+
+ //then
+ assertNotNull(usersByController, "В контроллере нет пользователей");
+ assertEquals(2, usersByController.size(), "В контроллере не верное количество пользователей");
+ assertEquals(USER_NAME, usersByController.get(0).getName(),
+ "В контроллере не корректный 1-ый пользователь");
+ assertEquals(USER_NAME_2, usersByController.get(1).getName(),
+ "В контроллере не корректный 2-ой пользователь");
+ }
+
+ @Test
+ @DisplayName("При добавлении пользователя с корректными полями контроллер должен добавить его")
+ void test_addUser_WhenCorrectFields_ShouldAddToController() {
+ //given
+ User user = User.builder().name(USER_NAME).email(USER_EMAIL).login(USER_LOGIN).birthday(USER_BIRTHDAY).build();
+
+ //when
+ userController.addUser(user);
+ List usersByController = userController.getUsers().getBody();
+
+ //then
+ assertNotNull(usersByController,"В контроллере нет пользователей");
+ assertEquals(1, usersByController.size(), "В контроллере не верное количество пользователей");
+ assertEquals(USER_NAME, usersByController.get(0).getName(), "В контроллере некорректный пользователь");
+ }
+
+ @Test
+ @DisplayName("При добавлении пользователя с некорректным логином контроллер должен выбросить ошибку")
+ void test_addUser_WhenIncorrectLogin_ShouldThrowsError() {
+ //given && when
+ User user = User.builder().name(USER_NAME).email(USER_EMAIL).login(USER_LOGIN_INCORRECT)
+ .birthday(USER_BIRTHDAY).build();
+
+ //then
+ assertThrows(ValidationException.class,
+ () -> userController.addUser(user),
+ "Пользователь добавлен с некорректным логином");
+ }
+
+ @Test
+ @DisplayName("При добавлении пользователя без имени в контроллере имя будет равно логину")
+ void test_addUser_WhenNameIsNull_ShouldReturnNameWithLoginValue() {
+ //given && when
+ User user = User.builder().email(USER_EMAIL).login(USER_LOGIN).birthday(USER_BIRTHDAY).build();
+
+ //when
+ userController.addUser(user);
+ List usersByController = userController.getUsers().getBody();
+
+ //then
+ assertNotNull(usersByController,"В контроллере нет пользователей");
+ assertEquals(1, usersByController.size(), "В контроллере не верное количество пользователей");
+ assertEquals(USER_LOGIN, usersByController.get(0).getName(), "Имя пользователя не равно логину");
+ }
+
+ @Test
+ @DisplayName("При добавлении пользователя с датой рождения в будущем контроллер должен выбросить ошибку")
+ void test_addUser_WhenBirthdayInFuture_ShouldThrowsError() {
+ //given && when
+ User user = User.builder().name(USER_NAME).email(USER_EMAIL).login(USER_LOGIN)
+ .birthday(USER_BIRTHDAY_INCORRECT).build();
+
+ //then
+ assertThrows(ValidationException.class,
+ () -> userController.addUser(user),
+ "Пользователь добавлен с датой рождения в будущем");
+ }
+
+ @Test
+ @DisplayName("При обновлении пользователя с корректными полями контроллер должен обновить его")
+ void test_updateUser_WhenCorrectFields_ShouldUpdateInController() {
+ //given
+ User user = User.builder().name(USER_NAME).email(USER_EMAIL).login(USER_LOGIN).birthday(USER_BIRTHDAY).build();
+ userController.addUser(user);
+
+ //when
+ User updateUser = user.toBuilder().name(USER_NAME_2).build();
+ userController.updateUser(updateUser);
+ List usersByController = userController.getUsers().getBody();
+
+ //then
+ assertNotNull(usersByController,"В контроллере нет пользователей");
+ assertEquals(1, usersByController.size(), "В контроллере не верное количество пользователей");
+ assertEquals(USER_NAME_2, usersByController.get(0).getName(), "В контроллере некорректный пользователь");
+ }
+
+ @Test
+ @DisplayName("При обновлении пользователя с некорректным логином контроллер должен выбросить ошибку")
+ void test_updateUser_WhenIncorrectLogin_ShouldThrowsError() {
+ //given && when
+ User user = User.builder().name(USER_NAME).email(USER_EMAIL).login(USER_LOGIN).birthday(USER_BIRTHDAY).build();
+ userController.addUser(user);
+
+ //when
+ User updateUser = user.toBuilder().login(USER_LOGIN_INCORRECT).build();
+
+ //then
+ assertThrows(ValidationException.class,
+ () -> userController.updateUser(updateUser),
+ "Пользователь обновлён с некорректным логином");
+ }
+
+ @Test
+ @DisplayName("При обновлении пользователя без имени в контроллере имя будет равно логину")
+ void test_updateUser_WhenNameIsNull_ShouldReturnNameWithLoginValue() {
+ //given && when
+ User user = User.builder().name(USER_NAME).email(USER_EMAIL).login(USER_LOGIN).birthday(USER_BIRTHDAY).build();
+ userController.addUser(user);
+
+ //when
+ User updateUser = user.toBuilder().name("").build();
+ userController.updateUser(updateUser);
+ List usersByController = userController.getUsers().getBody();
+
+ //then
+ assertNotNull(usersByController,"В контроллере нет пользователей");
+ assertEquals(1, usersByController.size(), "В контроллере не верное количество пользователей");
+ assertEquals(USER_LOGIN, usersByController.get(0).getName(), "Имя пользователя не равно логину");
+ }
+
+ @Test
+ @DisplayName("При обновлении пользователя с датой рождения в будущем контроллер должен выбросить ошибку")
+ void test_updateUser_WhenBirthdayInFuture_ShouldThrowsError() {
+ //given && when
+ User user = User.builder().name(USER_NAME).email(USER_EMAIL).login(USER_LOGIN).birthday(USER_BIRTHDAY).build();
+ userController.addUser(user);
+
+ //when
+ User updateUser = user.toBuilder().birthday(USER_BIRTHDAY_INCORRECT).build();
+
+ //then
+ assertThrows(ValidationException.class,
+ () -> userController.updateUser(updateUser),
+ "Пользователь обновлён с датой рождения в будущем");
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/ru/yandex/practicum/filmorate/model/FilmTest.java b/src/test/java/ru/yandex/practicum/filmorate/model/FilmTest.java
new file mode 100644
index 0000000..297f749
--- /dev/null
+++ b/src/test/java/ru/yandex/practicum/filmorate/model/FilmTest.java
@@ -0,0 +1,38 @@
+package ru.yandex.practicum.filmorate.model;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDate;
+import java.time.Month;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class FilmTest {
+ private static final int FILM_ID = 1;
+ private static final String FILM_NAME = "Фильм";
+ private static final String FILM_DESCRIPTION = "Описание фильма";
+ private static final int FILM_DURATION = 100;
+ private static final LocalDate FILM_RELEASE_DATE = LocalDate.of(1992, Month.DECEMBER, 12);
+
+ @Test
+ @DisplayName("Проверяет, что фильма создаётся с переданными параметрами")
+ public void test_createFilm_WhenCreateShouldNotEmptyValues() {
+ //given && when
+ Film film = Film.builder()
+ .id(FILM_ID)
+ .name(FILM_NAME)
+ .description(FILM_DESCRIPTION)
+ .releaseDate(FILM_RELEASE_DATE)
+ .duration(FILM_DURATION).build();
+
+ //then
+ assertEquals(FILM_ID, film.getId(), "Фильм создался с неверным id");
+ assertEquals(FILM_NAME, film.getName(), "Фильм создался с неверным именем");
+ assertEquals(FILM_DESCRIPTION, film.getDescription(), "Фильм создался с неверным описанием");
+ assertEquals(FILM_RELEASE_DATE, film.getReleaseDate(),
+ "Фильм создался с неверной датой релиза");
+ assertEquals(FILM_DURATION, film.getDuration(),
+ "Фильм создался с неверной длительностью");
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/ru/yandex/practicum/filmorate/model/UserTest.java b/src/test/java/ru/yandex/practicum/filmorate/model/UserTest.java
new file mode 100644
index 0000000..889bc2c
--- /dev/null
+++ b/src/test/java/ru/yandex/practicum/filmorate/model/UserTest.java
@@ -0,0 +1,37 @@
+package ru.yandex.practicum.filmorate.model;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import java.time.LocalDate;
+import java.time.Month;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class UserTest {
+ private static final int USER_ID = 1;
+ private static final String USER_NAME = "Имя";
+ private static final String USER_EMAIL = "test@mail.ru";
+ private static final String USER_LOGIN = "user";
+ private static final LocalDate USER_BIRTHDAY = LocalDate.of(1992, Month.DECEMBER, 12);
+
+ @Test
+ @DisplayName("Проверяет, что пользователь создаётся с переданными параметрами")
+ public void test_createUser_WhenCreateShouldNotEmptyValues() {
+ //given && when
+ User user = User.builder()
+ .id(USER_ID)
+ .name(USER_NAME)
+ .email(USER_EMAIL)
+ .login(USER_LOGIN)
+ .birthday(USER_BIRTHDAY).build();
+
+ //then
+ assertEquals(USER_ID, user.getId(), "Пользователь создался с неверным id");
+ assertEquals(USER_NAME, user.getName(), "Пользователь создался с неверным именем");
+ assertEquals(USER_EMAIL, user.getEmail(), "Пользователь создался с неверной почтой");
+ assertEquals(USER_LOGIN, user.getLogin(), "Пользователь создался с неверным логином");
+ assertEquals(USER_BIRTHDAY, user.getBirthday(), "Пользователь создался с неверной датой рождения");
+ }
+
+}
\ No newline at end of file