From 4aedaec175fdbd58295da9e0ea910769e2a880f1 Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Mon, 15 Apr 2024 19:53:42 +0400 Subject: [PATCH] lab-3 it is work --- .../ip/library/books/model/BookEntity.java | 38 ++++++++- .../favorites/api/FavoriteController.java | 56 +++++++++++++ .../favorites/service/FavoriteService.java | 47 +++++++++++ .../ip/library/users/api/UserController.java | 12 +-- .../ip/library/users/model/UserEntity.java | 29 +++++++ .../ip/library/users/service/UserService.java | 20 +---- .../test/java/com/ip/library/BooksTests.java | 1 + .../java/com/ip/library/FavoritesTests.java | 82 +++++++++++++++++++ .../test/java/com/ip/library/UsersTests.java | 41 +--------- 9 files changed, 257 insertions(+), 69 deletions(-) create mode 100644 SpringApp/library/src/main/java/com/ip/library/favorites/api/FavoriteController.java create mode 100644 SpringApp/library/src/main/java/com/ip/library/favorites/service/FavoriteService.java create mode 100644 SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java diff --git a/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java b/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java index 85831e7..01d7365 100644 --- a/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/books/model/BookEntity.java @@ -1,14 +1,20 @@ package com.ip.library.books.model; +import java.util.HashSet; import java.util.Objects; +import java.util.Set; import com.ip.library.core.model.BaseEntity; import com.ip.library.types.model.TypeEntity; +import com.ip.library.users.model.UserEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToOne; +import jakarta.persistence.OrderBy; import jakarta.persistence.Table; import com.ip.library.authors.model.AuthorEntity; @@ -20,10 +26,15 @@ public class BookEntity extends BaseEntity { private String name; @ManyToOne @JoinColumn(name = "typeId", nullable = false) + @OrderBy("id ASC") private TypeEntity type; @ManyToOne @JoinColumn(name = "authorId", nullable = false) + @OrderBy("id ASC") private AuthorEntity author; + @ManyToMany(mappedBy = "books", fetch = FetchType.EAGER) + @OrderBy("id ASC") + private Set users = new HashSet<>(); public BookEntity() { super(); @@ -59,6 +70,30 @@ public class BookEntity extends BaseEntity { this.author = author; } + public Set getUsers() { + return users; + } + + public void setUsers(Set users) { + this.users = users; + } + + public UserEntity addUser(UserEntity user) { + users.add(user); + if (!user.getBooks().contains(this)){ + user.getBooks().add(this); + } + return user; + } + + public UserEntity removeUser(UserEntity user) { + users.remove(user); + if (user.getBooks().contains(this)) { + user.getBooks().remove(this); + } + return user; + } + @Override public int hashCode() { return Objects.hash(id, type, author); @@ -74,6 +109,7 @@ public class BookEntity extends BaseEntity { return Objects.equals(other.getId(), id) && Objects.equals(other.getName(), name) && Objects.equals(other.getType(), type) - && Objects.equals(other.getAuthor(), author); + && Objects.equals(other.getAuthor(), author) + && Objects.equals(other.getUsers(), users); } } diff --git a/SpringApp/library/src/main/java/com/ip/library/favorites/api/FavoriteController.java b/SpringApp/library/src/main/java/com/ip/library/favorites/api/FavoriteController.java new file mode 100644 index 0000000..317a931 --- /dev/null +++ b/SpringApp/library/src/main/java/com/ip/library/favorites/api/FavoriteController.java @@ -0,0 +1,56 @@ +package com.ip.library.favorites.api; + +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +import org.modelmapper.ModelMapper; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; + +import com.ip.library.books.api.BookDto; +import com.ip.library.books.model.BookEntity; +import com.ip.library.core.configuration.Constants; +import com.ip.library.favorites.service.FavoriteService; + + +@RestController +@RequestMapping(Constants.API_URL + "/favorities") +public class FavoriteController { + private FavoriteService favoriteService; + private final ModelMapper modelMapper; + + public FavoriteController (FavoriteService favorityService, ModelMapper modelMapper) { + this.favoriteService = favorityService; + this.modelMapper = modelMapper; + } + private BookDto toBookDto (BookEntity entity) { + return modelMapper.map(entity, BookDto.class); + } + + @GetMapping("/user/{userId}/books/{bookId}") + public boolean addFavorite( + @PathVariable(name = "userId") Long userId, + @PathVariable(name = "bookId") Long bookId) { + return favoriteService.addFavorite(userId, bookId); + } + + @DeleteMapping("/user/{userId}/books/{bookId}") + public boolean removeFavorite( + @PathVariable(name = "userId") Long userId, + @PathVariable(name = "bookId") Long bookId) { + return favoriteService.removeFavorite(userId, bookId); + } + + @GetMapping("/user/{userId}/books") + public List getUserFavorites(@PathVariable(name = "userId") Long userId) { + return favoriteService.getUserFavorities(userId).stream().map(this::toBookDto).toList(); + } + + @GetMapping("/book/{bookId}/users/number") + public int getBookSubscribersNumber(@PathVariable(name = "bookId") Long bookId) { + return favoriteService.getBookSubscribersNumber(bookId); + } +} diff --git a/SpringApp/library/src/main/java/com/ip/library/favorites/service/FavoriteService.java b/SpringApp/library/src/main/java/com/ip/library/favorites/service/FavoriteService.java new file mode 100644 index 0000000..09682be --- /dev/null +++ b/SpringApp/library/src/main/java/com/ip/library/favorites/service/FavoriteService.java @@ -0,0 +1,47 @@ +package com.ip.library.favorites.service; + +import java.util.Set; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.ip.library.books.model.BookEntity; +import com.ip.library.books.service.BookService; +import com.ip.library.users.model.UserEntity; +import com.ip.library.users.service.UserService; +@Service +public class FavoriteService { + BookService bookService; + UserService userService; + + public FavoriteService (BookService bookService, UserService userService) { + this.bookService = bookService; + this.userService = userService; + } + + @Transactional + public boolean addFavorite(long userId, long bookId) { + final UserEntity existsUser = userService.get(userId); + final BookEntity book = bookService.get(bookId); + existsUser.addBook(book); + return true; + } + + @Transactional + public boolean removeFavorite(long userId, long bookId) { + final UserEntity existsUser = userService.get(userId); + final BookEntity book = bookService.get(bookId); + existsUser.removeBook(book); + return true; + } + + @Transactional(readOnly = true) + public Set getUserFavorities (long userId) { + return userService.get(userId).getBooks(); + } + + @Transactional(readOnly = true) + public int getBookSubscribersNumber(long bookId) { + return bookService.get(bookId).getUsers().size(); + } +} diff --git a/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java b/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java index 6da222c..978779b 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/api/UserController.java @@ -62,18 +62,8 @@ public class UserController { return toDto(userService.delete(id)); } - @PutMapping("password/{id}") + @PutMapping("/password/{id}") public UserDto changePassword(@PathVariable(name = "id") Long id, @RequestBody String newPassword) { return toDto(userService.changePassword(id, newPassword)); } - - @GetMapping("{id}/books/{bookId}") - public boolean addBook(@PathVariable(name = "id") Long id, @PathVariable(name = "bookId") Long bookId) { - return userService.addBook(id, bookId); - } - - @DeleteMapping("{id}/books/{bookId}") - public boolean removeBook(@PathVariable(name = "id") Long id, @PathVariable(name = "bookId") Long bookId) { - return userService.removeBook(id, bookId); - } } diff --git a/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java b/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java index 69fc764..6886caa 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/model/UserEntity.java @@ -7,8 +7,14 @@ import java.util.Set; import com.ip.library.books.model.BookEntity; import com.ip.library.core.model.BaseEntity; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.JoinTable; +import jakarta.persistence.ManyToMany; +import jakarta.persistence.OrderBy; import jakarta.persistence.Table; @Entity @@ -20,6 +26,13 @@ public class UserEntity extends BaseEntity { private String password; @Column(nullable = false, unique = false, length = 20) private String role = "user"; + @ManyToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) + @JoinTable( + name = "favorities", + joinColumns = { @JoinColumn(name = "userId", nullable = false) }, + inverseJoinColumns = { @JoinColumn(name = "bookId", nullable = false) } + ) + @OrderBy("id ASC") private Set books = new HashSet<>(); public UserEntity() { @@ -63,6 +76,22 @@ public class UserEntity extends BaseEntity { this.books = books; } + public BookEntity addBook(BookEntity book) { + books.add(book); + if (!book.getUsers().contains(this)) { + book.getUsers().add(this); + } + return book; + } + + public BookEntity removeBook(BookEntity book) { + books.remove(book); + if (book.getUsers().contains(this)) { + book.getUsers().remove(this); + } + return book; + } + @Override public int hashCode() { return Objects.hash(id, login, password, role); diff --git a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java index 9280612..0818d36 100644 --- a/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java +++ b/SpringApp/library/src/main/java/com/ip/library/users/service/UserService.java @@ -6,8 +6,6 @@ import java.util.stream.StreamSupport; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import com.ip.library.books.model.BookEntity; -import com.ip.library.books.service.BookService; import com.ip.library.core.error.NotFoundException; import com.ip.library.users.model.UserEntity; import com.ip.library.users.repository.UserRepository; @@ -15,11 +13,9 @@ import com.ip.library.users.repository.UserRepository; @Service public class UserService { private final UserRepository repository; - private final BookService bookService; - public UserService(UserRepository repository, BookService bookService) { + public UserService(UserRepository repository) { this.repository = repository; - this.bookService = bookService; } private void checkLoginUniqueness(String name){ @@ -82,18 +78,4 @@ public class UserService { existsEntity.setPassword(newPassword); return repository.save(existsEntity); } - - @Transactional - public boolean addBook(long id, long bookId) { - final UserEntity existsEntity = get(id); - final BookEntity book = bookService.get(bookId); - return existsEntity.getBooks().add(book); - } - - @Transactional - public boolean removeBook(long id, long bookId) { - final UserEntity existsEntity = get(id); - final BookEntity book = bookService.get(bookId); - return existsEntity.getBooks().remove(book); - } } diff --git a/SpringApp/library/src/test/java/com/ip/library/BooksTests.java b/SpringApp/library/src/test/java/com/ip/library/BooksTests.java index f3addf7..e50f654 100644 --- a/SpringApp/library/src/test/java/com/ip/library/BooksTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/BooksTests.java @@ -52,6 +52,7 @@ class BooksTests { Assertions.assertEquals("book3", book.getName()); Assertions.assertEquals(type, book.getType()); Assertions.assertEquals(author, book.getAuthor()); + Assertions.assertEquals(0, book.getUsers().size()); } @Test diff --git a/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java b/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java new file mode 100644 index 0000000..11a8bb6 --- /dev/null +++ b/SpringApp/library/src/test/java/com/ip/library/FavoritesTests.java @@ -0,0 +1,82 @@ +package com.ip.library; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import com.ip.library.authors.model.AuthorEntity; +import com.ip.library.authors.service.AuthorService; +import com.ip.library.books.model.BookEntity; +import com.ip.library.books.service.BookService; +import com.ip.library.favorites.service.FavoriteService; +import com.ip.library.types.model.TypeEntity; +import com.ip.library.types.service.TypeService; +import com.ip.library.users.model.UserEntity; +import com.ip.library.users.service.UserService; + +@SpringBootTest +class FavoritesTests { + @Autowired + private FavoriteService favorityService; + @Autowired + private BookService bookService; + @Autowired + private UserService userService; + @Autowired + private TypeService typeService; + @Autowired + private AuthorService authorService; + private UserEntity user; + private BookEntity book1; + private BookEntity book2; + + @AfterEach + void removeData() { + bookService.getAll().forEach(item -> bookService.delete(item.getId())); + authorService.getAll().forEach(item -> authorService.delete(item.getId())); + typeService.getAll().forEach(item -> typeService.delete(item.getId())); + userService.getAll().forEach(item -> userService.delete(item.getId())); + } + + @BeforeEach + void createData() { + removeData(); + TypeEntity type = typeService.create(new TypeEntity("type1")); + AuthorEntity author = authorService.create(new AuthorEntity("author1")); + book1 = bookService.create(new BookEntity("book1", type, author)); + book2 = bookService.create(new BookEntity("book2", type, author)); + userService.create(new UserEntity("user1", "123")); + userService.create(new UserEntity("user2", "456")); + user = userService.create(new UserEntity("user3", "aqw2sed45")); + } + + @Test + void addAndRemoveTest() { + Assertions.assertEquals(0, user.getBooks().size()); + Assertions.assertEquals(0, book1.getUsers().size()); + Assertions.assertEquals(0, book2.getUsers().size()); + favorityService.addFavorite(user.getId(), book1.getId()); + user = userService.get(user.getId()); + book1 = bookService.get(book1.getId()); + Assertions.assertEquals(1, user.getBooks().size()); + Assertions.assertEquals(1, book1.getUsers().size()); + favorityService.addFavorite(user.getId(), book2.getId()); + user = userService.get(user.getId()); + book2 = bookService.get(book2.getId()); + Assertions.assertEquals(2, user.getBooks().size()); + Assertions.assertEquals(1, book2.getUsers().size()); + favorityService.removeFavorite(user.getId(), book1.getId()); + user = userService.get(user.getId()); + book1 = bookService.get(book1.getId()); + Assertions.assertEquals(1, user.getBooks().size()); + Assertions.assertEquals(0, book1.getUsers().size()); + favorityService.removeFavorite(user.getId(), book2.getId()); + user = userService.get(user.getId()); + book2 = bookService.get(book2.getId()); + Assertions.assertEquals(0, user.getBooks().size()); + Assertions.assertEquals(0, book2.getUsers().size()); + } +} diff --git a/SpringApp/library/src/test/java/com/ip/library/UsersTests.java b/SpringApp/library/src/test/java/com/ip/library/UsersTests.java index a648407..3feb106 100644 --- a/SpringApp/library/src/test/java/com/ip/library/UsersTests.java +++ b/SpringApp/library/src/test/java/com/ip/library/UsersTests.java @@ -7,45 +7,24 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import com.ip.library.authors.model.AuthorEntity; -import com.ip.library.authors.service.AuthorService; -import com.ip.library.books.model.BookEntity; -import com.ip.library.books.service.BookService; import com.ip.library.core.error.NotFoundException; -import com.ip.library.types.model.TypeEntity; -import com.ip.library.types.service.TypeService; import com.ip.library.users.model.UserEntity; import com.ip.library.users.service.UserService; @SpringBootTest class UsersTests { - @Autowired - private BookService bookService; - @Autowired - private TypeService typeService; - @Autowired - private AuthorService authorService; @Autowired private UserService userService; private UserEntity user; - private BookEntity book1; - private BookEntity book2; @AfterEach void removeData() { - authorService.getAll().forEach(item -> authorService.delete(item.getId())); - bookService.getAll().forEach(item -> bookService.delete(item.getId())); - typeService.getAll().forEach(item -> typeService.delete(item.getId())); userService.getAll().forEach(item -> userService.delete(item.getId())); } @BeforeEach void createData() { removeData(); - var type = typeService.create(new TypeEntity("type1")); - var author = authorService.create(new AuthorEntity("author1")); - book1 = bookService.create(new BookEntity("book1", type, author)); - book2 = bookService.create(new BookEntity("book2", type, author)); userService.create(new UserEntity("user1", "123")); userService.create(new UserEntity("user2", "456")); user = userService.create(new UserEntity("user3", "aqw2sed45")); @@ -93,30 +72,16 @@ class UsersTests { @Test void changePasswordTest() { String newPassword = user.getPassword() + "TEST"; - userService.changePassword(user.getId(), newPassword); + user = userService.changePassword(user.getId(), newPassword); Assertions.assertEquals(newPassword, user.getPassword()); } @Test void changeRoleTest() { Assertions.assertEquals("user", user.getRole()); - userService.giveAdminRole(user.getId()); + user = userService.giveAdminRole(user.getId()); Assertions.assertEquals("admin", user.getRole()); - userService.giveUserRole(user.getId()); + user = userService.giveUserRole(user.getId()); Assertions.assertEquals("user", user.getRole()); } - - @Test - void BooksTest() { - Assertions.assertEquals(0, user.getBooks().size()); - userService.addBook(user.getId(), book1.getId()); - Assertions.assertEquals(1, user.getBooks().size()); - userService.addBook(user.getId(), book2.getId()); - Assertions.assertEquals(2, user.getBooks().size()); - Assertions.assertEquals(2, user.getBooks().size()); - userService.removeBook(user.getId(), book1.getId()); - Assertions.assertEquals(1, user.getBooks().size()); - userService.removeBook(user.getId(), book2.getId()); - Assertions.assertEquals(0, user.getBooks().size()); - } }