diff --git a/pom.xml b/pom.xml
index 0cad031..9522a8a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,6 +22,11 @@
spring-boot-starter-web
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
org.projectlombok
lombok
diff --git a/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java b/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java
index dca451b..843905e 100644
--- a/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java
+++ b/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java
@@ -5,8 +5,8 @@
@SpringBootApplication
public class FilmorateApplication {
- public static void main(String[] args) {
- SpringApplication.run(FilmorateApplication.class, args);
- }
+ 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..752734a 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,65 @@
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.exception.ValidationException;
+import ru.yandex.practicum.filmorate.model.Film;
+
+import java.time.LocalDate;
+import java.time.Month;
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
@RestController
+@RequestMapping("/films")
+@Slf4j
public class FilmController {
+ private final Map films = new ConcurrentHashMap<>();
+ private int nextId = 1;
+
+ @GetMapping
+ public Collection getFilms() {
+ return films.values();
+ }
+
+
+ @PostMapping
+ public Film createFilm(@Valid @RequestBody Film film) throws ValidationException {
+ LocalDate date = LocalDate.of(1895, Month.DECEMBER, 28);
+ if (film.getName() == null || film.getName().isEmpty()) {
+ throw new ValidationException("Название фильма не может быть пустым");
+ }
+ if (film.getDescription() == null || film.getDescription().length() > 200) {
+ throw new ValidationException("Максимальная длина описания — 200 символов");
+ }
+ if (film.getReleaseDate().isBefore(date)) {
+ throw new ValidationException("Дата релиза — не раньше 28 декабря 1895 года");
+ }
+ if (film.getDuration() <= 0) {
+ throw new ValidationException("Продолжительность фильма должна быть положительным числом");
+ }
+ film.setId(getNextId());
+ films.put(film.getId(), film);
+ log.debug("Фильм успешно добавлен");
+ return film;
+
+ }
+
+ @PutMapping
+ public Film updateFilm(@RequestBody Film newFilm) throws ValidationException {
+
+ if (newFilm.getId() != null && films.containsKey(newFilm.getId())) {
+ films.put(newFilm.getId(), newFilm);
+ log.debug("Фильм успешно изменён");
+ return newFilm;
+ }
+ throw new ValidationException("Некорректный Id");
+ }
+
+ private int getNextId() {
+ return nextId++;
+
+ }
}
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..3d67a63
--- /dev/null
+++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java
@@ -0,0 +1,63 @@
+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.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@RestController
+@RequestMapping("/users")
+@Slf4j
+public class UserController {
+ private final Map users = new ConcurrentHashMap<>();
+ private int nextId = 1;
+
+ @GetMapping
+ public Collection getUsers() {
+ return users.values();
+ }
+
+ @PostMapping
+ public User createUser(@RequestBody User user) throws ValidationException {
+ if (user.getEmail().isEmpty() || !user.getEmail().contains("@")) {
+ throw new ValidationException("Электронная почта не может быть пустой и должна содержать символ @");
+ }
+ if (user.getLogin() == null || user.getLogin().isEmpty() || user.getLogin().contains(" ")) {
+ throw new ValidationException("Логин не может быть пустым и содержать пробелы");
+ }
+ if (user.getName() == null) {
+ user.setName(user.getLogin());
+ }
+ if (user.getBirthday().isAfter(LocalDate.now())) {
+ throw new ValidationException("Дата рождения не может быть в будущем");
+ }
+ user.setId(getNextId());
+ users.put(user.getId(), user);
+ log.debug("Пользователь успешно добавлен");
+ return user;
+ }
+
+ @PutMapping
+ public User updateUser(@RequestBody User newUser) throws ValidationException {
+
+ if (newUser.getId() != null && users.containsKey(newUser.getId())) {
+ users.put(newUser.getId(), newUser);
+ log.debug("Пользователь успешно изменён");
+ return newUser;
+ }
+
+ throw new ValidationException("Некорректный Id");
+
+ }
+
+
+ private int getNextId() {
+ return nextId++;
+
+ }
+}
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..fd0100a
--- /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 Exception {
+ 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..8063357 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,22 @@
package ru.yandex.practicum.filmorate.model;
import lombok.Getter;
+import lombok.NoArgsConstructor;
import lombok.Setter;
+import java.time.LocalDate;
+
/**
* Film.
*/
@Getter
@Setter
+@NoArgsConstructor
public class Film {
+ private Integer id;
+ private String name;
+ private String description;
+ private LocalDate releaseDate;
+ private Long 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..a489737
--- /dev/null
+++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java
@@ -0,0 +1,19 @@
+package ru.yandex.practicum.filmorate.model;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.time.LocalDate;
+
+@Getter
+@Setter
+@NoArgsConstructor
+public class User {
+ private Integer id;
+ private String email;
+ private String login;
+ private String name;
+ private LocalDate birthday;
+
+}
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..af87af4
--- /dev/null
+++ b/src/test/java/ru/yandex/practicum/filmorate/controller/FilmControllerTest.java
@@ -0,0 +1,89 @@
+package ru.yandex.practicum.filmorate.controller;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import ru.yandex.practicum.filmorate.exception.ValidationException;
+import ru.yandex.practicum.filmorate.model.Film;
+
+import java.time.LocalDate;
+import java.util.Collection;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@SpringBootTest
+public class FilmControllerTest {
+
+ @Autowired
+ private FilmController filmController;
+
+ @Test
+ public void returnFilmsTest() throws ValidationException {
+ Film film1 = new Film();
+ film1.setName("filmName1");
+ film1.setDescription("Descr1");
+ film1.setReleaseDate(LocalDate.of(2023, 12, 15));
+ film1.setDuration(168L);
+
+ Film film2 = new Film();
+ film2.setName("filmName2");
+ film2.setDescription("Descr2");
+ film2.setReleaseDate(LocalDate.of(2023, 12, 15));
+ film2.setDuration(168L);
+
+ filmController.createFilm(film1);
+ filmController.createFilm(film2);
+
+ Collection films = filmController.getFilms();
+
+ assertTrue(films.contains(film1));
+ assertTrue(films.contains(film2));
+ }
+
+ @Test
+ void filmsValidTest() throws ValidationException {
+ Film film = new Film();
+ film.setName("filmName1");
+ film.setDescription("Descr1");
+ film.setReleaseDate(LocalDate.of(2023, 12, 15));
+ film.setDuration(168L);
+
+ Film savedFilm = filmController.createFilm(film);
+
+ assertNotNull(savedFilm.getId());
+ assertEquals("filmName1", savedFilm.getName());
+ assertEquals("Descr1", savedFilm.getDescription());
+ assertEquals(LocalDate.of(2023, 12, 15), savedFilm.getReleaseDate());
+ assertEquals(168L, savedFilm.getDuration());
+
+ film.setName(null);
+ assertThrows(ValidationException.class, () -> filmController.createFilm(film));
+
+ film.setName("filmName1");
+ film.setDescription("1111111111111111111111111111111111111111111111111111111111111111111" + "111111111111111111111111111111111111111111111111111111111111111111111111111111111" + "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
+ assertThrows(ValidationException.class, () -> filmController.createFilm(film));
+
+ film.setDescription("Descr1");
+ film.setReleaseDate(LocalDate.of(1894, 12, 15));
+ assertThrows(ValidationException.class, () -> filmController.createFilm(film));
+
+ film.setReleaseDate(LocalDate.of(2023, 12, 15));
+ film.setDuration(-1L);
+ assertThrows(ValidationException.class, () -> filmController.createFilm(film));
+ }
+
+ @Test
+ void updateFilmTest() throws ValidationException {
+ Film film = new Film();
+ film.setName("filmName1");
+ film.setDescription("Descr1");
+ film.setReleaseDate(LocalDate.of(2023, 12, 15));
+ film.setDuration(168L);
+
+ filmController.createFilm(film);
+
+ Film filmUpdate = new Film();
+ filmUpdate.setId(8);
+ assertThrows(ValidationException.class, () -> filmController.updateFilm(filmUpdate));
+ }
+}
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..8f40a1a
--- /dev/null
+++ b/src/test/java/ru/yandex/practicum/filmorate/controller/UserControllerTest.java
@@ -0,0 +1,99 @@
+package ru.yandex.practicum.filmorate.controller;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import ru.yandex.practicum.filmorate.exception.ValidationException;
+import ru.yandex.practicum.filmorate.model.User;
+
+import java.time.LocalDate;
+import java.util.Collection;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+
+@SpringBootTest
+public class UserControllerTest {
+
+
+ @Autowired
+ private UserController userController = new UserController();
+
+ @Test
+ public void returnsUsersTest() throws ValidationException {
+ User user1 = new User();
+ user1.setEmail("user1@yandex.ru");
+ user1.setLogin("user1");
+ user1.setName("User1");
+ user1.setBirthday(LocalDate.of(1999, 8, 6));
+
+ User user2 = new User();
+ user2.setEmail("user2@yandex.ru");
+ user2.setLogin("user2");
+ user2.setName("User2");
+ user2.setBirthday(LocalDate.of(1991, 3, 20));
+
+ userController.createUser(user1);
+ userController.createUser(user2);
+
+ Collection users = userController.getUsers();
+
+ assertTrue(users.contains(user1));
+ assertTrue(users.contains(user2));
+ }
+
+ @Test
+ void userValidTest() throws ValidationException {
+ User user = new User();
+ user.setEmail("user1@yandex.ru");
+ user.setLogin("user1");
+ user.setName("user1");
+ user.setBirthday(LocalDate.of(1999, 8, 6));
+
+ User savedUser1 = userController.createUser(user);
+
+ assertNotNull(savedUser1.getId());
+ assertEquals("user1@yandex.ru", savedUser1.getEmail());
+ assertEquals("user1", savedUser1.getLogin());
+ assertEquals("user1", savedUser1.getName());
+ assertEquals(LocalDate.of(1999, 8, 6), savedUser1.getBirthday());
+
+ user.setEmail("12345");
+ assertThrows(ValidationException.class, () -> userController.createUser(user));
+
+ user.setEmail("user3.com");
+ assertThrows(ValidationException.class, () -> userController.createUser(user));
+
+ user.setEmail("user1@yandex.ru");
+ user.setLogin("");
+ assertThrows(ValidationException.class, () -> userController.createUser(user));
+
+ user.setLogin(null);
+ assertThrows(ValidationException.class, () -> userController.createUser(user));
+
+ user.setLogin("user 1");
+ assertThrows(ValidationException.class, () -> userController.createUser(user));
+
+ user.setBirthday(LocalDate.now().plusMonths(5));
+ assertThrows(ValidationException.class, () -> userController.createUser(user));
+ }
+
+ @Test
+ void updateUserTest() throws ValidationException {
+ User user1 = new User();
+ user1.setEmail("user1@yandex.ru");
+ user1.setLogin("user1");
+ user1.setName(null);
+ user1.setBirthday(LocalDate.of(1999, 8, 6));
+
+ userController.createUser(user1);
+
+ User userUpdate = new User();
+ userUpdate.setEmail("user1@yandex.ru");
+ userUpdate.setLogin("user1");
+ userUpdate.setName(null);
+ userUpdate.setBirthday(LocalDate.of(1999, 8, 6));
+ userUpdate.setId(8);
+ assertThrows(ValidationException.class, () -> userController.updateUser(userUpdate));
+ }
+}