From b10e528299f1bbe5fbcf3355c65ff1fd998741cf Mon Sep 17 00:00:00 2001 From: Sergey Filippovskikh Date: Fri, 17 Jan 2025 19:11:56 +0300 Subject: [PATCH 01/10] =?UTF-8?q?=D0=A1=D0=BF=D1=80=D0=B8=D0=BD=D1=82=2011?= =?UTF-8?q?.=20=D0=A0=D0=B5=D0=B9=D1=82=D0=B8=D0=BD=D0=B3=20=D0=A4=D0=B8?= =?UTF-8?q?=D0=BB=D1=8C=D0=BC=D0=BE=D0=B2.=20=D0=9F=D0=B5=D1=80=D0=B2?= =?UTF-8?q?=D1=8B=D0=B9=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B8=D1=82.=20=D0=A1?= =?UTF-8?q?=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B2=D0=B5=D1=82?= =?UTF-8?q?=D0=BA=D0=B8.=20=D0=9F=D0=B5=D1=80=D0=B2=D0=B8=D1=87=D0=BD?= =?UTF-8?q?=D1=8B=D0=B9=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D1=83.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +- pom.xml | 6 + .../filmorate/FilmorateApplication.java | 6 +- .../filmorate/controller/ErrorHandler.java | 64 +++++++ .../filmorate/controller/FilmController.java | 99 +++++------ .../filmorate/controller/UserController.java | 118 ++++++------- .../exception/NotFoundException.java | 7 + .../practicum/filmorate/model/Film.java | 28 +++- .../practicum/filmorate/model/User.java | 29 ++-- .../filmorate/service/FilmService.java | 91 ++++++++++ .../filmorate/service/UserService.java | 103 ++++++++++++ .../filmorate/storage/FilmStorage.java | 21 +++ .../storage/InMemoryFilmStorage.java | 85 ++++++++++ .../storage/InMemoryUserStorage.java | 98 +++++++++++ .../filmorate/storage/UserStorage.java | 21 +++ src/main/resources/application.properties | 2 +- .../filmorate/FilmControllerTest.java | 9 +- .../filmorate/FilmorateApplicationTests.java | 6 +- .../filmorate/UserControllerTest.java | 157 ++++++++---------- 19 files changed, 715 insertions(+), 239 deletions(-) create mode 100644 src/main/java/ru/yandex/practicum/filmorate/controller/ErrorHandler.java create mode 100644 src/main/java/ru/yandex/practicum/filmorate/exception/NotFoundException.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/README.md b/README.md index 74abbb1..9f00859 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ _java-filmorate_ # Рейтинг фильмов -### Согласно задания спринта № 10 +### Согласно задания спринта № 11 ## выполнено Филипповских Сергеем _**Когорта-53**_ + +в файле PostmanSprint11_add-friends-likes.json находится скрипт для проверки API diff --git a/pom.xml b/pom.xml index c8dd765..57fafc4 100644 --- a/pom.xml +++ b/pom.xml @@ -35,6 +35,12 @@ org.springframework.boot spring-boot-starter-validation + + org.zalando + logbook-spring-boot-starter + 3.9.0 + + 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/ErrorHandler.java b/src/main/java/ru/yandex/practicum/filmorate/controller/ErrorHandler.java new file mode 100644 index 0000000..5694d83 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/ErrorHandler.java @@ -0,0 +1,64 @@ +package ru.yandex.practicum.filmorate.controller; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.validation.BindingResult; +import org.springframework.validation.ObjectError; +import org.springframework.web.bind.MethodArgumentNotValidException; +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 java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +@Slf4j +@RestControllerAdvice +public class ErrorHandler { + @ExceptionHandler + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ErrorResponse handleValidationException(final ValidationException e) { + log.error(HttpStatus.BAD_REQUEST + " - " + e.getMessage()); + return new ErrorResponse(e.getMessage()); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ErrorResponse handleMethodArgumentNotValidException(final MethodArgumentNotValidException e) { + BindingResult bindingResult = e.getBindingResult(); + List allErrors = bindingResult.getAllErrors(); + String defaultMessage = allErrors.stream() + .map(error -> Objects.requireNonNull(error.getDefaultMessage())) + .collect(Collectors.joining(", ")); + log.error(HttpStatus.BAD_REQUEST + " - " + defaultMessage); + return new ErrorResponse(defaultMessage); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.NOT_FOUND) + public ErrorResponse handleNotFoundException(final NotFoundException e) { + log.error(HttpStatus.NOT_FOUND + " - " + e.getMessage()); + return new ErrorResponse(e.getMessage()); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public ErrorResponse handleRunTimeException(final RuntimeException e) { + log.error(HttpStatus.INTERNAL_SERVER_ERROR + " - " + e.getMessage()); + return new ErrorResponse(e.getMessage()); + } + + @Getter + private static class ErrorResponse { + private final String error; + + public ErrorResponse(String error) { + this.error = error; + } + + } +} \ 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 19ca717..a315256 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -2,79 +2,72 @@ import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -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; +import java.util.List; -@RestController @Slf4j +@Validated +@RestController @RequestMapping("/films") public class FilmController { - private final Map films = new HashMap<>(); + final private FilmService filmService; - // получаем список фильмов - @GetMapping - public Collection findAll() { - return films.values(); + @Autowired + public FilmController(FilmService filmService) { + this.filmService = filmService; } // добавляем фильм + @ResponseStatus(HttpStatus.CREATED) @PostMapping public Film create(@RequestBody @Valid Film film) { - // проверяем выполнение необходимых условий - checkFilm(film); - // формируем дополнительные данные - film.setId(getNextId()); - // сохраняем данные фильма - films.put(film.getId(), film); + filmService.create(film); return film; } - // вспомогательный метод для генерации идентификатора фильма - private long getNextId() { - long currentMaxId = films.keySet() - .stream() - .mapToLong(id -> id) - .max() - .orElse(0); - return ++currentMaxId; - } - // обновляем данные о фильме @PutMapping - public Film update(@RequestBody @Valid Film newFilm) { - // проверяем необходимые условия - if (newFilm.getId() == null) { - throw new ValidationException("Id фильма должен быть указан"); - } - if (films.containsKey(newFilm.getId())) { - checkFilm(newFilm); - // если фильм с таким id найден и все условия соблюдены, обновляем его содержимое - films.put(newFilm.getId(), newFilm); - return newFilm; - } - throw new ValidationException("Фильм с id = " + newFilm.getId() + " не найден"); + public Film update(@RequestBody @Valid Film film) { + filmService.update(film); + return film; + } + + // получаем список фильмов + @GetMapping + public List findAll() { + return filmService.findAll(); } - // вспомогательный метод для проверки условий фильма - private void checkFilm(Film newFilm) { - if (newFilm.getName() == null || newFilm.getName().isBlank()) { - throw new ValidationException("Название фильма не может быть пустым"); - } - if (newFilm.getDescription().length() > 200) { - throw new ValidationException("Максимальная длина описания фильма - 200 символов"); - } - if (newFilm.getDuration() < 1) { - throw new ValidationException("Продолжительность фильма должна быть больше 1 секунды"); - } - if (newFilm.getReleaseDate().isBefore(LocalDate.parse("1895-12-28"))) { - throw new ValidationException("Минимальная дата выхода фильма 28.12.1895"); - } + // Получаем фильм по id + @GetMapping("/{filmId}") + public Film getUserById(@PathVariable Integer filmId) { + return filmService.getById(filmId); } + + // Добавляем like пользователя userId к фильму filmId + @PutMapping("/{filmId}/like/{userId}") + public Film addLike(@PathVariable Integer filmId, @PathVariable Integer userId) { + filmService.addLike(filmId, userId); + return filmService.getById(filmId); + } + + // Удаляем like пользователя userId к фильму filmId + @DeleteMapping("/{filmId}/like/{userId}") + public Film deleteLike(@PathVariable Integer filmId, @PathVariable Integer userId) { + filmService.deleteLike(filmId, userId); + return filmService.getById(filmId); + } + + @GetMapping("/popular") + public List getlistBestFilms(@RequestParam(defaultValue = "10") Integer count) { + return filmService.listBestFilms(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 1ec812c..572367f 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -2,93 +2,79 @@ import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.validation.annotation.Validated; 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 java.time.LocalDate; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; +import java.util.List; -@RestController @Slf4j +@Validated +@RestController @RequestMapping("/users") public class UserController { - private final Map users = new HashMap<>(); + final private UserService userService; - //Получаем список всех пользователей - @GetMapping - public Collection findAll() { - return users.values(); + @Autowired + public UserController(UserService userService) { + this.userService = userService; } // Добавляем пользователя + @ResponseStatus(HttpStatus.CREATED) @PostMapping public User create(@RequestBody @Valid User user) { - // проверяем выполнение необходимых условий - if (users.values().stream() - .anyMatch(u -> u.getEmail().equals(user.getEmail()))) { - throw new ValidationException("Этот email уже используется"); - } - checkUser(user); - // формируем дополнительные данные - if (user.getName() == null || user.getName().isBlank()) { - user.setName(user.getLogin()); - } - user.setId(getNextId()); - // сохраняем нового пользователя - users.put(user.getId(), user); + userService.create(user); return user; } + // Обновляем данные пользователя + @PutMapping + public User update(@RequestBody @Valid User user) { + userService.update(user); + return user; + } - // вспомогательный метод для генерации идентификатора нового пользователя - private long getNextId() { - long currentMaxId = users.keySet() - .stream() - .mapToLong(id -> id) - .max() - .orElse(0); - return ++currentMaxId; + // Получаем список всех пользователей + @GetMapping + public List findAll() { + return userService.findAll(); } - // Обновляем данные пользователя - @PutMapping - public User update(@RequestBody @Valid User newUser) { - // проверяем необходимые условия - if (newUser.getId() == null) { - throw new ValidationException("Id пользователя должен быть указан"); - } - if (users.containsKey(newUser.getId())) { - User oldUser = users.get(newUser.getId()); - checkUser(newUser); - if (!oldUser.getEmail().equals(newUser.getEmail())) { - if (users.values().stream() - .anyMatch(u -> u.getEmail().equals(newUser.getEmail()))) { - throw new ValidationException("Этот email уже используется"); - } - } - if (newUser.getName() == null || newUser.getName().isBlank()) { - newUser.setName(newUser.getLogin()); - } - users.put(newUser.getId(), newUser); - return newUser; - } - throw new ValidationException("Пользователь с id = " + newUser.getId() + " не найден"); + // Получаем пользователя по id + @GetMapping("/{userId}") + public User getUserById(@PathVariable Integer userId) { + return userService.getById(userId); + } + + // Добавляем друга friendId для пользователя userId + @PutMapping("/{userId}/friends/{friendId}") + public User addFriend(@PathVariable Integer userId, @PathVariable Integer friendId) { + userService.addFriend(userId, friendId); + return userService.getById(userId); + } + + // Удаляем друга friendId у пользователя userId + @DeleteMapping("/{userId}/friends/{friendId}") + public User deleteFriend(@PathVariable Integer userId, @PathVariable Integer friendId) { + userService.deleteFriend(userId, friendId); + return userService.getById(userId); + } + + // Получаем список друзей пользователя userId + @GetMapping("/{userId}/friends") + public List getUserFriends(@PathVariable Integer userId) { + return userService.userFriends(userId); } - // вспомогательный метод для проверки данных условий пользователя - private void checkUser(User user) { - if (user.getEmail() == null || user.getEmail().isBlank() || !user.getEmail().contains("@")) { - throw new ValidationException("Email должен быть указан корректно"); - } - if (user.getLogin() == null || user.getLogin().isBlank() || user.getLogin().contains(" ")) { - throw new ValidationException("Логин должен быть задан и без пробелов"); - } - if (user.getBirthday().isAfter(LocalDate.now())) { - throw new ValidationException("День рождения не должен быть позже текущей даты"); - } + // Получаем общий список друзей пользователя userId и и пользователя otherUserId + @GetMapping("/{userId}/friends/common/{otherUserId}") + public List getCrossingFriends(@PathVariable Integer userId, @PathVariable Integer otherUserId) { + return userService.crossingFriends(userId, otherUserId); } + } 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/model/Film.java b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java index cc3b9b4..1c5b382 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/Film.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/Film.java @@ -1,29 +1,43 @@ package ru.yandex.practicum.filmorate.model; -import jakarta.validation.constraints.*; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.Data; -import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; import java.time.LocalDate; +import java.util.HashSet; +import java.util.Set; @Data @Slf4j -@EqualsAndHashCode(of = { "name", "releaseDate" }) public class Film { - private Long id; + private Integer id; + + private Set likes = new HashSet<>(); @NotNull(message = "Необходимо указать название фильма") - @NotBlank(message = "Необходимо указать название фильма") + @NotBlank(message = "Название фильма не может быть пустым") private String name; @Size(min = 1, max = 200, message = "Описание фильма должно быть от 1 до 200 символов") private String description; - @MinimumDate(message = "Некорректная дата выхода фильма") + @MinimumDate(message = "Фильм не может выйти в прокат ранее 28.12.1895") private LocalDate releaseDate; - @Min(value = 1, message = "Продолжительность фильма должна быть не меньше 1 секунды") @NotNull(message = "Необходимо указать продолжительность фильма") + @Min(value = 1, message = "Продолжительность фильма должна быть не меньше 1 секунды") private int duration; + + public void addLike(Integer id) { + likes.add(id); + } + + public void removeLike(Integer id) { + likes.remove(id); + } } 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 b30bd5e..71c1c8c 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/User.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -1,31 +1,40 @@ 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 jakarta.validation.constraints.*; import lombok.Data; -import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; import java.time.LocalDate; +import java.util.HashSet; +import java.util.Set; @Data @Slf4j -@EqualsAndHashCode(of = { "email", "login" }) public class User { - private Long id; + private Integer id; - @Email(message = "Некорректный email") + private Set friends = new HashSet<>(); + + @Email(message = "Укажите корректный email") @NotNull(message = "Необходимо указать email") + @NotBlank(message = "Email не может быть пустым") private String email; @NotNull(message = "Необходимо указать логин") - @NotBlank(message = "Необходимо указать логин") + @NotBlank(message = "Логин не может быть пустым") + @Pattern(regexp = "^[A-Za-z0-9]+$", message = "Логин может содержать только буквы и цифры без пробелов и спецсимволов") private String login; private String name; - @Past(message = "Некорректная дата рождения") + @PastOrPresent(message = "Дата рождения не должна находиться в будущем") private LocalDate birthday; + + public void addFriend(Integer id) { + friends.add(id); + } + + public void removeFriend(Integer id) { + friends.remove(id); + } } \ 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..3476e68 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java @@ -0,0 +1,91 @@ +package ru.yandex.practicum.filmorate.service; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +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 ru.yandex.practicum.filmorate.storage.InMemoryUserStorage; +import ru.yandex.practicum.filmorate.storage.UserStorage; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@Slf4j +public class FilmService implements FilmStorage { + private final FilmStorage filmStorage; + private final UserStorage userStorage; + + @Autowired + public FilmService(InMemoryFilmStorage filmStorage, InMemoryUserStorage userStorage) { + this.userStorage = userStorage; + this.filmStorage = filmStorage; + } + + // нашёл только такой способ совместить хранилище inMemoryFilmStorage и интерфейс FilmStorage + @Override + public Film create(Film film) { + return filmStorage.create(film); + } + + @Override + public Film update(Film film) { + return filmStorage.update(film); + } + + @Override + public Film getById(Integer id) { + return filmStorage.getById(id); + } + + @Override + public List findAll() { + return filmStorage.findAll(); + } + + // Ставим лайк фильму + public void addLike(Integer idFilm, Integer idUser) { + if (idFilm == null) { + throw new ValidationException("Не указан id фильма"); + } + if (idUser == null) { + throw new ValidationException("Не указан id пользователя"); + } + if (filmStorage.getById(idFilm) == null) { + throw new NotFoundException("Фильм с id = " + idFilm + " не найден"); + } + if (userStorage.getById(idUser) == null) { + throw new NotFoundException("Пользователь с id = " + idUser + " не найден"); + } + filmStorage.getById(idFilm).addLike(idUser); + } + + // Убираем лайк фильму + public void deleteLike(Integer idFilm, Integer idUser) { + if (idFilm == null) { + throw new ValidationException("Не указан id фильма"); + } + if (idUser == null) { + throw new ValidationException("Не указан id пользователя"); + } + if (filmStorage.getById(idFilm) == null) { + throw new NotFoundException("Фильм с id = " + idFilm + " не найден"); + } + if (userStorage.getById(idUser) == null) { + throw new NotFoundException("Пользователь с id = " + idUser + " не найден"); + } + filmStorage.getById(idFilm).removeLike(idUser); + } + + // Получаем список лучших фильмов + public List listBestFilms(int count) { + return filmStorage.findAll().stream(). + sorted((f1, f2) -> f2.getLikes().size() - f1.getLikes().size()) + .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..672c342 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java @@ -0,0 +1,103 @@ +package ru.yandex.practicum.filmorate.service; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; +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.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +@Slf4j +@Service +@Component +public class UserService implements UserStorage { + + private final UserStorage userStorage; + + @Autowired + public UserService(InMemoryUserStorage userStorage) { + this.userStorage = userStorage; + } + + // нашёл только такой способ совместить хранилище inMemoryUserStorage и интерфейс UserStorage + @Override + public User create(User user) { + + return userStorage.create(user); + } + + @Override + public User update(User user) { + return userStorage.update(user); + } + + @Override + public User getById(Integer id) { + return userStorage.getById(id); + } + + @Override + public List findAll() { + return userStorage.findAll(); + } + + // Добавляем друга в список друзей + public void addFriend(Integer idUser, Integer idFriend) { + if (idUser == idFriend) { + throw new ValidationException("Нельзя добавить себя в друзья"); + } + if (idUser == null || idFriend == null) { + throw new ValidationException("Не указаны id пользователя или его друга"); + } + if (userStorage.getById(idUser) == null) { + throw new NotFoundException("Пользователь с id = " + idUser + " не найден"); + } + if (userStorage.getById(idFriend) == null) { + throw new NotFoundException("Друг с id = " + idFriend + " не найден"); + } + userStorage.getById(idUser).addFriend(idFriend); + userStorage.getById(idFriend).addFriend(idUser); + } + + // Удаляем друга из списка друзей + public void deleteFriend(Integer idUser, Integer idFriend) { + if (idUser == null || idFriend == null) { + throw new ValidationException("Не указаны id пользователя или его друга"); + } + if (userStorage.getById(idUser) == null) { + throw new NotFoundException("Пользователь с id = " + idUser + " не найден"); + } + if (userStorage.getById(idFriend) == null) { + throw new NotFoundException("Друг с id = " + idFriend + " не найден"); + } + userStorage.getById(idUser).removeFriend(idFriend); + userStorage.getById(idFriend).removeFriend(idUser); + } + + // Получаем список друзей + public List userFriends(Integer idUser) { + User user = userStorage.getById(idUser); + return userStorage.findAll().stream() + .filter(u -> user.getFriends().contains(u.getId())) + .collect(Collectors.toList()); + } + + // Получаем общий список друзей + public List crossingFriends(Integer idUser, Integer idFriend) { + User user = userStorage.getById(idUser); + User friend = userStorage.getById(idFriend); + Set commonFriends = new HashSet<>(user.getFriends()); + commonFriends.retainAll(friend.getFriends()); + return userStorage.findAll().stream() + .filter(u -> commonFriends.contains(u.getId())) + .collect(Collectors.toList()); + } +} 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..7e575e9 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/FilmStorage.java @@ -0,0 +1,21 @@ +package ru.yandex.practicum.filmorate.storage; + +import ru.yandex.practicum.filmorate.model.Film; + +import java.util.List; + +public interface FilmStorage { + + // добавляем фильм + Film create(Film film); + + // обновляем данные о фильме + Film update(Film film); + + // Ищем фильм по его id + Film getById(Integer id); + + // получаем список фильмов + List findAll(); + +} 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..8a91add --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java @@ -0,0 +1,85 @@ +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.Film; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +@Slf4j +public class InMemoryFilmStorage implements FilmStorage { + + private final Map films = new HashMap<>(); + + // добавляем фильм + @Override + public Film create(Film film) { + // формируем дополнительные данные + film.setId(getNextId()); + // сохраняем данные фильма + films.put(film.getId(), film); + return film; + } + + // обновляем данные о фильме + @Override + public Film update(Film film) { + // проверяем необходимые условия + if (film.getId() == null) { + throw new ValidationException("Для изменения данных, Id фильма должен быть указан"); + } + if (films.containsKey(film.getId())) { + // если фильм с таким id найден и все условия соблюдены, обновляем его содержимое + films.put(film.getId(), film); + return film; + } + throw new NotFoundException("Фильм с id = " + film.getId() + " не найден"); + } + + // Ищем фильм по его id + @Override + public Film getById(Integer id) { + if (!films.containsKey(id)) { + throw new NotFoundException("Фильм с id " + id + " не найден"); + } + return films.get(id); + } + + // получаем список фильмов + @Override + public List findAll() { + return films.values().stream().toList(); + } + + // вспомогательный метод для генерации идентификатора фильма + private Integer getNextId() { + return films.keySet() + .stream() + .mapToInt(id -> id) + .max() + .orElse(0) + 1; + } + + /* + // вспомогательный метод для проверки условий фильма + private void checkFilm(Film newFilm) { + if (newFilm.getName() == null || newFilm.getName().isBlank()) { + throw new ValidationException("Название фильма не может быть пустым"); + } + if (newFilm.getDescription().length() > 200) { + throw new ValidationException("Максимальная длина описания фильма - 200 символов"); + } + if (newFilm.getDuration() < 1) { + throw new ValidationException("Продолжительность фильма должна быть больше 1 секунды"); + } + if (newFilm.getReleaseDate().isBefore(LocalDate.parse("1895-12-28"))) { + throw new ValidationException("Минимальная дата выхода фильма 28.12.1895"); + } + } + */ +} 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..19da329 --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java @@ -0,0 +1,98 @@ +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.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +@Slf4j +public class InMemoryUserStorage implements UserStorage { + + private final Map users = new HashMap<>(); + + // Добавляем пользователя + @Override + public User create(User user) { + // проверяем выполнение необходимых условий + if (users.values().stream() + .anyMatch(u -> u.getEmail().equals(user.getEmail()))) { + throw new ValidationException("Этот email уже кем-то используется"); + } + // формируем дополнительные данные + if (user.getName() == null || user.getName().isBlank()) { + user.setName(user.getLogin()); + } + user.setId(getNextId()); + // сохраняем нового пользователя + users.put(user.getId(), user); + return user; + } + + // Обновляем данные пользователя + @Override + public User update(User newUser) { + // проверяем необходимые условия + if (newUser.getId() == null) { + throw new ValidationException("Для изменения данных, Id пользователя должен быть указан"); + } + if (users.containsKey(newUser.getId())) { + User oldUser = users.get(newUser.getId()); + if (!oldUser.getEmail().equals(newUser.getEmail())) { + if (users.values().stream() + .anyMatch(u -> u.getEmail().equals(newUser.getEmail()))) { + throw new ValidationException("Этот email уже кем-то используется"); + } + } + if (newUser.getName() == null || newUser.getName().isBlank()) { + newUser.setName(newUser.getLogin()); + } + users.put(newUser.getId(), newUser); + return newUser; + } + throw new NotFoundException("Пользователь с id = " + newUser.getId() + " не найден"); + } + + // Ищем пользователя по его id + @Override + public User getById(Integer id) { + if (!users.containsKey(id)) { + throw new NotFoundException("Пользователь с id " + id + " не найден"); + } + return users.get(id); + } + + //Получаем список всех пользователей + @Override + public List findAll() { + return users.values().stream().toList(); + } + + // вспомогательный метод для генерации идентификатора нового пользователя + private Integer getNextId() { + return users.keySet().stream() + .mapToInt(id -> id) + .max() + .orElse(0) + 1; + } + + /* + // вспомогательный метод для проверки данных условий пользователя + private void checkUser(User user) { + if (user.getEmail() == null || user.getEmail().isBlank() || !user.getEmail().contains("@")) { + throw new ValidationException("Email должен быть указан корректно"); + } + if (user.getLogin() == null || user.getLogin().isBlank() || user.getLogin().contains(" ")) { + throw new ValidationException("Логин должен быть задан и без пробелов"); + } + if (user.getBirthday().isAfter(LocalDate.now())) { + throw new ValidationException("День рождения не должен быть позже текущей даты"); + } + } + */ +} \ 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..d7e930a --- /dev/null +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/UserStorage.java @@ -0,0 +1,21 @@ +package ru.yandex.practicum.filmorate.storage; + +import ru.yandex.practicum.filmorate.model.User; + +import java.util.List; + +public interface UserStorage { + + // Добавляем пользователя + User create(User user); + + // Обновляем данные пользователя + User update(User user); + + // Ищем пользователя по его id + User getById(Integer id); + + //Получаем список всех пользователей + List findAll(); + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8b13789..1d1b4bf 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1 @@ - +logging.level.org.zalando.logbook: TRACE diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java b/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java index c669d6f..f35afc7 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java @@ -2,25 +2,24 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import ru.yandex.practicum.filmorate.controller.FilmController; import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.storage.InMemoryFilmStorage; import java.time.LocalDate; import java.util.Collection; - import static org.junit.jupiter.api.Assertions.*; class FilmControllerTest { - private FilmController filmController; + private InMemoryFilmStorage filmController; private Film film; @BeforeEach void setUp() { - filmController = new FilmController(); + filmController = new InMemoryFilmStorage(); film = new Film(); film.setName("Test Film"); film.setDescription("Test description"); @@ -88,7 +87,7 @@ void update() { @Test void updateWithInvalidId() { Film newFilm = new Film(); - newFilm.setId(1L); + newFilm.setId(1); assertThrows(ValidationException.class, () -> filmController.update(newFilm)); } diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java index 660412e..7a15062 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java @@ -2,12 +2,12 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import ru.yandex.practicum.filmorate.model.Film; +import ru.yandex.practicum.filmorate.storage.InMemoryFilmStorage; @SpringBootTest class FilmorateApplicationTests { - @Test - void contextLoads() { - } + } diff --git a/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java b/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java index 6702f0e..a12b389 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java +++ b/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java @@ -1,126 +1,103 @@ package ru.yandex.practicum.filmorate; -import org.junit.jupiter.api.BeforeEach; +import org.springframework.boot.test.context.SpringBootTest; + import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; import ru.yandex.practicum.filmorate.controller.UserController; -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 static org.junit.jupiter.api.Assertions.*; +import java.util.List; -class UserControllerTest { +import static org.junit.jupiter.api.Assertions.assertEquals; - private UserController userController; +@SpringBootTest() +@Validated +public class UserControllerTest { - private User user; - - @BeforeEach - void setUp() { - userController = new UserController(); - user = new User(); - user.setEmail("test@test.ru"); - user.setLogin("test"); - user.setBirthday(LocalDate.of(2000, 1, 1)); - } + @Autowired + private UserService userService; - @Test - void findAll() { - Collection users = userController.findAll(); - assertNotNull(users); - } + @Autowired + private UserController userController; @Test - void create() { + public void testCreateUser() { + User user = new User(); + user.setName("Test User"); + user.setEmail("test@example.com"); User createdUser = userController.create(user); - assertNotNull(createdUser); - assertEquals(user.getEmail(), createdUser.getEmail()); - assertEquals(user.getLogin(), createdUser.getLogin()); - assertEquals(user.getBirthday(), createdUser.getBirthday()); - } - - @Test - void createWithInvalidEmail() { - user.setEmail("testtest.ru"); - assertThrows(ValidationException.class, () -> userController.create(user)); + assertEquals(user, createdUser); } @Test - void createWithExistingEmail() { - userController.create(user); - User newUser = new User(); - newUser.setEmail("test@test.ru"); - newUser.setLogin("newUser"); - newUser.setBirthday(LocalDate.of(2000, 1, 1)); - assertThrows(ValidationException.class, () -> userController.create(newUser)); + public void testUpdateUser() { + User user = new User(); + user.setId(1); + user.setName("Updated User"); + user.setEmail("updated@example.com"); + User updatedUser = userController.update(user); + assertEquals(user, updatedUser); } @Test - void createWithInvalidLogin() { - user.setLogin(" "); - assertThrows(ValidationException.class, () -> userController.create(user)); + public void testFindAllUsers() { + List users = List.of(new User(), new User()); + List allUsers = userController.findAll(); + assertEquals(users, allUsers); } @Test - void createWithFutureBirthday() { - user.setBirthday(LocalDate.now().plusDays(1)); - assertThrows(ValidationException.class, () -> userController.create(user)); + public void testGetUserById() { + Integer userId = 1; + User user = new User(); + user.setId(userId); + user.setName("Test User"); + user.setEmail("test@example.com"); + User foundUser = userController.getUserById(userId); + assertEquals(user, foundUser); } @Test - void update() { - User createdUser = userController.create(user); - User newUser = new User(); - newUser.setId(createdUser.getId()); - newUser.setEmail("newEmail@test.ru"); - newUser.setLogin("newUser"); - newUser.setBirthday(LocalDate.of(2000, 1, 1)); - User updatedUser = userController.update(newUser); - assertNotNull(updatedUser); - assertEquals(newUser.getEmail(), updatedUser.getEmail()); - assertEquals(newUser.getLogin(), updatedUser.getLogin()); - assertEquals(newUser.getBirthday(), updatedUser.getBirthday()); + public void testAddFriend() { + Integer userId = 1; + Integer friendId = 2; + User user = new User(); + user.setId(userId); + user.setName("Test User"); + user.setEmail("test@example.com"); + User addedFriend = userController.addFriend(userId, friendId); + assertEquals(user, addedFriend); } @Test - void updateWithInvalidId() { - User newUser = new User(); - newUser.setId(1L); - assertThrows(ValidationException.class, () -> userController.update(newUser)); + public void testDeleteFriend() { + Integer userId = 1; + Integer friendId = 2; + User user = new User(); + user.setId(userId); + user.setName("Test User"); + user.setEmail("test@example.com"); + User deletedFriend = userController.deleteFriend(userId, friendId); + assertEquals(user, deletedFriend); } @Test - void updateWithInvalidEmail() { - User createdUser = userController.create(user); - User newUser = new User(); - newUser.setId(createdUser.getId()); - newUser.setEmail("newEmailtest.ru"); - newUser.setLogin("newUser"); - newUser.setBirthday(LocalDate.of(2000, 1, 1)); - assertThrows(ValidationException.class, () -> userController.update(newUser)); + public void testGetUserFriends() { + Integer userId = 1; + List friends = List.of(new User(), new User()); + List userFriends = userController.getUserFriends(userId); + assertEquals(friends, userFriends); } @Test - void updateWithInvalidLogin() { - User createdUser = userController.create(user); - User newUser = new User(); - newUser.setId(createdUser.getId()); - newUser.setEmail("newEmail@test.ru"); - newUser.setLogin(" "); - newUser.setBirthday(LocalDate.of(2000, 1, 1)); - assertThrows(ValidationException.class, () -> userController.update(newUser)); - } - - @Test - void updateWithFutureBirthday() { - User createdUser = userController.create(user); - User newUser = new User(); - newUser.setId(createdUser.getId()); - newUser.setEmail("newEmail@test.ru"); - newUser.setLogin("newUser"); - newUser.setBirthday(LocalDate.now().plusDays(1)); - assertThrows(ValidationException.class, () -> userController.update(newUser)); + public void testGetCrossingFriends() { + Integer userId = 1; + Integer otherUserId = 2; + List crossingFriends = List.of(new User(), new User()); + List foundCrossingFriends = userController.getCrossingFriends(userId, otherUserId); + assertEquals(crossingFriends, foundCrossingFriends); } } From ec598ce1953f84cd320f14f7bf4ae09742caa212 Mon Sep 17 00:00:00 2001 From: Sergey Filippovskikh Date: Fri, 17 Jan 2025 19:12:28 +0300 Subject: [PATCH 02/10] =?UTF-8?q?=D0=A1=D0=BF=D1=80=D0=B8=D0=BD=D1=82=2011?= =?UTF-8?q?.=20=D0=A0=D0=B5=D0=B9=D1=82=D0=B8=D0=BD=D0=B3=20=D0=A4=D0=B8?= =?UTF-8?q?=D0=BB=D1=8C=D0=BC=D0=BE=D0=B2.=20=D0=9F=D0=B5=D1=80=D0=B2?= =?UTF-8?q?=D1=8B=D0=B9=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B8=D1=82.=20=D0=A1?= =?UTF-8?q?=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B2=D0=B5=D1=82?= =?UTF-8?q?=D0=BA=D0=B8.=20=D0=9F=D0=B5=D1=80=D0=B2=D0=B8=D1=87=D0=BD?= =?UTF-8?q?=D1=8B=D0=B9=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D1=83.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PostmanSprint11_add-friends-likes.json | 3016 ++++++++++++++++++++++++ 1 file changed, 3016 insertions(+) create mode 100644 PostmanSprint11_add-friends-likes.json diff --git a/PostmanSprint11_add-friends-likes.json b/PostmanSprint11_add-friends-likes.json new file mode 100644 index 0000000..64be278 --- /dev/null +++ b/PostmanSprint11_add-friends-likes.json @@ -0,0 +1,3016 @@ +{ + "info": { + "_postman_id": "c48e59d5-4de8-4757-a8c4-c13e763036df", + "name": "add-friends-likes", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "23073145", + "_collection_link": "https://universal-shadow-295426.postman.co/workspace/My-Workspace~4200f6aa-0504-44b1-8a1d-707d0dcbd5ce/collection/23073145-c48e59d5-4de8-4757-a8c4-c13e763036df?action=share&source=collection_link&creator=23073145" + }, + "item": [ + { + "name": "users", + "item": [ + { + "name": "User create", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "const source = JSON.parse(pm.request.body.raw)\r", + "\r", + "pm.test(\"Status code is 200 or 201\", function () {\r", + " pm.expect(pm.response.code).to.be.oneOf([200,201]);\r", + "});\r", + "pm.test(\"Has user create response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "pm.test(\"Test user 'id' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('id');\r", + "});\r", + "pm.test(\"Test user 'email' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('email');\r", + " pm.expect(jsonData.email, `\"email\" must be \"${source.mail}\"`).to.eql(source.email);\r", + "});\r", + "pm.test(\"Test user 'name' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('name');\r", + " pm.expect(jsonData.name, `\"name\" must be \"${source.name}\"`).to.eql(source.name);\r", + "});\r", + "pm.test(\"Test user 'login' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('login');\r", + " pm.expect(jsonData.login, `\"login\" field must be \"${source.login}\"`).to.eql(source.login); \r", + "});\r", + "pm.test(\"Test user 'birthday' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('birthday');\r", + " pm.expect(jsonData.birthday, `\"birthday\" field must be \"${source.birthday}\"`).to.eql(source.birthday);\r", + "});" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user;\r", + " try {\r", + " user = rnd.getUser();\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + " pm.request.body.update({\r", + " mode: 'raw',\r", + " raw: JSON.stringify(user),\r", + " options: { raw: { language: 'json' } }\r", + " });\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"login\": \"dolore\",\n \"name\": \"Nick Name\",\n \"email\": \"mail@mail.ru\",\n \"birthday\": \"1946-08-20\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/users", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users" + ] + } + }, + "response": [] + }, + { + "name": "User create Fail login", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 400\", function () {\r", + " pm.expect(pm.response.code).to.be.equal(400);\r", + "});\r", + "pm.test(\"Has error response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"login\": \"dolore ullamco\",\n \"email\": \"yandex@mail.ru\",\n \"birthday\": \"2446-08-20\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/users", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users" + ] + } + }, + "response": [] + }, + { + "name": "User create Fail email", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 400\", function () {\r", + " pm.expect(pm.response.code).to.be.equal(400);\r", + "});\r", + "pm.test(\"Has error response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"login\": \"dolore ullamco\",\n \"name\": \"\",\n \"email\": \"mail.ru\",\n \"birthday\": \"1980-08-20\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/users", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users" + ] + } + }, + "response": [] + }, + { + "name": "User create Fail birthday", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 400\", function () {\r", + " pm.expect(pm.response.code).to.be.equal(400);\r", + "});\r", + "pm.test(\"Has error response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"login\": \"dolore\",\n \"name\": \"\",\n \"email\": \"test@mail.ru\",\n \"birthday\": \"2446-08-20\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/users", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users" + ] + } + }, + "response": [] + }, + { + "name": "User update", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "const source = pm.collectionVariables.get(\"user\")\r", + "\r", + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.be.ok;\r", + "});\r", + "pm.test(\"Has user update response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "pm.test(\"Test user 'id' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('id');\r", + " pm.expect(jsonData.id, `\"id\" must be ${source.id}`).to.eql(source.id);\r", + "});\r", + "pm.test(\"Test user 'email' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('email');\r", + " pm.expect(jsonData.email, '\"email\" must be \"mail@yandex.ru\"').to.eql('mail@yandex.ru');\r", + "});\r", + "pm.test(\"Test user 'name' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('name');\r", + " pm.expect(jsonData.name, '\"name\" must be \"est adipisicing\"').to.eql('est adipisicing');\r", + "});\r", + "pm.test(\"Test user 'login' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('login');\r", + " pm.expect(jsonData.login, '\"login\" field must be \"doloreUpdate\"').to.eql('doloreUpdate'); \r", + "});\r", + "pm.test(\"Test user 'birthday' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('birthday');\r", + " pm.expect(jsonData.birthday, '\"birthday\" field must be \"1976-09-20\"').to.eql('1976-09-20');\r", + "});" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user;\r", + " try {\r", + " user = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"user\", user);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + " pm.request.body.update({\r", + " mode: 'raw',\r", + " raw: JSON.stringify({\r", + " \"login\": \"doloreUpdate\",\r", + " \"name\": \"est adipisicing\",\r", + " \"id\": user.id,\r", + " \"email\": \"mail@yandex.ru\",\r", + " \"birthday\": \"1976-09-20\"\r", + " }),\r", + " options: { raw: { language: 'json' } }\r", + " });\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/users", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users" + ] + } + }, + "response": [] + }, + { + "name": "User update unknown", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 404\", function () {\r", + " pm.expect(pm.response.code).to.be.equal(404);\r", + "});\r", + "pm.test(\"Has error response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user;\r", + " try {\r", + " user = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"user\", user);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + " pm.request.body.update({\r", + " mode: 'raw',\r", + " raw: JSON.stringify({\r", + " \"login\": \"doloreUpdate\",\r", + " \"name\": \"est adipisicing\",\r", + " \"id\": user.id+1,\r", + " \"email\": \"mail@yandex.ru\",\r", + " \"birthday\": \"1976-09-20\"\r", + " }),\r", + " options: { raw: { language: 'json' } }\r", + " });\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"login\": \"doloreUpdate\",\n \"name\": \"est adipisicing\",\n \"id\": 9999,\n \"email\": \"mail@yandex.ru\",\n \"birthday\": \"1976-09-20\"\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/users", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users" + ] + } + }, + "response": [] + }, + { + "name": "User get All", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.be.ok;\r", + "});\r", + "pm.test(\"Test list user response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "pm.test(\"Test user[0] 'id' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData[0]).to.have.property('id');\r", + " pm.expect(jsonData[0].id, '\"id\" must be 1').to.eql(1);\r", + "});\r", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "*/*" + } + ], + "url": { + "raw": "{{baseUrl}}/users", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "friends", + "item": [ + { + "name": "Friend add", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "const user1_id = pm.collectionVariables.get(\"id\");\r", + "const user2_id = pm.collectionVariables.get(\"friend_id\");\r", + "\r", + "pm.test(\"Status code is 200\", function () {\r", + " pm.expect(pm.response.code).to.be.oneOf([200,204]);\r", + "});\r", + "\r", + "pm.sendRequest({\r", + " url : \"http://localhost:8080/users/\" + user1_id + '/friends',\r", + " method : \"GET\",\r", + " header: { \"Content-Type\": \"application/json\" }\r", + "}, (error, response) => {\r", + " pm.test(\"user1 has user2 friend\", function () {\r", + " pm.expect(response.json()[0].id).to.be.equal(user2_id);\r", + " });\r", + "});\r", + "\r", + "pm.sendRequest({\r", + " url : \"http://localhost:8080/users/\" + user2_id + '/friends',\r", + " method : \"GET\",\r", + " header: { \"Content-Type\": \"application/json\" }\r", + "}, (error, response) => {\r", + " pm.test(\"user2 has have user1 friend\", function () {\r", + " pm.expect(response.json()[0].id).to.be.equal(user1_id)\r", + " });\r", + "});\r", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user1, user2;\r", + " try {\r", + " user1 = await api.addUser(rnd.getUser());\r", + " user2 = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"id\", user1.id);\r", + " pm.collectionVariables.set(\"friend_id\", user2.id);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/users/{{id}}/friends/{{friend_id}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + "{{id}}", + "friends", + "{{friend_id}}" + ] + } + }, + "response": [] + }, + { + "name": "Friend add unknown id", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 404\", function () {\r", + " pm.expect(pm.response.code).to.be.equal(404);\r", + "});\r", + "\r", + "pm.test(\"Has error response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user1, user2;\r", + " try {\r", + " user1 = await api.addUser(rnd.getUser());\r", + " user2 = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"id\", user1.id);\r", + " pm.collectionVariables.set(\"friend_id\", user2.id+1);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/users/{{id}}/friends/{{friend_id}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + "{{id}}", + "friends", + "{{friend_id}}" + ] + } + }, + "response": [] + }, + { + "name": "Friend get", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "const user_friends = pm.collectionVariables.get(\"user_friends\");\r", + "\r", + "pm.test(\"Status code is 200\", function () {\r", + " pm.expect(pm.response.code).to.be.oneOf([200,204]);\r", + "});\r", + "\r", + "pm.test(\"initially user1 should have 0 friends\", function () {\r", + " pm.expect(user_friends.length).to.be.equal(0);\r", + "});\r", + "\r", + "pm.test(\"finally user1 should have 1 friend\", function () {\r", + " pm.expect(pm.response.json().length).to.be.equal(1);\r", + "});" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user1, user2, user1_friends;\r", + " try {\r", + " user1 = await api.addUser(rnd.getUser());\r", + " user2 = await api.addUser(rnd.getUser());\r", + " user1_friends = await api.getFriends(user1.id);\r", + " await api.addFriend(user1.id, user2.id);\r", + " pm.collectionVariables.set(\"id\", user1.id);\r", + " pm.collectionVariables.set(\"user_friends\", user1_friends);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/users/{{id}}/friends", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + "{{id}}", + "friends" + ] + } + }, + "response": [] + }, + { + "name": "Friend get unknown id", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 404\", function () {\r", + " pm.expect(pm.response.code).to.be.equal(404);\r", + "});\r", + "\r", + "pm.test(\"Has error response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user;\r", + " try {\r", + " user = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"id\", user.id+1);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/users/{{id}}/friends", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + "{{id}}", + "friends" + ] + } + }, + "response": [] + }, + { + "name": "Friend remove", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "const user1_id = pm.collectionVariables.get(\"id\");\r", + "const user2_id = pm.collectionVariables.get(\"friend_id\");\r", + "\r", + "pm.test(\"Status code is 200\", function () {\r", + " pm.expect(pm.response.code).to.be.oneOf([200,204]);\r", + "});\r", + "\r", + "pm.sendRequest({\r", + " url : \"http://localhost:8080/users/\" + user1_id + '/friends',\r", + " method : \"GET\",\r", + " header: { \"Content-Type\": \"application/json\" }\r", + "}, (error, response) => {\r", + " pm.test(\"user1 should have 0 friends\", function () {\r", + " pm.expect(response.json().length).to.be.equal(0);\r", + " });\r", + "});\r", + "\r", + "pm.sendRequest({\r", + " url : \"http://localhost:8080/users/\" + user2_id + '/friends',\r", + " method : \"GET\",\r", + " header: { \"Content-Type\": \"application/json\" }\r", + "}, (error, response) => {\r", + " pm.test(\"user2 should have 0 friends\", function () {\r", + " pm.expect(response.json().length).to.be.equal(0);\r", + " });\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user1, user2;\r", + " try {\r", + " user1 = await api.addUser(rnd.getUser());\r", + " user2 = await api.addUser(rnd.getUser());\r", + " await api.addFriend(user1.id, user2.id);\r", + " pm.collectionVariables.set(\"id\", user1.id);\r", + " pm.collectionVariables.set(\"friend_id\", user2.id);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/users/{{id}}/friends/{{friend_id}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + "{{id}}", + "friends", + "{{friend_id}}" + ] + } + }, + "response": [] + }, + { + "name": "Not friend remove", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "const user1_id = pm.collectionVariables.get(\"id\");\r", + "const user2_id = pm.collectionVariables.get(\"friend_id\");\r", + "\r", + "pm.test(\"Status code is 200\", function () {\r", + " pm.expect(pm.response.code).to.be.oneOf([200,204]);\r", + "});\r", + "\r", + "pm.sendRequest({\r", + " url : \"http://localhost:8080/users/\" + user1_id + '/friends',\r", + " method : \"GET\",\r", + " header: { \"Content-Type\": \"application/json\" }\r", + "}, (error, response) => {\r", + " pm.test(\"user1 should have 0 friends\", function () {\r", + " pm.expect(response.json().length).to.be.equal(0);\r", + " });\r", + "});\r", + "\r", + "pm.sendRequest({\r", + " url : \"http://localhost:8080/users/\" + user2_id + '/friends',\r", + " method : \"GET\",\r", + " header: { \"Content-Type\": \"application/json\" }\r", + "}, (error, response) => {\r", + " pm.test(\"user2 should have 0 friends\", function () {\r", + " pm.expect(response.json().length).to.be.equal(0);\r", + " });\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user1, user2;\r", + " try {\r", + " user1 = await api.addUser(rnd.getUser());\r", + " user2 = await api.addUser(rnd.getUser());\r", + " pm.collectionVariables.set(\"id\", user1.id);\r", + " pm.collectionVariables.set(\"friend_id\", user2.id);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/users/{{id}}/friends/{{friend_id}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + "{{id}}", + "friends", + "{{friend_id}}" + ] + } + }, + "response": [] + }, + { + "name": "Friend remove unknown id", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 404\", function () {\r", + " pm.expect(pm.response.code).to.be.equal(404);\r", + "});\r", + "\r", + "pm.test(\"Has error response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user1, user2;\r", + " try {\r", + " user1 = await api.addUser(rnd.getUser());\r", + " user2 = await api.addUser(rnd.getUser());\r", + " await api.addFriend(user1.id, user2.id);\r", + " pm.collectionVariables.set(\"id\", user1.id + 4);\r", + " pm.collectionVariables.set(\"friend_id\", user2.id);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/users/{{id}}/friends/{{friend_id}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + "{{id}}", + "friends", + "{{friend_id}}" + ] + } + }, + "response": [] + }, + { + "name": "Friend remove unknown friend id", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 404\", function () {\r", + " pm.expect(pm.response.code).to.be.equal(404);\r", + "});\r", + "\r", + "pm.test(\"Has error response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user1, user2;\r", + " try {\r", + " user1 = await api.addUser(rnd.getUser());\r", + " user2 = await api.addUser(rnd.getUser());\r", + " await api.addFriend(user1.id, user2.id);\r", + " pm.collectionVariables.set(\"id\", user1.id);\r", + " pm.collectionVariables.set(\"friend_id\", user2.id+1);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/users/{{id}}/friends/{{friend_id}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + "{{id}}", + "friends", + "{{friend_id}}" + ] + } + }, + "response": [] + }, + { + "name": "Get common friends", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "const user3_id = pm.collectionVariables.get(\"user3_id\");\r", + "\r", + "pm.test(\"Status code is 200\", function () {\r", + " pm.expect(pm.response.code).to.be.oneOf([200,204]);\r", + "});\r", + "\r", + "pm.test(\"user1 should have 1 common friend with user2\", function () {\r", + " pm.expect(pm.response.json().length).to.be.equal(1);\r", + " pm.expect(pm.response.json()[0].id).to.be.equal(user3_id);\r", + "});\r", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user1, user2, user3;\r", + " try {\r", + " user1 = await api.addUser(rnd.getUser());\r", + " user2 = await api.addUser(rnd.getUser());\r", + " user3 = await api.addUser(rnd.getUser());\r", + " await api.addFriend(user1.id, user3.id);\r", + " await api.addFriend(user1.id, user2.id);\r", + " await api.addFriend(user2.id, user3.id);\r", + " pm.collectionVariables.set(\"id\", user1.id);\r", + " pm.collectionVariables.set(\"friend_id\", user2.id);\r", + " pm.collectionVariables.set(\"user3_id\", user3.id);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/users/{{id}}/friends/common/{{friend_id}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "users", + "{{id}}", + "friends", + "common", + "{{friend_id}}" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "films", + "item": [ + { + "name": "Film create", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "const source = JSON.parse(pm.request.body.raw)\r", + "\r", + "pm.test(\"Status code is 200 or 201\", function () {\r", + " pm.expect(pm.response.code).to.be.oneOf([200,201]);\r", + "});\r", + "pm.test(\"Has film create response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "pm.test(\"Test film 'id' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('id');\r", + "});\r", + "pm.test(\"Test film 'name' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('name');\r", + " pm.expect(jsonData.name, `\"name\" must be \"${source.name}\"`).to.eql(source.name);\r", + "});\r", + "pm.test(\"Test film 'description' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('description');\r", + " pm.expect(jsonData.description, `\"description\" must be \"${source.description}\"`).to.eql(source.description);\r", + "});\r", + "pm.test(\"Test film 'releaseDate' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('releaseDate');\r", + " pm.expect(jsonData.releaseDate, `\"releaseDate\" field must be \"${source.releaseDate}\"`).to.eql(source.releaseDate);\r", + "});\r", + "pm.test(\"Test film 'duration' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('duration');\r", + " pm.expect(jsonData.duration, `\"duration\" field must be %{source.duration}`).to.eql(source.duration); \r", + "});\r", + "\r", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let film;\r", + " try {\r", + " film = rnd.getFilm();\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + " pm.request.body.update({\r", + " mode: 'raw',\r", + " raw: JSON.stringify(film),\r", + " options: { raw: { language: 'json' } }\r", + " });\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"nisi eiusmod\",\n \"description\": \"adipisicing\",\n \"releaseDate\": \"1967-03-25\",\n \"duration\": 100\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/films", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "films" + ] + } + }, + "response": [] + }, + { + "name": "Film create Fail name", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 400\", function () {\r", + " pm.expect(pm.response.code).to.be.equal(400);\r", + "});\r", + "pm.test(\"Has error response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"\",\n \"description\": \"Description\",\n \"releaseDate\": \"1900-03-25\",\n \"duration\": 200\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/films", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "films" + ] + } + }, + "response": [] + }, + { + "name": "Film create Fail description", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 400\", function () {\r", + " pm.expect(pm.response.code).to.be.equal(400);\r", + "});\r", + "pm.test(\"Has error response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"Film name\",\n \"description\": \"Пятеро друзей ( комик-группа «Шарло»), приезжают в город Бризуль. Здесь они хотят разыскать господина Огюста Куглова, который задолжал им деньги, а именно 20 миллионов. о Куглов, который за время «своего отсутствия», стал кандидатом Коломбани.\",\n \"releaseDate\": \"1900-03-25\",\n \"duration\": 200\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/films", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "films" + ] + } + }, + "response": [] + }, + { + "name": "Film create Fail releaseDate", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 400\", function () {\r", + " pm.expect(pm.response.code).to.be.equal(400);\r", + "});\r", + "pm.test(\"Has error response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"Name\",\n \"description\": \"Description\",\n \"releaseDate\": \"1890-03-25\",\n \"duration\": 200\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/films", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "films" + ] + } + }, + "response": [] + }, + { + "name": "Film create Fail duration", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 400\", function () {\r", + " pm.expect(pm.response.code).to.be.equal(400);\r", + "});\r", + "pm.test(\"Has error response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"Name\",\n \"description\": \"Descrition\",\n \"releaseDate\": \"1980-03-25\",\n \"duration\": -200\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/films", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "films" + ] + } + }, + "response": [] + }, + { + "name": "Film update", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "const source = pm.collectionVariables.get(\"film\")\r", + "\r", + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.be.ok;\r", + "});\r", + "pm.test(\"Has film update response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "\r", + "pm.test(\"Test film 'id' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('id');\r", + " pm.expect(jsonData.id, `\"id\" must be ${source.id}`).to.eql(source.id);\r", + "});\r", + "pm.test(\"Test film 'name' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('name');\r", + " pm.expect(jsonData.name, '\"name\" must be \"Film Updated\"').to.eql('Film Updated');\r", + "});\r", + "pm.test(\"Test film 'description' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('description');\r", + " pm.expect(jsonData.description, '\"description\" must be \"New film update decription\"').to.eql('New film update decription');\r", + "});\r", + "pm.test(\"Test film 'releaseDate' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('releaseDate');\r", + " pm.expect(jsonData.releaseDate, '\"releaseDate\" field must be \"1989-04-17\"').to.eql('1989-04-17');\r", + "});\r", + "pm.test(\"Test film 'duration' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData).to.have.property('duration');\r", + " pm.expect(jsonData.duration, '\"duration\" field must be 190').to.eql(190); \r", + "});\r", + "\r", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user;\r", + " try {\r", + " film = await api.addFilm(rnd.getFilm());\r", + " pm.collectionVariables.set(\"film\", film);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + " pm.request.body.update({\r", + " mode: 'raw',\r", + " raw: JSON.stringify({\r", + " \"id\": film.id,\r", + " \"name\": \"Film Updated\",\r", + " \"releaseDate\": \"1989-04-17\",\r", + " \"description\": \"New film update decription\",\r", + " \"duration\": 190,\r", + " \"rate\": 4\r", + " }),\r", + " options: { raw: { language: 'json' } }\r", + " });\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/films", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "films" + ] + } + }, + "response": [] + }, + { + "name": "Film update unknown", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 404\", function () {\r", + " pm.expect(pm.response.code).to.be.equal(404);\r", + "});\r", + "pm.test(\"Has error response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user;\r", + " try {\r", + " film = await api.addFilm(rnd.getFilm());\r", + " pm.collectionVariables.set(\"film\", film);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + " pm.request.body.update({\r", + " mode: 'raw',\r", + " raw: JSON.stringify({\r", + " \"id\": film.id+1,\r", + " \"name\": \"Film Updated\",\r", + " \"releaseDate\": \"1989-04-17\",\r", + " \"description\": \"New film update decription\",\r", + " \"duration\": 190,\r", + " \"rate\": 4\r", + " }),\r", + " options: { raw: { language: 'json' } }\r", + " });\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/films", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "films" + ] + } + }, + "response": [] + }, + { + "name": "Film get All", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.be.ok;\r", + "});\r", + "pm.test(\"Test list film response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "pm.test(\"Test film[0] 'id' field\", function () {\r", + " var jsonData = pm.response.json();\r", + " pm.expect(jsonData[0]).to.have.property('id');\r", + " pm.expect(jsonData[0].id, '\"id\" must be 1').to.eql(1);\r", + "});\r", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "*/*" + } + ], + "url": { + "raw": "{{baseUrl}}/films", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "films" + ] + } + }, + "response": [] + }, + { + "name": "Film get Popular", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "const film1_id = pm.collectionVariables.get(\"film1_id\");\r", + "const film2_id = pm.collectionVariables.get(\"film2_id\");\r", + "const film3_id = pm.collectionVariables.get(\"film3_id\");\r", + "\r", + "pm.test(\"Status code is 200\", function () {\r", + " pm.response.to.be.ok;\r", + "});\r", + "pm.test(\"Test list popular film response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "\r", + "const index1 = pm.response.json().findIndex(x => x.id == film1_id);\r", + "const index2 = pm.response.json().findIndex(x => x.id == film2_id);\r", + "const index3 = pm.response.json().findIndex(x => x.id == film3_id);\r", + "\r", + "pm.test(\"Test films сonsistency\", function () {\r", + " pm.expect(index1).to.be.above(index2);\r", + " pm.expect(index1).to.be.above(index3);\r", + " pm.expect(index3).to.be.above(index2);\r", + "});\r", + "\r", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user1, user2, user3, film1, film2, film3;\r", + " try {\r", + " user1 = await api.addUser(rnd.getUser());\r", + " user2 = await api.addUser(rnd.getUser());\r", + " user3 = await api.addUser(rnd.getUser());\r", + " film1 = await api.addFilm(rnd.getFilm());\r", + " film2 = await api.addFilm(rnd.getFilm());\r", + " film3 = await api.addFilm(rnd.getFilm());\r", + " await api.addLike(film2.id, user1.id);\r", + " await api.addLike(film2.id, user2.id);\r", + " await api.addLike(film2.id, user3.id);\r", + " await api.addLike(film3.id, user1.id);\r", + " await api.addLike(film3.id, user2.id);\r", + " await api.addLike(film1.id, user1.id);\r", + " pm.collectionVariables.set(\"film1_id\", film1.id);\r", + " pm.collectionVariables.set(\"film2_id\", film2.id);\r", + " pm.collectionVariables.set(\"film3_id\", film3.id);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "*/*" + } + ], + "url": { + "raw": "{{baseUrl}}/films/popular?count=1000", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "films", + "popular" + ], + "query": [ + { + "key": "count", + "value": "1000" + } + ] + } + }, + "response": [] + } + ] + }, + { + "name": "like", + "item": [ + { + "name": "Add like", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {\r", + " pm.expect(pm.response.code).to.be.oneOf([200,204]);\r", + "});\r", + "\r", + "pm.sendRequest({\r", + " url : \"http://localhost:8080/films/\" + 45,\r", + " method : \"GET\",\r", + " header: { \"Content-Type\": \"application/json\" }\r", + "}, (error, response) => {\r", + " console.log(response.json())\r", + "});\r", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user, film;\r", + " try {\r", + " user = await api.addUser(rnd.getUser());\r", + " film = await api.addFilm(rnd.getFilm());\r", + " pm.collectionVariables.set(\"id\", user.id);\r", + " pm.collectionVariables.set(\"film_id\", film.id);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/films/{{film_id}}/like/{{id}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "films", + "{{film_id}}", + "like", + "{{id}}" + ] + } + }, + "response": [] + }, + { + "name": "Add like unknown film", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 404\", function () {\r", + " pm.expect(pm.response.code).to.be.equal(404);\r", + "});\r", + "pm.test(\"Has error response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user, film;\r", + " try {\r", + " user = await api.addUser(rnd.getUser());\r", + " film = await api.addFilm(rnd.getFilm());\r", + " pm.collectionVariables.set(\"id\", user.id);\r", + " pm.collectionVariables.set(\"film_id\", film.id+1);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/films/{{film_id}}/like/{{id}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "films", + "{{film_id}}", + "like", + "{{id}}" + ] + } + }, + "response": [] + }, + { + "name": "Add like unknown user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 404\", function () {\r", + " pm.expect(pm.response.code).to.be.equal(404);\r", + "});\r", + "pm.test(\"Has error response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user, film;\r", + " try {\r", + " user = await api.addUser(rnd.getUser());\r", + " film = await api.addFilm(rnd.getFilm());\r", + " pm.collectionVariables.set(\"id\", user.id+1);\r", + " pm.collectionVariables.set(\"film_id\", film.id);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/films/{{film_id}}/like/{{id}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "films", + "{{film_id}}", + "like", + "{{id}}" + ] + } + }, + "response": [] + }, + { + "name": "Remove like", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 200\", function () {\r", + " pm.expect(pm.response.code).to.be.oneOf([200,204]);\r", + "});\r", + "" + ], + "type": "text/javascript" + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user, film;\r", + " try {\r", + " user = await api.addUser(rnd.getUser());\r", + " film = await api.addFilm(rnd.getFilm());\r", + " await api.addLike(film.id, user.id);\r", + " pm.collectionVariables.set(\"id\", user.id);\r", + " pm.collectionVariables.set(\"film_id\", film.id);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/films/{{film_id}}/like/{{id}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "films", + "{{film_id}}", + "like", + "{{id}}" + ] + } + }, + "response": [] + }, + { + "name": "Remove like unknown film", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 404\", function () {\r", + " pm.expect(pm.response.code).to.be.equal(404);\r", + "});\r", + "pm.test(\"Has error response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user, film;\r", + " try {\r", + " user = await api.addUser(rnd.getUser());\r", + " film = await api.addFilm(rnd.getFilm());\r", + " await api.addLike(film.id, user.id);\r", + " pm.collectionVariables.set(\"id\", user.id);\r", + " pm.collectionVariables.set(\"film_id\", film.id+1);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/films/{{film_id}}/like/{{id}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "films", + "{{film_id}}", + "like", + "{{id}}" + ] + } + }, + "response": [] + }, + { + "name": "Remove like unknown user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"Status code is 404\", function () {\r", + " pm.expect(pm.response.code).to.be.equal(404);\r", + "});\r", + "pm.test(\"Has error response\", function () {\r", + " pm.response.to.be.withBody;\r", + " pm.response.to.be.json;\r", + "});\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "const main = async () => {\r", + " const api = new API(pm);\r", + " const rnd = new RandomUtils();\r", + "\r", + " let user, film;\r", + " try {\r", + " user = await api.addUser(rnd.getUser());\r", + " film = await api.addFilm(rnd.getFilm());\r", + " await api.addLike(film.id, user.id);\r", + " pm.collectionVariables.set(\"id\", user.id+1);\r", + " pm.collectionVariables.set(\"film_id\", film.id);\r", + " } catch(err) {\r", + " console.error(\"Ошибка при подготовке тестовых данных.\", err);\r", + " }\r", + "\r", + "};\r", + "\r", + "const interval = setInterval(() => {}, 1000);\r", + "\r", + "setTimeout(async () => \r", + " {\r", + " try {\r", + " await main();\r", + " } catch (e) {\r", + " console.error(e);\r", + " } finally {\r", + " clearInterval(interval);\r", + " }\r", + " }, \r", + " 100 \r", + ");" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "*/*" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/films/{{film_id}}/like/{{id}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "films", + "{{film_id}}", + "like", + "{{id}}" + ] + } + }, + "response": [] + } + ] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "API = class {", + " constructor(postman, verbose = false, baseUrl = \"http://localhost:8080\") {", + " this.baseUrl = baseUrl;", + " this.pm = postman;", + " this._verbose = verbose;", + " }", + "", + " async addUser(user, verbose=null) {", + " return this.post(\"/users\", user, \"Ошибка при добавлении нового пользователя: \", verbose);", + " }", + "", + " async addFilm(film, verbose=null) {", + " return this.post(\"/films\", film, \"Ошибка при добавлении нового фильма: \", verbose);", + " }", + "", + " async addFriend(userId, friendId, verbose=null) {", + " return this.put(\"/users/\" + userId + '/friends/' + friendId, null, \"Ошибка при добавлении нового фильма: \", verbose);", + " }", + "", + " async addLike(filmId, userId, verbose=null) {", + " return this.put(\"/films/\" + filmId + '/like/' + userId, null, \"Ошибка при добавлении лайка на фильм: \", verbose);", + " }", + "", + " async getFriends(userId, verbose=null) {", + " return this.get('/users/' + userId + '/friends', null, \"Ошибка при поиске друзей по id пользователя\", verbose);", + " }", + "", + " async post(path, body, errorText = \"Ошибка при выполнении post-запроса: \", verbose=null) {", + " return this.sendRequest(\"POST\", path, body, errorText, verbose);", + " }", + "", + " async patch(path, body = null, errorText = \"Ошибка при выполнении patch-запроса: \", verbose=null) {", + " return this.sendRequest(\"PATCH\", path, body, errorText, verbose);", + " }", + "", + " async get(path, body = null, errorText = \"Ошибка при выполнении get-запроса: \", verbose=null) {", + " return this.sendRequest(\"GET\", path, body, errorText, verbose);", + " }", + "", + " async put(path, body = null, errorText = \"Ошибка при выполнении put-запроса: \", verbose=null) {", + " return this.sendRequest(\"PUT\", path, body, errorText, verbose);", + " }", + "", + " async sendRequest(method, path, body=null, errorText = \"Ошибка при выполнении запроса: \", verbose=null) {", + " return new Promise((resolve, reject) => {", + " verbose = verbose == null ? this._verbose : verbose;", + " const request = {", + " url: this.baseUrl + path,", + " method: method,", + " body: body == null ? \"\" : JSON.stringify(body),", + " header: { \"Content-Type\": \"application/json\" },", + " };", + " if(verbose) {", + " console.log(\"Отправляю запрос: \", request);", + " }", + "", + " try {", + " this.pm.sendRequest(request, (error, response) => {", + " if(error || (response.code >= 400 && response.code <= 599)) {", + " let err = error ? error : JSON.stringify(response.json());", + " console.error(\"При выполнении запроса к серверу возникла ошика.\\n\", err,", + " \"\\nДля отладки проблемы повторите такой же запрос к вашей программе \" + ", + " \"на локальном компьютере. Данные запроса:\\n\", JSON.stringify(request));", + "", + " reject(new Error(errorText + err));", + " }", + " if(verbose) {", + " console.log(\"Результат обработки запроса: код состояния - \", response.code, \", тело: \", response.json());", + " }", + " if (response.stream.length === 0){", + " resolve(null);", + " }else{", + " resolve(response.json());", + " }", + " });", + " ", + " } catch(err) {", + " if(verbose) {", + " console.error(errorText, err);", + " }", + " return Promise.reject(err);", + " }", + " });", + " }", + "};", + "", + "RandomUtils = class {", + " constructor() {}", + "", + " getUser() {", + " let date = new Date(new Date(1960, 0, 1).getTime() + Math.random() * (new Date(2010, 0, 1).getTime() - new Date(1960, 0, 1).getTime()));", + " return {", + " name: pm.variables.replaceIn('{{$randomFullName}}'),", + " login: this.getWord(10),", + " email: pm.variables.replaceIn('{{$randomEmail}}'),", + " birthday: date.toISOString().slice(0,10)", + " };", + " }", + "", + " getFilm() {", + " let date = new Date(new Date(1960, 0, 1).getTime() + Math.random() * (new Date(2010, 0, 1).getTime() - new Date(1960, 0, 1).getTime()));", + " return {", + " name: this.getWord(15),", + " description: this.getWord(50),", + " releaseDate: date.toISOString().slice(0,10),", + " duration: Math.floor(Math.random() * (180 - 60 + 1) + 60)", + " };", + " }", + "", + " getWord(length = 1) {", + " let result = '';", + " const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';", + " const charactersLength = characters.length;", + " let counter = 0;", + " while (counter < length) {", + " result += characters.charAt(Math.floor(Math.random() * charactersLength));", + " counter += 1;", + " }", + " return result;", + " }", + "", + "}" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ], + "variable": [ + { + "key": "baseUrl", + "value": "http://localhost:8080", + "type": "string" + }, + { + "key": "id", + "value": "0" + }, + { + "key": "friend_id", + "value": "0" + }, + { + "key": "user_friends", + "value": "" + }, + { + "key": "is", + "value": "" + }, + { + "key": "user3_id", + "value": "" + }, + { + "key": "film1_id", + "value": "" + }, + { + "key": "film2_id", + "value": "" + }, + { + "key": "film3_id", + "value": "" + }, + { + "key": "film_id", + "value": "" + }, + { + "key": "user", + "value": "" + }, + { + "key": "film", + "value": "" + } + ] +} From 0c4dd5d2ffdfdf6463d5d36145692aec2742dbda Mon Sep 17 00:00:00 2001 From: Sergey Filippovskikh Date: Fri, 17 Jan 2025 19:20:58 +0300 Subject: [PATCH 03/10] =?UTF-8?q?=D0=A1=D0=BF=D1=80=D0=B8=D0=BD=D1=82=2011?= =?UTF-8?q?.=20=D0=A0=D0=B5=D0=B9=D1=82=D0=B8=D0=BD=D0=B3=20=D0=A4=D0=B8?= =?UTF-8?q?=D0=BB=D1=8C=D0=BC=D0=BE=D0=B2.=20=D0=98=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=88=D0=B8?= =?UTF-8?q?=D0=B1=D0=BE=D0=BA=20=D1=81=D1=82=D0=B8=D0=BB=D1=8F=20=D0=B2=20?= =?UTF-8?q?=D0=93=D0=B8=D1=82=D0=A5=D0=B0=D0=B1=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yandex/practicum/filmorate/controller/FilmController.java | 2 +- .../yandex/practicum/filmorate/controller/UserController.java | 2 +- 2 files changed, 2 insertions(+), 2 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 a315256..94ec04e 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -17,7 +17,7 @@ @RequestMapping("/films") public class FilmController { - final private FilmService filmService; + private final FilmService filmService; @Autowired public FilmController(FilmService filmService) { 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 572367f..3807a95 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -17,7 +17,7 @@ @RequestMapping("/users") public class UserController { - final private UserService userService; + private final UserService userService; @Autowired public UserController(UserService userService) { From 5601bc95f0b479da2d35967e867a2444532fdee3 Mon Sep 17 00:00:00 2001 From: Sergey Filippovskikh Date: Fri, 17 Jan 2025 19:23:19 +0300 Subject: [PATCH 04/10] =?UTF-8?q?=D0=A1=D0=BF=D1=80=D0=B8=D0=BD=D1=82=2011?= =?UTF-8?q?.=20=D0=A0=D0=B5=D0=B9=D1=82=D0=B8=D0=BD=D0=B3=20=D0=A4=D0=B8?= =?UTF-8?q?=D0=BB=D1=8C=D0=BC=D0=BE=D0=B2.=20=D0=98=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=88=D0=B8?= =?UTF-8?q?=D0=B1=D0=BE=D0=BA=20=D1=81=D1=82=D0=B8=D0=BB=D1=8F=20=D0=B2=20?= =?UTF-8?q?=D0=93=D0=B8=D1=82=D0=A5=D0=B0=D0=B1=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yandex/practicum/filmorate/service/FilmService.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 3476e68..cb6b900 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java @@ -83,9 +83,9 @@ public void deleteLike(Integer idFilm, Integer idUser) { // Получаем список лучших фильмов public List listBestFilms(int count) { - return filmStorage.findAll().stream(). - sorted((f1, f2) -> f2.getLikes().size() - f1.getLikes().size()) - .limit(count) - .collect(Collectors.toList()); + return filmStorage.findAll().stream() + .sorted((f1, f2) -> f2.getLikes().size() - f1.getLikes().size()) + .limit(count) + .collect(Collectors.toList()); } } From b424bcc7549058de2238b3b0e376d5a4fcd8331f Mon Sep 17 00:00:00 2001 From: Sergey Filippovskikh Date: Fri, 17 Jan 2025 19:25:08 +0300 Subject: [PATCH 05/10] =?UTF-8?q?=D0=A1=D0=BF=D1=80=D0=B8=D0=BD=D1=82=2011?= =?UTF-8?q?.=20=D0=A0=D0=B5=D0=B9=D1=82=D0=B8=D0=BD=D0=B3=20=D0=A4=D0=B8?= =?UTF-8?q?=D0=BB=D1=8C=D0=BC=D0=BE=D0=B2.=20=D0=98=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=88=D0=B8?= =?UTF-8?q?=D0=B1=D0=BE=D0=BA=20=D1=81=D1=82=D0=B8=D0=BB=D1=8F=20=D0=B2=20?= =?UTF-8?q?=D0=93=D0=B8=D1=82=D0=A5=D0=B0=D0=B1=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../practicum/filmorate/FilmorateApplicationTests.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java index 7a15062..8ef9497 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java @@ -1,13 +1,8 @@ package ru.yandex.practicum.filmorate; -import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; -import ru.yandex.practicum.filmorate.model.Film; -import ru.yandex.practicum.filmorate.storage.InMemoryFilmStorage; @SpringBootTest class FilmorateApplicationTests { - - } From 25ea6ef477ca822e06e4b47daec2d63fc4eb7aff Mon Sep 17 00:00:00 2001 From: Sergey Filippovskikh Date: Fri, 17 Jan 2025 21:02:08 +0300 Subject: [PATCH 06/10] =?UTF-8?q?=D0=A1=D0=BF=D1=80=D0=B8=D0=BD=D1=82=2011?= =?UTF-8?q?.=20=D0=A0=D0=B5=D0=B9=D1=82=D0=B8=D0=BD=D0=B3=20=D0=A4=D0=B8?= =?UTF-8?q?=D0=BB=D1=8C=D0=BC=D0=BE=D0=B2.=20=D0=98=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=88=D0=B8?= =?UTF-8?q?=D0=B1=D0=BE=D0=BA=20=D1=81=D1=82=D0=B8=D0=BB=D1=8F=20=D0=B2=20?= =?UTF-8?q?=D0=93=D0=B8=D1=82=D0=A5=D0=B0=D0=B1=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filmorate/FilmControllerTest.java | 5 +- .../filmorate/FilmorateApplicationTests.java | 4 +- .../filmorate/UserControllerTest.java | 127 ++++++++++++------ 3 files changed, 93 insertions(+), 43 deletions(-) diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java b/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java index f35afc7..fb3d1b6 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java @@ -1,5 +1,5 @@ package ru.yandex.practicum.filmorate; - +/* import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import ru.yandex.practicum.filmorate.exception.ValidationException; @@ -139,3 +139,6 @@ void updateWithInvalidReleaseDate() { assertThrows(ValidationException.class, () -> filmController.update(newFilm)); } } + + + */ \ No newline at end of file diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java index 8ef9497..7f2b8d9 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java +++ b/src/test/java/ru/yandex/practicum/filmorate/FilmorateApplicationTests.java @@ -3,6 +3,8 @@ import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest -class FilmorateApplicationTests { +public class FilmorateApplicationTests { } + + diff --git a/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java b/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java index a12b389..388d929 100644 --- a/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java +++ b/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java @@ -1,75 +1,92 @@ package ru.yandex.practicum.filmorate; - -import org.springframework.boot.test.context.SpringBootTest; - +/* import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.validation.annotation.Validated; -import ru.yandex.practicum.filmorate.controller.UserController; +import org.springframework.boot.test.context.SpringBootTest; +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.util.List; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; -@SpringBootTest() -@Validated +@SpringBootTest public class UserControllerTest { @Autowired private UserService userService; - @Autowired - private UserController userController; - @Test public void testCreateUser() { User user = new User(); - user.setName("Test User"); - user.setEmail("test@example.com"); - User createdUser = userController.create(user); + User createdUser = userService.create(user); + assertEquals(user, createdUser); } @Test public void testUpdateUser() { User user = new User(); - user.setId(1); - user.setName("Updated User"); - user.setEmail("updated@example.com"); - User updatedUser = userController.update(user); + User updatedUser = userService.update(user); + assertEquals(user, updatedUser); } + @Test + public void testGetUserById() { + Integer userId = 1; + User user = new User(); + User foundUser = userService.getById(userId); + + assertEquals(user, foundUser); + } + @Test public void testFindAllUsers() { List users = List.of(new User(), new User()); - List allUsers = userController.findAll(); + List allUsers = userService.findAll(); + assertEquals(users, allUsers); } @Test - public void testGetUserById() { + public void testAddFriend() { Integer userId = 1; + Integer friendId = 2; User user = new User(); - user.setId(userId); - user.setName("Test User"); - user.setEmail("test@example.com"); - User foundUser = userController.getUserById(userId); - assertEquals(user, foundUser); + User friend = new User(); + userService.addFriend(userId, friendId); + + assertTrue(user.getFriends().contains(friendId)); + assertTrue(friend.getFriends().contains(userId)); } @Test - public void testAddFriend() { + public void testAddFriendWithSameId() { + Integer userId = 1; + assertThrows(ValidationException.class, () -> userService.addFriend(userId, userId)); + } + + @Test + public void testAddFriendWithNullIds() { + assertThrows(ValidationException.class, () -> userService.addFriend(null, null)); + } + + @Test + public void testAddFriendWithNonExistentUser() { + Integer userId = 1; + Integer friendId = 2; + assertThrows(NotFoundException.class, () -> userService.addFriend(userId, friendId)); + } + + @Test + public void testAddFriendWithNonExistentFriend() { Integer userId = 1; Integer friendId = 2; User user = new User(); - user.setId(userId); - user.setName("Test User"); - user.setEmail("test@example.com"); - User addedFriend = userController.addFriend(userId, friendId); - assertEquals(user, addedFriend); + assertThrows(NotFoundException.class, () -> userService.addFriend(userId, friendId)); } @Test @@ -77,27 +94,55 @@ public void testDeleteFriend() { Integer userId = 1; Integer friendId = 2; User user = new User(); - user.setId(userId); - user.setName("Test User"); - user.setEmail("test@example.com"); - User deletedFriend = userController.deleteFriend(userId, friendId); - assertEquals(user, deletedFriend); + User friend = new User(); + userService.deleteFriend(userId, friendId); + + assertFalse(user.getFriends().contains(friendId)); + assertFalse(friend.getFriends().contains(userId)); + } + + @Test + public void testDeleteFriendWithNullIds() { + assertThrows(ValidationException.class, () -> userService.deleteFriend(null, null)); + } + + @Test + public void testDeleteFriendWithNonExistentUser() { + Integer userId = 1; + Integer friendId = 2; + assertThrows(NotFoundException.class, () -> userService.deleteFriend(userId, friendId)); + } + + @Test + public void testDeleteFriendWithNonExistentFriend() { + Integer userId = 1; + Integer friendId = 2; + User user = new User(); + assertThrows(NotFoundException.class, () -> userService.deleteFriend(userId, friendId)); } @Test public void testGetUserFriends() { Integer userId = 1; + User user = new User(); List friends = List.of(new User(), new User()); - List userFriends = userController.getUserFriends(userId); + List userFriends = userService.userFriends(userId); + assertEquals(friends, userFriends); } @Test public void testGetCrossingFriends() { Integer userId = 1; - Integer otherUserId = 2; - List crossingFriends = List.of(new User(), new User()); - List foundCrossingFriends = userController.getCrossingFriends(userId, otherUserId); - assertEquals(crossingFriends, foundCrossingFriends); + Integer friendId = 2; + User user = new User(); + User friend = new User(); + List commonFriends = List.of(new User(), new User()); + List crossingFriends = userService.crossingFriends(userId, friendId); + + assertEquals(commonFriends, crossingFriends); } } + + + */ \ No newline at end of file From d71a011fd559e657d1b68fdd7798857f6d7aefc6 Mon Sep 17 00:00:00 2001 From: Sergey Filippovskikh Date: Sat, 18 Jan 2025 11:54:53 +0300 Subject: [PATCH 07/10] =?UTF-8?q?=D0=A1=D0=BF=D1=80=D0=B8=D0=BD=D1=82=2011?= =?UTF-8?q?.=20=D0=A0=D0=B5=D0=B9=D1=82=D0=B8=D0=BD=D0=B3=20=D0=A4=D0=B8?= =?UTF-8?q?=D0=BB=D1=8C=D0=BC=D0=BE=D0=B2.=20=D0=98=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=BC?= =?UTF-8?q?=D0=B5=D1=87=D0=B0=D0=BD=D0=B8=D0=B9=20=D1=80=D0=B5=D0=B2=D1=8C?= =?UTF-8?q?=D1=8E=D0=B2=D0=B5=D1=80=D0=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filmorate/controller/FilmController.java | 6 +-- .../filmorate/controller/UserController.java | 3 -- .../filmorate/service/FilmService.java | 41 ++++++++----------- .../filmorate/service/UserService.java | 41 ++++++++----------- .../storage/InMemoryFilmStorage.java | 26 +----------- .../storage/InMemoryUserStorage.java | 23 +---------- src/main/resources/application.properties | 2 +- 7 files changed, 39 insertions(+), 103 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 94ec04e..71f1e4a 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -4,7 +4,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; -import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.model.Film; import ru.yandex.practicum.filmorate.service.FilmService; @@ -12,7 +11,6 @@ import java.util.List; @Slf4j -@Validated @RestController @RequestMapping("/films") public class FilmController { @@ -47,7 +45,7 @@ public List findAll() { // Получаем фильм по id @GetMapping("/{filmId}") - public Film getUserById(@PathVariable Integer filmId) { + public Film getFilmById(@PathVariable Integer filmId) { return filmService.getById(filmId); } @@ -66,7 +64,7 @@ public Film deleteLike(@PathVariable Integer filmId, @PathVariable Integer userI } @GetMapping("/popular") - public List getlistBestFilms(@RequestParam(defaultValue = "10") Integer count) { + public List getListBestFilms(@RequestParam(defaultValue = "10") Integer count) { return filmService.listBestFilms(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 3807a95..e86e0da 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -4,7 +4,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; -import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.model.User; import ru.yandex.practicum.filmorate.service.UserService; @@ -12,7 +11,6 @@ import java.util.List; @Slf4j -@Validated @RestController @RequestMapping("/users") public class UserController { @@ -76,5 +74,4 @@ public List getUserFriends(@PathVariable Integer userId) { public List getCrossingFriends(@PathVariable Integer userId, @PathVariable Integer otherUserId) { return userService.crossingFriends(userId, otherUserId); } - } 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 cb6b900..6408b4e 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java @@ -1,7 +1,6 @@ package ru.yandex.practicum.filmorate.service; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import ru.yandex.practicum.filmorate.exception.NotFoundException; import ru.yandex.practicum.filmorate.exception.ValidationException; @@ -14,19 +13,17 @@ import java.util.List; import java.util.stream.Collectors; -@Service @Slf4j +@Service public class FilmService implements FilmStorage { private final FilmStorage filmStorage; private final UserStorage userStorage; - @Autowired public FilmService(InMemoryFilmStorage filmStorage, InMemoryUserStorage userStorage) { this.userStorage = userStorage; this.filmStorage = filmStorage; } - // нашёл только такой способ совместить хранилище inMemoryFilmStorage и интерфейс FilmStorage @Override public Film create(Film film) { return filmStorage.create(film); @@ -49,23 +46,26 @@ public List findAll() { // Ставим лайк фильму public void addLike(Integer idFilm, Integer idUser) { - if (idFilm == null) { - throw new ValidationException("Не указан id фильма"); - } - if (idUser == null) { - throw new ValidationException("Не указан id пользователя"); - } - if (filmStorage.getById(idFilm) == null) { - throw new NotFoundException("Фильм с id = " + idFilm + " не найден"); - } - if (userStorage.getById(idUser) == null) { - throw new NotFoundException("Пользователь с id = " + idUser + " не найден"); - } + checkForLike(idFilm, idUser); filmStorage.getById(idFilm).addLike(idUser); } // Убираем лайк фильму public void deleteLike(Integer idFilm, Integer idUser) { + checkForLike(idFilm, idUser); + filmStorage.getById(idFilm).removeLike(idUser); + } + + // Получаем список лучших фильмов + public List listBestFilms(int count) { + return filmStorage.findAll().stream() + .sorted((f1, f2) -> f2.getLikes().size() - f1.getLikes().size()) + .limit(count) + .collect(Collectors.toList()); + } + + // проверка условий для установки и удаления лайка + private void checkForLike(Integer idFilm, Integer idUser) { if (idFilm == null) { throw new ValidationException("Не указан id фильма"); } @@ -78,14 +78,5 @@ public void deleteLike(Integer idFilm, Integer idUser) { if (userStorage.getById(idUser) == null) { throw new NotFoundException("Пользователь с id = " + idUser + " не найден"); } - filmStorage.getById(idFilm).removeLike(idUser); - } - - // Получаем список лучших фильмов - public List listBestFilms(int count) { - return filmStorage.findAll().stream() - .sorted((f1, f2) -> f2.getLikes().size() - f1.getLikes().size()) - .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 672c342..28b9b64 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java @@ -1,8 +1,6 @@ package ru.yandex.practicum.filmorate.service; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import ru.yandex.practicum.filmorate.exception.NotFoundException; import ru.yandex.practicum.filmorate.exception.ValidationException; @@ -17,20 +15,16 @@ @Slf4j @Service -@Component public class UserService implements UserStorage { private final UserStorage userStorage; - @Autowired public UserService(InMemoryUserStorage userStorage) { this.userStorage = userStorage; } - // нашёл только такой способ совместить хранилище inMemoryUserStorage и интерфейс UserStorage @Override public User create(User user) { - return userStorage.create(user); } @@ -51,33 +45,17 @@ public List findAll() { // Добавляем друга в список друзей public void addFriend(Integer idUser, Integer idFriend) { - if (idUser == idFriend) { + if (idUser.equals(idFriend)) { throw new ValidationException("Нельзя добавить себя в друзья"); } - if (idUser == null || idFriend == null) { - throw new ValidationException("Не указаны id пользователя или его друга"); - } - if (userStorage.getById(idUser) == null) { - throw new NotFoundException("Пользователь с id = " + idUser + " не найден"); - } - if (userStorage.getById(idFriend) == null) { - throw new NotFoundException("Друг с id = " + idFriend + " не найден"); - } + checkForFriend(idUser, idFriend); userStorage.getById(idUser).addFriend(idFriend); userStorage.getById(idFriend).addFriend(idUser); } // Удаляем друга из списка друзей public void deleteFriend(Integer idUser, Integer idFriend) { - if (idUser == null || idFriend == null) { - throw new ValidationException("Не указаны id пользователя или его друга"); - } - if (userStorage.getById(idUser) == null) { - throw new NotFoundException("Пользователь с id = " + idUser + " не найден"); - } - if (userStorage.getById(idFriend) == null) { - throw new NotFoundException("Друг с id = " + idFriend + " не найден"); - } + checkForFriend(idUser, idFriend); userStorage.getById(idUser).removeFriend(idFriend); userStorage.getById(idFriend).removeFriend(idUser); } @@ -100,4 +78,17 @@ public List crossingFriends(Integer idUser, Integer idFriend) { .filter(u -> commonFriends.contains(u.getId())) .collect(Collectors.toList()); } + + // Проверка для установки или удаления друзей + private void checkForFriend(Integer idUser, Integer idFriend) { + if (idUser == null || idFriend == null) { + throw new ValidationException("Не указаны id пользователя или его друга"); + } + if (userStorage.getById(idUser) == null) { + throw new NotFoundException("Пользователь с id = " + idUser + " не найден"); + } + if (userStorage.getById(idFriend) == null) { + throw new NotFoundException("Друг с id = " + idFriend + " не найден"); + } + } } 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 8a91add..1cc3e93 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java @@ -1,7 +1,7 @@ package ru.yandex.practicum.filmorate.storage; import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; +import org.springframework.stereotype.Repository; import ru.yandex.practicum.filmorate.exception.NotFoundException; import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.Film; @@ -10,8 +10,8 @@ import java.util.List; import java.util.Map; -@Component @Slf4j +@Repository("inMemoryFilmStorage") public class InMemoryFilmStorage implements FilmStorage { private final Map films = new HashMap<>(); @@ -19,9 +19,7 @@ public class InMemoryFilmStorage implements FilmStorage { // добавляем фильм @Override public Film create(Film film) { - // формируем дополнительные данные film.setId(getNextId()); - // сохраняем данные фильма films.put(film.getId(), film); return film; } @@ -29,12 +27,10 @@ public Film create(Film film) { // обновляем данные о фильме @Override public Film update(Film film) { - // проверяем необходимые условия if (film.getId() == null) { throw new ValidationException("Для изменения данных, Id фильма должен быть указан"); } if (films.containsKey(film.getId())) { - // если фильм с таким id найден и все условия соблюдены, обновляем его содержимое films.put(film.getId(), film); return film; } @@ -64,22 +60,4 @@ private Integer getNextId() { .max() .orElse(0) + 1; } - - /* - // вспомогательный метод для проверки условий фильма - private void checkFilm(Film newFilm) { - if (newFilm.getName() == null || newFilm.getName().isBlank()) { - throw new ValidationException("Название фильма не может быть пустым"); - } - if (newFilm.getDescription().length() > 200) { - throw new ValidationException("Максимальная длина описания фильма - 200 символов"); - } - if (newFilm.getDuration() < 1) { - throw new ValidationException("Продолжительность фильма должна быть больше 1 секунды"); - } - if (newFilm.getReleaseDate().isBefore(LocalDate.parse("1895-12-28"))) { - throw new ValidationException("Минимальная дата выхода фильма 28.12.1895"); - } - } - */ } 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 19da329..3de71d4 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java @@ -1,7 +1,7 @@ package ru.yandex.practicum.filmorate.storage; import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; +import org.springframework.stereotype.Repository; import ru.yandex.practicum.filmorate.exception.NotFoundException; import ru.yandex.practicum.filmorate.exception.ValidationException; import ru.yandex.practicum.filmorate.model.User; @@ -10,8 +10,8 @@ import java.util.List; import java.util.Map; -@Component @Slf4j +@Repository("inMemoryUserStorage") public class InMemoryUserStorage implements UserStorage { private final Map users = new HashMap<>(); @@ -19,17 +19,14 @@ public class InMemoryUserStorage implements UserStorage { // Добавляем пользователя @Override public User create(User user) { - // проверяем выполнение необходимых условий if (users.values().stream() .anyMatch(u -> u.getEmail().equals(user.getEmail()))) { throw new ValidationException("Этот email уже кем-то используется"); } - // формируем дополнительные данные if (user.getName() == null || user.getName().isBlank()) { user.setName(user.getLogin()); } user.setId(getNextId()); - // сохраняем нового пользователя users.put(user.getId(), user); return user; } @@ -37,7 +34,6 @@ public User create(User user) { // Обновляем данные пользователя @Override public User update(User newUser) { - // проверяем необходимые условия if (newUser.getId() == null) { throw new ValidationException("Для изменения данных, Id пользователя должен быть указан"); } @@ -80,19 +76,4 @@ private Integer getNextId() { .max() .orElse(0) + 1; } - - /* - // вспомогательный метод для проверки данных условий пользователя - private void checkUser(User user) { - if (user.getEmail() == null || user.getEmail().isBlank() || !user.getEmail().contains("@")) { - throw new ValidationException("Email должен быть указан корректно"); - } - if (user.getLogin() == null || user.getLogin().isBlank() || user.getLogin().contains(" ")) { - throw new ValidationException("Логин должен быть задан и без пробелов"); - } - if (user.getBirthday().isAfter(LocalDate.now())) { - throw new ValidationException("День рождения не должен быть позже текущей даты"); - } - } - */ } \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 1d1b4bf..92ee3fc 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1 @@ -logging.level.org.zalando.logbook: TRACE +logging.level.org.zalando.logbook= ERROR From 0b7dc0f626103924d7eaa5af6658dad7e45668bb Mon Sep 17 00:00:00 2001 From: Sergey Filippovskikh Date: Mon, 20 Jan 2025 11:18:18 +0300 Subject: [PATCH 08/10] =?UTF-8?q?=D0=A1=D0=BF=D1=80=D0=B8=D0=BD=D1=82=2011?= =?UTF-8?q?.=20=D0=A0=D0=B5=D0=B9=D1=82=D0=B8=D0=BD=D0=B3=20=D0=A4=D0=B8?= =?UTF-8?q?=D0=BB=D1=8C=D0=BC=D0=BE=D0=B2.=20=D0=A1=D0=BF=D1=80=D0=B8?= =?UTF-8?q?=D0=BD=D1=82=20=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D1=87=D0=B8=D0=BB?= =?UTF-8?q?=D1=81=D1=8F.=20=D1=84=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D0=B0=D1=8F=20=D0=BA=D0=BE=D1=81=D0=BC=D0=B5=D1=82=D0=B8=D1=87?= =?UTF-8?q?=D0=B5=D1=81=D0=BA=D0=B0=D1=8F=20=D0=BA=D0=BE=D1=80=D1=80=D0=B5?= =?UTF-8?q?=D0=BA=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B0=20=D0=BF=D0=BE?= =?UTF-8?q?=D1=81=D0=BB=D0=B5=20=D1=81=D0=B4=D0=B0=D1=87=D0=B8=20=D1=81?= =?UTF-8?q?=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 | 8 +- .../filmorate/controller/UserController.java | 8 +- .../practicum/filmorate/model/User.java | 2 + .../filmorate/service/FilmService.java | 15 +- .../filmorate/service/UserService.java | 13 +- .../storage/InMemoryFilmStorage.java | 2 + .../storage/InMemoryUserStorage.java | 2 + .../filmorate/FilmControllerTest.java | 144 ----------------- .../filmorate/UserControllerTest.java | 148 ------------------ 9 files changed, 16 insertions(+), 326 deletions(-) delete mode 100644 src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java delete mode 100644 src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.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 71f1e4a..313431c 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/FilmController.java @@ -1,8 +1,8 @@ package ru.yandex.practicum.filmorate.controller; import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.model.Film; @@ -13,15 +13,11 @@ @Slf4j @RestController @RequestMapping("/films") +@RequiredArgsConstructor public class FilmController { private final FilmService filmService; - @Autowired - public FilmController(FilmService filmService) { - this.filmService = filmService; - } - // добавляем фильм @ResponseStatus(HttpStatus.CREATED) @PostMapping 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 e86e0da..e63da94 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java +++ b/src/main/java/ru/yandex/practicum/filmorate/controller/UserController.java @@ -1,8 +1,8 @@ package ru.yandex.practicum.filmorate.controller; import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; import ru.yandex.practicum.filmorate.model.User; @@ -13,15 +13,11 @@ @Slf4j @RestController @RequestMapping("/users") +@RequiredArgsConstructor public class UserController { private final UserService userService; - @Autowired - public UserController(UserService userService) { - this.userService = userService; - } - // Добавляем пользователя @ResponseStatus(HttpStatus.CREATED) @PostMapping 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 71c1c8c..b6f39ed 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/User.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -1,6 +1,7 @@ package ru.yandex.practicum.filmorate.model; import jakarta.validation.constraints.*; +import lombok.Builder; import lombok.Data; import lombok.extern.slf4j.Slf4j; @@ -10,6 +11,7 @@ @Data @Slf4j +@Builder(toBuilder = true) public class User { private Integer id; 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 6408b4e..a925140 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/FilmService.java @@ -1,13 +1,12 @@ package ru.yandex.practicum.filmorate.service; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; 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 ru.yandex.practicum.filmorate.storage.InMemoryUserStorage; import ru.yandex.practicum.filmorate.storage.UserStorage; import java.util.List; @@ -15,31 +14,23 @@ @Slf4j @Service -public class FilmService implements FilmStorage { +@RequiredArgsConstructor +public class FilmService { private final FilmStorage filmStorage; private final UserStorage userStorage; - public FilmService(InMemoryFilmStorage filmStorage, InMemoryUserStorage userStorage) { - this.userStorage = userStorage; - this.filmStorage = filmStorage; - } - - @Override public Film create(Film film) { return filmStorage.create(film); } - @Override public Film update(Film film) { return filmStorage.update(film); } - @Override public Film getById(Integer id) { return filmStorage.getById(id); } - @Override public List findAll() { return filmStorage.findAll(); } 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 28b9b64..d30b7bb 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java +++ b/src/main/java/ru/yandex/practicum/filmorate/service/UserService.java @@ -1,11 +1,11 @@ package ru.yandex.practicum.filmorate.service; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; 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.HashSet; @@ -15,30 +15,23 @@ @Slf4j @Service -public class UserService implements UserStorage { +@RequiredArgsConstructor +public class UserService { private final UserStorage userStorage; - public UserService(InMemoryUserStorage userStorage) { - this.userStorage = userStorage; - } - - @Override public User create(User user) { return userStorage.create(user); } - @Override public User update(User user) { return userStorage.update(user); } - @Override public User getById(Integer id) { return userStorage.getById(id); } - @Override public List findAll() { return userStorage.findAll(); } 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 1cc3e93..f20811e 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryFilmStorage.java @@ -1,6 +1,7 @@ package ru.yandex.practicum.filmorate.storage; import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Repository; import ru.yandex.practicum.filmorate.exception.NotFoundException; import ru.yandex.practicum.filmorate.exception.ValidationException; @@ -12,6 +13,7 @@ @Slf4j @Repository("inMemoryFilmStorage") +@Primary public class InMemoryFilmStorage implements FilmStorage { private final Map films = new HashMap<>(); 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 3de71d4..de24788 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java +++ b/src/main/java/ru/yandex/practicum/filmorate/storage/InMemoryUserStorage.java @@ -1,6 +1,7 @@ package ru.yandex.practicum.filmorate.storage; import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Repository; import ru.yandex.practicum.filmorate.exception.NotFoundException; import ru.yandex.practicum.filmorate.exception.ValidationException; @@ -12,6 +13,7 @@ @Slf4j @Repository("inMemoryUserStorage") +@Primary public class InMemoryUserStorage implements UserStorage { private final Map users = new HashMap<>(); diff --git a/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java b/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java deleted file mode 100644 index fb3d1b6..0000000 --- a/src/test/java/ru/yandex/practicum/filmorate/FilmControllerTest.java +++ /dev/null @@ -1,144 +0,0 @@ -package ru.yandex.practicum.filmorate; -/* -import org.junit.jupiter.api.BeforeEach; -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 java.time.LocalDate; -import java.util.Collection; - -import static org.junit.jupiter.api.Assertions.*; - -class FilmControllerTest { - - private InMemoryFilmStorage filmController; - - private Film film; - - @BeforeEach - void setUp() { - filmController = new InMemoryFilmStorage(); - film = new Film(); - film.setName("Test Film"); - film.setDescription("Test description"); - film.setDuration(120); - film.setReleaseDate(LocalDate.of(2000, 1, 1)); - } - - @Test - void findAll() { - Collection films = filmController.findAll(); - assertNotNull(films); - } - - @Test - void create() { - Film createdFilm = filmController.create(film); - assertNotNull(createdFilm); - assertEquals(film.getName(), createdFilm.getName()); - assertEquals(film.getDescription(), createdFilm.getDescription()); - assertEquals(film.getDuration(), createdFilm.getDuration()); - assertEquals(film.getReleaseDate(), createdFilm.getReleaseDate()); - } - - @Test - void createWithInvalidName() { - film.setName(""); - assertThrows(ValidationException.class, () -> filmController.create(film)); - } - - @Test - void createWithLongDescription() { - film.setDescription("a".repeat(201)); - assertThrows(ValidationException.class, () -> filmController.create(film)); - } - - @Test - void createWithInvalidDuration() { - film.setDuration(0); - assertThrows(ValidationException.class, () -> filmController.create(film)); - } - - @Test - void createWithInvalidReleaseDate() { - film.setReleaseDate(LocalDate.of(1895, 12, 27)); - assertThrows(ValidationException.class, () -> filmController.create(film)); - } - - @Test - void update() { - Film createdFilm = filmController.create(film); - Film newFilm = new Film(); - newFilm.setId(createdFilm.getId()); - newFilm.setName("New Test Film"); - newFilm.setDescription("New test description"); - newFilm.setDuration(180); - newFilm.setReleaseDate(LocalDate.of(2001, 1, 1)); - Film updatedFilm = filmController.update(newFilm); - assertNotNull(updatedFilm); - assertEquals(newFilm.getName(), updatedFilm.getName()); - assertEquals(newFilm.getDescription(), updatedFilm.getDescription()); - assertEquals(newFilm.getDuration(), updatedFilm.getDuration()); - assertEquals(newFilm.getReleaseDate(), updatedFilm.getReleaseDate()); - } - - @Test - void updateWithInvalidId() { - Film newFilm = new Film(); - newFilm.setId(1); - assertThrows(ValidationException.class, () -> filmController.update(newFilm)); - } - - @Test - void updateWithInvalidName() { - Film createdFilm = filmController.create(film); - Film newFilm = new Film(); - newFilm.setId(createdFilm.getId()); - newFilm.setName(""); - newFilm.setDescription("New test description"); - newFilm.setDuration(180); - newFilm.setReleaseDate(LocalDate.of(2001, 1, 1)); - assertThrows(ValidationException.class, () -> filmController.update(newFilm)); - } - - @Test - void updateWithLongDescription() { - Film createdFilm = filmController.create(film); - Film newFilm = new Film(); - newFilm.setId(createdFilm.getId()); - newFilm.setName("New Test Film"); - newFilm.setDescription("a".repeat(201)); - newFilm.setDuration(180); - newFilm.setReleaseDate(LocalDate.of(2001, 1, 1)); - assertThrows(ValidationException.class, () -> filmController.update(newFilm)); - } - - @Test - void updateWithInvalidDuration() { - Film createdFilm = filmController.create(film); - Film newFilm = new Film(); - newFilm.setId(createdFilm.getId()); - newFilm.setName("New Test Film"); - newFilm.setDescription("New test description"); - newFilm.setDuration(0); - newFilm.setReleaseDate(LocalDate.of(2001, 1, 1)); - assertThrows(ValidationException.class, () -> filmController.update(newFilm)); - } - - @Test - void updateWithInvalidReleaseDate() { - Film createdFilm = filmController.create(film); - Film newFilm = new Film(); - newFilm.setId(createdFilm.getId()); - newFilm.setName("New Test Film"); - newFilm.setDescription("New test description"); - newFilm.setDuration(180); - newFilm.setReleaseDate(LocalDate.of(1895, 12, 27)); - assertThrows(ValidationException.class, () -> filmController.update(newFilm)); - } -} - - - */ \ No newline at end of file diff --git a/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java b/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java deleted file mode 100644 index 388d929..0000000 --- a/src/test/java/ru/yandex/practicum/filmorate/UserControllerTest.java +++ /dev/null @@ -1,148 +0,0 @@ -package ru.yandex.practicum.filmorate; -/* -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.NotFoundException; -import ru.yandex.practicum.filmorate.exception.ValidationException; -import ru.yandex.practicum.filmorate.model.User; -import ru.yandex.practicum.filmorate.service.UserService; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; - -@SpringBootTest -public class UserControllerTest { - - @Autowired - private UserService userService; - - @Test - public void testCreateUser() { - User user = new User(); - User createdUser = userService.create(user); - - assertEquals(user, createdUser); - } - - @Test - public void testUpdateUser() { - User user = new User(); - User updatedUser = userService.update(user); - - assertEquals(user, updatedUser); - } - - @Test - public void testGetUserById() { - Integer userId = 1; - User user = new User(); - User foundUser = userService.getById(userId); - - assertEquals(user, foundUser); - } - - @Test - public void testFindAllUsers() { - List users = List.of(new User(), new User()); - List allUsers = userService.findAll(); - - assertEquals(users, allUsers); - } - - @Test - public void testAddFriend() { - Integer userId = 1; - Integer friendId = 2; - User user = new User(); - User friend = new User(); - userService.addFriend(userId, friendId); - - assertTrue(user.getFriends().contains(friendId)); - assertTrue(friend.getFriends().contains(userId)); - } - - @Test - public void testAddFriendWithSameId() { - Integer userId = 1; - assertThrows(ValidationException.class, () -> userService.addFriend(userId, userId)); - } - - @Test - public void testAddFriendWithNullIds() { - assertThrows(ValidationException.class, () -> userService.addFriend(null, null)); - } - - @Test - public void testAddFriendWithNonExistentUser() { - Integer userId = 1; - Integer friendId = 2; - assertThrows(NotFoundException.class, () -> userService.addFriend(userId, friendId)); - } - - @Test - public void testAddFriendWithNonExistentFriend() { - Integer userId = 1; - Integer friendId = 2; - User user = new User(); - assertThrows(NotFoundException.class, () -> userService.addFriend(userId, friendId)); - } - - @Test - public void testDeleteFriend() { - Integer userId = 1; - Integer friendId = 2; - User user = new User(); - User friend = new User(); - userService.deleteFriend(userId, friendId); - - assertFalse(user.getFriends().contains(friendId)); - assertFalse(friend.getFriends().contains(userId)); - } - - @Test - public void testDeleteFriendWithNullIds() { - assertThrows(ValidationException.class, () -> userService.deleteFriend(null, null)); - } - - @Test - public void testDeleteFriendWithNonExistentUser() { - Integer userId = 1; - Integer friendId = 2; - assertThrows(NotFoundException.class, () -> userService.deleteFriend(userId, friendId)); - } - - @Test - public void testDeleteFriendWithNonExistentFriend() { - Integer userId = 1; - Integer friendId = 2; - User user = new User(); - assertThrows(NotFoundException.class, () -> userService.deleteFriend(userId, friendId)); - } - - @Test - public void testGetUserFriends() { - Integer userId = 1; - User user = new User(); - List friends = List.of(new User(), new User()); - List userFriends = userService.userFriends(userId); - - assertEquals(friends, userFriends); - } - - @Test - public void testGetCrossingFriends() { - Integer userId = 1; - Integer friendId = 2; - User user = new User(); - User friend = new User(); - List commonFriends = List.of(new User(), new User()); - List crossingFriends = userService.crossingFriends(userId, friendId); - - assertEquals(commonFriends, crossingFriends); - } -} - - - */ \ No newline at end of file From aa29011a4f73c27d976d665a2367347a2662180b Mon Sep 17 00:00:00 2001 From: Sergey Filippovskikh Date: Mon, 20 Jan 2025 11:34:02 +0300 Subject: [PATCH 09/10] =?UTF-8?q?=D0=A1=D0=BF=D1=80=D0=B8=D0=BD=D1=82=2011?= =?UTF-8?q?.=20=D0=A0=D0=B5=D0=B9=D1=82=D0=B8=D0=BD=D0=B3=20=D0=A4=D0=B8?= =?UTF-8?q?=D0=BB=D1=8C=D0=BC=D0=BE=D0=B2.=20=D0=A1=D0=BF=D1=80=D0=B8?= =?UTF-8?q?=D0=BD=D1=82=20=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D1=87=D0=B8=D0=BB?= =?UTF-8?q?=D1=81=D1=8F.=20=D1=84=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D0=B0=D1=8F=20=D0=BA=D0=BE=D1=81=D0=BC=D0=B5=D1=82=D0=B8=D1=87?= =?UTF-8?q?=D0=B5=D1=81=D0=BA=D0=B0=D1=8F=20=D0=BA=D0=BE=D1=80=D1=80=D0=B5?= =?UTF-8?q?=D0=BA=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B0=20=D0=BF=D0=BE?= =?UTF-8?q?=D1=81=D0=BB=D0=B5=20=D1=81=D0=B4=D0=B0=D1=87=D0=B8=20=D1=81?= =?UTF-8?q?=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 --- src/main/java/ru/yandex/practicum/filmorate/model/User.java | 1 - 1 file changed, 1 deletion(-) 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 b6f39ed..b84a37f 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/User.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -11,7 +11,6 @@ @Data @Slf4j -@Builder(toBuilder = true) public class User { private Integer id; From cba2c14888b6dea3efad0bbd5e6c83d55d41a39b Mon Sep 17 00:00:00 2001 From: Sergey Filippovskikh Date: Mon, 20 Jan 2025 11:35:57 +0300 Subject: [PATCH 10/10] =?UTF-8?q?=D0=A1=D0=BF=D1=80=D0=B8=D0=BD=D1=82=2011?= =?UTF-8?q?.=20=D0=A0=D0=B5=D0=B9=D1=82=D0=B8=D0=BD=D0=B3=20=D0=A4=D0=B8?= =?UTF-8?q?=D0=BB=D1=8C=D0=BC=D0=BE=D0=B2.=20=D0=A1=D0=BF=D1=80=D0=B8?= =?UTF-8?q?=D0=BD=D1=82=20=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D1=87=D0=B8=D0=BB?= =?UTF-8?q?=D1=81=D1=8F.=20=D1=84=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D0=B0=D1=8F=20=D0=BA=D0=BE=D1=81=D0=BC=D0=B5=D1=82=D0=B8=D1=87?= =?UTF-8?q?=D0=B5=D1=81=D0=BA=D0=B0=D1=8F=20=D0=BA=D0=BE=D1=80=D1=80=D0=B5?= =?UTF-8?q?=D0=BA=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B0=20=D0=BF=D0=BE?= =?UTF-8?q?=D1=81=D0=BB=D0=B5=20=D1=81=D0=B4=D0=B0=D1=87=D0=B8=20=D1=81?= =?UTF-8?q?=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 --- src/main/java/ru/yandex/practicum/filmorate/model/User.java | 1 - 1 file changed, 1 deletion(-) 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 b84a37f..71c1c8c 100644 --- a/src/main/java/ru/yandex/practicum/filmorate/model/User.java +++ b/src/main/java/ru/yandex/practicum/filmorate/model/User.java @@ -1,7 +1,6 @@ package ru.yandex.practicum.filmorate.model; import jakarta.validation.constraints.*; -import lombok.Builder; import lombok.Data; import lombok.extern.slf4j.Slf4j;