diff --git a/pom.xml b/pom.xml index 8439ff4..7cd7b4c 100644 --- a/pom.xml +++ b/pom.xml @@ -43,6 +43,12 @@ org.slf4j slf4j-api + + + org.zalando + logbook-spring-boot-starter + 3.7.2 + diff --git a/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java b/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java index e55e710..8f860a2 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java +++ b/src/main/java/ru/yandex/practicum/filmorate/FilmorateApplication.java @@ -8,4 +8,4 @@ public class FilmorateApplication { public static void main(String[] args) { SpringApplication.run(FilmorateApplication.class, args); } -} +} \ No newline at end of file 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..aaf6f71 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/ErrorHandler.java @@ -0,0 +1,31 @@ +package ru.yandex.practicum.filmorate.controller; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import ru.yandex.practicum.filmorate.exception.NotFoundException; +import ru.yandex.practicum.filmorate.exception.ValidationException; +import ru.yandex.practicum.filmorate.model.ErrorResponse; + +@RestControllerAdvice +public class ErrorHandler { + + @ExceptionHandler + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ErrorResponse handleValidationException(final ValidationException e) { + return new ErrorResponse(e.getMessage()); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.NOT_FOUND) + public ErrorResponse handleNotFoundException(final NotFoundException e) { + return new ErrorResponse(e.getMessage()); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public ErrorResponse handleAllOtherExceptions(Throwable e) { + return new ErrorResponse(e.getMessage()); + } +} \ No newline at end of file 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 4116f66..6f50e3c 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -1,85 +1,67 @@ package ru.yandex.practicum.filmorate.controller; -import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.model.Film; -import jakarta.validation.ValidationException; +import ru.yandex.practicum.filmorate.service.FilmService; +import ru.yandex.practicum.filmorate.storage.FilmStorage; -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<>(); + private final FilmStorage inMemoryFilmStorage; + private final FilmService filmService; + + @Autowired + public FilmController(FilmStorage inMemoryFilmStorage, FilmService filmService) { + this.inMemoryFilmStorage = inMemoryFilmStorage; + this.filmService = filmService; + } @GetMapping public Collection findAll() { log.info("Список фильмов выведен"); - return films.values(); + return inMemoryFilmStorage.findAll(); + } + + @GetMapping("/{id}") + public Film findById(@PathVariable("id") int filmId) { + log.info("Фильм с id: {} выведен", filmId); + return inMemoryFilmStorage.findFilmById(filmId); } - private int getNextId() { - int currentMaxId = films.keySet() - .stream() - .mapToInt(id -> id) - .max() - .orElse(0); - return ++currentMaxId; + @GetMapping("/popular") + public Collection getPopular(@RequestParam(defaultValue = "10") int count) { + log.info("Список популярных фильмов выведен"); + return filmService.getPopular(count); } @PostMapping - public Film create(@Valid @RequestBody Film film) { - validateFilm(film); - film.setId(getNextId()); - films.put(film.getId(), film); + public Film create(@RequestBody Film film) { log.info("Фильм: {} добавлен в базу", film); - return film; + return inMemoryFilmStorage.create(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; + public Film update(@RequestBody Film newFilm) { + log.info("Данные о фильме: {} обновлены", newFilm); + return inMemoryFilmStorage.update(newFilm); } - 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("Название не может быть пустым"); - } + @PutMapping("/{id}/like/{userId}") + public void addLike(@PathVariable int id, @PathVariable int userId) { + log.info("Фильму с id: {} поставил лайк пользователь с id: {}", id, userId); + filmService.addLike(id, userId); + } - if (film.getDuration() < 1) { - log.warn("Ошибка длительности"); - throw new ValidationException("Длительность не может быть меньше 1"); - } + @DeleteMapping("/{id}/like/{userId}") + public void deleteLike(@PathVariable int id, @PathVariable int userId) { + log.info("У фильма с id: {} убрал лайк пользователь с id: {}", id, userId); + filmService.deleteLike(id, userId); } } \ 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 915a2df..c134492 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -2,81 +2,70 @@ 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 ru.yandex.practicum.filmorate.service.UserService; +import ru.yandex.practicum.filmorate.storage.InMemoryUserStorage; -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<>(); + private final InMemoryUserStorage inMemoryUserStorage; + private final UserService userService; + + public UserController(InMemoryUserStorage inMemoryUserStorage, UserService userService) { + this.inMemoryUserStorage = inMemoryUserStorage; + this.userService = userService; + } @GetMapping public Collection findAll() { - log.info("Список фильмов выведен"); - return users.values(); + log.info("Список пользователей выведен"); + return inMemoryUserStorage.findAll(); + } + + @GetMapping("/{id}") + public User findUserById(@PathVariable("id") int userId) { + log.info("Пользователь с id: {} выведен", userId); + return inMemoryUserStorage.findUserById(userId); } - private int getNextId() { - int currentMaxId = users.keySet() - .stream() - .mapToInt(id -> id) - .max() - .orElse(0); - return ++currentMaxId; + @GetMapping("/{id}/friends") + public Collection findAllFriends(@PathVariable("id") int userId) { + log.info("Список друзей пользователя с id: {} выведен", userId); + return userService.getFriendList(userId); + } + + @GetMapping("/{id}/friends/common/{otherId}") + public Collection findAllCommonFriends(@PathVariable int id, @PathVariable int otherId) { + log.info("Список общих друзей пользователей с id: {} и {} выведен", id, otherId); + return userService.getCommonFriendList(id, otherId); } @PostMapping public User create(@RequestBody User user) { - validateUser(user); - user.setId(getNextId()); - users.put(user.getId(), user); - log.info("Пользователь: {} добавлен в базу", user); - return user; + log.info("Пользоввтель: {} создан и добавлен", user); + return inMemoryUserStorage.create(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; + log.info("Данные о пользователе: {} обновлены", newUser); + return inMemoryUserStorage.update(newUser); + } + + @PutMapping("/{id}/friends/{friendId}") + public void addFriend(@PathVariable("id") int userId, @PathVariable int friendId) { + log.info("Пользователь с id: {} добавил пользователя с id: {} в друзья", userId, friendId); + userService.addFriend(userId, friendId); } - 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()); - } + @DeleteMapping("/{id}/friends/{friendId}") + public void deleteFriend(@PathVariable("id") int userId, @PathVariable int friendId) { + log.info("Пользователь с id: {} удалил пользователя с id: {} из друзей", userId, friendId); + userService.deleteFriend(userId, friendId); } } \ No newline at end of file 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..82e3f72 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.java @@ -0,0 +1,7 @@ +package ru.yandex.practicum.filmorate.exception; + +public class NotFoundException extends RuntimeException { + public NotFoundException(String message) { + super(message); + } +} \ 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 index 52dc49c..532f9bd 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java +++ b/src/main/java/ru/yandex/practicum/filmorate/exception/ValidationException.java @@ -4,4 +4,4 @@ public class ValidationException extends RuntimeException { public ValidationException(String message) { super(message); } -} +} \ No newline at end of file diff --git a/src/main/java/ru/yandex/practicum/filmorate/model/ErrorResponse.java b/src/main/java/ru/yandex/practicum/filmorate/model/ErrorResponse.java new file mode 100644 index 0000000..6a9e1f5 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/model/ErrorResponse.java @@ -0,0 +1,13 @@ +package ru.yandex.practicum.filmorate.model; + +public class ErrorResponse { + String error; + + public ErrorResponse(String error) { + this.error = error; + } + + public String getError() { + return error; + } +} \ No newline at end of file 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 b9e156e..6fbe6f5 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -1,11 +1,10 @@ package ru.yandex.practicum.filmorate.model; -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import lombok.Data; import java.time.LocalDate; +import java.util.HashSet; +import java.util.Set; /** * Film. @@ -13,11 +12,13 @@ @Data public class Film { private Integer id; - @NotBlank private String name; private String description; - @NotNull private LocalDate releaseDate; - @Min(1) private int duration; -} + private Set likes = new HashSet<>(); + + public int getRating() { + return likes.size(); + } +} \ 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 index 0060c62..e06c2d7 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/User.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -3,6 +3,8 @@ import lombok.Data; import java.time.LocalDate; +import java.util.HashSet; +import java.util.Set; @Data public class User { @@ -11,4 +13,5 @@ public class User { private String login; private String name; private LocalDate birthday; + private Set friends = new HashSet<>(); } \ 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 new file mode 100644 index 0000000..4ea7853 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java @@ -0,0 +1,58 @@ +package ru.yandex.practicum.filmorate.service; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +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.UserStorage; + +import java.util.Collection; +import java.util.Comparator; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class FilmService { + + private final FilmStorage filmStorage; + private final UserStorage userStorage; + + @Autowired + public FilmService(@Qualifier("inMemoryFilmStorage") FilmStorage filmStorage, + @Qualifier("inMemoryUserStorage") UserStorage userStorage) { + this.filmStorage = filmStorage; + this.userStorage = userStorage; + } + + public void addLike(int id, int userId) { + Film film = filmStorage.findFilmById(id); + userStorage.findUserById(userId); + if (film.getLikes().contains(userId)) { + log.warn("Ошибка добавления лайка"); + throw new ValidationException("Лайк от этого пользователя уже стоит"); + } + film.getLikes().add(userId); + } + + public void deleteLike(int id, int userId) { + Film film = filmStorage.findFilmById(id); + userStorage.findUserById(userId); + if (!film.getLikes().contains(userId)) { + log.warn("Ошибка удаления лайка"); + throw new ValidationException("У фильма нет лайка от этого пользователя"); + } + film.getLikes().remove(userId); + } + + public Collection getPopular(int count) { + return filmStorage.findAll().stream() + .sorted(comparator) + .limit(count) + .collect(Collectors.toList()); + } + + public static final Comparator comparator = Comparator.comparingInt(Film::getRating).reversed(); +} \ No newline at end of file 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..e03525e --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java @@ -0,0 +1,70 @@ +package ru.yandex.practicum.filmorate.service; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +import ru.yandex.practicum.filmorate.exception.ValidationException; +import ru.yandex.practicum.filmorate.model.User; +import ru.yandex.practicum.filmorate.storage.UserStorage; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Slf4j +@Service +public class UserService { + + private final UserStorage userStorage; + + public UserService(@Qualifier("inMemoryUserStorage") UserStorage userStorage) { + this.userStorage = userStorage; + } + + public void addFriend(int userId, int friendId) { + if (userId == friendId) { + log.warn("Ошибка добавления в друзья"); + throw new ValidationException("Пользователь не может добавить сам себя в друзья"); + } + User user = userStorage.findUserById(userId); + User usersFriend = userStorage.findUserById(friendId); + if (user.getFriends().contains(friendId)) { + log.warn("Ошибка добавления в друзья"); + throw new ValidationException("Пользователь уже добавлен в друзья"); + } + user.getFriends().add(friendId); + usersFriend.getFriends().add(userId); + } + + public void deleteFriend(int userId, int friendId) { + if (userId == friendId) { + log.warn("Ошибка удаления из друзей"); + throw new ValidationException("Пользователь не может удалить сам себя"); + } + User user = userStorage.findUserById(userId); + User usersFriend = userStorage.findUserById(friendId); + user.getFriends().remove(friendId); + usersFriend.getFriends().remove(userId); + } + + public Collection getFriendList(int userId) { + User user = userStorage.findUserById(userId); + List list = new ArrayList<>(); + for (Integer id : user.getFriends()) { + list.add(userStorage.findUserById(id)); + } + return list; + } + + public Collection getCommonFriendList(int id, int otherId) { + User user1 = userStorage.findUserById(id); + User user2 = userStorage.findUserById(otherId); + List list = new ArrayList<>(); + for (Integer userid : user1.getFriends()) { + if (user2.getFriends().contains(userid)) { + list.add(userStorage.findUserById(userid)); + } + } + return list; + } +} \ No newline at end of file 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..0b380f8 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java @@ -0,0 +1,16 @@ +package ru.yandex.practicum.filmorate.storage; + +import ru.yandex.practicum.filmorate.model.Film; + +import java.util.Collection; + +public interface FilmStorage { + + Collection findAll(); + + Film create(Film film); + + Film update(Film newFilm); + + Film findFilmById(int id); +} \ No newline at end of file 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..b6b340a --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java @@ -0,0 +1,87 @@ +package ru.yandex.practicum.filmorate.storage; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import ru.yandex.practicum.filmorate.exception.ValidationException; +import ru.yandex.practicum.filmorate.exception.NotFoundException; +import ru.yandex.practicum.filmorate.model.Film; + +import java.time.LocalDate; +import java.util.*; + +@Slf4j +@Component("inMemoryFilmStorage") +public class InMemoryFilmStorage implements FilmStorage { + + private final Map films = new HashMap<>(); + + @Override + public Collection findAll() { + return films.values(); + } + + @Override + public Film create(Film film) { + validateFilm(film); + film.setId(getNextId()); + films.put(film.getId(), film); + return film; + } + + @Override + public Film update(Film newFilm) { + if (newFilm.getId() == null) { + log.warn("Не указан id"); + throw new ValidationException("Id должен быть указан"); + } + if (!films.containsKey(newFilm.getId())) { + log.warn("Фильм с указанным id не найден"); + throw new NotFoundException("Фильм с 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()); + return oldFilm; + } + + @Override + public Film findFilmById(int id) { + if (!films.containsKey(id)) { + throw new NotFoundException("Фильма с таким id не найдено"); + } + return films.get(id); + } + + private int getNextId() { + int currentMaxId = films.keySet() + .stream() + .mapToInt(id -> id) + .max() + .orElse(0); + return ++currentMaxId; + } + + private void validateFilm(Film film) { + if (film.getDescription() != null && 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/storage/InMemoryUserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java new file mode 100644 index 0000000..d9468af --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java @@ -0,0 +1,87 @@ +package ru.yandex.practicum.filmorate.storage; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +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; + +@Slf4j +@Component("inMemoryUserStorage") +public class InMemoryUserStorage implements UserStorage { + + private final Map users = new HashMap<>(); + + @Override + public Collection findAll() { + return users.values(); + } + + @Override + public User create(User user) { + validateUser(user); + user.setId(getNextId()); + users.put(user.getId(), user); + return user; + } + + @Override + public User update(User newUser) { + if (newUser.getId() == null) { + log.warn("Не указан id"); + throw new ValidationException("Id должен быть указан"); + } + if (!users.containsKey(newUser.getId())) { + log.warn("Пользователь с указанным id не найден"); + throw new NotFoundException("Пользователь с 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()); + return oldUser; + } + + private int getNextId() { + int currentMaxId = users.keySet() + .stream() + .mapToInt(id -> id) + .max() + .orElse(0); + return ++currentMaxId; + } + + public User findUserById(int userId) { + if (!users.containsKey(userId)) { + log.warn("Пользователь не найден"); + throw new NotFoundException("Пользователя с таким id не найдено"); + } + return users.get(userId); + } + + 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/storage/UserStorage.java b/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java new file mode 100644 index 0000000..04935d0 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java @@ -0,0 +1,16 @@ +package ru.yandex.practicum.filmorate.storage; + +import ru.yandex.practicum.filmorate.model.User; + +import java.util.Collection; + +public interface UserStorage { + + Collection findAll(); + + User create(User user); + + User update(User newUser); + + User findUserById(int id); +} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4c00e40..4a23bbc 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,2 @@ server.port=8080 +logging.level.org.zalando.logbook=TRACE \ 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/InMemoryFilmStorageTest.java similarity index 54% rename from src/test/java/ru/yandex/practicum/filmorate/controller/FilmControllerTest.java rename to src/test/java/ru/yandex/practicum/filmorate/controller/InMemoryFilmStorageTest.java index 7bb1ead..875d090 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/controller/FilmControllerTest.java +++ b/src/test/java/ru/yandex/practicum/filmorate/controller/InMemoryFilmStorageTest.java @@ -1,15 +1,16 @@ package ru.yandex.practicum.filmorate.controller; -import jakarta.validation.ValidationException; import org.junit.jupiter.api.Test; +import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.storage.InMemoryFilmStorage; + import static org.junit.jupiter.api.Assertions.*; import java.time.LocalDate; -public class FilmControllerTest { - - FilmController filmController = new FilmController(); +public class InMemoryFilmStorageTest { + InMemoryFilmStorage inMemoryFilmStorage = new InMemoryFilmStorage(); @Test void getFilmTest() { @@ -18,18 +19,18 @@ void getFilmTest() { film.setDuration(100); film.setName("test"); film.setDescription("t"); - filmController.create(film); + inMemoryFilmStorage.create(film); film.setName(" "); - assertThrows(ValidationException.class, () -> filmController.update(film)); + assertThrows(ValidationException.class, () -> inMemoryFilmStorage.update(film)); film.setName("test"); String description200 = "A".repeat(200); film.setDescription(film.getDescription() + description200); - assertThrows(ValidationException.class, () -> filmController.update(film)); + assertThrows(ValidationException.class, () -> inMemoryFilmStorage.update(film)); film.setDescription("t"); film.setReleaseDate(LocalDate.of(1895, 12, 27)); - assertThrows(ValidationException.class, () -> filmController.update(film)); + assertThrows(ValidationException.class, () -> inMemoryFilmStorage.update(film)); film.setReleaseDate(LocalDate.now()); film.setDuration(0); - assertThrows(ValidationException.class, () -> filmController.update(film)); + assertThrows(ValidationException.class, () -> inMemoryFilmStorage.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/InMemoryUserStorageTest.java similarity index 62% rename from src/test/java/ru/yandex/practicum/filmorate/controller/UserControllerTest.java rename to src/test/java/ru/yandex/practicum/filmorate/controller/InMemoryUserStorageTest.java index f2af4a7..3174a9a 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/controller/UserControllerTest.java +++ b/src/test/java/ru/yandex/practicum/filmorate/controller/InMemoryUserStorageTest.java @@ -3,14 +3,15 @@ import org.junit.jupiter.api.Test; import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.User; +import ru.yandex.practicum.filmorate.storage.InMemoryUserStorage; 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(); +public class InMemoryUserStorageTest { + InMemoryUserStorage inMemoryUserStorage = new InMemoryUserStorage(); @Test void getFilmTest() { @@ -19,17 +20,17 @@ void getFilmTest() { user.setLogin("test2"); user.setBirthday(LocalDate.of(2000, 12, 27)); user.setEmail("test@"); - userController.create(user); + inMemoryUserStorage.create(user); user.setEmail(" "); - assertThrows(ValidationException.class, () -> userController.update(user)); + assertThrows(ValidationException.class, () -> inMemoryUserStorage.update(user)); user.setEmail("test2@"); user.setLogin("TEST ETS"); - assertThrows(ValidationException.class, () -> userController.update(user)); + assertThrows(ValidationException.class, () -> inMemoryUserStorage.update(user)); user.setLogin("test2"); user.setName(" "); - userController.update(user); + inMemoryUserStorage.update(user); assertEquals(user.getLogin(), user.getName(), "Имя совпадает с логином"); user.setBirthday(LocalDate.of(2200, 12, 27)); - assertThrows(ValidationException.class, () -> userController.update(user)); + assertThrows(ValidationException.class, () -> inMemoryUserStorage.update(user)); } } \ No newline at end of file