diff --git a/pom.xml b/pom.xml
index 0cad031..8439ff4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,11 +27,22 @@
lombok
provided
+
org.springframework.boot
spring-boot-starter-test
test
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+
+ org.slf4j
+ slf4j-api
+
diff --git a/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java b/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java
index dca451b..e55e710 100644
--- a/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java
+++ b/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java
@@ -8,5 +8,4 @@ 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 08cf0a1..4116f66 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,85 @@
package ru.yandex.practicum.filmorate.controller;
-import org.springframework.web.bind.annotation.RestController;
+import jakarta.validation.Valid;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import ru.yandex.practicum.filmorate.model.Film;
+import jakarta.validation.ValidationException;
+import java.time.LocalDate;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+@Slf4j
@RestController
+@RequestMapping("/films")
public class FilmController {
-}
+
+ private final Map films = new HashMap<>();
+
+ @GetMapping
+ public Collection findAll() {
+ log.info("Список фильмов выведен");
+ return films.values();
+ }
+
+ private int getNextId() {
+ int currentMaxId = films.keySet()
+ .stream()
+ .mapToInt(id -> id)
+ .max()
+ .orElse(0);
+ return ++currentMaxId;
+ }
+
+ @PostMapping
+ public Film create(@Valid @RequestBody Film film) {
+ validateFilm(film);
+ film.setId(getNextId());
+ films.put(film.getId(), film);
+ log.info("Фильм: {} добавлен в базу", film);
+ return film;
+ }
+
+ @PutMapping
+ public Film update(@Valid @RequestBody Film newFilm) {
+ if (newFilm.getId() == null) {
+ log.warn("Не указан id");
+ throw new ValidationException("Id должен быть указан");
+ }
+ if (!films.containsKey(newFilm.getId())) {
+ log.warn("Фильм с указанным id не найден");
+ throw new ValidationException("Фильм с id = " + newFilm.getId() + " не найден");
+ }
+ validateFilm(newFilm);
+ Film oldFilm = films.get(newFilm.getId());
+ oldFilm.setDescription(newFilm.getDescription());
+ oldFilm.setDuration(newFilm.getDuration());
+ oldFilm.setName(newFilm.getName());
+ oldFilm.setReleaseDate(newFilm.getReleaseDate());
+ log.info("Данные о фильме: {} обновлены", oldFilm);
+ return oldFilm;
+ }
+
+ private void validateFilm(Film film) {
+ if (film.getDescription().length() > 200) {
+ log.warn("Ошибка лимита");
+ throw new ValidationException("Описание превышает 200 символов");
+ }
+ if (film.getReleaseDate().isBefore(LocalDate.of(1895, 12, 28))) {
+ log.warn("Ошибка даты");
+ throw new ValidationException("Неверная дата релиза");
+ }
+
+ if (film.getName() == null || film.getName().isBlank()) {
+ log.warn("Пустое название фильма");
+ throw new ValidationException("Название не может быть пустым");
+ }
+
+ if (film.getDuration() < 1) {
+ log.warn("Ошибка длительности");
+ throw new ValidationException("Длительность не может быть меньше 1");
+ }
+ }
+}
\ 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..915a2df
--- /dev/null
+++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java
@@ -0,0 +1,82 @@
+package ru.yandex.practicum.filmorate.controller;
+
+import lombok.extern.slf4j.Slf4j;
+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.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+@Slf4j
+@RestController
+@RequestMapping("/users")
+public class UserController {
+
+ private final Map users = new HashMap<>();
+
+ @GetMapping
+ public Collection findAll() {
+ log.info("Список фильмов выведен");
+ return users.values();
+ }
+
+ private int getNextId() {
+ int currentMaxId = users.keySet()
+ .stream()
+ .mapToInt(id -> id)
+ .max()
+ .orElse(0);
+ return ++currentMaxId;
+ }
+
+ @PostMapping
+ public User create(@RequestBody User user) {
+ validateUser(user);
+ user.setId(getNextId());
+ users.put(user.getId(), user);
+ log.info("Пользователь: {} добавлен в базу", user);
+ return user;
+ }
+
+ @PutMapping
+ public User update(@RequestBody User newUser) {
+ if (newUser.getId() == null) {
+ log.warn("Не указан id");
+ throw new ValidationException("Id должен быть указан");
+ }
+ if (!users.containsKey(newUser.getId())) {
+ log.warn("Пользователь с указанным id не найден");
+ throw new ValidationException("Пользователь с id = " + newUser.getId() + " не найден");
+ }
+ validateUser(newUser);
+ User oldUser = users.get(newUser.getId());
+ oldUser.setEmail(newUser.getEmail());
+ oldUser.setName(newUser.getName());
+ oldUser.setLogin(newUser.getLogin());
+ oldUser.setBirthday(newUser.getBirthday());
+ log.info("Данные о пользователе: {} обновлены", oldUser);
+ return oldUser;
+ }
+
+ private void validateUser(User user) {
+ if (!user.getEmail().contains("@")) {
+ log.warn("Ошибка в формате почты");
+ throw new ValidationException("Неверная почта");
+ }
+ if (user.getBirthday().isAfter(LocalDate.now())) {
+ log.warn("Ошибка в дате рождения");
+ throw new ValidationException("Неверная дата рождения");
+ }
+ if (user.getLogin().contains(" ")) {
+ log.warn("Ошибка в формате логина");
+ throw new ValidationException("Неправильный формат логина");
+ }
+ if (user.getName() == null || user.getName().trim().isEmpty()) {
+ log.info("Пустое имя пользователя заменено на логин");
+ 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..b9e156e 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,23 @@
package ru.yandex.practicum.filmorate.model;
-import lombok.Getter;
-import lombok.Setter;
+import jakarta.validation.constraints.Min;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.time.LocalDate;
/**
* Film.
*/
-@Getter
-@Setter
+@Data
public class Film {
+ private Integer id;
+ @NotBlank
+ private String name;
+ private String description;
+ @NotNull
+ private LocalDate releaseDate;
+ @Min(1)
+ private int duration;
}
diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/User.java b/src/main/java/ru/yandex/practicum/filmorate/model/User.java
new file mode 100644
index 0000000..0060c62
--- /dev/null
+++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java
@@ -0,0 +1,14 @@
+package ru.yandex.practicum.filmorate.model;
+
+import lombok.Data;
+
+import java.time.LocalDate;
+
+@Data
+public class User {
+ private Integer id;
+ private String email;
+ private String login;
+ private String name;
+ private LocalDate birthday;
+}
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 8b13789..4c00e40 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1 +1 @@
-
+server.port=8080
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..7bb1ead
--- /dev/null
+++ b/src/test/java/ru/yandex/practicum/filmorate/controller/FilmControllerTest.java
@@ -0,0 +1,35 @@
+package ru.yandex.practicum.filmorate.controller;
+
+import jakarta.validation.ValidationException;
+import org.junit.jupiter.api.Test;
+import ru.yandex.practicum.filmorate.model.Film;
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.time.LocalDate;
+
+public class FilmControllerTest {
+
+ FilmController filmController = new FilmController();
+
+ @Test
+ void getFilmTest() {
+ Film film = new Film();
+ film.setReleaseDate(LocalDate.now());
+ film.setDuration(100);
+ film.setName("test");
+ film.setDescription("t");
+ filmController.create(film);
+ film.setName(" ");
+ assertThrows(ValidationException.class, () -> filmController.update(film));
+ film.setName("test");
+ String description200 = "A".repeat(200);
+ film.setDescription(film.getDescription() + description200);
+ assertThrows(ValidationException.class, () -> filmController.update(film));
+ film.setDescription("t");
+ film.setReleaseDate(LocalDate.of(1895, 12, 27));
+ assertThrows(ValidationException.class, () -> filmController.update(film));
+ film.setReleaseDate(LocalDate.now());
+ film.setDuration(0);
+ assertThrows(ValidationException.class, () -> filmController.update(film));
+ }
+}
\ 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..f2af4a7
--- /dev/null
+++ b/src/test/java/ru/yandex/practicum/filmorate/controller/UserControllerTest.java
@@ -0,0 +1,35 @@
+package ru.yandex.practicum.filmorate.controller;
+
+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 static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class UserControllerTest {
+ UserController userController = new UserController();
+
+ @Test
+ void getFilmTest() {
+ User user = new User();
+ user.setName("test1");
+ user.setLogin("test2");
+ user.setBirthday(LocalDate.of(2000, 12, 27));
+ user.setEmail("test@");
+ userController.create(user);
+ user.setEmail(" ");
+ assertThrows(ValidationException.class, () -> userController.update(user));
+ user.setEmail("test2@");
+ user.setLogin("TEST ETS");
+ assertThrows(ValidationException.class, () -> userController.update(user));
+ user.setLogin("test2");
+ user.setName(" ");
+ userController.update(user);
+ assertEquals(user.getLogin(), user.getName(), "Имя совпадает с логином");
+ user.setBirthday(LocalDate.of(2200, 12, 27));
+ assertThrows(ValidationException.class, () -> userController.update(user));
+ }
+}
\ No newline at end of file