From e3e81340e52e078de78496c669f4676014282fd1 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Fri, 3 Feb 2023 18:01:31 +0300 Subject: [PATCH 01/45] IT SHOULD WORKKKKKKK --- pom.xml | 481 +++++++++--------- .../java/ru/practicum/shareit/ShareItApp.java | 1 + .../shareit/booking/BookingController.java | 56 +- .../shareit/booking/BookingMapper.java | 69 +++ .../shareit/booking/BookingRepository.java | 60 +++ .../ru/practicum/shareit/booking/State.java | 5 + .../shareit/booking/dto/BookingDTO.java | 24 + .../booking/dto/BookingDTOForItem.java | 12 + .../booking/dto/BookingDTOToReturn.java | 24 + .../shareit/booking/model/Booking.java | 55 ++ .../booking/service/BookingService.java | 18 + .../booking/service/BookingServiceImpl.java | 179 +++++++ .../exception/BadRequestException.java | 7 + .../shareit/exception/ConflictException.java | 7 + .../shareit/exception/ErrorHandler.java | 69 +++ .../shareit/exception/ForbiddenException.java | 7 + .../shareit/exception/NotFoundException.java | 11 + .../exception/StatusBadRequestException.java | 11 + .../shareit/item/CommentRepository.java | 11 + .../shareit/item/ItemController.java | 59 ++- .../shareit/item/ItemRepository.java | 18 + .../practicum/shareit/item/dto/ItemDTO.java | 28 + .../shareit/item/dto/ItemDTOWithComment.java | 23 + .../shareit/item/dto/ItemDTOWithDate.java | 35 ++ .../shareit/item/mapper/CommentMapper.java | 41 ++ .../shareit/item/mapper/ItemMapper.java | 74 +++ .../practicum/shareit/item/model/Comment.java | 52 ++ .../ru/practicum/shareit/item/model/Item.java | 51 +- .../shareit/item/service/ItemService.java | 22 + .../shareit/item/service/ItemServiceImpl.java | 158 ++++++ .../item/storage/ItemInMemoryStorage.java | 85 ++++ .../shareit/item/storage/ItemStorage.java | 22 + .../request/ItemRequestController.java | 3 - .../shareit/request/dto/ItemRequestDto.java | 17 +- .../shareit/request/model/ItemRequest.java | 29 ++ .../shareit/user/UserController.java | 47 +- .../ru/practicum/shareit/user/UserMapper.java | 36 ++ .../shareit/user/UserRepository.java | 7 + .../practicum/shareit/user/dto/UserDTO.java | 19 + .../ru/practicum/shareit/user/model/User.java | 44 ++ .../shareit/user/service/UserService.java | 17 + .../shareit/user/service/UserServiceImpl.java | 69 +++ .../user/storage/UserInMemoryStorage.java | 68 +++ .../shareit/user/storage/UserStorage.java | 19 + src/main/resources/application.properties | 18 +- src/main/resources/schema.sql | 55 ++ 46 files changed, 1957 insertions(+), 266 deletions(-) create mode 100644 src/main/java/ru/practicum/shareit/booking/BookingMapper.java create mode 100644 src/main/java/ru/practicum/shareit/booking/BookingRepository.java create mode 100644 src/main/java/ru/practicum/shareit/booking/State.java create mode 100644 src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java create mode 100644 src/main/java/ru/practicum/shareit/booking/dto/BookingDTOForItem.java create mode 100644 src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java create mode 100644 src/main/java/ru/practicum/shareit/booking/model/Booking.java create mode 100644 src/main/java/ru/practicum/shareit/booking/service/BookingService.java create mode 100644 src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java create mode 100644 src/main/java/ru/practicum/shareit/exception/BadRequestException.java create mode 100644 src/main/java/ru/practicum/shareit/exception/ConflictException.java create mode 100644 src/main/java/ru/practicum/shareit/exception/ErrorHandler.java create mode 100644 src/main/java/ru/practicum/shareit/exception/ForbiddenException.java create mode 100644 src/main/java/ru/practicum/shareit/exception/NotFoundException.java create mode 100644 src/main/java/ru/practicum/shareit/exception/StatusBadRequestException.java create mode 100644 src/main/java/ru/practicum/shareit/item/CommentRepository.java create mode 100644 src/main/java/ru/practicum/shareit/item/ItemRepository.java create mode 100644 src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java create mode 100644 src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithComment.java create mode 100644 src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java create mode 100644 src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java create mode 100644 src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java create mode 100644 src/main/java/ru/practicum/shareit/item/model/Comment.java create mode 100644 src/main/java/ru/practicum/shareit/item/service/ItemService.java create mode 100644 src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java create mode 100644 src/main/java/ru/practicum/shareit/item/storage/ItemInMemoryStorage.java create mode 100644 src/main/java/ru/practicum/shareit/item/storage/ItemStorage.java create mode 100644 src/main/java/ru/practicum/shareit/request/model/ItemRequest.java create mode 100644 src/main/java/ru/practicum/shareit/user/UserMapper.java create mode 100644 src/main/java/ru/practicum/shareit/user/UserRepository.java create mode 100644 src/main/java/ru/practicum/shareit/user/dto/UserDTO.java create mode 100644 src/main/java/ru/practicum/shareit/user/model/User.java create mode 100644 src/main/java/ru/practicum/shareit/user/service/UserService.java create mode 100644 src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java create mode 100644 src/main/java/ru/practicum/shareit/user/storage/UserInMemoryStorage.java create mode 100644 src/main/java/ru/practicum/shareit/user/storage/UserStorage.java create mode 100644 src/main/resources/schema.sql diff --git a/pom.xml b/pom.xml index 870ae8526..0efdef4b2 100644 --- a/pom.xml +++ b/pom.xml @@ -1,241 +1,260 @@ - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.7.2 - - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.7.2 + + - ru.practicum - shareit - 0.0.1-SNAPSHOT + ru.practicum + shareit + 0.0.1-SNAPSHOT - ShareIt + ShareIt - - 11 - + + 11 + - - - org.springframework.boot - spring-boot-starter-web - + + + org.springframework.boot + spring-boot-starter-web + - - org.postgresql - postgresql - runtime - - - com.h2database - h2 - runtime - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.projectlombok - lombok - true - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.boot - spring-boot-starter-validation - - + + org.postgresql + postgresql + runtime + + + org.hibernate.validator + hibernate-validator + 6.0.10.Final + + + org.springframework.boot + spring-boot-starter-validation + + + com.h2database + h2 + runtime + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + org.mockito + mockito-core + test + + + org.springframework.boot + spring-boot-starter + - - - - src/main/resources - true - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - org.projectlombok - lombok - - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - test - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - 3.1.2 - - checkstyle.xml - true - true - true - - - - - check - - compile - - - - - com.puppycrawl.tools - checkstyle - 10.3 - - - - - com.github.spotbugs - spotbugs-maven-plugin - 4.7.0.0 - - Max - High - - - - - check - - - - - - org.jacoco - jacoco-maven-plugin - 0.8.8 - - file - - - - jacoco-initialize - - prepare-agent - - - - jacoco-check - - check - - - - - BUNDLE - - - INSTRUCTION - COVEREDRATIO - 0.01 - - - LINE - COVEREDRATIO - 0.9 - - - BRANCH - COVEREDRATIO - 0.6 - - - COMPLEXITY - COVEREDRATIO - 0.6 - - - METHOD - COVEREDRATIO - 0.7 - - - CLASS - MISSEDCOUNT - 1 - - - - - - - - jacoco-report - test - - report - - - - - - - - - - check - - - - org.apache.maven.plugins - maven-checkstyle-plugin - - - com.github.spotbugs - spotbugs-maven-plugin - - - - - - - com.github.spotbugs - spotbugs-maven-plugin - - - - - - coverage - - - - org.jacoco - jacoco-maven-plugin - - - - - + + org.springframework.boot + spring-boot-starter-data-jpa + + + + + + + src/main/resources + true + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + test + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.1.2 + + checkstyle.xml + true + true + true + + + + + check + + compile + + + + + com.puppycrawl.tools + checkstyle + 10.3 + + + + + com.github.spotbugs + spotbugs-maven-plugin + 4.7.0.0 + + Max + High + + + + + check + + + + + + org.jacoco + jacoco-maven-plugin + 0.8.8 + + file + + + + jacoco-initialize + + prepare-agent + + + + jacoco-check + + check + + + + + BUNDLE + + + INSTRUCTION + COVEREDRATIO + 0.01 + + + LINE + COVEREDRATIO + 0.9 + + + BRANCH + COVEREDRATIO + 0.6 + + + COMPLEXITY + COVEREDRATIO + 0.6 + + + METHOD + COVEREDRATIO + 0.7 + + + CLASS + MISSEDCOUNT + 1 + + + + + + + + jacoco-report + test + + report + + + + + + + + + + check + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + com.github.spotbugs + spotbugs-maven-plugin + + + + + + + com.github.spotbugs + spotbugs-maven-plugin + + + + + + coverage + + + + org.jacoco + jacoco-maven-plugin + + + + + diff --git a/src/main/java/ru/practicum/shareit/ShareItApp.java b/src/main/java/ru/practicum/shareit/ShareItApp.java index a00ad567d..b69dbb5a6 100644 --- a/src/main/java/ru/practicum/shareit/ShareItApp.java +++ b/src/main/java/ru/practicum/shareit/ShareItApp.java @@ -7,6 +7,7 @@ public class ShareItApp { public static void main(String[] args) { + SpringApplication.run(ShareItApp.class, args); } diff --git a/src/main/java/ru/practicum/shareit/booking/BookingController.java b/src/main/java/ru/practicum/shareit/booking/BookingController.java index b94493d49..a75d450b7 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingController.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingController.java @@ -1,12 +1,58 @@ package ru.practicum.shareit.booking; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import ru.practicum.shareit.booking.dto.BookingDTO; +import ru.practicum.shareit.booking.dto.BookingDTOToReturn; +import ru.practicum.shareit.booking.service.BookingService; + +import java.util.Collection; -/** - * TODO Sprint add-bookings. - */ @RestController @RequestMapping(path = "/bookings") +@RequiredArgsConstructor(onConstructor_ = @Autowired) +@Slf4j public class BookingController { + private final BookingService bookingService; + + @PostMapping + public BookingDTOToReturn addBooking(@RequestHeader("X-Sharer-User-Id") Long userId, + @RequestBody BookingDTO bookingDto) { + log.info("Добавление запроса на аренду пользователем с id {}", userId); + return bookingService.addBooking(userId, bookingDto); + } + + @PatchMapping("/{bookingId}") + public BookingDTOToReturn updateStatusBooking(@RequestHeader("X-Sharer-User-Id") Long userId, + @PathVariable Long bookingId, + @RequestParam Boolean approved) { + log.info("Обновление статуса запроса на аренду с id {}", bookingId); + return bookingService.updateStatusBooking(userId, bookingId, approved); + + } + + @GetMapping("/{bookingId}") + public BookingDTOToReturn getBooking(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long bookingId) { + log.info("Просмотр запроса на пренду с id {}", bookingId); + return bookingService.getBooking(userId, bookingId); + } + + @GetMapping + public Collection findBookingByBooker(@RequestHeader("X-Sharer-User-Id") Long userId, + @RequestParam(required = false) + String state) { + log.info("Получение списка бронирований пользовалеля с id {}", userId); + return bookingService.getBookingByBooker(userId, state); + } + + @GetMapping("/owner") + public Collection findBookingByOwner(@RequestHeader("X-Sharer-User-Id") Long userId, + @RequestParam(required = false) + String state) { + log.info("Получение списка бронирований для всех вещей пользователя с id {}", userId); + return bookingService.getBookingByOwner(userId, state); + } + } diff --git a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java new file mode 100644 index 000000000..35cbe56e9 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java @@ -0,0 +1,69 @@ +package ru.practicum.shareit.booking; + +import org.springframework.stereotype.Component; +import ru.practicum.shareit.booking.dto.BookingDTO; +import ru.practicum.shareit.booking.dto.BookingDTOForItem; +import ru.practicum.shareit.booking.dto.BookingDTOToReturn; +import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Component +public class BookingMapper { + + public static BookingDTO toBookingDto(Booking booking) { + BookingDTO bookingDto = new BookingDTO(); + bookingDto.setId(booking.getId()); + bookingDto.setStart(booking.getStart()); + bookingDto.setEnd(booking.getEnd()); + bookingDto.setStatus(booking.getStatus()); + bookingDto.setItemId(booking.getItem() != null ? booking.getItem().getId() : null); + bookingDto.setItemName(booking.getItem() != null ? booking.getItem().getName() : null); + bookingDto.setBookerId(booking.getBooker() != null ? booking.getBooker().getId() : null); + return bookingDto; + } + + + public static BookingDTOToReturn toBookingDtoFrom(Booking booking) { + BookingDTOToReturn bookingDto = new BookingDTOToReturn(); + bookingDto.setId(booking.getId()); + bookingDto.setStart(booking.getStart()); + bookingDto.setEnd(booking.getEnd()); + bookingDto.setStatus(booking.getStatus()); + bookingDto.setItem(booking.getItem()); + bookingDto.setBooker(booking.getBooker()); + return bookingDto; + } + + public static Booking toBooking(BookingDTO bookingDto, Item item, User user) { + Booking booking = new Booking(); + booking.setStart(bookingDto.getStart()); + booking.setEnd(bookingDto.getEnd()); + booking.setId(bookingDto.getId()); + booking.setStatus(bookingDto.getStatus()); + booking.setItem(item); + booking.setBooker(user); + return booking; + } + + public static BookingDTOForItem toBookingDtoForItem(Booking booking, LocalDateTime dateTime) { + BookingDTOForItem bookingDtoForItem = new BookingDTOForItem(); + bookingDtoForItem.setId(booking.getId()); + bookingDtoForItem.setBookerId(booking.getBooker().getId()); + bookingDtoForItem.setDateTime(dateTime); + return bookingDtoForItem; + } + + + public static List mapToBookingDtoFrom(Iterable bookings) { + List dtos = new ArrayList<>(); + for (Booking booking : bookings) { + dtos.add(toBookingDtoFrom(booking)); + } + return dtos; + } +} diff --git a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java new file mode 100644 index 000000000..50c17dfe2 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java @@ -0,0 +1,60 @@ +package ru.practicum.shareit.booking; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; +import java.util.List; + +public interface BookingRepository extends JpaRepository { + + List findByItemOrderByStartDesc(Item item); + + List findByBookerAndStatusOrderByStartDesc(User booker, State status); + + List findByBookerOrderByStartDesc(User booker); + + List findByBookerAndStartAfterOrderByStartDesc(User booker, LocalDateTime now); + + List findByBookerAndStartBeforeAndEndAfterOrderByStartDesc(User booker, LocalDateTime s, LocalDateTime e); + + List findByBookerAndStartBeforeAndEndBeforeOrderByStartDesc(User booker, LocalDateTime s, + LocalDateTime e); + + List findByItemAndBookerAndStartBeforeAndEndBefore(Item item, User booker, LocalDateTime s, + LocalDateTime e); + + @Query(nativeQuery = true, value = "SELECT * FROM BOOKINGS as b " + + "LEFT JOIN ITEMS as i ON b.ITEM_ID = i.ID " + + "WHERE i.OWNER_ID = ?1 AND b.END_DATE < ?2 AND b.START_DATE < ?3 " + + "ORDER BY b.START_DATE DESC") + List findByBookingForOwnerWithPast(Long i, LocalDateTime e, LocalDateTime s); + + @Query(nativeQuery = true, value = "SELECT * FROM BOOKINGS as b " + + "LEFT JOIN ITEMS as i ON b.ITEM_ID = i.ID " + + "WHERE i.OWNER_ID = ?1 AND b.START_DATE < ?2 AND b.END_DATE > ?3 " + + "ORDER BY b.START_DATE DESC") + List findByBookingForOwnerWithCurrent(Long i, LocalDateTime s, LocalDateTime e); + + @Query(nativeQuery = true, value = "SELECT * FROM BOOKINGS as b " + + "LEFT JOIN ITEMS as i ON b.ITEM_ID = i.ID " + + "WHERE i.OWNER_ID = ?1 AND b.START_DATE > ?2 " + + "ORDER BY b.START_DATE DESC") + List findByBookingForOwnerWithFuture(Long i, LocalDateTime s); + + @Query(nativeQuery = true, value = "SELECT * FROM BOOKINGS as b " + + "LEFT JOIN ITEMS as i ON b.ITEM_ID = i.ID " + + "WHERE i.OWNER_ID = ?1 " + + "ORDER BY b.START_DATE DESC") + List findByBookingForOwnerWithAll(Long i); + + @Query(nativeQuery = true, value = "SELECT * FROM BOOKINGS as b " + + "LEFT JOIN ITEMS as i ON b.ITEM_ID = i.ID " + + "WHERE i.OWNER_ID = ?1 AND b.STATUS LIKE ?2 " + + "ORDER BY b.START_DATE DESC") + List findByBookingForOwnerWithWaitingOrRejected(Long i, String status); + +} diff --git a/src/main/java/ru/practicum/shareit/booking/State.java b/src/main/java/ru/practicum/shareit/booking/State.java new file mode 100644 index 000000000..429348b1c --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/State.java @@ -0,0 +1,5 @@ +package ru.practicum.shareit.booking; + +public enum State { + WAITING, APPROVED, REJECTED, CANCELED; +} diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java new file mode 100644 index 000000000..3ebb00d24 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java @@ -0,0 +1,24 @@ +package ru.practicum.shareit.booking.dto; + +import lombok.Data; +import ru.practicum.shareit.booking.State; + +import java.time.LocalDateTime; + +@Data +public class BookingDTO { + + private long id; + + private LocalDateTime start; + + private LocalDateTime end; + + private Long itemId; + + private String itemName; + + private Long bookerId; + + private State status; +} diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOForItem.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOForItem.java new file mode 100644 index 000000000..44b3f9077 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOForItem.java @@ -0,0 +1,12 @@ +package ru.practicum.shareit.booking.dto; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class BookingDTOForItem { + private long id; + private Long bookerId; + private LocalDateTime dateTime; +} diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java new file mode 100644 index 000000000..fefbdd7fa --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java @@ -0,0 +1,24 @@ +package ru.practicum.shareit.booking.dto; + +import lombok.Data; +import ru.practicum.shareit.booking.State; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; + +@Data +public class BookingDTOToReturn { + + private long id; + + private LocalDateTime start; + + private LocalDateTime end; + + private Item item; + + private User booker; + + private State status; +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/booking/model/Booking.java b/src/main/java/ru/practicum/shareit/booking/model/Booking.java new file mode 100644 index 000000000..defb511b1 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/model/Booking.java @@ -0,0 +1,55 @@ +package ru.practicum.shareit.booking.model; + +import lombok.*; +import org.hibernate.Hibernate; +import ru.practicum.shareit.booking.State; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.model.User; + +import javax.persistence.*; +import java.time.LocalDateTime; +import java.util.Objects; + +@Entity +@Table(name = "bookings", schema = "public") +@Getter +@Setter +@ToString +@RequiredArgsConstructor +public class Booking { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column(name = "start_date") + private LocalDateTime start; + + @Column(name = "end_date") + private LocalDateTime end; + + @ManyToOne + @JoinColumn(name = "item_id") + private Item item; + + @OneToOne + @JoinColumn(name = "booker_id") + private User booker; + + @Enumerated(EnumType.STRING) + @Column(nullable = false) + private State status; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + Booking booking = (Booking) o; + return id != 0 && Objects.equals(id, booking.id); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } +} diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingService.java b/src/main/java/ru/practicum/shareit/booking/service/BookingService.java new file mode 100644 index 000000000..3716e6a1a --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingService.java @@ -0,0 +1,18 @@ +package ru.practicum.shareit.booking.service; + +import ru.practicum.shareit.booking.dto.BookingDTO; +import ru.practicum.shareit.booking.dto.BookingDTOToReturn; + +import java.util.Collection; + +public interface BookingService { + BookingDTOToReturn addBooking(Long userId, BookingDTO bookingDto); + + BookingDTOToReturn updateStatusBooking(Long userId, Long bookingId, Boolean approved); + + BookingDTOToReturn getBooking(Long bookingId, Long userId); + + Collection getBookingByBooker(Long usersId, String state); + + Collection getBookingByOwner(Long usersId, String status); +} diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java new file mode 100644 index 000000000..bfe4702db --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java @@ -0,0 +1,179 @@ +package ru.practicum.shareit.booking.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import ru.practicum.shareit.booking.BookingMapper; +import ru.practicum.shareit.booking.BookingRepository; +import ru.practicum.shareit.booking.State; +import ru.practicum.shareit.booking.dto.BookingDTO; +import ru.practicum.shareit.booking.dto.BookingDTOToReturn; +import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.exception.BadRequestException; +import ru.practicum.shareit.exception.StatusBadRequestException; +import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.item.ItemRepository; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.UserRepository; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; +import java.util.*; + +@Service + +@RequiredArgsConstructor(onConstructor_ = @Autowired) +public class BookingServiceImpl implements BookingService { + + private final BookingRepository bRepository; + private final ItemRepository iRepository; + private final UserRepository uRepository; + + @Transactional + @Override + public BookingDTOToReturn addBooking(Long userId, BookingDTO bookingDto) { + Optional item = iRepository.findById(bookingDto.getItemId()); + Optional user = uRepository.findById(userId); + if (user.isEmpty()) { + throw new NotFoundException("User not found"); + } + if (item.isPresent() && !item.get().getAvailable()) { + throw new BadRequestException("You can not book this item"); + } + if (item.isEmpty()) { + throw new NotFoundException("Cannot create booking"); + } + if (Objects.equals(item.get().getOwner().getId(), userId)) { + throw new NotFoundException("You cannot book your item"); + } + if (bookingDto.getEnd().isBefore(LocalDateTime.now()) || + bookingDto.getStart().isBefore(LocalDateTime.now()) || + (bookingDto.getEnd().isBefore(bookingDto.getStart()) && + !bookingDto.getEnd().equals(bookingDto.getStart()))) { + throw new BadRequestException("Wrong date"); + } + bookingDto.setBookerId(userId); + bookingDto.setStatus(State.WAITING); + Booking booking = bRepository.save(BookingMapper.toBooking(bookingDto, item.get(), user.get())); + return BookingMapper.toBookingDtoFrom(booking); + } + + @Transactional + @Override + public BookingDTOToReturn updateStatusBooking(Long userId, Long bookingId, Boolean approved) { + Booking booking; + if (bRepository.existsById(bookingId)) { + booking = bRepository.getReferenceById(bookingId); + } else { + throw new NotFoundException("Booking is empty"); + } + Long ownerId = booking.getItem().getOwner().getId(); + + if (!Objects.equals(userId, ownerId)) { + throw new NotFoundException("No rights"); + } + + if (!Objects.equals(String.valueOf(booking.getStatus()), "WAITING")) { + throw new BadRequestException("Status has already been changed"); + } + + if (approved) { + booking.setStatus(State.APPROVED); + } else { + booking.setStatus(State.REJECTED); + } + return BookingMapper.toBookingDtoFrom(bRepository.save(booking)); + } + + @Override + public BookingDTOToReturn getBooking(Long userId, Long bookingId) { + Booking booking; + if (bRepository.existsById(bookingId)) { + booking = bRepository.getReferenceById(bookingId); + } else { + throw new NotFoundException("Booking not found"); + } + Long ownerId = booking.getItem().getOwner().getId(); + Long bookerId = booking.getBooker().getId(); + if (Objects.equals(ownerId, userId) || Objects.equals(bookerId, userId)) { + return BookingMapper.toBookingDtoFrom(booking); + } + throw new NotFoundException("No rights"); + } + + @Override + public Collection getBookingByBooker(Long usersId, String status) { + Optional booker = uRepository.findById(usersId); + List bookingsByBooker; + if (booker.isEmpty()) { + throw new NotFoundException("No rights"); + } + if (status == null || status.equals("")) { + status = "ALL"; + } + switch (status) { + case "ALL": + bookingsByBooker = bRepository.findByBookerOrderByStartDesc(booker.get()); + break; + case "CURRENT": + bookingsByBooker = bRepository.findByBookerAndStartBeforeAndEndAfterOrderByStartDesc(booker.get(), + LocalDateTime.now(), LocalDateTime.now()); + break; + case "PAST": + bookingsByBooker = bRepository.findByBookerAndStartBeforeAndEndBeforeOrderByStartDesc(booker.get(), + LocalDateTime.now(), LocalDateTime.now()); + break; + case "FUTURE": + bookingsByBooker = bRepository.findByBookerAndStartAfterOrderByStartDesc(booker.get(), + LocalDateTime.now()); + break; + case "WAITING": + bookingsByBooker = bRepository.findByBookerAndStatusOrderByStartDesc(booker.get(), State.WAITING); + break; + case "REJECTED": + bookingsByBooker = bRepository.findByBookerAndStatusOrderByStartDesc(booker.get(), State.REJECTED); + break; + default: + throw new StatusBadRequestException("Unknown state: UNSUPPORTED_STATUS"); + } + return BookingMapper.mapToBookingDtoFrom(bookingsByBooker); + } + + @Override + public Collection getBookingByOwner(Long usersId, String status) { + Optional owner = uRepository.findById(usersId); + List bookingsByOwner; + if (owner.isEmpty()) { + throw new NotFoundException("No rights"); + } + if (status == null || status.equals("")) { + status = "ALL"; + } + switch (status) { + case "ALL": + bookingsByOwner = bRepository.findByBookingForOwnerWithAll(usersId); + break; + case "CURRENT": + bookingsByOwner = bRepository.findByBookingForOwnerWithCurrent(usersId, LocalDateTime.now(), + LocalDateTime.now()); + break; + case "PAST": + bookingsByOwner = bRepository.findByBookingForOwnerWithPast(usersId, LocalDateTime.now(), + LocalDateTime.now()); + break; + case "FUTURE": + bookingsByOwner = bRepository.findByBookingForOwnerWithFuture(usersId, LocalDateTime.now()); + break; + case "WAITING": + bookingsByOwner = bRepository.findByBookingForOwnerWithWaitingOrRejected(usersId, "WAITING"); + break; + case "REJECTED": + bookingsByOwner = bRepository.findByBookingForOwnerWithWaitingOrRejected(usersId, "REJECTED"); + break; + default: + throw new StatusBadRequestException("Unknown state: UNSUPPORTED_STATUS"); + } + return BookingMapper.mapToBookingDtoFrom(bookingsByOwner); + } +} diff --git a/src/main/java/ru/practicum/shareit/exception/BadRequestException.java b/src/main/java/ru/practicum/shareit/exception/BadRequestException.java new file mode 100644 index 000000000..2d29b341e --- /dev/null +++ b/src/main/java/ru/practicum/shareit/exception/BadRequestException.java @@ -0,0 +1,7 @@ +package ru.practicum.shareit.exception; + +public class BadRequestException extends IllegalArgumentException { + public BadRequestException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/practicum/shareit/exception/ConflictException.java b/src/main/java/ru/practicum/shareit/exception/ConflictException.java new file mode 100644 index 000000000..788512303 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/exception/ConflictException.java @@ -0,0 +1,7 @@ +package ru.practicum.shareit.exception; + +public class ConflictException extends RuntimeException { + public ConflictException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java b/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java new file mode 100644 index 000000000..91204e8d4 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java @@ -0,0 +1,69 @@ +package ru.practicum.shareit.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageConversionException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.util.Map; + +@RestControllerAdvice +public class ErrorHandler { + + @ExceptionHandler({HttpMessageConversionException.class, BadRequestException.class}) + public ResponseEntity> handleValid(final RuntimeException e) { + return new ResponseEntity<>( + Map.of("Ошибка в валидации", e.getMessage()), + HttpStatus.BAD_REQUEST + ); + } + + @ExceptionHandler + public ResponseEntity> handleValidation(final MethodArgumentNotValidException e) { + return new ResponseEntity<>( + Map.of("Ошибка в валидации", e.getMessage()), + HttpStatus.BAD_REQUEST + ); + } + + @ExceptionHandler + public ResponseEntity> handleNotFound(final NotFoundException e) { + return new ResponseEntity<>( + Map.of("Объект не найден", e.getMessage()), + HttpStatus.NOT_FOUND + ); + } + + @ExceptionHandler + public ResponseEntity> handleStatus(final StatusBadRequestException e) { + return new ResponseEntity<>( + Map.of("error", e.getMessage()), + HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler + public ResponseEntity> handleForbiddenError(final ForbiddenException e) { + return new ResponseEntity<>( + Map.of("Отказано в доступе", e.getMessage()), + HttpStatus.FORBIDDEN + ); + } + + @ExceptionHandler + public ResponseEntity> handleInternalServerError(final Exception e) { + return new ResponseEntity<>( + Map.of("Серверу не удается обработать запрос", e.getMessage()), + HttpStatus.INTERNAL_SERVER_ERROR + ); + } + + @ExceptionHandler + public ResponseEntity> handleConflictError(final ConflictException e) { + return new ResponseEntity<>( + Map.of("Запрос не может быть выполнен из-за конфликтного обращения к ресурсу", e.getMessage()), + HttpStatus.CONFLICT + ); + } +} diff --git a/src/main/java/ru/practicum/shareit/exception/ForbiddenException.java b/src/main/java/ru/practicum/shareit/exception/ForbiddenException.java new file mode 100644 index 000000000..926615376 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/exception/ForbiddenException.java @@ -0,0 +1,7 @@ +package ru.practicum.shareit.exception; + +public class ForbiddenException extends RuntimeException { + public ForbiddenException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/practicum/shareit/exception/NotFoundException.java b/src/main/java/ru/practicum/shareit/exception/NotFoundException.java new file mode 100644 index 000000000..74bf630cf --- /dev/null +++ b/src/main/java/ru/practicum/shareit/exception/NotFoundException.java @@ -0,0 +1,11 @@ +package ru.practicum.shareit.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(HttpStatus.NOT_FOUND) +public class NotFoundException extends RuntimeException { + public NotFoundException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/practicum/shareit/exception/StatusBadRequestException.java b/src/main/java/ru/practicum/shareit/exception/StatusBadRequestException.java new file mode 100644 index 000000000..d8817ac67 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/exception/StatusBadRequestException.java @@ -0,0 +1,11 @@ +package ru.practicum.shareit.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(HttpStatus.NOT_FOUND) +public class StatusBadRequestException extends RuntimeException { + public StatusBadRequestException(String s) { + super(s); + } +} diff --git a/src/main/java/ru/practicum/shareit/item/CommentRepository.java b/src/main/java/ru/practicum/shareit/item/CommentRepository.java new file mode 100644 index 000000000..6e014be9f --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/CommentRepository.java @@ -0,0 +1,11 @@ +package ru.practicum.shareit.item; + +import org.springframework.data.jpa.repository.JpaRepository; +import ru.practicum.shareit.item.model.Comment; +import ru.practicum.shareit.item.model.Item; + +import java.util.List; + +public interface CommentRepository extends JpaRepository { + List findByItem(Item item); +} diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/src/main/java/ru/practicum/shareit/item/ItemController.java index bb17668ba..df03562c6 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -1,12 +1,61 @@ package ru.practicum.shareit.item; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import ru.practicum.shareit.item.dto.ItemDTOWithComment; +import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.item.dto.ItemDTOWithDate; +import ru.practicum.shareit.item.service.ItemService; + +import javax.validation.Valid; +import java.util.Collection; -/** - * TODO Sprint add-controllers. - */ @RestController @RequestMapping("/items") +@RequiredArgsConstructor(onConstructor_ = @Autowired) +@Slf4j public class ItemController { + + private final ItemService itemService; + + @PostMapping + public ItemDTO addItem(@RequestHeader("X-Sharer-User-Id") Long userId, @Valid @RequestBody ItemDTO itemDto) { + log.info("Добавления новой вещи пользователем с id {}", userId); + return itemService.addItem(userId, itemDto); + } + + @PatchMapping("/{itemId}") + public ItemDTO changeItem(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long itemId, + @RequestBody ItemDTO itemDto) { + log.info("Обновление данные о вещи"); + return itemService.changeItem(userId, itemId, itemDto); + } + + @GetMapping("/{itemId}") + public ItemDTOWithDate getItem(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long itemId) { + log.info("Получение вещи с id {}", itemId); + return itemService.getItem(userId, itemId); + } + + @GetMapping + public Collection getAllOwnItems(@RequestHeader("X-Sharer-User-Id") Long userId) { + log.info("Получение всех вещей пользователя с id {}", userId); + return itemService.getAllOwnItems(userId); + } + + @GetMapping("/search") + public Collection getItemsForRent(@RequestHeader("X-Sharer-User-Id") Long userId, + @RequestParam String text) { + log.info("Получение вещей для аренды содержащие в названии или описании текст {}", text); + return itemService.getItemsForRent(text); + } + + @PostMapping("{itemId}/comment") + public ItemDTOWithComment addComment(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long itemId, + @Valid @RequestBody ItemDTOWithComment itemDtoWithComment) { + log.info("Добавление комментария для вещи с id {}", itemId); + return itemService.addComment(userId, itemId, itemDtoWithComment); + } } diff --git a/src/main/java/ru/practicum/shareit/item/ItemRepository.java b/src/main/java/ru/practicum/shareit/item/ItemRepository.java new file mode 100644 index 000000000..822579403 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/ItemRepository.java @@ -0,0 +1,18 @@ +package ru.practicum.shareit.item; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.model.User; + +import java.util.List; + +public interface ItemRepository extends JpaRepository { + List findByOwner(User user); + + @Query(nativeQuery = true, value = "SELECT * FROM items AS i " + + "WHERE ((LOWER(name) iLike CONCAT('%', LOWER(?1), '%')) " + + "OR (LOWER(description) Like CONCAT('%', LOWER(?1), '%'))) " + + "AND (available)") + List findItemsByNameOrDescription(String substring); +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java new file mode 100644 index 000000000..ebfa53cfb --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java @@ -0,0 +1,28 @@ +package ru.practicum.shareit.item.dto; + +import lombok.Data; +import ru.practicum.shareit.user.model.User; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +@Data +public class ItemDTO { + + private long id; + + @NotBlank + private String name; + + @NotBlank + private String description; + + @NotNull + private Boolean available; + + private User owner; + + private Long request; + + +} diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithComment.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithComment.java new file mode 100644 index 000000000..2f6136a31 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithComment.java @@ -0,0 +1,23 @@ +package ru.practicum.shareit.item.dto; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.time.LocalDateTime; + +@Data +public class ItemDTOWithComment { + + private Long id; + + @NotBlank + @Size(min = 1, max = 1000) + private String text; + + private String itemName; + + private String authorName; + + LocalDateTime created; +} diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java new file mode 100644 index 000000000..61a216f05 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java @@ -0,0 +1,35 @@ +package ru.practicum.shareit.item.dto; + +import lombok.Data; +import ru.practicum.shareit.booking.dto.BookingDTOForItem; +import ru.practicum.shareit.user.model.User; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.ArrayList; +import java.util.List; + +@Data +public class ItemDTOWithDate { + private long id; + + @NotBlank + private String name; + + @NotBlank + private String description; + + @NotNull + private Boolean available; + + private User owner; + + private Long request; + + private BookingDTOForItem nextBooking; + + private BookingDTOForItem lastBooking; + + private List comments = new ArrayList<>(); + +} diff --git a/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java new file mode 100644 index 000000000..5c5228287 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java @@ -0,0 +1,41 @@ +package ru.practicum.shareit.item.mapper; + +import org.springframework.stereotype.Component; +import ru.practicum.shareit.item.dto.ItemDTOWithComment; +import ru.practicum.shareit.item.model.Comment; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.model.User; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class CommentMapper { + + public static ItemDTOWithComment toCommentDto(Comment comment) { + ItemDTOWithComment itemDtoWithComment = new ItemDTOWithComment(); + itemDtoWithComment.setId(comment.getId()); + itemDtoWithComment.setText(comment.getText()); + itemDtoWithComment.setItemName(comment.getItem().getName()); + itemDtoWithComment.setAuthorName(comment.getAuthor().getName()); + itemDtoWithComment.setCreated(comment.getCreated()); + return itemDtoWithComment; + } + + public static Comment toComment(ItemDTOWithComment itemDtoWithComment, Item item, User author) { + Comment comment = new Comment(); + comment.setId(comment.getId()); + comment.setText(itemDtoWithComment.getText()); + comment.setItem(item); + comment.setAuthor(author); + return comment; + } + + public static List mapToCommentDto(Iterable comments) { + List dtos = new ArrayList<>(); + for (Comment comment : comments) { + dtos.add(toCommentDto(comment)); + } + return dtos; + } +} diff --git a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java new file mode 100644 index 000000000..5ae4c0c6e --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java @@ -0,0 +1,74 @@ +package ru.practicum.shareit.item.mapper; + +import org.springframework.stereotype.Component; +import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.item.dto.ItemDTOWithDate; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.model.User; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class ItemMapper { + + public static ItemDTO toItemDto(Item item) { + ItemDTO itemDto = new ItemDTO(); + itemDto.setId(item.getId()); + itemDto.setName(item.getName()); + itemDto.setDescription(item.getDescription()); + itemDto.setAvailable(item.getAvailable()); + //itemDto.setRequest(item.getRequest() != null ? item.getRequest().getId() : null); + return itemDto; + } + + public static ItemDTOWithDate toItemDtoWithDate(Item item) { + ItemDTOWithDate itemDto = new ItemDTOWithDate(); + itemDto.setId(item.getId()); + itemDto.setName(item.getName()); + itemDto.setDescription(item.getDescription()); + itemDto.setAvailable(item.getAvailable()); + //itemDto.setRequest(item.getRequest() != null ? item.getRequest().getId() : null); + return itemDto; + + } + + public static Item toItem(ItemDTO itemDto, User user) { + Item item = new Item(); + item.setId(itemDto.getId()); + item.setName(itemDto.getName()); + item.setDescription(itemDto.getDescription()); + item.setAvailable(itemDto.getAvailable()); + item.setOwner(user); + return item; + + } + + public static Item toItemWithDate(ItemDTOWithDate itemDto, User user) { + Item item = new Item(); + item.setId(itemDto.getId()); + item.setName(itemDto.getName()); + item.setDescription(itemDto.getDescription()); + item.setAvailable(itemDto.getAvailable()); + item.setOwner(user); + return item; + + } + + public static List mapToItemDto(Iterable items) { + List dtos = new ArrayList<>(); + for (Item item : items) { + dtos.add(toItemDto(item)); + } + return dtos; + } + + public static List mapToItemDtoWithDate(Iterable items) { + List dtos = new ArrayList<>(); + for (Item item : items) { + dtos.add(toItemDtoWithDate(item)); + } + return dtos; + } +} + diff --git a/src/main/java/ru/practicum/shareit/item/model/Comment.java b/src/main/java/ru/practicum/shareit/item/model/Comment.java new file mode 100644 index 000000000..c50612fcc --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/model/Comment.java @@ -0,0 +1,52 @@ +package ru.practicum.shareit.item.model; + +import lombok.*; +import org.hibernate.Hibernate; +import ru.practicum.shareit.user.model.User; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.time.LocalDateTime; +import java.util.Objects; + +@Entity +@Table(name = "comments", schema = "public") +@Getter +@Setter +@ToString +@RequiredArgsConstructor +public class Comment { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotBlank + @Size(min = 1, max = 200) + @Column(nullable = false) + private String text; + + @ManyToOne + @JoinColumn(name = "item_id") + private Item item; + + @ManyToOne + @JoinColumn(name = "author_id") + private User author; + + @Column(nullable = false) + LocalDateTime created = LocalDateTime.now(); + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + Comment comment = (Comment) o; + return id != null && Objects.equals(id, comment.id); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } +} diff --git a/src/main/java/ru/practicum/shareit/item/model/Item.java b/src/main/java/ru/practicum/shareit/item/model/Item.java index 44eb73ddc..013e3d341 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Item.java +++ b/src/main/java/ru/practicum/shareit/item/model/Item.java @@ -1,7 +1,52 @@ package ru.practicum.shareit.item.model; -/** - * TODO Sprint add-controllers. - */ +import lombok.*; +import org.hibernate.Hibernate; +import ru.practicum.shareit.user.model.User; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.Objects; + +@Entity +@Table(name = "items", schema = "public") +@Getter +@Setter +@ToString +@RequiredArgsConstructor public class Item { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @NotBlank + @Column(nullable = false) + private String name; + + @NotBlank + @Column(nullable = false) + private String description; + + @NotNull + @Column + private Boolean available; + + @ManyToOne + @JoinColumn(name = "owner_id") + private User owner; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + Item item = (Item) o; + return id != 0 && Objects.equals(id, item.id); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } } diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemService.java b/src/main/java/ru/practicum/shareit/item/service/ItemService.java new file mode 100644 index 000000000..f2691d3db --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/service/ItemService.java @@ -0,0 +1,22 @@ +package ru.practicum.shareit.item.service; + +import ru.practicum.shareit.item.dto.ItemDTOWithComment; +import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.item.dto.ItemDTOWithDate; + +import java.util.Collection; + +public interface ItemService { + + ItemDTO addItem(Long userId, ItemDTO itemDto); + + ItemDTOWithDate getItem(Long userId, Long itemId); + + ItemDTO changeItem(Long userId, Long itemId, ItemDTO itemDto); + + Collection getAllOwnItems(Long userId); + + Collection getItemsForRent(String substring); + + ItemDTOWithComment addComment(Long authorId, Long itemId, ItemDTOWithComment comment); +} diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java new file mode 100644 index 000000000..b7ac82ab8 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -0,0 +1,158 @@ +package ru.practicum.shareit.item.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import ru.practicum.shareit.booking.BookingMapper; +import ru.practicum.shareit.booking.BookingRepository; +import ru.practicum.shareit.booking.dto.BookingDTOForItem; +import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.exception.BadRequestException; +import ru.practicum.shareit.exception.ForbiddenException; +import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.item.mapper.CommentMapper; +import ru.practicum.shareit.item.CommentRepository; +import ru.practicum.shareit.item.mapper.ItemMapper; +import ru.practicum.shareit.item.ItemRepository; +import ru.practicum.shareit.item.dto.ItemDTOWithComment; +import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.item.dto.ItemDTOWithDate; +import ru.practicum.shareit.item.model.Comment; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.UserRepository; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; +import java.util.*; + +@Service +@RequiredArgsConstructor(onConstructor_ = @Autowired) +public class ItemServiceImpl implements ItemService { + + private final ItemRepository repository; + private final UserRepository userRepository; + private final BookingRepository bookingRepository; + private final CommentRepository commentRepository; + + @Transactional + @Override + public ItemDTO addItem(Long userId, ItemDTO itemDto) throws BadRequestException { + Optional user = userRepository.findById(userId); + if (user.isEmpty()) { + throw new NotFoundException("User not found"); + } + Item item = repository.save(ItemMapper.toItem(itemDto, user.get())); + return ItemMapper.toItemDto(item); + } + + @Transactional + @Override + public ItemDTO changeItem(Long userId, Long itemId, ItemDTO itemDto) throws BadRequestException { + Optional itemOpt = repository.findById(itemId); + if (itemOpt.isEmpty()) { + throw new NotFoundException("Item not found"); + } + Item item = itemOpt.get(); + User user = item.getOwner(); + if (Objects.equals(user.getId(), userId)) { + if (itemDto.getName() != null) { + item.setName(itemDto.getName()); + } + if (itemDto.getDescription() != null) { + item.setDescription(itemDto.getDescription()); + } + if (itemDto.getAvailable() != null) { + item.setAvailable(itemDto.getAvailable()); + } + repository.save(item); + return ItemMapper.toItemDto(item); + } + throw new ForbiddenException("No rights"); + } + + @Override + public ItemDTOWithDate getItem(Long userId, Long itemId) { + Optional itemOpt = repository.findById(itemId); + if (itemOpt.isEmpty()) { + throw new NotFoundException("Item not found"); + } + Item item = itemOpt.get(); + ItemDTOWithDate itemDto = ItemMapper.toItemDtoWithDate(item); + List comments = commentRepository.findByItem(item); + itemDto.setComments(CommentMapper.mapToCommentDto(comments)); + if (Objects.equals(item.getOwner().getId(), userId)) { + List bookings = bookingRepository.findByItemOrderByStartDesc(item); + if (!bookings.isEmpty()) { + + LocalDateTime next = bookings.get(0).getStart(); + Booking nextBooking = bookings.get(0); + BookingDTOForItem bookingNext = BookingMapper.toBookingDtoForItem(nextBooking, next); + itemDto.setNextBooking(bookingNext); + if (bookings.size() >= 2) { + LocalDateTime last = bookings.get(1).getStart(); + Booking lastBooking = bookings.get(1); + BookingDTOForItem bookingLast = BookingMapper.toBookingDtoForItem(lastBooking, last); + itemDto.setLastBooking(bookingLast); + } + } + } + return itemDto; + } + + @Override + public Collection getAllOwnItems(Long userId) { + Optional userOpt = userRepository.findById(userId); + if (userOpt.isEmpty()) { + throw new NotFoundException("User not found"); + } + User user = userOpt.get(); + List items = repository.findByOwner(user); + List itemDtos = ItemMapper.mapToItemDtoWithDate(items); + for (ItemDTOWithDate itemDto : itemDtos) { + List comments = commentRepository.findByItem(ItemMapper.toItemWithDate(itemDto, user)); + itemDto.setComments(CommentMapper.mapToCommentDto(comments)); + List bookings = bookingRepository.findByItemOrderByStartDesc(ItemMapper.toItemWithDate(itemDto, user)); + if (!bookings.isEmpty()) { + LocalDateTime next = bookings.get(0).getStart(); + LocalDateTime last = bookings.get(1).getStart(); + Booking nextBooking = bookings.get(0); + Booking lastBooking = bookings.get(1); + BookingDTOForItem bookingNext = BookingMapper.toBookingDtoForItem(nextBooking, next); + BookingDTOForItem bookingLast = BookingMapper.toBookingDtoForItem(lastBooking, last); + itemDto.setNextBooking(bookingNext); + itemDto.setLastBooking(bookingLast); + } + } + return itemDtos; + } + + @Override + public Collection getItemsForRent(String substring) { + if (!Objects.equals(substring, "")) { + return ItemMapper.mapToItemDto(repository.findItemsByNameOrDescription(substring)); + } + return new ArrayList<>(); + } + + @Transactional + @Override + public ItemDTOWithComment addComment(Long authorId, Long itemId, ItemDTOWithComment itemDtoWithComment) { + Optional itemOpt = repository.findById(itemId); + if (itemOpt.isEmpty()) { + throw new NotFoundException("Item not found"); + } + Item item = itemOpt.get(); + Optional author = userRepository.findById(authorId); + if (author.isEmpty()) { + throw new NotFoundException("User not found"); + } + List bookings = bookingRepository.findByItemAndBookerAndStartBeforeAndEndBefore(item, author.get(), + LocalDateTime.now(), LocalDateTime.now()); + if (bookings.isEmpty()) { + throw new BadRequestException("Booking is empty"); + } + Comment comment = CommentMapper.toComment(itemDtoWithComment, item, author.get()); + return CommentMapper.toCommentDto(commentRepository.save(comment)); + } +} diff --git a/src/main/java/ru/practicum/shareit/item/storage/ItemInMemoryStorage.java b/src/main/java/ru/practicum/shareit/item/storage/ItemInMemoryStorage.java new file mode 100644 index 000000000..19d0a6ebe --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/storage/ItemInMemoryStorage.java @@ -0,0 +1,85 @@ +package ru.practicum.shareit.item.storage; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import ru.practicum.shareit.item.mapper.ItemMapper; +import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.model.User; + +import java.util.*; + +@Component +@RequiredArgsConstructor(onConstructor_ = @Autowired) +@Slf4j +public class ItemInMemoryStorage implements ItemStorage { + private final Map items = new HashMap<>(); + private long id = 0; + + @Override + public ItemDTO addItem(User user, ItemDTO itemDto) { + id = id + 1; + itemDto.setId(id); + items.put(id, ItemMapper.toItem(itemDto, user)); + log.info("Добавлена новая вещь: {},", itemDto.getName()); + return itemDto; + } + + @Override + public ItemDTO changeItem(Long userId, Long itemId, ItemDTO itemDto) { + Item item = items.get(itemId); + if (itemDto.getName() != null) { + item.setName(itemDto.getName()); + } + if (itemDto.getDescription() != null) { + item.setDescription(itemDto.getDescription()); + } + if (itemDto.getAvailable() != null) { + item.setAvailable(itemDto.getAvailable()); + } + + items.put(itemId, item); + log.info("Обновлены данные для вещи: {}", itemDto.getName()); + return ItemMapper.toItemDto(item); + } + + @Override + public Optional getItem(Long userId, Long itemId) { + return Optional.of(ItemMapper.toItemDto(items.get(itemId))); + } + + @Override + public Collection getAllOwnItems(Long userId) { + List itemsDto = new ArrayList<>(); + for (Item item : items.values()) { + if (Objects.equals(item.getOwner().getId(), userId)) { + itemsDto.add(ItemMapper.toItemDto(item)); + } + } + log.info("Колличество найденных вещей: {}", itemsDto.size()); + return itemsDto; + } + + @Override + public Collection getItemsForRent(String substring) { + List itemsDto = new ArrayList<>(); + if (!substring.equals("")) { + for (Item item : items.values()) { + if ((item.getName().toLowerCase().contains(substring.toLowerCase()) + || item.getDescription().toLowerCase().contains(substring.toLowerCase())) + && item.getAvailable()) { + itemsDto.add(ItemMapper.toItemDto(item)); + } + } + } + log.info("Колличество найденных вещей: {}", itemsDto.size()); + return itemsDto; + } + + @Override + public Optional getItemFromMap(Long itemId) { + return Optional.ofNullable(items.get(itemId)); + } +} diff --git a/src/main/java/ru/practicum/shareit/item/storage/ItemStorage.java b/src/main/java/ru/practicum/shareit/item/storage/ItemStorage.java new file mode 100644 index 000000000..8f6b17f4c --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/storage/ItemStorage.java @@ -0,0 +1,22 @@ +package ru.practicum.shareit.item.storage; + +import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.model.User; + +import java.util.*; + +public interface ItemStorage { + + ItemDTO addItem(User user, ItemDTO itemDto); + + ItemDTO changeItem(Long userId, Long itemId, ItemDTO itemDto); + + Optional getItem(Long userId, Long itemId); + + Collection getAllOwnItems(Long userId); + + Collection getItemsForRent(String substring); + + Optional getItemFromMap(Long itemId); +} diff --git a/src/main/java/ru/practicum/shareit/request/ItemRequestController.java b/src/main/java/ru/practicum/shareit/request/ItemRequestController.java index 064e2e9c6..d149fdb46 100644 --- a/src/main/java/ru/practicum/shareit/request/ItemRequestController.java +++ b/src/main/java/ru/practicum/shareit/request/ItemRequestController.java @@ -3,9 +3,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -/** - * TODO Sprint add-item-requests. - */ @RestController @RequestMapping(path = "/requests") public class ItemRequestController { diff --git a/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDto.java b/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDto.java index 7b3ed5440..608cf6f4a 100644 --- a/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDto.java +++ b/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDto.java @@ -1,7 +1,18 @@ package ru.practicum.shareit.request.dto; -/** - * TODO Sprint add-item-requests. - */ +import lombok.Data; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; + +@Data public class ItemRequestDto { + + private Long id; + + private String description; + + private User requestor; + + private LocalDateTime created; } diff --git a/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java b/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java new file mode 100644 index 000000000..1f1d6cef8 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java @@ -0,0 +1,29 @@ +package ru.practicum.shareit.request.model; + +import lombok.Data; +import ru.practicum.shareit.user.model.User; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; + +@Entity +@Table(name = "requests", schema = "public") +@Data +public class ItemRequest { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotNull + @Column + private String description; + + @OneToOne + @JoinColumn(name = "requestor_id") + private User requestor; + + @NotNull + private LocalDateTime created; +} diff --git a/src/main/java/ru/practicum/shareit/user/UserController.java b/src/main/java/ru/practicum/shareit/user/UserController.java index 03039b9da..0ee53220d 100644 --- a/src/main/java/ru/practicum/shareit/user/UserController.java +++ b/src/main/java/ru/practicum/shareit/user/UserController.java @@ -1,12 +1,49 @@ package ru.practicum.shareit.user; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import ru.practicum.shareit.user.dto.UserDTO; +import ru.practicum.shareit.user.service.UserService; + +import javax.validation.Valid; +import java.util.Collection; -/** - * TODO Sprint add-controllers. - */ @RestController @RequestMapping(path = "/users") +@RequiredArgsConstructor(onConstructor_ = @Autowired) +@Slf4j public class UserController { + private final UserService userService; + + @PostMapping + public UserDTO createUser(@Valid @RequestBody UserDTO user) { + log.info("Добавление нового пользователя"); + return userService.createUser(user); + } + + @PatchMapping("/{userId}") + public UserDTO update(@Valid @PathVariable Long userId, @RequestBody UserDTO user) { + log.info("Обновление данных о пользователе с id {}", userId); + return userService.updateUser(userId, user); + } + + @DeleteMapping("/{id}") + public void deleteUser(@PathVariable Long id) { + log.info("Удаление пользователя с id {}", id); + userService.deleteUser(id); + } + + @GetMapping + public Collection getUsers() { + log.info("Получение списка всех пользователей"); + return userService.getAllUsers(); + } + + @GetMapping("/{id}") + public UserDTO getUser(@PathVariable Long id) { + log.info("Получение пользователя с id {}", id); + return userService.getUser(id); + } } diff --git a/src/main/java/ru/practicum/shareit/user/UserMapper.java b/src/main/java/ru/practicum/shareit/user/UserMapper.java new file mode 100644 index 000000000..f09ab8fb0 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/UserMapper.java @@ -0,0 +1,36 @@ +package ru.practicum.shareit.user; + +import org.springframework.stereotype.Component; +import ru.practicum.shareit.user.dto.UserDTO; +import ru.practicum.shareit.user.model.User; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class UserMapper { + + public static UserDTO toUserDto(User user) { + UserDTO userDto = new UserDTO(); + userDto.setId(user.getId()); + userDto.setName(user.getName()); + userDto.setEmail(user.getEmail()); + return userDto; + } + + public static User toUser(UserDTO userDto) { + User user = new User(); + user.setId(userDto.getId()); + user.setName(userDto.getName()); + user.setEmail(userDto.getEmail()); + return user; + } + + public static List mapToUserDto(Iterable users) { + List dtos = new ArrayList<>(); + for (User user : users) { + dtos.add(toUserDto(user)); + } + return dtos; + } +} diff --git a/src/main/java/ru/practicum/shareit/user/UserRepository.java b/src/main/java/ru/practicum/shareit/user/UserRepository.java new file mode 100644 index 000000000..59324814d --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/UserRepository.java @@ -0,0 +1,7 @@ +package ru.practicum.shareit.user; + +import org.springframework.data.jpa.repository.JpaRepository; +import ru.practicum.shareit.user.model.User; + +public interface UserRepository extends JpaRepository { +} diff --git a/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java b/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java new file mode 100644 index 000000000..8e3c9c937 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java @@ -0,0 +1,19 @@ +package ru.practicum.shareit.user.dto; + +import lombok.Data; + +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; + +@Data +public class UserDTO { + + private long id; + + @NotBlank + private String name; + + @Email + @NotBlank + private String email; +} diff --git a/src/main/java/ru/practicum/shareit/user/model/User.java b/src/main/java/ru/practicum/shareit/user/model/User.java new file mode 100644 index 000000000..527b23780 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/model/User.java @@ -0,0 +1,44 @@ +package ru.practicum.shareit.user.model; + +import lombok.*; +import org.hibernate.Hibernate; + +import javax.persistence.*; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; +import java.util.Objects; + +@Entity +@Table(name = "users", schema = "public") +@Getter +@Setter +@ToString +@RequiredArgsConstructor +public class User { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotBlank + @Column(nullable = false) + private String name; + + @Email + @NotBlank + @Column(nullable = false) + private String email; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; + User user = (User) o; + return id != null && Objects.equals(id, user.id); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } +} diff --git a/src/main/java/ru/practicum/shareit/user/service/UserService.java b/src/main/java/ru/practicum/shareit/user/service/UserService.java new file mode 100644 index 000000000..80fe60e38 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/service/UserService.java @@ -0,0 +1,17 @@ +package ru.practicum.shareit.user.service; + +import ru.practicum.shareit.user.dto.UserDTO; + +import java.util.Collection; + +public interface UserService { + UserDTO createUser(UserDTO userDto); + + UserDTO updateUser(Long userId, UserDTO userDto); + + void deleteUser(Long id); + + Collection getAllUsers(); + + UserDTO getUser(Long id); +} diff --git a/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java new file mode 100644 index 000000000..29af46453 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java @@ -0,0 +1,69 @@ +package ru.practicum.shareit.user.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import ru.practicum.shareit.exception.BadRequestException; +import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.user.UserMapper; +import ru.practicum.shareit.user.UserRepository; +import ru.practicum.shareit.user.dto.UserDTO; +import ru.practicum.shareit.user.model.User; + +import java.util.Collection; +import java.util.Optional; + +@Service +@RequiredArgsConstructor(onConstructor_ = @Autowired) +public class UserServiceImpl implements UserService { + private final UserRepository repository; + + @Transactional + @Override + public UserDTO createUser(UserDTO userDto) throws BadRequestException { + User user = repository.save(UserMapper.toUser(userDto)); + return UserMapper.toUserDto(user); + } + + @Transactional + @Override + public UserDTO updateUser(Long userId, UserDTO userDto) throws BadRequestException { + Optional userOptional = repository.findById(userId); + if (userOptional.isEmpty()) { + throw new NotFoundException("User not found"); + } + User user = userOptional.get(); + if (userDto.getName() != null) { + user.setName(userDto.getName()); + } + if (userDto.getEmail() != null) { + user.setEmail(userDto.getEmail()); + } + return UserMapper.toUserDto(repository.save(user)); + } + + @Transactional + @Override + public void deleteUser(Long id) { + Optional user = repository.findById(id); + if (user.isEmpty()) { + throw new NotFoundException("User not found"); + } + repository.deleteById(id); + } + + @Override + public Collection getAllUsers() { + return UserMapper.mapToUserDto(repository.findAll()); + } + + @Override + public UserDTO getUser(Long id) { + Optional user = repository.findById(id); + if (user.isEmpty()) { + throw new NotFoundException("User not found"); + } + return UserMapper.toUserDto(user.get()); + } +} diff --git a/src/main/java/ru/practicum/shareit/user/storage/UserInMemoryStorage.java b/src/main/java/ru/practicum/shareit/user/storage/UserInMemoryStorage.java new file mode 100644 index 000000000..378447f90 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/storage/UserInMemoryStorage.java @@ -0,0 +1,68 @@ +package ru.practicum.shareit.user.storage; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import ru.practicum.shareit.user.model.User; +import ru.practicum.shareit.user.UserMapper; +import ru.practicum.shareit.user.dto.UserDTO; + +import java.util.*; + +@Component +@Slf4j +public class UserInMemoryStorage implements UserStorage { + private final Map users = new HashMap<>(); + private long id = 0; + + @Override + public UserDTO addUser(UserDTO userDto) { + id = id + 1; + userDto.setId(id); + users.put(id, UserMapper.toUser(userDto)); + log.info("Добавлен пользователь: {},", userDto.getName()); + return userDto; + } + + @Override + public UserDTO updateUser(Long userId, UserDTO userDto) { + userDto.setId(userId); + User user = UserMapper.toUser(getUser(userId).get()); + if (userDto.getName() != null) { + user.setName(userDto.getName()); + } + if (userDto.getEmail() != null) { + user.setEmail(userDto.getEmail()); + } + user.setId(userId); + users.put(userId, user); + log.info("Обновлены данные пользователя: {}", userDto.getName()); + return UserMapper.toUserDto(user); + } + + @Override + public void deleteUser(Long id) { + users.remove(id); + log.info("Пользователь c id {} удален", id); + } + + @Override + public Collection getAllUsers() { + List usersDto = new ArrayList<>(); + for (Long id : users.keySet()) { + usersDto.add(UserMapper.toUserDto(users.get(id))); + } + log.info("Количество найденных пользвателей {}:", users.size()); + return usersDto; + } + + @Override + public Optional getUser(Long id) { + log.info("Пользователь с id {} найден", id); + User user = users.get(id); + if (user == null) { + return Optional.empty(); + } + return Optional.ofNullable(UserMapper.toUserDto(user)); + } + +} diff --git a/src/main/java/ru/practicum/shareit/user/storage/UserStorage.java b/src/main/java/ru/practicum/shareit/user/storage/UserStorage.java new file mode 100644 index 000000000..9ba7294a7 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/storage/UserStorage.java @@ -0,0 +1,19 @@ +package ru.practicum.shareit.user.storage; + +import ru.practicum.shareit.user.dto.UserDTO; + +import java.util.Collection; +import java.util.Optional; + +public interface UserStorage { + + UserDTO addUser(UserDTO userDto); + + UserDTO updateUser(Long userId, UserDTO userDto); + + void deleteUser(Long id); + + Collection getAllUsers(); + + Optional getUser(Long id); +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c359e8d7a..dc7cf84ea 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,22 +1,18 @@ spring.jpa.hibernate.ddl-auto=none -spring.jpa.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect -spring.jpa.hibernate.show_sql=true - +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL10Dialect +spring.jpa.properties.hibernate.format_sql=true spring.sql.init.mode=always -# TODO Append connection to DB - - - logging.level.org.springframework.orm.jpa=INFO logging.level.org.springframework.transaction=INFO logging.level.org.springframework.transaction.interceptor=TRACE logging.level.org.springframework.orm.jpa.JpaTransactionManager=DEBUG + +#--- +# TODO Append connection to DB #--- -spring.config.activate.on-profile=ci,test +#spring.config.activate.on-profile=ci,test spring.datasource.driverClassName=org.h2.Driver -spring.datasource.url=jdbc:h2:mem:shareit +spring.datasource.url=jdbc:h2:./db/shareit spring.datasource.username=test spring.datasource.password=test - -spring.h2.console.enabled=true \ No newline at end of file diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql new file mode 100644 index 000000000..819bb0ac0 --- /dev/null +++ b/src/main/resources/schema.sql @@ -0,0 +1,55 @@ +DROP TABLE IF EXISTS comments; +DROP TABLE IF EXISTS bookings; +DROP TABLE IF EXISTS items; +DROP TABLE IF EXISTS requests; +DROP TABLE IF EXISTS users; + +CREATE TABLE IF NOT EXISTS users +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + name VARCHAR(100) NOT NULL, + email VARCHAR(320) NOT NULL, + CONSTRAINT pk_user PRIMARY KEY (id), + CONSTRAINT UQ_USER_EMAIL UNIQUE (email), + CONSTRAINT EMAIL_FORMAT CHECK (email LIKE '%@%.%' AND email NOT LIKE '@%' AND email NOT LIKE '%@%@%') +); + +CREATE TABLE IF NOT EXISTS items +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + name VARCHAR(100) NOT NULL, + description VARCHAR(512) NOT NULL, + available BOOLEAN NOT NULL, + owner_id BIGINT NOT NULL, + request_id BIGINT, + CONSTRAINT pk_item PRIMARY KEY (id) +); + +CREATE TABLE IF NOT EXISTS bookings +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + start_date TIMESTAMP WITHOUT TIME ZONE NOT NULL, + end_date TIMESTAMP WITHOUT TIME ZONE NOT NULL, + item_id BIGINT NOT NULL, + booker_id BIGINT NOT NULL, + status VARCHAR(100) NOT NULL, + CONSTRAINT pk_booking PRIMARY KEY (id) +); + +CREATE TABLE IF NOT EXISTS requests +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + description VARCHAR(1000) NOT NULL, + requestor_id BIGINT NOT NULL, + CONSTRAINT pk_requests PRIMARY KEY (id) +); + +CREATE TABLE IF NOT EXISTS comments +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + text VARCHAR(1000) NOT NULL, + item_id BIGINT NOT NULL, + author_id BIGINT NOT NULL, + created TIMESTAMP WITHOUT TIME ZONE NOT NULL, + CONSTRAINT pk_comments PRIMARY KEY (id) +) \ No newline at end of file From 0777e6517daed5d3d5693d6ed30df9af43425edc Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Fri, 3 Feb 2023 18:04:53 +0300 Subject: [PATCH 02/45] Delete BookingDto.java --- .../java/ru/practicum/shareit/booking/dto/BookingDto.java | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 src/main/java/ru/practicum/shareit/booking/dto/BookingDto.java diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDto.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDto.java deleted file mode 100644 index 861de9e01..000000000 --- a/src/main/java/ru/practicum/shareit/booking/dto/BookingDto.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.practicum.shareit.booking.dto; - -/** - * TODO Sprint add-bookings. - */ -public class BookingDto { -} From 89c108a2f6efb5a826f75824c359fcfc2572ee1f Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Fri, 3 Feb 2023 18:05:10 +0300 Subject: [PATCH 03/45] Delete Booking.java --- src/main/java/ru/practicum/shareit/booking/Booking.java | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 src/main/java/ru/practicum/shareit/booking/Booking.java diff --git a/src/main/java/ru/practicum/shareit/booking/Booking.java b/src/main/java/ru/practicum/shareit/booking/Booking.java deleted file mode 100644 index 2d9c6668d..000000000 --- a/src/main/java/ru/practicum/shareit/booking/Booking.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.practicum.shareit.booking; - -/** - * TODO Sprint add-bookings. - */ -public class Booking { -} From be1331102bc71f8017f34f2f7fb123064c1955a2 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Fri, 3 Feb 2023 18:05:41 +0300 Subject: [PATCH 04/45] Delete ItemDto.java --- src/main/java/ru/practicum/shareit/item/dto/ItemDto.java | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 src/main/java/ru/practicum/shareit/item/dto/ItemDto.java diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDto.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDto.java deleted file mode 100644 index 9319d7d73..000000000 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemDto.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.practicum.shareit.item.dto; - -/** - * TODO Sprint add-controllers. - */ -public class ItemDto { -} From 1fc35dbafb46d31afb0fc4b9e2de880da075b26b Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Fri, 3 Feb 2023 18:06:17 +0300 Subject: [PATCH 05/45] Delete User.java --- src/main/java/ru/practicum/shareit/user/User.java | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 src/main/java/ru/practicum/shareit/user/User.java diff --git a/src/main/java/ru/practicum/shareit/user/User.java b/src/main/java/ru/practicum/shareit/user/User.java deleted file mode 100644 index ae6e7f33e..000000000 --- a/src/main/java/ru/practicum/shareit/user/User.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.practicum.shareit.user; - -/** - * TODO Sprint add-controllers. - */ -public class User { -} From c164368b9857477cf6834c766568485529571f36 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Sun, 5 Feb 2023 22:35:53 +0300 Subject: [PATCH 06/45] Add files via upload --- .../shareit/booking/BookingController.java | 24 ++--- .../shareit/booking/BookingMapper.java | 12 +-- .../shareit/booking/BookingRepository.java | 54 ++++++----- .../shareit/booking/dto/BookingDTO.java | 12 ++- .../booking/dto/BookingDTOToReturn.java | 16 +++- .../shareit/booking/model/Booking.java | 5 +- .../shareit/booking/model/State.java | 5 ++ .../shareit/booking/model/Status.java | 10 +++ .../booking/service/BookingService.java | 10 +-- .../booking/service/BookingServiceImpl.java | 90 ++++++++----------- .../shareit/exception/ErrorHandler.java | 9 ++ .../shareit/item/ItemController.java | 24 ++--- .../practicum/shareit/item/dto/ItemDTO.java | 7 +- .../shareit/item/dto/ItemDTOWithComment.java | 2 +- .../shareit/item/mapper/CommentMapper.java | 4 +- .../shareit/item/mapper/ItemMapper.java | 11 ++- .../practicum/shareit/item/model/Comment.java | 4 +- .../ru/practicum/shareit/item/model/Item.java | 1 + .../shareit/item/service/ItemService.java | 12 +-- .../shareit/item/service/ItemServiceImpl.java | 11 +-- .../shareit/user/UserController.java | 18 ++-- .../ru/practicum/shareit/user/UserMapper.java | 9 +- .../shareit/user/service/UserService.java | 10 +-- .../shareit/user/service/UserServiceImpl.java | 26 +++--- 24 files changed, 211 insertions(+), 175 deletions(-) create mode 100644 src/main/java/ru/practicum/shareit/booking/model/State.java create mode 100644 src/main/java/ru/practicum/shareit/booking/model/Status.java diff --git a/src/main/java/ru/practicum/shareit/booking/BookingController.java b/src/main/java/ru/practicum/shareit/booking/BookingController.java index a75d450b7..f34f6fc94 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingController.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingController.java @@ -18,41 +18,41 @@ public class BookingController { private final BookingService bookingService; @PostMapping - public BookingDTOToReturn addBooking(@RequestHeader("X-Sharer-User-Id") Long userId, + public BookingDTOToReturn add(@RequestHeader("X-Sharer-User-Id") Long userId, @RequestBody BookingDTO bookingDto) { log.info("Добавление запроса на аренду пользователем с id {}", userId); - return bookingService.addBooking(userId, bookingDto); + return bookingService.add(userId, bookingDto); } @PatchMapping("/{bookingId}") - public BookingDTOToReturn updateStatusBooking(@RequestHeader("X-Sharer-User-Id") Long userId, + public BookingDTOToReturn update(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long bookingId, @RequestParam Boolean approved) { log.info("Обновление статуса запроса на аренду с id {}", bookingId); - return bookingService.updateStatusBooking(userId, bookingId, approved); + return bookingService.update(userId, bookingId, approved); } @GetMapping("/{bookingId}") - public BookingDTOToReturn getBooking(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long bookingId) { + public BookingDTOToReturn get(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long bookingId) { log.info("Просмотр запроса на пренду с id {}", bookingId); - return bookingService.getBooking(userId, bookingId); + return bookingService.get(userId, bookingId); } @GetMapping - public Collection findBookingByBooker(@RequestHeader("X-Sharer-User-Id") Long userId, - @RequestParam(required = false) + public Collection findByBooker(@RequestHeader("X-Sharer-User-Id") Long userId, + @RequestParam(defaultValue = "ALL") String state) { log.info("Получение списка бронирований пользовалеля с id {}", userId); - return bookingService.getBookingByBooker(userId, state); + return bookingService.getByBooker(userId, state); } @GetMapping("/owner") - public Collection findBookingByOwner(@RequestHeader("X-Sharer-User-Id") Long userId, - @RequestParam(required = false) + public Collection findByOwner(@RequestHeader("X-Sharer-User-Id") Long userId, + @RequestParam(defaultValue = "ALL") String state) { log.info("Получение списка бронирований для всех вещей пользователя с id {}", userId); - return bookingService.getBookingByOwner(userId, state); + return bookingService.getByOwner(userId, state); } } diff --git a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java index 35cbe56e9..dc7229126 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java @@ -1,18 +1,20 @@ package ru.practicum.shareit.booking; -import org.springframework.stereotype.Component; +import lombok.experimental.UtilityClass; import ru.practicum.shareit.booking.dto.BookingDTO; import ru.practicum.shareit.booking.dto.BookingDTOForItem; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.UserMapper; import ru.practicum.shareit.user.model.User; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; -@Component +@UtilityClass public class BookingMapper { public static BookingDTO toBookingDto(Booking booking) { @@ -21,7 +23,7 @@ public static BookingDTO toBookingDto(Booking booking) { bookingDto.setStart(booking.getStart()); bookingDto.setEnd(booking.getEnd()); bookingDto.setStatus(booking.getStatus()); - bookingDto.setItemId(booking.getItem() != null ? booking.getItem().getId() : null); + bookingDto.setItemId(booking.getItem().getId()); bookingDto.setItemName(booking.getItem() != null ? booking.getItem().getName() : null); bookingDto.setBookerId(booking.getBooker() != null ? booking.getBooker().getId() : null); return bookingDto; @@ -34,8 +36,8 @@ public static BookingDTOToReturn toBookingDtoFrom(Booking booking) { bookingDto.setStart(booking.getStart()); bookingDto.setEnd(booking.getEnd()); bookingDto.setStatus(booking.getStatus()); - bookingDto.setItem(booking.getItem()); - bookingDto.setBooker(booking.getBooker()); + bookingDto.setItem(ItemMapper.toItemToBookingDTO(booking.getItem())); + bookingDto.setBooker(UserMapper.toUserToBookingDTO(booking.getBooker())); return bookingDto; } diff --git a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java index 50c17dfe2..7f880bfa6 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java @@ -3,6 +3,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.booking.model.State; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.user.model.User; @@ -27,34 +28,29 @@ List findByBookerAndStartBeforeAndEndBeforeOrderByStartDesc(User booker List findByItemAndBookerAndStartBeforeAndEndBefore(Item item, User booker, LocalDateTime s, LocalDateTime e); - @Query(nativeQuery = true, value = "SELECT * FROM BOOKINGS as b " + - "LEFT JOIN ITEMS as i ON b.ITEM_ID = i.ID " + - "WHERE i.OWNER_ID = ?1 AND b.END_DATE < ?2 AND b.START_DATE < ?3 " + - "ORDER BY b.START_DATE DESC") - List findByBookingForOwnerWithPast(Long i, LocalDateTime e, LocalDateTime s); - - @Query(nativeQuery = true, value = "SELECT * FROM BOOKINGS as b " + - "LEFT JOIN ITEMS as i ON b.ITEM_ID = i.ID " + - "WHERE i.OWNER_ID = ?1 AND b.START_DATE < ?2 AND b.END_DATE > ?3 " + - "ORDER BY b.START_DATE DESC") - List findByBookingForOwnerWithCurrent(Long i, LocalDateTime s, LocalDateTime e); - - @Query(nativeQuery = true, value = "SELECT * FROM BOOKINGS as b " + - "LEFT JOIN ITEMS as i ON b.ITEM_ID = i.ID " + - "WHERE i.OWNER_ID = ?1 AND b.START_DATE > ?2 " + - "ORDER BY b.START_DATE DESC") - List findByBookingForOwnerWithFuture(Long i, LocalDateTime s); - - @Query(nativeQuery = true, value = "SELECT * FROM BOOKINGS as b " + - "LEFT JOIN ITEMS as i ON b.ITEM_ID = i.ID " + - "WHERE i.OWNER_ID = ?1 " + - "ORDER BY b.START_DATE DESC") - List findByBookingForOwnerWithAll(Long i); - - @Query(nativeQuery = true, value = "SELECT * FROM BOOKINGS as b " + - "LEFT JOIN ITEMS as i ON b.ITEM_ID = i.ID " + - "WHERE i.OWNER_ID = ?1 AND b.STATUS LIKE ?2 " + - "ORDER BY b.START_DATE DESC") - List findByBookingForOwnerWithWaitingOrRejected(Long i, String status); + @Query("SELECT b FROM Booking b WHERE b.item.id IN" + + " (SELECT i.id FROM Item i WHERE i.owner.id = ?1)" + + " ORDER BY b.id DESC") + List findByOwnerAll(long userId); + + @Query("SELECT b FROM Booking b WHERE b.item.id IN " + + "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.start < ?2 AND b.end > ?2" + + " ORDER BY b.id DESC") + List findByOwnerAndCurrent(long userId, LocalDateTime currentDate); + + @Query("SELECT b FROM Booking b WHERE b.item.id IN " + + "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.end < ?2" + + " ORDER BY b.id DESC") + List findByOwnerAndPast(long userId, LocalDateTime currentDate); + + @Query("SELECT b FROM Booking b WHERE b.item.id IN " + + "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.start > ?2" + + " ORDER BY b.id DESC") + List findByUserAndFuture(long userId, LocalDateTime currentDate); + + @Query("SELECT b FROM Booking b WHERE b.item.id IN " + + "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.status = ?2" + + " ORDER BY b.id DESC") + List findByOwnerAndByStatus(long userId, State status); } diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java index 3ebb00d24..72c70d70d 100644 --- a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java @@ -1,19 +1,29 @@ package ru.practicum.shareit.booking.dto; import lombok.Data; -import ru.practicum.shareit.booking.State; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import ru.practicum.shareit.booking.model.State; +import javax.validation.constraints.Future; +import javax.validation.constraints.FutureOrPresent; import java.time.LocalDateTime; @Data +@NoArgsConstructor public class BookingDTO { private long id; + @FutureOrPresent + @NonNull private LocalDateTime start; + @Future + @NonNull private LocalDateTime end; + @NonNull private Long itemId; private String itemName; diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java index fefbdd7fa..2e174bcea 100644 --- a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java @@ -1,9 +1,7 @@ package ru.practicum.shareit.booking.dto; import lombok.Data; -import ru.practicum.shareit.booking.State; -import ru.practicum.shareit.item.model.Item; -import ru.practicum.shareit.user.model.User; +import ru.practicum.shareit.booking.model.State; import java.time.LocalDateTime; @@ -21,4 +19,16 @@ public class BookingDTOToReturn { private User booker; private State status; + + @Data + public static class User { + private final long id; + private final String name; + } + + @Data + public static class Item { + private final long id; + private final String name; + } } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/booking/model/Booking.java b/src/main/java/ru/practicum/shareit/booking/model/Booking.java index defb511b1..023ca13a4 100644 --- a/src/main/java/ru/practicum/shareit/booking/model/Booking.java +++ b/src/main/java/ru/practicum/shareit/booking/model/Booking.java @@ -2,7 +2,6 @@ import lombok.*; import org.hibernate.Hibernate; -import ru.practicum.shareit.booking.State; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.user.model.User; @@ -30,10 +29,12 @@ public class Booking { @ManyToOne @JoinColumn(name = "item_id") + @ToString.Exclude private Item item; - @OneToOne + @ManyToOne @JoinColumn(name = "booker_id") + @ToString.Exclude private User booker; @Enumerated(EnumType.STRING) diff --git a/src/main/java/ru/practicum/shareit/booking/model/State.java b/src/main/java/ru/practicum/shareit/booking/model/State.java new file mode 100644 index 000000000..03ea64110 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/model/State.java @@ -0,0 +1,5 @@ +package ru.practicum.shareit.booking.model; + +public enum State { + WAITING, APPROVED, REJECTED, CANCELED; +} diff --git a/src/main/java/ru/practicum/shareit/booking/model/Status.java b/src/main/java/ru/practicum/shareit/booking/model/Status.java new file mode 100644 index 000000000..9229d107b --- /dev/null +++ b/src/main/java/ru/practicum/shareit/booking/model/Status.java @@ -0,0 +1,10 @@ +package ru.practicum.shareit.booking.model; + +public enum Status { + ALL, + CURRENT, + PAST, + FUTURE, + WAITING, + REJECTED +} diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingService.java b/src/main/java/ru/practicum/shareit/booking/service/BookingService.java index 3716e6a1a..882c72425 100644 --- a/src/main/java/ru/practicum/shareit/booking/service/BookingService.java +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingService.java @@ -6,13 +6,13 @@ import java.util.Collection; public interface BookingService { - BookingDTOToReturn addBooking(Long userId, BookingDTO bookingDto); + BookingDTOToReturn add(Long userId, BookingDTO bookingDto); - BookingDTOToReturn updateStatusBooking(Long userId, Long bookingId, Boolean approved); + BookingDTOToReturn update(Long userId, Long bookingId, Boolean approved); - BookingDTOToReturn getBooking(Long bookingId, Long userId); + BookingDTOToReturn get(Long bookingId, Long userId); - Collection getBookingByBooker(Long usersId, String state); + Collection getByBooker(Long usersId, String state); - Collection getBookingByOwner(Long usersId, String status); + Collection getByOwner(Long usersId, String status); } diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java index bfe4702db..fe759119d 100644 --- a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java @@ -1,12 +1,13 @@ package ru.practicum.shareit.booking.service; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.practicum.shareit.booking.BookingMapper; import ru.practicum.shareit.booking.BookingRepository; -import ru.practicum.shareit.booking.State; +import ru.practicum.shareit.booking.model.State; import ru.practicum.shareit.booking.dto.BookingDTO; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; import ru.practicum.shareit.booking.model.Booking; @@ -22,8 +23,9 @@ import java.util.*; @Service - +@Transactional(readOnly = true) @RequiredArgsConstructor(onConstructor_ = @Autowired) +@Slf4j public class BookingServiceImpl implements BookingService { private final BookingRepository bRepository; @@ -32,18 +34,14 @@ public class BookingServiceImpl implements BookingService { @Transactional @Override - public BookingDTOToReturn addBooking(Long userId, BookingDTO bookingDto) { - Optional item = iRepository.findById(bookingDto.getItemId()); - Optional user = uRepository.findById(userId); - if (user.isEmpty()) { - throw new NotFoundException("User not found"); - } + public BookingDTOToReturn add(Long userId, BookingDTO bookingDto) { + Optional item = Optional.ofNullable(iRepository.findById(bookingDto.getItemId()) + .orElseThrow(() -> new NotFoundException("User not found"))); + Optional user = Optional.ofNullable(uRepository.findById(userId) + .orElseThrow(() -> new NotFoundException("Item not found"))); if (item.isPresent() && !item.get().getAvailable()) { throw new BadRequestException("You can not book this item"); } - if (item.isEmpty()) { - throw new NotFoundException("Cannot create booking"); - } if (Objects.equals(item.get().getOwner().getId(), userId)) { throw new NotFoundException("You cannot book your item"); } @@ -61,57 +59,47 @@ public BookingDTOToReturn addBooking(Long userId, BookingDTO bookingDto) { @Transactional @Override - public BookingDTOToReturn updateStatusBooking(Long userId, Long bookingId, Boolean approved) { - Booking booking; - if (bRepository.existsById(bookingId)) { - booking = bRepository.getReferenceById(bookingId); - } else { - throw new NotFoundException("Booking is empty"); - } - Long ownerId = booking.getItem().getOwner().getId(); + public BookingDTOToReturn update(Long userId, Long bookingId, Boolean approved) { + Optional booking = Optional.ofNullable(Optional.of(bRepository.getReferenceById(bookingId)) + .orElseThrow(() -> new NotFoundException("Booking not found"))); + Long ownerId = booking.get().getItem().getOwner().getId(); if (!Objects.equals(userId, ownerId)) { throw new NotFoundException("No rights"); } - if (!Objects.equals(String.valueOf(booking.getStatus()), "WAITING")) { + if (!Objects.equals(String.valueOf(booking.get().getStatus()), "WAITING")) { throw new BadRequestException("Status has already been changed"); } if (approved) { - booking.setStatus(State.APPROVED); + booking.get().setStatus(State.APPROVED); } else { - booking.setStatus(State.REJECTED); + booking.get().setStatus(State.REJECTED); } - return BookingMapper.toBookingDtoFrom(bRepository.save(booking)); + return BookingMapper.toBookingDtoFrom(booking.get()); } @Override - public BookingDTOToReturn getBooking(Long userId, Long bookingId) { - Booking booking; - if (bRepository.existsById(bookingId)) { - booking = bRepository.getReferenceById(bookingId); - } else { - throw new NotFoundException("Booking not found"); - } + public BookingDTOToReturn get(Long userId, Long bookingId) { + log.info("start"); + Booking booking = Optional.of(bRepository.getReferenceById(bookingId)) + .orElseThrow(() -> new NotFoundException("Booking not found")); + log.info("continue" + booking.getId() + booking.getItem()); Long ownerId = booking.getItem().getOwner().getId(); Long bookerId = booking.getBooker().getId(); if (Objects.equals(ownerId, userId) || Objects.equals(bookerId, userId)) { + log.info("end"); return BookingMapper.toBookingDtoFrom(booking); } throw new NotFoundException("No rights"); } @Override - public Collection getBookingByBooker(Long usersId, String status) { - Optional booker = uRepository.findById(usersId); + public List getByBooker(Long usersId, String status) { + Optional booker = Optional.ofNullable(uRepository.findById(usersId) + .orElseThrow(() -> new NotFoundException("No rights"))); List bookingsByBooker; - if (booker.isEmpty()) { - throw new NotFoundException("No rights"); - } - if (status == null || status.equals("")) { - status = "ALL"; - } switch (status) { case "ALL": bookingsByBooker = bRepository.findByBookerOrderByStartDesc(booker.get()); @@ -141,35 +129,29 @@ public Collection getBookingByBooker(Long usersId, String st } @Override - public Collection getBookingByOwner(Long usersId, String status) { - Optional owner = uRepository.findById(usersId); - List bookingsByOwner; - if (owner.isEmpty()) { - throw new NotFoundException("No rights"); - } - if (status == null || status.equals("")) { - status = "ALL"; + public List getByOwner(Long userId, String status) { + if (uRepository.findById(userId).isEmpty()) { + throw new NotFoundException("User not found"); } + List bookingsByOwner; switch (status) { case "ALL": - bookingsByOwner = bRepository.findByBookingForOwnerWithAll(usersId); + bookingsByOwner = bRepository.findByOwnerAll(userId); break; case "CURRENT": - bookingsByOwner = bRepository.findByBookingForOwnerWithCurrent(usersId, LocalDateTime.now(), - LocalDateTime.now()); + bookingsByOwner = bRepository.findByOwnerAndCurrent(userId, LocalDateTime.now()); break; case "PAST": - bookingsByOwner = bRepository.findByBookingForOwnerWithPast(usersId, LocalDateTime.now(), - LocalDateTime.now()); + bookingsByOwner = bRepository.findByOwnerAndPast(userId, LocalDateTime.now()); break; case "FUTURE": - bookingsByOwner = bRepository.findByBookingForOwnerWithFuture(usersId, LocalDateTime.now()); + bookingsByOwner = bRepository.findByUserAndFuture(userId, LocalDateTime.now()); break; case "WAITING": - bookingsByOwner = bRepository.findByBookingForOwnerWithWaitingOrRejected(usersId, "WAITING"); + bookingsByOwner = bRepository.findByOwnerAndByStatus(userId, State.WAITING); break; case "REJECTED": - bookingsByOwner = bRepository.findByBookingForOwnerWithWaitingOrRejected(usersId, "REJECTED"); + bookingsByOwner = bRepository.findByOwnerAndByStatus(userId, State.REJECTED); break; default: throw new StatusBadRequestException("Unknown state: UNSUPPORTED_STATUS"); diff --git a/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java b/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java index 91204e8d4..f1fbe7102 100644 --- a/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java +++ b/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java @@ -1,5 +1,6 @@ package ru.practicum.shareit.exception; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageConversionException; @@ -10,10 +11,12 @@ import java.util.Map; @RestControllerAdvice +@Slf4j public class ErrorHandler { @ExceptionHandler({HttpMessageConversionException.class, BadRequestException.class}) public ResponseEntity> handleValid(final RuntimeException e) { + log.error("Validation error"); return new ResponseEntity<>( Map.of("Ошибка в валидации", e.getMessage()), HttpStatus.BAD_REQUEST @@ -22,6 +25,7 @@ public ResponseEntity> handleValid(final RuntimeException e) @ExceptionHandler public ResponseEntity> handleValidation(final MethodArgumentNotValidException e) { + log.error("Not valid argument"); return new ResponseEntity<>( Map.of("Ошибка в валидации", e.getMessage()), HttpStatus.BAD_REQUEST @@ -30,6 +34,7 @@ public ResponseEntity> handleValidation(final MethodArgument @ExceptionHandler public ResponseEntity> handleNotFound(final NotFoundException e) { + log.error("Not found"); return new ResponseEntity<>( Map.of("Объект не найден", e.getMessage()), HttpStatus.NOT_FOUND @@ -38,6 +43,7 @@ public ResponseEntity> handleNotFound(final NotFoundExceptio @ExceptionHandler public ResponseEntity> handleStatus(final StatusBadRequestException e) { + log.error("Bad request"); return new ResponseEntity<>( Map.of("error", e.getMessage()), HttpStatus.BAD_REQUEST); @@ -45,6 +51,7 @@ public ResponseEntity> handleStatus(final StatusBadRequestEx @ExceptionHandler public ResponseEntity> handleForbiddenError(final ForbiddenException e) { + log.error("No rights"); return new ResponseEntity<>( Map.of("Отказано в доступе", e.getMessage()), HttpStatus.FORBIDDEN @@ -53,6 +60,7 @@ public ResponseEntity> handleForbiddenError(final ForbiddenE @ExceptionHandler public ResponseEntity> handleInternalServerError(final Exception e) { + log.error("Server error"); return new ResponseEntity<>( Map.of("Серверу не удается обработать запрос", e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR @@ -61,6 +69,7 @@ public ResponseEntity> handleInternalServerError(final Excep @ExceptionHandler public ResponseEntity> handleConflictError(final ConflictException e) { + log.error("Conflict!"); return new ResponseEntity<>( Map.of("Запрос не может быть выполнен из-за конфликтного обращения к ресурсу", e.getMessage()), HttpStatus.CONFLICT diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/src/main/java/ru/practicum/shareit/item/ItemController.java index df03562c6..02b34d23c 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -10,7 +10,7 @@ import ru.practicum.shareit.item.service.ItemService; import javax.validation.Valid; -import java.util.Collection; +import java.util.List; @RestController @RequestMapping("/items") @@ -21,35 +21,35 @@ public class ItemController { private final ItemService itemService; @PostMapping - public ItemDTO addItem(@RequestHeader("X-Sharer-User-Id") Long userId, @Valid @RequestBody ItemDTO itemDto) { + public ItemDTO add(@RequestHeader("X-Sharer-User-Id") Long userId, @Valid @RequestBody ItemDTO itemDto) { log.info("Добавления новой вещи пользователем с id {}", userId); - return itemService.addItem(userId, itemDto); + return itemService.add(userId, itemDto); } @PatchMapping("/{itemId}") - public ItemDTO changeItem(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long itemId, + public ItemDTO update(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long itemId, @RequestBody ItemDTO itemDto) { log.info("Обновление данные о вещи"); - return itemService.changeItem(userId, itemId, itemDto); + return itemService.update(userId, itemId, itemDto); } @GetMapping("/{itemId}") - public ItemDTOWithDate getItem(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long itemId) { + public ItemDTOWithDate get(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long itemId) { log.info("Получение вещи с id {}", itemId); - return itemService.getItem(userId, itemId); + return itemService.get(userId, itemId); } @GetMapping - public Collection getAllOwnItems(@RequestHeader("X-Sharer-User-Id") Long userId) { + public List getAllByOwner(@RequestHeader("X-Sharer-User-Id") Long userId) { log.info("Получение всех вещей пользователя с id {}", userId); - return itemService.getAllOwnItems(userId); + return itemService.getAllByOwner(userId); } @GetMapping("/search") - public Collection getItemsForRent(@RequestHeader("X-Sharer-User-Id") Long userId, - @RequestParam String text) { + public List getAllByText(@RequestHeader("X-Sharer-User-Id") Long userId, + @RequestParam String text) { log.info("Получение вещей для аренды содержащие в названии или описании текст {}", text); - return itemService.getItemsForRent(text); + return itemService.getAllByText(text); } @PostMapping("{itemId}/comment") diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java index ebfa53cfb..fadc6668f 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java @@ -1,7 +1,6 @@ package ru.practicum.shareit.item.dto; import lombok.Data; -import ru.practicum.shareit.user.model.User; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @@ -24,5 +23,9 @@ public class ItemDTO { private Long request; - + @Data + public static class User { + private final long id; + private final String name; + } } diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithComment.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithComment.java index 2f6136a31..4cc8ce883 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithComment.java +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithComment.java @@ -19,5 +19,5 @@ public class ItemDTOWithComment { private String authorName; - LocalDateTime created; + private LocalDateTime created; } diff --git a/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java index 5c5228287..bf81adb4e 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java @@ -1,6 +1,6 @@ package ru.practicum.shareit.item.mapper; -import org.springframework.stereotype.Component; +import lombok.experimental.UtilityClass; import ru.practicum.shareit.item.dto.ItemDTOWithComment; import ru.practicum.shareit.item.model.Comment; import ru.practicum.shareit.item.model.Item; @@ -9,7 +9,7 @@ import java.util.ArrayList; import java.util.List; -@Component +@UtilityClass public class CommentMapper { public static ItemDTOWithComment toCommentDto(Comment comment) { diff --git a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java index 5ae4c0c6e..76d462173 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java @@ -1,6 +1,7 @@ package ru.practicum.shareit.item.mapper; -import org.springframework.stereotype.Component; +import lombok.experimental.UtilityClass; +import ru.practicum.shareit.booking.dto.BookingDTOToReturn; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithDate; import ru.practicum.shareit.item.model.Item; @@ -9,7 +10,7 @@ import java.util.ArrayList; import java.util.List; -@Component +@UtilityClass public class ItemMapper { public static ItemDTO toItemDto(Item item) { @@ -18,7 +19,6 @@ public static ItemDTO toItemDto(Item item) { itemDto.setName(item.getName()); itemDto.setDescription(item.getDescription()); itemDto.setAvailable(item.getAvailable()); - //itemDto.setRequest(item.getRequest() != null ? item.getRequest().getId() : null); return itemDto; } @@ -28,7 +28,6 @@ public static ItemDTOWithDate toItemDtoWithDate(Item item) { itemDto.setName(item.getName()); itemDto.setDescription(item.getDescription()); itemDto.setAvailable(item.getAvailable()); - //itemDto.setRequest(item.getRequest() != null ? item.getRequest().getId() : null); return itemDto; } @@ -70,5 +69,9 @@ public static List mapToItemDtoWithDate(Iterable items) { } return dtos; } + + public static BookingDTOToReturn.Item toItemToBookingDTO (Item item) { + return new BookingDTOToReturn.Item(item.getId(), item.getName()); + } } diff --git a/src/main/java/ru/practicum/shareit/item/model/Comment.java b/src/main/java/ru/practicum/shareit/item/model/Comment.java index c50612fcc..b14bd1f14 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Comment.java +++ b/src/main/java/ru/practicum/shareit/item/model/Comment.java @@ -28,14 +28,16 @@ public class Comment { @ManyToOne @JoinColumn(name = "item_id") + @ToString.Exclude private Item item; @ManyToOne @JoinColumn(name = "author_id") + @ToString.Exclude private User author; @Column(nullable = false) - LocalDateTime created = LocalDateTime.now(); + private LocalDateTime created = LocalDateTime.now(); @Override public boolean equals(Object o) { diff --git a/src/main/java/ru/practicum/shareit/item/model/Item.java b/src/main/java/ru/practicum/shareit/item/model/Item.java index 013e3d341..dc1c3670a 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Item.java +++ b/src/main/java/ru/practicum/shareit/item/model/Item.java @@ -35,6 +35,7 @@ public class Item { @ManyToOne @JoinColumn(name = "owner_id") + @ToString.Exclude private User owner; @Override diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemService.java b/src/main/java/ru/practicum/shareit/item/service/ItemService.java index f2691d3db..3df690d8e 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemService.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemService.java @@ -4,19 +4,19 @@ import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithDate; -import java.util.Collection; +import java.util.List; public interface ItemService { - ItemDTO addItem(Long userId, ItemDTO itemDto); + ItemDTO add(Long userId, ItemDTO itemDto); - ItemDTOWithDate getItem(Long userId, Long itemId); + ItemDTOWithDate get(Long userId, Long itemId); - ItemDTO changeItem(Long userId, Long itemId, ItemDTO itemDto); + ItemDTO update(Long userId, Long itemId, ItemDTO itemDto); - Collection getAllOwnItems(Long userId); + List getAllByOwner(Long userId); - Collection getItemsForRent(String substring); + List getAllByText(String substring); ItemDTOWithComment addComment(Long authorId, Long itemId, ItemDTOWithComment comment); } diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index b7ac82ab8..0414d89d8 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -28,6 +28,7 @@ @Service @RequiredArgsConstructor(onConstructor_ = @Autowired) +@Transactional(readOnly = true) public class ItemServiceImpl implements ItemService { private final ItemRepository repository; @@ -37,7 +38,7 @@ public class ItemServiceImpl implements ItemService { @Transactional @Override - public ItemDTO addItem(Long userId, ItemDTO itemDto) throws BadRequestException { + public ItemDTO add(Long userId, ItemDTO itemDto) throws BadRequestException { Optional user = userRepository.findById(userId); if (user.isEmpty()) { throw new NotFoundException("User not found"); @@ -48,7 +49,7 @@ public ItemDTO addItem(Long userId, ItemDTO itemDto) throws BadRequestException @Transactional @Override - public ItemDTO changeItem(Long userId, Long itemId, ItemDTO itemDto) throws BadRequestException { + public ItemDTO update(Long userId, Long itemId, ItemDTO itemDto) throws BadRequestException { Optional itemOpt = repository.findById(itemId); if (itemOpt.isEmpty()) { throw new NotFoundException("Item not found"); @@ -72,7 +73,7 @@ public ItemDTO changeItem(Long userId, Long itemId, ItemDTO itemDto) throws BadR } @Override - public ItemDTOWithDate getItem(Long userId, Long itemId) { + public ItemDTOWithDate get(Long userId, Long itemId) { Optional itemOpt = repository.findById(itemId); if (itemOpt.isEmpty()) { throw new NotFoundException("Item not found"); @@ -101,7 +102,7 @@ public ItemDTOWithDate getItem(Long userId, Long itemId) { } @Override - public Collection getAllOwnItems(Long userId) { + public List getAllByOwner(Long userId) { Optional userOpt = userRepository.findById(userId); if (userOpt.isEmpty()) { throw new NotFoundException("User not found"); @@ -128,7 +129,7 @@ public Collection getAllOwnItems(Long userId) { } @Override - public Collection getItemsForRent(String substring) { + public List getAllByText(String substring) { if (!Objects.equals(substring, "")) { return ItemMapper.mapToItemDto(repository.findItemsByNameOrDescription(substring)); } diff --git a/src/main/java/ru/practicum/shareit/user/UserController.java b/src/main/java/ru/practicum/shareit/user/UserController.java index 0ee53220d..37d9d121c 100644 --- a/src/main/java/ru/practicum/shareit/user/UserController.java +++ b/src/main/java/ru/practicum/shareit/user/UserController.java @@ -18,32 +18,32 @@ public class UserController { private final UserService userService; @PostMapping - public UserDTO createUser(@Valid @RequestBody UserDTO user) { + public UserDTO create(@Valid @RequestBody UserDTO user) { log.info("Добавление нового пользователя"); - return userService.createUser(user); + return userService.create(user); } @PatchMapping("/{userId}") public UserDTO update(@Valid @PathVariable Long userId, @RequestBody UserDTO user) { log.info("Обновление данных о пользователе с id {}", userId); - return userService.updateUser(userId, user); + return userService.update(userId, user); } @DeleteMapping("/{id}") - public void deleteUser(@PathVariable Long id) { + public void delete(@PathVariable Long id) { log.info("Удаление пользователя с id {}", id); - userService.deleteUser(id); + userService.delete(id); } @GetMapping - public Collection getUsers() { + public Collection getAll() { log.info("Получение списка всех пользователей"); - return userService.getAllUsers(); + return userService.getAll(); } @GetMapping("/{id}") - public UserDTO getUser(@PathVariable Long id) { + public UserDTO get(@PathVariable Long id) { log.info("Получение пользователя с id {}", id); - return userService.getUser(id); + return userService.get(id); } } diff --git a/src/main/java/ru/practicum/shareit/user/UserMapper.java b/src/main/java/ru/practicum/shareit/user/UserMapper.java index f09ab8fb0..b8453972e 100644 --- a/src/main/java/ru/practicum/shareit/user/UserMapper.java +++ b/src/main/java/ru/practicum/shareit/user/UserMapper.java @@ -1,13 +1,14 @@ package ru.practicum.shareit.user; -import org.springframework.stereotype.Component; +import lombok.experimental.UtilityClass; +import ru.practicum.shareit.booking.dto.BookingDTOToReturn; import ru.practicum.shareit.user.dto.UserDTO; import ru.practicum.shareit.user.model.User; import java.util.ArrayList; import java.util.List; -@Component +@UtilityClass public class UserMapper { public static UserDTO toUserDto(User user) { @@ -33,4 +34,8 @@ public static List mapToUserDto(Iterable users) { } return dtos; } + + public static BookingDTOToReturn.User toUserToBookingDTO (User user) { + return new BookingDTOToReturn.User(user.getId(), user.getName()); + } } diff --git a/src/main/java/ru/practicum/shareit/user/service/UserService.java b/src/main/java/ru/practicum/shareit/user/service/UserService.java index 80fe60e38..6b6026a9e 100644 --- a/src/main/java/ru/practicum/shareit/user/service/UserService.java +++ b/src/main/java/ru/practicum/shareit/user/service/UserService.java @@ -5,13 +5,13 @@ import java.util.Collection; public interface UserService { - UserDTO createUser(UserDTO userDto); + UserDTO create(UserDTO userDto); - UserDTO updateUser(Long userId, UserDTO userDto); + UserDTO update(Long userId, UserDTO userDto); - void deleteUser(Long id); + void delete(Long id); - Collection getAllUsers(); + Collection getAll(); - UserDTO getUser(Long id); + UserDTO get(Long id); } diff --git a/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java index 29af46453..860bf2551 100644 --- a/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java @@ -4,35 +4,33 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import ru.practicum.shareit.exception.BadRequestException; import ru.practicum.shareit.exception.NotFoundException; import ru.practicum.shareit.user.UserMapper; import ru.practicum.shareit.user.UserRepository; import ru.practicum.shareit.user.dto.UserDTO; import ru.practicum.shareit.user.model.User; -import java.util.Collection; +import java.util.List; import java.util.Optional; @Service @RequiredArgsConstructor(onConstructor_ = @Autowired) +@Transactional(readOnly = true) public class UserServiceImpl implements UserService { private final UserRepository repository; @Transactional @Override - public UserDTO createUser(UserDTO userDto) throws BadRequestException { + public UserDTO create(UserDTO userDto) { User user = repository.save(UserMapper.toUser(userDto)); return UserMapper.toUserDto(user); } @Transactional @Override - public UserDTO updateUser(Long userId, UserDTO userDto) throws BadRequestException { - Optional userOptional = repository.findById(userId); - if (userOptional.isEmpty()) { - throw new NotFoundException("User not found"); - } + public UserDTO update(Long userId, UserDTO userDto) { + Optional userOptional = Optional.ofNullable(repository.findById(userId) + .orElseThrow(() -> new NotFoundException("User not found"))); User user = userOptional.get(); if (userDto.getName() != null) { user.setName(userDto.getName()); @@ -45,7 +43,7 @@ public UserDTO updateUser(Long userId, UserDTO userDto) throws BadRequestExcepti @Transactional @Override - public void deleteUser(Long id) { + public void delete(Long id) { Optional user = repository.findById(id); if (user.isEmpty()) { throw new NotFoundException("User not found"); @@ -54,16 +52,14 @@ public void deleteUser(Long id) { } @Override - public Collection getAllUsers() { + public List getAll() { return UserMapper.mapToUserDto(repository.findAll()); } @Override - public UserDTO getUser(Long id) { - Optional user = repository.findById(id); - if (user.isEmpty()) { - throw new NotFoundException("User not found"); - } + public UserDTO get(Long id) { + Optional user = Optional.ofNullable(repository.findById(id) + .orElseThrow(() -> new NotFoundException("User not found"))); return UserMapper.toUserDto(user.get()); } } From 946485163ed3963d9fd39b9ea35074f357620c45 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Sun, 5 Feb 2023 22:38:22 +0300 Subject: [PATCH 07/45] Add files via upload --- .../practicum/shareit/booking/service/BookingServiceImpl.java | 2 +- src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java | 2 +- src/main/java/ru/practicum/shareit/user/UserMapper.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java index fe759119d..ede030904 100644 --- a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java @@ -60,7 +60,7 @@ public BookingDTOToReturn add(Long userId, BookingDTO bookingDto) { @Transactional @Override public BookingDTOToReturn update(Long userId, Long bookingId, Boolean approved) { - Optional booking = Optional.ofNullable(Optional.of(bRepository.getReferenceById(bookingId)) + Optional booking = Optional.ofNullable(Optional.of(bRepository.getReferenceById(bookingId)) .orElseThrow(() -> new NotFoundException("Booking not found"))); Long ownerId = booking.get().getItem().getOwner().getId(); diff --git a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java index 76d462173..28322538d 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java @@ -70,7 +70,7 @@ public static List mapToItemDtoWithDate(Iterable items) { return dtos; } - public static BookingDTOToReturn.Item toItemToBookingDTO (Item item) { + public static BookingDTOToReturn.Item toItemToBookingDTO(Item item) { return new BookingDTOToReturn.Item(item.getId(), item.getName()); } } diff --git a/src/main/java/ru/practicum/shareit/user/UserMapper.java b/src/main/java/ru/practicum/shareit/user/UserMapper.java index b8453972e..b4f5742d4 100644 --- a/src/main/java/ru/practicum/shareit/user/UserMapper.java +++ b/src/main/java/ru/practicum/shareit/user/UserMapper.java @@ -35,7 +35,7 @@ public static List mapToUserDto(Iterable users) { return dtos; } - public static BookingDTOToReturn.User toUserToBookingDTO (User user) { + public static BookingDTOToReturn.User toUserToBookingDTO(User user) { return new BookingDTOToReturn.User(user.getId(), user.getName()); } } From 81656d144784ad4f0f9ac0f598d01b317028cb1e Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Mon, 6 Feb 2023 00:48:29 +0300 Subject: [PATCH 08/45] Add files via upload --- .../booking/service/BookingServiceImpl.java | 59 +++++++++---------- .../shareit/item/CommentRepository.java | 4 ++ .../shareit/item/ItemRepository.java | 3 + .../shareit/item/dto/ItemDTOWithDate.java | 11 +++- .../shareit/item/mapper/CommentMapper.java | 6 ++ .../shareit/item/service/ItemServiceImpl.java | 51 ++++++---------- 6 files changed, 68 insertions(+), 66 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java index ede030904..ff8be08ea 100644 --- a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java @@ -35,14 +35,14 @@ public class BookingServiceImpl implements BookingService { @Transactional @Override public BookingDTOToReturn add(Long userId, BookingDTO bookingDto) { - Optional item = Optional.ofNullable(iRepository.findById(bookingDto.getItemId()) - .orElseThrow(() -> new NotFoundException("User not found"))); - Optional user = Optional.ofNullable(uRepository.findById(userId) - .orElseThrow(() -> new NotFoundException("Item not found"))); - if (item.isPresent() && !item.get().getAvailable()) { + Item item = iRepository.findById(bookingDto.getItemId()) + .orElseThrow(() -> new NotFoundException("User not found")); + User user = uRepository.findById(userId) + .orElseThrow(() -> new NotFoundException("Item not found")); + if (!item.getAvailable()) { throw new BadRequestException("You can not book this item"); } - if (Objects.equals(item.get().getOwner().getId(), userId)) { + if (Objects.equals(item.getOwner().getId(), userId)) { throw new NotFoundException("You cannot book your item"); } if (bookingDto.getEnd().isBefore(LocalDateTime.now()) || @@ -53,74 +53,71 @@ public BookingDTOToReturn add(Long userId, BookingDTO bookingDto) { } bookingDto.setBookerId(userId); bookingDto.setStatus(State.WAITING); - Booking booking = bRepository.save(BookingMapper.toBooking(bookingDto, item.get(), user.get())); + Booking booking = bRepository.save(BookingMapper.toBooking(bookingDto, item, user)); return BookingMapper.toBookingDtoFrom(booking); } @Transactional @Override public BookingDTOToReturn update(Long userId, Long bookingId, Boolean approved) { - Optional booking = Optional.ofNullable(Optional.of(bRepository.getReferenceById(bookingId)) - .orElseThrow(() -> new NotFoundException("Booking not found"))); - Long ownerId = booking.get().getItem().getOwner().getId(); + Booking booking = Optional.of(bRepository.getReferenceById(bookingId)) + .orElseThrow(() -> new NotFoundException("Booking not found")); + Long ownerId = booking.getItem().getOwner().getId(); if (!Objects.equals(userId, ownerId)) { throw new NotFoundException("No rights"); } - if (!Objects.equals(String.valueOf(booking.get().getStatus()), "WAITING")) { + if (!Objects.equals(String.valueOf(booking.getStatus()), "WAITING")) { throw new BadRequestException("Status has already been changed"); } if (approved) { - booking.get().setStatus(State.APPROVED); + booking.setStatus(State.APPROVED); } else { - booking.get().setStatus(State.REJECTED); + booking.setStatus(State.REJECTED); } - return BookingMapper.toBookingDtoFrom(booking.get()); + return BookingMapper.toBookingDtoFrom(booking); } @Override public BookingDTOToReturn get(Long userId, Long bookingId) { - log.info("start"); - Booking booking = Optional.of(bRepository.getReferenceById(bookingId)) - .orElseThrow(() -> new NotFoundException("Booking not found")); - log.info("continue" + booking.getId() + booking.getItem()); + Booking booking = bRepository.findById(bookingId) + .orElseThrow(() -> new NotFoundException(("Booking not found"))); Long ownerId = booking.getItem().getOwner().getId(); Long bookerId = booking.getBooker().getId(); - if (Objects.equals(ownerId, userId) || Objects.equals(bookerId, userId)) { - log.info("end"); - return BookingMapper.toBookingDtoFrom(booking); - } - throw new NotFoundException("No rights"); + if (Objects.equals(ownerId, userId) || Objects.equals(bookerId, userId)) { + return BookingMapper.toBookingDtoFrom(booking); + } + throw new NotFoundException("No rights"); } @Override public List getByBooker(Long usersId, String status) { - Optional booker = Optional.ofNullable(uRepository.findById(usersId) - .orElseThrow(() -> new NotFoundException("No rights"))); + User booker = uRepository.findById(usersId) + .orElseThrow(() -> new NotFoundException("No rights")); List bookingsByBooker; switch (status) { case "ALL": - bookingsByBooker = bRepository.findByBookerOrderByStartDesc(booker.get()); + bookingsByBooker = bRepository.findByBookerOrderByStartDesc(booker); break; case "CURRENT": - bookingsByBooker = bRepository.findByBookerAndStartBeforeAndEndAfterOrderByStartDesc(booker.get(), + bookingsByBooker = bRepository.findByBookerAndStartBeforeAndEndAfterOrderByStartDesc(booker, LocalDateTime.now(), LocalDateTime.now()); break; case "PAST": - bookingsByBooker = bRepository.findByBookerAndStartBeforeAndEndBeforeOrderByStartDesc(booker.get(), + bookingsByBooker = bRepository.findByBookerAndStartBeforeAndEndBeforeOrderByStartDesc(booker, LocalDateTime.now(), LocalDateTime.now()); break; case "FUTURE": - bookingsByBooker = bRepository.findByBookerAndStartAfterOrderByStartDesc(booker.get(), + bookingsByBooker = bRepository.findByBookerAndStartAfterOrderByStartDesc(booker, LocalDateTime.now()); break; case "WAITING": - bookingsByBooker = bRepository.findByBookerAndStatusOrderByStartDesc(booker.get(), State.WAITING); + bookingsByBooker = bRepository.findByBookerAndStatusOrderByStartDesc(booker, State.WAITING); break; case "REJECTED": - bookingsByBooker = bRepository.findByBookerAndStatusOrderByStartDesc(booker.get(), State.REJECTED); + bookingsByBooker = bRepository.findByBookerAndStatusOrderByStartDesc(booker, State.REJECTED); break; default: throw new StatusBadRequestException("Unknown state: UNSUPPORTED_STATUS"); diff --git a/src/main/java/ru/practicum/shareit/item/CommentRepository.java b/src/main/java/ru/practicum/shareit/item/CommentRepository.java index 6e014be9f..bf41371d0 100644 --- a/src/main/java/ru/practicum/shareit/item/CommentRepository.java +++ b/src/main/java/ru/practicum/shareit/item/CommentRepository.java @@ -1,11 +1,15 @@ package ru.practicum.shareit.item; +import org.springframework.data.domain.Sort; import org.springframework.data.jpa.repository.JpaRepository; import ru.practicum.shareit.item.model.Comment; import ru.practicum.shareit.item.model.Item; import java.util.List; +import java.util.Map; public interface CommentRepository extends JpaRepository { List findByItem(Item item); + + Map> findByItemIn(List items, Sort sort); } diff --git a/src/main/java/ru/practicum/shareit/item/ItemRepository.java b/src/main/java/ru/practicum/shareit/item/ItemRepository.java index 822579403..18b45a9db 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemRepository.java +++ b/src/main/java/ru/practicum/shareit/item/ItemRepository.java @@ -1,5 +1,6 @@ package ru.practicum.shareit.item; +import org.springframework.data.domain.Sort; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import ru.practicum.shareit.item.model.Item; @@ -15,4 +16,6 @@ public interface ItemRepository extends JpaRepository { "OR (LOWER(description) Like CONCAT('%', LOWER(?1), '%'))) " + "AND (available)") List findItemsByNameOrDescription(String substring); + + } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java index 61a216f05..26331b942 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java @@ -1,15 +1,17 @@ package ru.practicum.shareit.item.dto; import lombok.Data; +import lombok.Getter; +import lombok.Setter; import ru.practicum.shareit.booking.dto.BookingDTOForItem; -import ru.practicum.shareit.user.model.User; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.util.ArrayList; import java.util.List; -@Data +@Setter +@Getter public class ItemDTOWithDate { private long id; @@ -32,4 +34,9 @@ public class ItemDTOWithDate { private List comments = new ArrayList<>(); + @Data + public static class User { + private final long id; + private final String name; + } } diff --git a/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java index bf81adb4e..e47813df8 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java @@ -7,7 +7,9 @@ import ru.practicum.shareit.user.model.User; import java.util.ArrayList; +import java.util.Collection; import java.util.List; +import java.util.stream.Collectors; @UtilityClass public class CommentMapper { @@ -38,4 +40,8 @@ public static List mapToCommentDto(Iterable comment } return dtos; } + + public static List toCommentShortList(Collection comments) { + return new ArrayList<>(comments); + } } diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index 0414d89d8..e9d20385b 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -2,6 +2,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.practicum.shareit.booking.BookingMapper; @@ -26,6 +27,10 @@ import java.time.LocalDateTime; import java.util.*; +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.toList; +import static org.springframework.data.domain.Sort.Direction.DESC; + @Service @RequiredArgsConstructor(onConstructor_ = @Autowired) @Transactional(readOnly = true) @@ -39,28 +44,23 @@ public class ItemServiceImpl implements ItemService { @Transactional @Override public ItemDTO add(Long userId, ItemDTO itemDto) throws BadRequestException { - Optional user = userRepository.findById(userId); - if (user.isEmpty()) { - throw new NotFoundException("User not found"); - } - Item item = repository.save(ItemMapper.toItem(itemDto, user.get())); + User user = userRepository.findById(userId) + .orElseThrow(() -> new NotFoundException("User not found")); + Item item = repository.save(ItemMapper.toItem(itemDto, user)); return ItemMapper.toItemDto(item); } @Transactional @Override public ItemDTO update(Long userId, Long itemId, ItemDTO itemDto) throws BadRequestException { - Optional itemOpt = repository.findById(itemId); - if (itemOpt.isEmpty()) { - throw new NotFoundException("Item not found"); - } - Item item = itemOpt.get(); + Item item = repository.findById(itemId) + .orElseThrow(() -> new NotFoundException("Item not found")); User user = item.getOwner(); if (Objects.equals(user.getId(), userId)) { - if (itemDto.getName() != null) { + if (itemDto.getName() != null && !itemDto.getName().isBlank()) { item.setName(itemDto.getName()); } - if (itemDto.getDescription() != null) { + if (itemDto.getDescription() != null && !itemDto.getDescription().isBlank()) { item.setDescription(itemDto.getDescription()); } if (itemDto.getAvailable() != null) { @@ -74,11 +74,7 @@ public ItemDTO update(Long userId, Long itemId, ItemDTO itemDto) throws BadReque @Override public ItemDTOWithDate get(Long userId, Long itemId) { - Optional itemOpt = repository.findById(itemId); - if (itemOpt.isEmpty()) { - throw new NotFoundException("Item not found"); - } - Item item = itemOpt.get(); + Item item = repository.findById(itemId).orElseThrow(() -> new NotFoundException("Item not found")); ItemDTOWithDate itemDto = ItemMapper.toItemDtoWithDate(item); List comments = commentRepository.findByItem(item); itemDto.setComments(CommentMapper.mapToCommentDto(comments)); @@ -103,11 +99,7 @@ public ItemDTOWithDate get(Long userId, Long itemId) { @Override public List getAllByOwner(Long userId) { - Optional userOpt = userRepository.findById(userId); - if (userOpt.isEmpty()) { - throw new NotFoundException("User not found"); - } - User user = userOpt.get(); + User user = userRepository.findById(userId).orElseThrow(() -> new NotFoundException("User not found")); List items = repository.findByOwner(user); List itemDtos = ItemMapper.mapToItemDtoWithDate(items); for (ItemDTOWithDate itemDto : itemDtos) { @@ -139,21 +131,14 @@ public List getAllByText(String substring) { @Transactional @Override public ItemDTOWithComment addComment(Long authorId, Long itemId, ItemDTOWithComment itemDtoWithComment) { - Optional itemOpt = repository.findById(itemId); - if (itemOpt.isEmpty()) { - throw new NotFoundException("Item not found"); - } - Item item = itemOpt.get(); - Optional author = userRepository.findById(authorId); - if (author.isEmpty()) { - throw new NotFoundException("User not found"); - } - List bookings = bookingRepository.findByItemAndBookerAndStartBeforeAndEndBefore(item, author.get(), + Item item = repository.findById(itemId).orElseThrow(() -> new NotFoundException("Item not found")); + User author = userRepository.findById(authorId).orElseThrow(() -> new NotFoundException("User not found")); + List bookings = bookingRepository.findByItemAndBookerAndStartBeforeAndEndBefore(item, author, LocalDateTime.now(), LocalDateTime.now()); if (bookings.isEmpty()) { throw new BadRequestException("Booking is empty"); } - Comment comment = CommentMapper.toComment(itemDtoWithComment, item, author.get()); + Comment comment = CommentMapper.toComment(itemDtoWithComment, item, author); return CommentMapper.toCommentDto(commentRepository.save(comment)); } } From d53fceade657d618c280aed1171cfaf88c8806d1 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Mon, 6 Feb 2023 00:50:49 +0300 Subject: [PATCH 09/45] Add files via upload --- .../ru/practicum/shareit/item/ItemRepository.java | 1 - .../shareit/item/mapper/CommentMapper.java | 1 - .../shareit/item/service/ItemServiceImpl.java | 15 ++++++--------- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/item/ItemRepository.java b/src/main/java/ru/practicum/shareit/item/ItemRepository.java index 18b45a9db..4622e1080 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemRepository.java +++ b/src/main/java/ru/practicum/shareit/item/ItemRepository.java @@ -1,6 +1,5 @@ package ru.practicum.shareit.item; -import org.springframework.data.domain.Sort; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import ru.practicum.shareit.item.model.Item; diff --git a/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java index e47813df8..47d6f20ac 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java @@ -9,7 +9,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.stream.Collectors; @UtilityClass public class CommentMapper { diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index e9d20385b..e2449bdcb 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -2,7 +2,6 @@ import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.practicum.shareit.booking.BookingMapper; @@ -12,24 +11,22 @@ import ru.practicum.shareit.exception.BadRequestException; import ru.practicum.shareit.exception.ForbiddenException; import ru.practicum.shareit.exception.NotFoundException; -import ru.practicum.shareit.item.mapper.CommentMapper; import ru.practicum.shareit.item.CommentRepository; -import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.ItemRepository; -import ru.practicum.shareit.item.dto.ItemDTOWithComment; import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.item.dto.ItemDTOWithComment; import ru.practicum.shareit.item.dto.ItemDTOWithDate; +import ru.practicum.shareit.item.mapper.CommentMapper; +import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Comment; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.user.UserRepository; import ru.practicum.shareit.user.model.User; import java.time.LocalDateTime; -import java.util.*; - -import static java.util.stream.Collectors.groupingBy; -import static java.util.stream.Collectors.toList; -import static org.springframework.data.domain.Sort.Direction.DESC; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; @Service @RequiredArgsConstructor(onConstructor_ = @Autowired) From 15ec72aba86a7d7abe2bd4f0d3be1736a4a2f422 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Mon, 6 Feb 2023 17:12:28 +0300 Subject: [PATCH 10/45] Delete src/main/java/ru/practicum/shareit/item/storage directory --- .../item/storage/ItemInMemoryStorage.java | 85 ------------------- .../shareit/item/storage/ItemStorage.java | 22 ----- 2 files changed, 107 deletions(-) delete mode 100644 src/main/java/ru/practicum/shareit/item/storage/ItemInMemoryStorage.java delete mode 100644 src/main/java/ru/practicum/shareit/item/storage/ItemStorage.java diff --git a/src/main/java/ru/practicum/shareit/item/storage/ItemInMemoryStorage.java b/src/main/java/ru/practicum/shareit/item/storage/ItemInMemoryStorage.java deleted file mode 100644 index 19d0a6ebe..000000000 --- a/src/main/java/ru/practicum/shareit/item/storage/ItemInMemoryStorage.java +++ /dev/null @@ -1,85 +0,0 @@ -package ru.practicum.shareit.item.storage; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import ru.practicum.shareit.item.mapper.ItemMapper; -import ru.practicum.shareit.item.dto.ItemDTO; -import ru.practicum.shareit.item.model.Item; -import ru.practicum.shareit.user.model.User; - -import java.util.*; - -@Component -@RequiredArgsConstructor(onConstructor_ = @Autowired) -@Slf4j -public class ItemInMemoryStorage implements ItemStorage { - private final Map items = new HashMap<>(); - private long id = 0; - - @Override - public ItemDTO addItem(User user, ItemDTO itemDto) { - id = id + 1; - itemDto.setId(id); - items.put(id, ItemMapper.toItem(itemDto, user)); - log.info("Добавлена новая вещь: {},", itemDto.getName()); - return itemDto; - } - - @Override - public ItemDTO changeItem(Long userId, Long itemId, ItemDTO itemDto) { - Item item = items.get(itemId); - if (itemDto.getName() != null) { - item.setName(itemDto.getName()); - } - if (itemDto.getDescription() != null) { - item.setDescription(itemDto.getDescription()); - } - if (itemDto.getAvailable() != null) { - item.setAvailable(itemDto.getAvailable()); - } - - items.put(itemId, item); - log.info("Обновлены данные для вещи: {}", itemDto.getName()); - return ItemMapper.toItemDto(item); - } - - @Override - public Optional getItem(Long userId, Long itemId) { - return Optional.of(ItemMapper.toItemDto(items.get(itemId))); - } - - @Override - public Collection getAllOwnItems(Long userId) { - List itemsDto = new ArrayList<>(); - for (Item item : items.values()) { - if (Objects.equals(item.getOwner().getId(), userId)) { - itemsDto.add(ItemMapper.toItemDto(item)); - } - } - log.info("Колличество найденных вещей: {}", itemsDto.size()); - return itemsDto; - } - - @Override - public Collection getItemsForRent(String substring) { - List itemsDto = new ArrayList<>(); - if (!substring.equals("")) { - for (Item item : items.values()) { - if ((item.getName().toLowerCase().contains(substring.toLowerCase()) - || item.getDescription().toLowerCase().contains(substring.toLowerCase())) - && item.getAvailable()) { - itemsDto.add(ItemMapper.toItemDto(item)); - } - } - } - log.info("Колличество найденных вещей: {}", itemsDto.size()); - return itemsDto; - } - - @Override - public Optional getItemFromMap(Long itemId) { - return Optional.ofNullable(items.get(itemId)); - } -} diff --git a/src/main/java/ru/practicum/shareit/item/storage/ItemStorage.java b/src/main/java/ru/practicum/shareit/item/storage/ItemStorage.java deleted file mode 100644 index 8f6b17f4c..000000000 --- a/src/main/java/ru/practicum/shareit/item/storage/ItemStorage.java +++ /dev/null @@ -1,22 +0,0 @@ -package ru.practicum.shareit.item.storage; - -import ru.practicum.shareit.item.dto.ItemDTO; -import ru.practicum.shareit.item.model.Item; -import ru.practicum.shareit.user.model.User; - -import java.util.*; - -public interface ItemStorage { - - ItemDTO addItem(User user, ItemDTO itemDto); - - ItemDTO changeItem(Long userId, Long itemId, ItemDTO itemDto); - - Optional getItem(Long userId, Long itemId); - - Collection getAllOwnItems(Long userId); - - Collection getItemsForRent(String substring); - - Optional getItemFromMap(Long itemId); -} From 5fa3d76117e78bdcdc15d1704273c202ebc46111 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Mon, 6 Feb 2023 17:12:43 +0300 Subject: [PATCH 11/45] Delete src/main/java/ru/practicum/shareit/user/storage directory --- .../user/storage/UserInMemoryStorage.java | 68 ------------------- .../shareit/user/storage/UserStorage.java | 19 ------ 2 files changed, 87 deletions(-) delete mode 100644 src/main/java/ru/practicum/shareit/user/storage/UserInMemoryStorage.java delete mode 100644 src/main/java/ru/practicum/shareit/user/storage/UserStorage.java diff --git a/src/main/java/ru/practicum/shareit/user/storage/UserInMemoryStorage.java b/src/main/java/ru/practicum/shareit/user/storage/UserInMemoryStorage.java deleted file mode 100644 index 378447f90..000000000 --- a/src/main/java/ru/practicum/shareit/user/storage/UserInMemoryStorage.java +++ /dev/null @@ -1,68 +0,0 @@ -package ru.practicum.shareit.user.storage; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; -import ru.practicum.shareit.user.model.User; -import ru.practicum.shareit.user.UserMapper; -import ru.practicum.shareit.user.dto.UserDTO; - -import java.util.*; - -@Component -@Slf4j -public class UserInMemoryStorage implements UserStorage { - private final Map users = new HashMap<>(); - private long id = 0; - - @Override - public UserDTO addUser(UserDTO userDto) { - id = id + 1; - userDto.setId(id); - users.put(id, UserMapper.toUser(userDto)); - log.info("Добавлен пользователь: {},", userDto.getName()); - return userDto; - } - - @Override - public UserDTO updateUser(Long userId, UserDTO userDto) { - userDto.setId(userId); - User user = UserMapper.toUser(getUser(userId).get()); - if (userDto.getName() != null) { - user.setName(userDto.getName()); - } - if (userDto.getEmail() != null) { - user.setEmail(userDto.getEmail()); - } - user.setId(userId); - users.put(userId, user); - log.info("Обновлены данные пользователя: {}", userDto.getName()); - return UserMapper.toUserDto(user); - } - - @Override - public void deleteUser(Long id) { - users.remove(id); - log.info("Пользователь c id {} удален", id); - } - - @Override - public Collection getAllUsers() { - List usersDto = new ArrayList<>(); - for (Long id : users.keySet()) { - usersDto.add(UserMapper.toUserDto(users.get(id))); - } - log.info("Количество найденных пользвателей {}:", users.size()); - return usersDto; - } - - @Override - public Optional getUser(Long id) { - log.info("Пользователь с id {} найден", id); - User user = users.get(id); - if (user == null) { - return Optional.empty(); - } - return Optional.ofNullable(UserMapper.toUserDto(user)); - } - -} diff --git a/src/main/java/ru/practicum/shareit/user/storage/UserStorage.java b/src/main/java/ru/practicum/shareit/user/storage/UserStorage.java deleted file mode 100644 index 9ba7294a7..000000000 --- a/src/main/java/ru/practicum/shareit/user/storage/UserStorage.java +++ /dev/null @@ -1,19 +0,0 @@ -package ru.practicum.shareit.user.storage; - -import ru.practicum.shareit.user.dto.UserDTO; - -import java.util.Collection; -import java.util.Optional; - -public interface UserStorage { - - UserDTO addUser(UserDTO userDto); - - UserDTO updateUser(Long userId, UserDTO userDto); - - void deleteUser(Long id); - - Collection getAllUsers(); - - Optional getUser(Long id); -} From 64b8593883531d475b95b100dd057d0e7b0a654f Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Mon, 6 Feb 2023 19:20:11 +0300 Subject: [PATCH 12/45] Add files via upload --- .../java/ru/practicum/shareit/Create.java | 4 ++ .../shareit/booking/BookingController.java | 12 ++-- .../shareit/booking/BookingMapper.java | 6 +- .../shareit/booking/BookingRepository.java | 6 ++ .../shareit/booking/dto/BookingDTO.java | 15 ++--- .../booking/service/BookingServiceImpl.java | 9 +-- .../shareit/exception/ErrorHandler.java | 14 ++--- .../shareit/item/CommentRepository.java | 2 +- .../shareit/item/ItemRepository.java | 2 - .../shareit/item/dto/ItemDTOWithDate.java | 1 + .../ru/practicum/shareit/item/model/Item.java | 5 ++ .../shareit/item/service/ItemServiceImpl.java | 63 +++++++++++-------- .../shareit/user/UserController.java | 3 +- .../ru/practicum/shareit/user/UserMapper.java | 9 +++ .../practicum/shareit/user/dto/UserDTO.java | 3 +- .../shareit/user/dto/UserDTOToUpd.java | 19 ++++++ .../shareit/user/service/UserService.java | 3 +- .../shareit/user/service/UserServiceImpl.java | 11 ++-- 18 files changed, 116 insertions(+), 71 deletions(-) create mode 100644 src/main/java/ru/practicum/shareit/Create.java create mode 100644 src/main/java/ru/practicum/shareit/user/dto/UserDTOToUpd.java diff --git a/src/main/java/ru/practicum/shareit/Create.java b/src/main/java/ru/practicum/shareit/Create.java new file mode 100644 index 000000000..776ca0761 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/Create.java @@ -0,0 +1,4 @@ +package ru.practicum.shareit; + +public class Create { +} diff --git a/src/main/java/ru/practicum/shareit/booking/BookingController.java b/src/main/java/ru/practicum/shareit/booking/BookingController.java index f34f6fc94..60ee13a24 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingController.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingController.java @@ -6,8 +6,10 @@ import org.springframework.web.bind.annotation.*; import ru.practicum.shareit.booking.dto.BookingDTO; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; +import ru.practicum.shareit.booking.model.Status; import ru.practicum.shareit.booking.service.BookingService; +import javax.validation.Valid; import java.util.Collection; @RestController @@ -19,7 +21,7 @@ public class BookingController { @PostMapping public BookingDTOToReturn add(@RequestHeader("X-Sharer-User-Id") Long userId, - @RequestBody BookingDTO bookingDto) { + @Valid @RequestBody BookingDTO bookingDto) { log.info("Добавление запроса на аренду пользователем с id {}", userId); return bookingService.add(userId, bookingDto); } @@ -42,17 +44,17 @@ public BookingDTOToReturn get(@RequestHeader("X-Sharer-User-Id") Long userId, @P @GetMapping public Collection findByBooker(@RequestHeader("X-Sharer-User-Id") Long userId, @RequestParam(defaultValue = "ALL") - String state) { + String status) { log.info("Получение списка бронирований пользовалеля с id {}", userId); - return bookingService.getByBooker(userId, state); + return bookingService.getByBooker(userId, status); } @GetMapping("/owner") public Collection findByOwner(@RequestHeader("X-Sharer-User-Id") Long userId, @RequestParam(defaultValue = "ALL") - String state) { + String status) { log.info("Получение списка бронирований для всех вещей пользователя с id {}", userId); - return bookingService.getByOwner(userId, state); + return bookingService.getByOwner(userId, status); } } diff --git a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java index dc7229126..bb1797a0a 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java @@ -5,6 +5,7 @@ import ru.practicum.shareit.booking.dto.BookingDTOForItem; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.booking.model.State; import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.user.UserMapper; @@ -22,10 +23,7 @@ public static BookingDTO toBookingDto(Booking booking) { bookingDto.setId(booking.getId()); bookingDto.setStart(booking.getStart()); bookingDto.setEnd(booking.getEnd()); - bookingDto.setStatus(booking.getStatus()); bookingDto.setItemId(booking.getItem().getId()); - bookingDto.setItemName(booking.getItem() != null ? booking.getItem().getName() : null); - bookingDto.setBookerId(booking.getBooker() != null ? booking.getBooker().getId() : null); return bookingDto; } @@ -46,7 +44,7 @@ public static Booking toBooking(BookingDTO bookingDto, Item item, User user) { booking.setStart(bookingDto.getStart()); booking.setEnd(bookingDto.getEnd()); booking.setId(bookingDto.getId()); - booking.setStatus(bookingDto.getStatus()); + booking.setStatus(State.WAITING); booking.setItem(item); booking.setBooker(user); return booking; diff --git a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java index 7f880bfa6..6a0b6c028 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java @@ -1,5 +1,6 @@ package ru.practicum.shareit.booking; +import org.springframework.data.domain.Sort; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import ru.practicum.shareit.booking.model.Booking; @@ -9,6 +10,7 @@ import java.time.LocalDateTime; import java.util.List; +import java.util.Map; public interface BookingRepository extends JpaRepository { @@ -53,4 +55,8 @@ List findByItemAndBookerAndStartBeforeAndEndBefore(Item item, User book " ORDER BY b.id DESC") List findByOwnerAndByStatus(long userId, State status); + Booking findFirst1BookingByItem_IdAndStartIsBefore(long itemId, LocalDateTime currentTime, Sort sort); + + Booking findFirst1BookingByItem_IdAndStartIsAfter(long itemId, LocalDateTime currentTime, Sort sort); + } diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java index 72c70d70d..c59699fad 100644 --- a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java @@ -1,9 +1,8 @@ package ru.practicum.shareit.booking.dto; +import com.sun.istack.NotNull; import lombok.Data; import lombok.NoArgsConstructor; -import lombok.NonNull; -import ru.practicum.shareit.booking.model.State; import javax.validation.constraints.Future; import javax.validation.constraints.FutureOrPresent; @@ -16,19 +15,13 @@ public class BookingDTO { private long id; @FutureOrPresent - @NonNull + @NotNull private LocalDateTime start; @Future - @NonNull + @NotNull private LocalDateTime end; - @NonNull + @NotNull private Long itemId; - - private String itemName; - - private Long bookerId; - - private State status; } diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java index ff8be08ea..8d43b873d 100644 --- a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java @@ -45,15 +45,10 @@ public BookingDTOToReturn add(Long userId, BookingDTO bookingDto) { if (Objects.equals(item.getOwner().getId(), userId)) { throw new NotFoundException("You cannot book your item"); } - if (bookingDto.getEnd().isBefore(LocalDateTime.now()) || - bookingDto.getStart().isBefore(LocalDateTime.now()) || - (bookingDto.getEnd().isBefore(bookingDto.getStart()) && - !bookingDto.getEnd().equals(bookingDto.getStart()))) { + if ((!bookingDto.getEnd().isAfter(bookingDto.getStart()))) { throw new BadRequestException("Wrong date"); } - bookingDto.setBookerId(userId); - bookingDto.setStatus(State.WAITING); - Booking booking = bRepository.save(BookingMapper.toBooking(bookingDto, item, user)); + Booking booking = BookingMapper.toBooking(bookingDto, item, user); return BookingMapper.toBookingDtoFrom(booking); } diff --git a/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java b/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java index f1fbe7102..76d9e19d9 100644 --- a/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java +++ b/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java @@ -16,7 +16,7 @@ public class ErrorHandler { @ExceptionHandler({HttpMessageConversionException.class, BadRequestException.class}) public ResponseEntity> handleValid(final RuntimeException e) { - log.error("Validation error"); + log.error("Validation error{}", e.getMessage()); return new ResponseEntity<>( Map.of("Ошибка в валидации", e.getMessage()), HttpStatus.BAD_REQUEST @@ -25,7 +25,7 @@ public ResponseEntity> handleValid(final RuntimeException e) @ExceptionHandler public ResponseEntity> handleValidation(final MethodArgumentNotValidException e) { - log.error("Not valid argument"); + log.error("Not valid argument{}", e.getMessage()); return new ResponseEntity<>( Map.of("Ошибка в валидации", e.getMessage()), HttpStatus.BAD_REQUEST @@ -34,7 +34,7 @@ public ResponseEntity> handleValidation(final MethodArgument @ExceptionHandler public ResponseEntity> handleNotFound(final NotFoundException e) { - log.error("Not found"); + log.error("Not found{}", e.getMessage()); return new ResponseEntity<>( Map.of("Объект не найден", e.getMessage()), HttpStatus.NOT_FOUND @@ -43,7 +43,7 @@ public ResponseEntity> handleNotFound(final NotFoundExceptio @ExceptionHandler public ResponseEntity> handleStatus(final StatusBadRequestException e) { - log.error("Bad request"); + log.error("Bad request{}", e.getMessage()); return new ResponseEntity<>( Map.of("error", e.getMessage()), HttpStatus.BAD_REQUEST); @@ -51,7 +51,7 @@ public ResponseEntity> handleStatus(final StatusBadRequestEx @ExceptionHandler public ResponseEntity> handleForbiddenError(final ForbiddenException e) { - log.error("No rights"); + log.error("No rights{}", e.getMessage()); return new ResponseEntity<>( Map.of("Отказано в доступе", e.getMessage()), HttpStatus.FORBIDDEN @@ -60,7 +60,7 @@ public ResponseEntity> handleForbiddenError(final ForbiddenE @ExceptionHandler public ResponseEntity> handleInternalServerError(final Exception e) { - log.error("Server error"); + log.error("Server error{}", e.getMessage()); return new ResponseEntity<>( Map.of("Серверу не удается обработать запрос", e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR @@ -69,7 +69,7 @@ public ResponseEntity> handleInternalServerError(final Excep @ExceptionHandler public ResponseEntity> handleConflictError(final ConflictException e) { - log.error("Conflict!"); + log.error("Conflict!{}", e.getMessage()); return new ResponseEntity<>( Map.of("Запрос не может быть выполнен из-за конфликтного обращения к ресурсу", e.getMessage()), HttpStatus.CONFLICT diff --git a/src/main/java/ru/practicum/shareit/item/CommentRepository.java b/src/main/java/ru/practicum/shareit/item/CommentRepository.java index bf41371d0..0a4271de9 100644 --- a/src/main/java/ru/practicum/shareit/item/CommentRepository.java +++ b/src/main/java/ru/practicum/shareit/item/CommentRepository.java @@ -11,5 +11,5 @@ public interface CommentRepository extends JpaRepository { List findByItem(Item item); - Map> findByItemIn(List items, Sort sort); + Map> findByItemIn(List item, Sort sort); } diff --git a/src/main/java/ru/practicum/shareit/item/ItemRepository.java b/src/main/java/ru/practicum/shareit/item/ItemRepository.java index 4622e1080..822579403 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemRepository.java +++ b/src/main/java/ru/practicum/shareit/item/ItemRepository.java @@ -15,6 +15,4 @@ public interface ItemRepository extends JpaRepository { "OR (LOWER(description) Like CONCAT('%', LOWER(?1), '%'))) " + "AND (available)") List findItemsByNameOrDescription(String substring); - - } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java index 26331b942..f9cf39387 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java @@ -13,6 +13,7 @@ @Setter @Getter public class ItemDTOWithDate { + @NotNull private long id; @NotBlank diff --git a/src/main/java/ru/practicum/shareit/item/model/Item.java b/src/main/java/ru/practicum/shareit/item/model/Item.java index dc1c3670a..ac1c71dc0 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Item.java +++ b/src/main/java/ru/practicum/shareit/item/model/Item.java @@ -2,11 +2,14 @@ import lombok.*; import org.hibernate.Hibernate; +import ru.practicum.shareit.item.dto.ItemDTOWithComment; import ru.practicum.shareit.user.model.User; import javax.persistence.*; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; @Entity @@ -38,6 +41,8 @@ public class Item { @ToString.Exclude private User owner; + //private List comments = new ArrayList<>(); + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index e2449bdcb..e4719e046 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -1,7 +1,9 @@ package ru.practicum.shareit.item.service; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.practicum.shareit.booking.BookingMapper; @@ -27,10 +29,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor(onConstructor_ = @Autowired) @Transactional(readOnly = true) +@Slf4j public class ItemServiceImpl implements ItemService { private final ItemRepository repository; @@ -41,8 +45,7 @@ public class ItemServiceImpl implements ItemService { @Transactional @Override public ItemDTO add(Long userId, ItemDTO itemDto) throws BadRequestException { - User user = userRepository.findById(userId) - .orElseThrow(() -> new NotFoundException("User not found")); + User user = userRepository.findById(userId).orElseThrow(() -> new NotFoundException("User not found")); Item item = repository.save(ItemMapper.toItem(itemDto, user)); return ItemMapper.toItemDto(item); } @@ -50,8 +53,7 @@ public ItemDTO add(Long userId, ItemDTO itemDto) throws BadRequestException { @Transactional @Override public ItemDTO update(Long userId, Long itemId, ItemDTO itemDto) throws BadRequestException { - Item item = repository.findById(itemId) - .orElseThrow(() -> new NotFoundException("Item not found")); + Item item = repository.findById(itemId).orElseThrow(() -> new NotFoundException("Item not found")); User user = item.getOwner(); if (Objects.equals(user.getId(), userId)) { if (itemDto.getName() != null && !itemDto.getName().isBlank()) { @@ -63,7 +65,6 @@ public ItemDTO update(Long userId, Long itemId, ItemDTO itemDto) throws BadReque if (itemDto.getAvailable() != null) { item.setAvailable(itemDto.getAvailable()); } - repository.save(item); return ItemMapper.toItemDto(item); } throw new ForbiddenException("No rights"); @@ -96,27 +97,37 @@ public ItemDTOWithDate get(Long userId, Long itemId) { @Override public List getAllByOwner(Long userId) { - User user = userRepository.findById(userId).orElseThrow(() -> new NotFoundException("User not found")); - List items = repository.findByOwner(user); - List itemDtos = ItemMapper.mapToItemDtoWithDate(items); - for (ItemDTOWithDate itemDto : itemDtos) { - List comments = commentRepository.findByItem(ItemMapper.toItemWithDate(itemDto, user)); - itemDto.setComments(CommentMapper.mapToCommentDto(comments)); - List bookings = bookingRepository.findByItemOrderByStartDesc(ItemMapper.toItemWithDate(itemDto, user)); - if (!bookings.isEmpty()) { - LocalDateTime next = bookings.get(0).getStart(); - LocalDateTime last = bookings.get(1).getStart(); - Booking nextBooking = bookings.get(0); - Booking lastBooking = bookings.get(1); - BookingDTOForItem bookingNext = BookingMapper.toBookingDtoForItem(nextBooking, next); - BookingDTOForItem bookingLast = BookingMapper.toBookingDtoForItem(lastBooking, last); - itemDto.setNextBooking(bookingNext); - itemDto.setLastBooking(bookingLast); - } - } - return itemDtos; + User user = userRepository.getReferenceById(userId); + return repository.findByOwner(user).stream().map(this::toItemDtoWithBooking).collect(Collectors.toList()); } + private ItemDTOWithDate toItemDtoWithBooking(Item item) { + Booking lastBooking = bookingRepository.findFirst1BookingByItem_IdAndStartIsBefore(item.getId(), + LocalDateTime.now(), Sort.by("start").descending()); + Booking nextBooking = bookingRepository.findFirst1BookingByItem_IdAndStartIsAfter(item.getId(), + LocalDateTime.now(), Sort.by("start").ascending()); + + BookingDTOForItem lastBookingDto = lastBooking != null ? BookingMapper + .toBookingDtoForItem(lastBooking, LocalDateTime.now()) : null; + BookingDTOForItem nextBookingDto = nextBooking != null ? BookingMapper + .toBookingDtoForItem(nextBooking, LocalDateTime.now()) : null; + + ItemDTOWithDate itemDto = ItemMapper.toItemDtoWithDate(item); + itemDto.setLastBooking(lastBookingDto); + itemDto.setNextBooking(nextBookingDto); + itemDto.setComments(getItemComments(item)); + + return itemDto; + } + + private List getItemComments(Item item) { + return commentRepository.findByItem(item) + .stream() + .map(CommentMapper::toCommentDto) + .collect(Collectors.toList()); + } + + @Override public List getAllByText(String substring) { if (!Objects.equals(substring, "")) { @@ -130,8 +141,8 @@ public List getAllByText(String substring) { public ItemDTOWithComment addComment(Long authorId, Long itemId, ItemDTOWithComment itemDtoWithComment) { Item item = repository.findById(itemId).orElseThrow(() -> new NotFoundException("Item not found")); User author = userRepository.findById(authorId).orElseThrow(() -> new NotFoundException("User not found")); - List bookings = bookingRepository.findByItemAndBookerAndStartBeforeAndEndBefore(item, author, - LocalDateTime.now(), LocalDateTime.now()); + List bookings = bookingRepository + .findByItemAndBookerAndStartBeforeAndEndBefore(item, author, LocalDateTime.now(), LocalDateTime.now()); if (bookings.isEmpty()) { throw new BadRequestException("Booking is empty"); } diff --git a/src/main/java/ru/practicum/shareit/user/UserController.java b/src/main/java/ru/practicum/shareit/user/UserController.java index 37d9d121c..3d56616ec 100644 --- a/src/main/java/ru/practicum/shareit/user/UserController.java +++ b/src/main/java/ru/practicum/shareit/user/UserController.java @@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import ru.practicum.shareit.user.dto.UserDTO; +import ru.practicum.shareit.user.dto.UserDTOToUpd; import ru.practicum.shareit.user.service.UserService; import javax.validation.Valid; @@ -24,7 +25,7 @@ public UserDTO create(@Valid @RequestBody UserDTO user) { } @PatchMapping("/{userId}") - public UserDTO update(@Valid @PathVariable Long userId, @RequestBody UserDTO user) { + public UserDTOToUpd update(@Valid @PathVariable Long userId, @RequestBody UserDTO user) { log.info("Обновление данных о пользователе с id {}", userId); return userService.update(userId, user); } diff --git a/src/main/java/ru/practicum/shareit/user/UserMapper.java b/src/main/java/ru/practicum/shareit/user/UserMapper.java index b4f5742d4..9f12d52b3 100644 --- a/src/main/java/ru/practicum/shareit/user/UserMapper.java +++ b/src/main/java/ru/practicum/shareit/user/UserMapper.java @@ -3,6 +3,7 @@ import lombok.experimental.UtilityClass; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; import ru.practicum.shareit.user.dto.UserDTO; +import ru.practicum.shareit.user.dto.UserDTOToUpd; import ru.practicum.shareit.user.model.User; import java.util.ArrayList; @@ -19,6 +20,14 @@ public static UserDTO toUserDto(User user) { return userDto; } + public static UserDTOToUpd toUserDtoToUpd(User user) { + UserDTOToUpd userDto = new UserDTOToUpd(); + userDto.setId(user.getId()); + userDto.setName(user.getName()); + userDto.setEmail(user.getEmail()); + return userDto; + } + public static User toUser(UserDTO userDto) { User user = new User(); user.setId(userDto.getId()); diff --git a/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java b/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java index 8e3c9c937..337f73727 100644 --- a/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java +++ b/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java @@ -1,6 +1,7 @@ package ru.practicum.shareit.user.dto; import lombok.Data; +import ru.practicum.shareit.Create; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; @@ -10,7 +11,7 @@ public class UserDTO { private long id; - @NotBlank + @NotBlank(groups = {Create.class}) private String name; @Email diff --git a/src/main/java/ru/practicum/shareit/user/dto/UserDTOToUpd.java b/src/main/java/ru/practicum/shareit/user/dto/UserDTOToUpd.java new file mode 100644 index 000000000..def0ecd75 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/user/dto/UserDTOToUpd.java @@ -0,0 +1,19 @@ +package ru.practicum.shareit.user.dto; + +import lombok.Data; +import ru.practicum.shareit.Create; + +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; + +@Data +public class UserDTOToUpd { + + private long id; + + @NotBlank(groups = {Create.class}) + private String name; + + @NotBlank + private String email; +} diff --git a/src/main/java/ru/practicum/shareit/user/service/UserService.java b/src/main/java/ru/practicum/shareit/user/service/UserService.java index 6b6026a9e..8b1a49c54 100644 --- a/src/main/java/ru/practicum/shareit/user/service/UserService.java +++ b/src/main/java/ru/practicum/shareit/user/service/UserService.java @@ -1,13 +1,14 @@ package ru.practicum.shareit.user.service; import ru.practicum.shareit.user.dto.UserDTO; +import ru.practicum.shareit.user.dto.UserDTOToUpd; import java.util.Collection; public interface UserService { UserDTO create(UserDTO userDto); - UserDTO update(Long userId, UserDTO userDto); + UserDTOToUpd update(Long userId, UserDTO userDto); void delete(Long id); diff --git a/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java index 860bf2551..8cf72b696 100644 --- a/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java @@ -8,6 +8,7 @@ import ru.practicum.shareit.user.UserMapper; import ru.practicum.shareit.user.UserRepository; import ru.practicum.shareit.user.dto.UserDTO; +import ru.practicum.shareit.user.dto.UserDTOToUpd; import ru.practicum.shareit.user.model.User; import java.util.List; @@ -22,23 +23,23 @@ public class UserServiceImpl implements UserService { @Transactional @Override public UserDTO create(UserDTO userDto) { + User user = repository.save(UserMapper.toUser(userDto)); return UserMapper.toUserDto(user); } @Transactional @Override - public UserDTO update(Long userId, UserDTO userDto) { - Optional userOptional = Optional.ofNullable(repository.findById(userId) - .orElseThrow(() -> new NotFoundException("User not found"))); - User user = userOptional.get(); + public UserDTOToUpd update(Long userId, UserDTO userDto) { + User user = repository.findById(userId) + .orElseThrow(() -> new NotFoundException("User not found")); if (userDto.getName() != null) { user.setName(userDto.getName()); } if (userDto.getEmail() != null) { user.setEmail(userDto.getEmail()); } - return UserMapper.toUserDto(repository.save(user)); + return UserMapper.toUserDtoToUpd(user); } @Transactional From caf27e343163cee8d60295482120aceb12b9a43f Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Mon, 6 Feb 2023 20:50:25 +0300 Subject: [PATCH 13/45] Add files via upload --- .../shareit/booking/BookingController.java | 19 +++++++++---------- .../booking/service/BookingServiceImpl.java | 2 +- .../ru/practicum/shareit/item/model/Item.java | 5 ----- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/booking/BookingController.java b/src/main/java/ru/practicum/shareit/booking/BookingController.java index 60ee13a24..71cfcf3af 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingController.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingController.java @@ -6,7 +6,6 @@ import org.springframework.web.bind.annotation.*; import ru.practicum.shareit.booking.dto.BookingDTO; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; -import ru.practicum.shareit.booking.model.Status; import ru.practicum.shareit.booking.service.BookingService; import javax.validation.Valid; @@ -21,15 +20,15 @@ public class BookingController { @PostMapping public BookingDTOToReturn add(@RequestHeader("X-Sharer-User-Id") Long userId, - @Valid @RequestBody BookingDTO bookingDto) { + @Valid @RequestBody BookingDTO bookingDto) { log.info("Добавление запроса на аренду пользователем с id {}", userId); return bookingService.add(userId, bookingDto); } @PatchMapping("/{bookingId}") public BookingDTOToReturn update(@RequestHeader("X-Sharer-User-Id") Long userId, - @PathVariable Long bookingId, - @RequestParam Boolean approved) { + @PathVariable Long bookingId, + @RequestParam Boolean approved) { log.info("Обновление статуса запроса на аренду с id {}", bookingId); return bookingService.update(userId, bookingId, approved); @@ -43,18 +42,18 @@ public BookingDTOToReturn get(@RequestHeader("X-Sharer-User-Id") Long userId, @P @GetMapping public Collection findByBooker(@RequestHeader("X-Sharer-User-Id") Long userId, - @RequestParam(defaultValue = "ALL") - String status) { + @RequestParam(defaultValue = "ALL") + String state) { log.info("Получение списка бронирований пользовалеля с id {}", userId); - return bookingService.getByBooker(userId, status); + return bookingService.getByBooker(userId, state); } @GetMapping("/owner") public Collection findByOwner(@RequestHeader("X-Sharer-User-Id") Long userId, - @RequestParam(defaultValue = "ALL") - String status) { + @RequestParam(defaultValue = "ALL") + String state) { log.info("Получение списка бронирований для всех вещей пользователя с id {}", userId); - return bookingService.getByOwner(userId, status); + return bookingService.getByOwner(userId, state); } } diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java index 8d43b873d..ed91a7aa5 100644 --- a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java @@ -48,7 +48,7 @@ public BookingDTOToReturn add(Long userId, BookingDTO bookingDto) { if ((!bookingDto.getEnd().isAfter(bookingDto.getStart()))) { throw new BadRequestException("Wrong date"); } - Booking booking = BookingMapper.toBooking(bookingDto, item, user); + Booking booking = bRepository.save(BookingMapper.toBooking(bookingDto, item, user)); return BookingMapper.toBookingDtoFrom(booking); } diff --git a/src/main/java/ru/practicum/shareit/item/model/Item.java b/src/main/java/ru/practicum/shareit/item/model/Item.java index ac1c71dc0..dc1c3670a 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Item.java +++ b/src/main/java/ru/practicum/shareit/item/model/Item.java @@ -2,14 +2,11 @@ import lombok.*; import org.hibernate.Hibernate; -import ru.practicum.shareit.item.dto.ItemDTOWithComment; import ru.practicum.shareit.user.model.User; import javax.persistence.*; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; import java.util.Objects; @Entity @@ -41,8 +38,6 @@ public class Item { @ToString.Exclude private User owner; - //private List comments = new ArrayList<>(); - @Override public boolean equals(Object o) { if (this == o) return true; From c85e079643d036d92ec22ff57bf83d9ab8415260 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Mon, 6 Feb 2023 20:53:31 +0300 Subject: [PATCH 14/45] final i hope --- .../shareit/booking/BookingRepository.java | 31 ++++++++----------- .../shareit/user/dto/UserDTOToUpd.java | 1 - 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java index 6a0b6c028..481e52d54 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java @@ -10,7 +10,6 @@ import java.time.LocalDateTime; import java.util.List; -import java.util.Map; public interface BookingRepository extends JpaRepository { @@ -24,35 +23,31 @@ public interface BookingRepository extends JpaRepository { List findByBookerAndStartBeforeAndEndAfterOrderByStartDesc(User booker, LocalDateTime s, LocalDateTime e); - List findByBookerAndStartBeforeAndEndBeforeOrderByStartDesc(User booker, LocalDateTime s, - LocalDateTime e); + List findByBookerAndStartBeforeAndEndBeforeOrderByStartDesc(User booker, LocalDateTime s, LocalDateTime e); List findByItemAndBookerAndStartBeforeAndEndBefore(Item item, User booker, LocalDateTime s, LocalDateTime e); - @Query("SELECT b FROM Booking b WHERE b.item.id IN" + - " (SELECT i.id FROM Item i WHERE i.owner.id = ?1)" + - " ORDER BY b.id DESC") + @Query("SELECT b FROM Booking b WHERE b.item.id IN" + " (SELECT i.id FROM Item i WHERE i.owner.id = ?1)" + + " ORDER BY b.id DESC") List findByOwnerAll(long userId); - @Query("SELECT b FROM Booking b WHERE b.item.id IN " + - "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.start < ?2 AND b.end > ?2" + - " ORDER BY b.id DESC") + @Query("SELECT b FROM Booking b WHERE b.item.id IN " + + "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.start < ?2 AND b.end > ?2" + + " ORDER BY b.id DESC") List findByOwnerAndCurrent(long userId, LocalDateTime currentDate); - @Query("SELECT b FROM Booking b WHERE b.item.id IN " + - "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.end < ?2" + - " ORDER BY b.id DESC") + @Query("SELECT b FROM Booking b WHERE b.item.id IN " + + "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.end < ?2" + + " ORDER BY b.id DESC") List findByOwnerAndPast(long userId, LocalDateTime currentDate); - @Query("SELECT b FROM Booking b WHERE b.item.id IN " + - "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.start > ?2" + - " ORDER BY b.id DESC") + @Query("SELECT b FROM Booking b WHERE b.item.id IN " + + "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.start > ?2" + " ORDER BY b.id DESC") List findByUserAndFuture(long userId, LocalDateTime currentDate); - @Query("SELECT b FROM Booking b WHERE b.item.id IN " + - "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.status = ?2" + - " ORDER BY b.id DESC") + @Query("SELECT b FROM Booking b WHERE b.item.id IN " + + "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.status = ?2" + " ORDER BY b.id DESC") List findByOwnerAndByStatus(long userId, State status); Booking findFirst1BookingByItem_IdAndStartIsBefore(long itemId, LocalDateTime currentTime, Sort sort); diff --git a/src/main/java/ru/practicum/shareit/user/dto/UserDTOToUpd.java b/src/main/java/ru/practicum/shareit/user/dto/UserDTOToUpd.java index def0ecd75..745d3673c 100644 --- a/src/main/java/ru/practicum/shareit/user/dto/UserDTOToUpd.java +++ b/src/main/java/ru/practicum/shareit/user/dto/UserDTOToUpd.java @@ -3,7 +3,6 @@ import lombok.Data; import ru.practicum.shareit.Create; -import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; @Data From f3622f35865e21de8de8747a60362dad3af969b4 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Tue, 7 Feb 2023 13:01:56 +0300 Subject: [PATCH 15/45] Delete State.java --- src/main/java/ru/practicum/shareit/booking/State.java | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 src/main/java/ru/practicum/shareit/booking/State.java diff --git a/src/main/java/ru/practicum/shareit/booking/State.java b/src/main/java/ru/practicum/shareit/booking/State.java deleted file mode 100644 index 429348b1c..000000000 --- a/src/main/java/ru/practicum/shareit/booking/State.java +++ /dev/null @@ -1,5 +0,0 @@ -package ru.practicum.shareit.booking; - -public enum State { - WAITING, APPROVED, REJECTED, CANCELED; -} From 0452939e9094ca45535d05a6f4a0d0541fb5bebd Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Wed, 8 Feb 2023 01:37:17 +0300 Subject: [PATCH 16/45] Delete ItemRequest.java --- .../java/ru/practicum/shareit/request/ItemRequest.java | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 src/main/java/ru/practicum/shareit/request/ItemRequest.java diff --git a/src/main/java/ru/practicum/shareit/request/ItemRequest.java b/src/main/java/ru/practicum/shareit/request/ItemRequest.java deleted file mode 100644 index 95d6f23c8..000000000 --- a/src/main/java/ru/practicum/shareit/request/ItemRequest.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.practicum.shareit.request; - -/** - * TODO Sprint add-item-requests. - */ -public class ItemRequest { -} From 5c2a2478f05e8a8da0d092e0b5e3d22379da67b5 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Wed, 8 Feb 2023 01:38:39 +0300 Subject: [PATCH 17/45] Add files via upload --- .../java/ru/practicum/shareit/Update.java | 4 ++ .../shareit/booking/BookingController.java | 14 ++-- .../shareit/booking/BookingMapper.java | 17 +---- .../shareit/booking/BookingRepository.java | 11 +--- .../booking/dto/BookingDTOForItem.java | 15 +++-- .../booking/dto/BookingDTOToReturn.java | 4 +- .../shareit/booking/model/Booking.java | 2 +- .../shareit/booking/model/State.java | 15 +++-- .../shareit/booking/model/Status.java | 10 ++- .../booking/service/BookingService.java | 6 +- .../booking/service/BookingServiceImpl.java | 65 ++++++++++++------- .../shareit/item/CommentRepository.java | 5 +- .../shareit/item/ItemController.java | 6 +- .../shareit/item/ItemRepository.java | 24 ++++++- .../shareit/item/dto/CommentDTO.java | 23 +++++++ .../shareit/item/dto/ItemDTOWithDate.java | 11 ++-- .../shareit/item/mapper/CommentMapper.java | 12 ++-- .../shareit/item/mapper/ItemMapper.java | 63 +++++++++++++++--- .../shareit/item/model/ItemWithBookings.java | 19 ++++++ .../shareit/item/service/ItemService.java | 4 +- .../shareit/item/service/ItemServiceImpl.java | 57 ++++++---------- .../shareit/request/dto/ItemRequestDto.java | 2 +- .../shareit/request/model/ItemRequest.java | 4 +- .../shareit/user/UserController.java | 3 +- .../ru/practicum/shareit/user/UserMapper.java | 9 --- .../practicum/shareit/user/dto/UserDTO.java | 1 + .../shareit/user/service/UserService.java | 3 +- .../shareit/user/service/UserServiceImpl.java | 9 ++- src/main/resources/schema.sql | 2 +- 29 files changed, 253 insertions(+), 167 deletions(-) create mode 100644 src/main/java/ru/practicum/shareit/Update.java create mode 100644 src/main/java/ru/practicum/shareit/item/dto/CommentDTO.java create mode 100644 src/main/java/ru/practicum/shareit/item/model/ItemWithBookings.java diff --git a/src/main/java/ru/practicum/shareit/Update.java b/src/main/java/ru/practicum/shareit/Update.java new file mode 100644 index 000000000..99f0eab8c --- /dev/null +++ b/src/main/java/ru/practicum/shareit/Update.java @@ -0,0 +1,4 @@ +package ru.practicum.shareit; + +public class Update { +} diff --git a/src/main/java/ru/practicum/shareit/booking/BookingController.java b/src/main/java/ru/practicum/shareit/booking/BookingController.java index 71cfcf3af..e466bcbf6 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingController.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingController.java @@ -9,7 +9,7 @@ import ru.practicum.shareit.booking.service.BookingService; import javax.validation.Valid; -import java.util.Collection; +import java.util.List; @RestController @RequestMapping(path = "/bookings") @@ -41,17 +41,17 @@ public BookingDTOToReturn get(@RequestHeader("X-Sharer-User-Id") Long userId, @P } @GetMapping - public Collection findByBooker(@RequestHeader("X-Sharer-User-Id") Long userId, - @RequestParam(defaultValue = "ALL") - String state) { + public List findByBooker(@RequestHeader("X-Sharer-User-Id") Long userId, + @RequestParam(required = false, defaultValue = "ALL") + String state) { log.info("Получение списка бронирований пользовалеля с id {}", userId); return bookingService.getByBooker(userId, state); } @GetMapping("/owner") - public Collection findByOwner(@RequestHeader("X-Sharer-User-Id") Long userId, - @RequestParam(defaultValue = "ALL") - String state) { + public List findByOwner(@RequestHeader("X-Sharer-User-Id") Long userId, + @RequestParam(required = false, defaultValue = "ALL") + String state) { log.info("Получение списка бронирований для всех вещей пользователя с id {}", userId); return bookingService.getByOwner(userId, state); } diff --git a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java index bb1797a0a..751832e5a 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java @@ -5,7 +5,7 @@ import ru.practicum.shareit.booking.dto.BookingDTOForItem; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; import ru.practicum.shareit.booking.model.Booking; -import ru.practicum.shareit.booking.model.State; +import ru.practicum.shareit.booking.model.Status; import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.user.UserMapper; @@ -18,16 +18,6 @@ @UtilityClass public class BookingMapper { - public static BookingDTO toBookingDto(Booking booking) { - BookingDTO bookingDto = new BookingDTO(); - bookingDto.setId(booking.getId()); - bookingDto.setStart(booking.getStart()); - bookingDto.setEnd(booking.getEnd()); - bookingDto.setItemId(booking.getItem().getId()); - return bookingDto; - } - - public static BookingDTOToReturn toBookingDtoFrom(Booking booking) { BookingDTOToReturn bookingDto = new BookingDTOToReturn(); bookingDto.setId(booking.getId()); @@ -44,17 +34,16 @@ public static Booking toBooking(BookingDTO bookingDto, Item item, User user) { booking.setStart(bookingDto.getStart()); booking.setEnd(bookingDto.getEnd()); booking.setId(bookingDto.getId()); - booking.setStatus(State.WAITING); + booking.setStatus(Status.WAITING); booking.setItem(item); booking.setBooker(user); return booking; } - public static BookingDTOForItem toBookingDtoForItem(Booking booking, LocalDateTime dateTime) { + public static BookingDTOForItem toBookingDtoForItem(Booking booking) { BookingDTOForItem bookingDtoForItem = new BookingDTOForItem(); bookingDtoForItem.setId(booking.getId()); bookingDtoForItem.setBookerId(booking.getBooker().getId()); - bookingDtoForItem.setDateTime(dateTime); return bookingDtoForItem; } diff --git a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java index 481e52d54..876dac0b1 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java @@ -1,10 +1,9 @@ package ru.practicum.shareit.booking; -import org.springframework.data.domain.Sort; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import ru.practicum.shareit.booking.model.Booking; -import ru.practicum.shareit.booking.model.State; +import ru.practicum.shareit.booking.model.Status; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.user.model.User; @@ -15,7 +14,7 @@ public interface BookingRepository extends JpaRepository { List findByItemOrderByStartDesc(Item item); - List findByBookerAndStatusOrderByStartDesc(User booker, State status); + List findByBookerAndStatusOrderByStartDesc(User booker, Status status); List findByBookerOrderByStartDesc(User booker); @@ -48,10 +47,6 @@ List findByItemAndBookerAndStartBeforeAndEndBefore(Item item, User book @Query("SELECT b FROM Booking b WHERE b.item.id IN " + "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.status = ?2" + " ORDER BY b.id DESC") - List findByOwnerAndByStatus(long userId, State status); - - Booking findFirst1BookingByItem_IdAndStartIsBefore(long itemId, LocalDateTime currentTime, Sort sort); - - Booking findFirst1BookingByItem_IdAndStartIsAfter(long itemId, LocalDateTime currentTime, Sort sort); + List findByOwnerAndByStatus(long userId, Status status); } diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOForItem.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOForItem.java index 44b3f9077..0f68fa9b0 100644 --- a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOForItem.java +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOForItem.java @@ -1,12 +1,17 @@ package ru.practicum.shareit.booking.dto; -import lombok.Data; +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; -import java.time.LocalDateTime; - -@Data +@AllArgsConstructor +@Getter +@Setter +@JsonInclude(JsonInclude.Include.NON_NULL) +@NoArgsConstructor public class BookingDTOForItem { private long id; private Long bookerId; - private LocalDateTime dateTime; } diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java index 2e174bcea..8570bb54e 100644 --- a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java @@ -1,7 +1,7 @@ package ru.practicum.shareit.booking.dto; import lombok.Data; -import ru.practicum.shareit.booking.model.State; +import ru.practicum.shareit.booking.model.Status; import java.time.LocalDateTime; @@ -18,7 +18,7 @@ public class BookingDTOToReturn { private User booker; - private State status; + private Status status; @Data public static class User { diff --git a/src/main/java/ru/practicum/shareit/booking/model/Booking.java b/src/main/java/ru/practicum/shareit/booking/model/Booking.java index 023ca13a4..750870ded 100644 --- a/src/main/java/ru/practicum/shareit/booking/model/Booking.java +++ b/src/main/java/ru/practicum/shareit/booking/model/Booking.java @@ -39,7 +39,7 @@ public class Booking { @Enumerated(EnumType.STRING) @Column(nullable = false) - private State status; + private Status status; @Override public boolean equals(Object o) { diff --git a/src/main/java/ru/practicum/shareit/booking/model/State.java b/src/main/java/ru/practicum/shareit/booking/model/State.java index 03ea64110..2ecd29755 100644 --- a/src/main/java/ru/practicum/shareit/booking/model/State.java +++ b/src/main/java/ru/practicum/shareit/booking/model/State.java @@ -1,5 +1,10 @@ -package ru.practicum.shareit.booking.model; - -public enum State { - WAITING, APPROVED, REJECTED, CANCELED; -} +package ru.practicum.shareit.booking.model; + +public enum State { + ALL, + CURRENT, + PAST, + FUTURE, + REJECTED, + WAITING, +} diff --git a/src/main/java/ru/practicum/shareit/booking/model/Status.java b/src/main/java/ru/practicum/shareit/booking/model/Status.java index 9229d107b..3229f84ec 100644 --- a/src/main/java/ru/practicum/shareit/booking/model/Status.java +++ b/src/main/java/ru/practicum/shareit/booking/model/Status.java @@ -1,10 +1,8 @@ package ru.practicum.shareit.booking.model; public enum Status { - ALL, - CURRENT, - PAST, - FUTURE, - WAITING, - REJECTED + WAITING, + APPROVED, + REJECTED, + CANCELED } diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingService.java b/src/main/java/ru/practicum/shareit/booking/service/BookingService.java index 882c72425..a6b76c288 100644 --- a/src/main/java/ru/practicum/shareit/booking/service/BookingService.java +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingService.java @@ -3,7 +3,7 @@ import ru.practicum.shareit.booking.dto.BookingDTO; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; -import java.util.Collection; +import java.util.List; public interface BookingService { BookingDTOToReturn add(Long userId, BookingDTO bookingDto); @@ -12,7 +12,7 @@ public interface BookingService { BookingDTOToReturn get(Long bookingId, Long userId); - Collection getByBooker(Long usersId, String state); + List getByBooker(Long usersId, String stateString); - Collection getByOwner(Long usersId, String status); + List getByOwner(Long usersId, String state); } diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java index ed91a7aa5..953e263c4 100644 --- a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java @@ -7,20 +7,23 @@ import org.springframework.transaction.annotation.Transactional; import ru.practicum.shareit.booking.BookingMapper; import ru.practicum.shareit.booking.BookingRepository; -import ru.practicum.shareit.booking.model.State; import ru.practicum.shareit.booking.dto.BookingDTO; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.booking.model.State; +import ru.practicum.shareit.booking.model.Status; import ru.practicum.shareit.exception.BadRequestException; -import ru.practicum.shareit.exception.StatusBadRequestException; import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.exception.StatusBadRequestException; import ru.practicum.shareit.item.ItemRepository; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.user.UserRepository; import ru.practicum.shareit.user.model.User; import java.time.LocalDateTime; -import java.util.*; +import java.util.List; +import java.util.Objects; +import java.util.Optional; @Service @Transactional(readOnly = true) @@ -68,9 +71,9 @@ public BookingDTOToReturn update(Long userId, Long bookingId, Boolean approved) } if (approved) { - booking.setStatus(State.APPROVED); + booking.setStatus(Status.APPROVED); } else { - booking.setStatus(State.REJECTED); + booking.setStatus(Status.REJECTED); } return BookingMapper.toBookingDtoFrom(booking); } @@ -88,31 +91,33 @@ public BookingDTOToReturn get(Long userId, Long bookingId) { } @Override - public List getByBooker(Long usersId, String status) { + public List getByBooker(Long usersId, String stateString) { User booker = uRepository.findById(usersId) .orElseThrow(() -> new NotFoundException("No rights")); List bookingsByBooker; - switch (status) { - case "ALL": + stateValidation(stateString); + State state = State.valueOf(stateString); + switch (state) { + case ALL: bookingsByBooker = bRepository.findByBookerOrderByStartDesc(booker); break; - case "CURRENT": + case CURRENT: bookingsByBooker = bRepository.findByBookerAndStartBeforeAndEndAfterOrderByStartDesc(booker, LocalDateTime.now(), LocalDateTime.now()); break; - case "PAST": + case PAST: bookingsByBooker = bRepository.findByBookerAndStartBeforeAndEndBeforeOrderByStartDesc(booker, LocalDateTime.now(), LocalDateTime.now()); break; - case "FUTURE": + case FUTURE: bookingsByBooker = bRepository.findByBookerAndStartAfterOrderByStartDesc(booker, LocalDateTime.now()); break; - case "WAITING": - bookingsByBooker = bRepository.findByBookerAndStatusOrderByStartDesc(booker, State.WAITING); + case WAITING: + bookingsByBooker = bRepository.findByBookerAndStatusOrderByStartDesc(booker, Status.WAITING); break; - case "REJECTED": - bookingsByBooker = bRepository.findByBookerAndStatusOrderByStartDesc(booker, State.REJECTED); + case REJECTED: + bookingsByBooker = bRepository.findByBookerAndStatusOrderByStartDesc(booker, Status.REJECTED); break; default: throw new StatusBadRequestException("Unknown state: UNSUPPORTED_STATUS"); @@ -121,33 +126,43 @@ public List getByBooker(Long usersId, String status) { } @Override - public List getByOwner(Long userId, String status) { + public List getByOwner(Long userId, String stateString) { if (uRepository.findById(userId).isEmpty()) { throw new NotFoundException("User not found"); } List bookingsByOwner; - switch (status) { - case "ALL": + stateValidation(stateString); + State state = State.valueOf(stateString); + switch (state) { + case ALL: bookingsByOwner = bRepository.findByOwnerAll(userId); break; - case "CURRENT": + case CURRENT: bookingsByOwner = bRepository.findByOwnerAndCurrent(userId, LocalDateTime.now()); break; - case "PAST": + case PAST: bookingsByOwner = bRepository.findByOwnerAndPast(userId, LocalDateTime.now()); break; - case "FUTURE": + case FUTURE: bookingsByOwner = bRepository.findByUserAndFuture(userId, LocalDateTime.now()); break; - case "WAITING": - bookingsByOwner = bRepository.findByOwnerAndByStatus(userId, State.WAITING); + case WAITING: + bookingsByOwner = bRepository.findByOwnerAndByStatus(userId, Status.WAITING); break; - case "REJECTED": - bookingsByOwner = bRepository.findByOwnerAndByStatus(userId, State.REJECTED); + case REJECTED: + bookingsByOwner = bRepository.findByOwnerAndByStatus(userId, Status.REJECTED); break; default: throw new StatusBadRequestException("Unknown state: UNSUPPORTED_STATUS"); } return BookingMapper.mapToBookingDtoFrom(bookingsByOwner); } + + private void stateValidation(String state) { + try { + Enum.valueOf(State.class, state); + } catch (IllegalArgumentException e) { + throw new StatusBadRequestException("Unknown state: UNSUPPORTED_STATUS"); + } + } } diff --git a/src/main/java/ru/practicum/shareit/item/CommentRepository.java b/src/main/java/ru/practicum/shareit/item/CommentRepository.java index 0a4271de9..230fb5b27 100644 --- a/src/main/java/ru/practicum/shareit/item/CommentRepository.java +++ b/src/main/java/ru/practicum/shareit/item/CommentRepository.java @@ -6,10 +6,9 @@ import ru.practicum.shareit.item.model.Item; import java.util.List; -import java.util.Map; public interface CommentRepository extends JpaRepository { - List findByItem(Item item); + List findAllByItem(Item item); - Map> findByItemIn(List item, Sort sort); + List findAllByItemIdIn(List id, Sort created); } diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/src/main/java/ru/practicum/shareit/item/ItemController.java index 02b34d23c..59102f3a6 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -4,7 +4,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import ru.practicum.shareit.item.dto.ItemDTOWithComment; +import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithDate; import ru.practicum.shareit.item.service.ItemService; @@ -53,8 +53,8 @@ public List getAllByText(@RequestHeader("X-Sharer-User-Id") Long userId } @PostMapping("{itemId}/comment") - public ItemDTOWithComment addComment(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long itemId, - @Valid @RequestBody ItemDTOWithComment itemDtoWithComment) { + public CommentDTO addComment(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long itemId, + @Valid @RequestBody CommentDTO itemDtoWithComment) { log.info("Добавление комментария для вещи с id {}", itemId); return itemService.addComment(userId, itemId, itemDtoWithComment); } diff --git a/src/main/java/ru/practicum/shareit/item/ItemRepository.java b/src/main/java/ru/practicum/shareit/item/ItemRepository.java index 822579403..42d06e5ea 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemRepository.java +++ b/src/main/java/ru/practicum/shareit/item/ItemRepository.java @@ -3,16 +3,36 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.item.model.ItemWithBookings; import ru.practicum.shareit.user.model.User; +import java.time.LocalDateTime; import java.util.List; public interface ItemRepository extends JpaRepository { - List findByOwner(User user); - @Query(nativeQuery = true, value = "SELECT * FROM items AS i " + "WHERE ((LOWER(name) iLike CONCAT('%', LOWER(?1), '%')) " + "OR (LOWER(description) Like CONCAT('%', LOWER(?1), '%'))) " + "AND (available)") List findItemsByNameOrDescription(String substring); + + @Query(value = "select " + + "i.id, " + + "i.name, " + + "i.description, " + + "i.available, " + + "(select id from bookings " + + "where item_id = i.id and i.owner_id = ?2 and start_date <= ?1 " + + "order by start_date desc limit 1) \"lastBookingId\", " + + "(select booker_id from bookings " + + "where item_id = i.id and i.owner_id = ?2 and start_date <= ?1 " + + "order by start_date desc limit 1) \"lastBookerId\", " + + "(select id from bookings " + + "where item_id = i.id and i.owner_id = ?2 and start_date > ?1 " + + "order by start_date limit 1) \"nextBookingId\", " + + "(select booker_id from bookings " + + "where item_id = i.id and i.owner_id = ?2 and start_date > ?1 " + + "order by start_date limit 1) \"nextBookerId\" " + + "from items i" + " where i.owner_id = ?2 order by id", nativeQuery = true) + List findAllByOwnerWithBookings(LocalDateTime date, Long ownerId); } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/dto/CommentDTO.java b/src/main/java/ru/practicum/shareit/item/dto/CommentDTO.java new file mode 100644 index 000000000..61d7543c0 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/dto/CommentDTO.java @@ -0,0 +1,23 @@ +package ru.practicum.shareit.item.dto; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.time.LocalDateTime; + +@Data +public class CommentDTO { + + private Long id; + + @NotBlank + @Size(min = 1, max = 1000) + private String text; + + private String itemName; + + private String authorName; + + private LocalDateTime created; +} diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java index f9cf39387..3cb46b7dd 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java @@ -1,17 +1,14 @@ package ru.practicum.shareit.item.dto; -import lombok.Data; -import lombok.Getter; -import lombok.Setter; +import lombok.*; import ru.practicum.shareit.booking.dto.BookingDTOForItem; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; -import java.util.ArrayList; import java.util.List; -@Setter -@Getter +@Data +@NoArgsConstructor public class ItemDTOWithDate { @NotNull private long id; @@ -33,7 +30,7 @@ public class ItemDTOWithDate { private BookingDTOForItem lastBooking; - private List comments = new ArrayList<>(); + private List comments; @Data public static class User { diff --git a/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java index 47d6f20ac..af947313c 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java @@ -1,7 +1,7 @@ package ru.practicum.shareit.item.mapper; import lombok.experimental.UtilityClass; -import ru.practicum.shareit.item.dto.ItemDTOWithComment; +import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.model.Comment; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.user.model.User; @@ -13,8 +13,8 @@ @UtilityClass public class CommentMapper { - public static ItemDTOWithComment toCommentDto(Comment comment) { - ItemDTOWithComment itemDtoWithComment = new ItemDTOWithComment(); + public static CommentDTO toCommentDto(Comment comment) { + CommentDTO itemDtoWithComment = new CommentDTO(); itemDtoWithComment.setId(comment.getId()); itemDtoWithComment.setText(comment.getText()); itemDtoWithComment.setItemName(comment.getItem().getName()); @@ -23,7 +23,7 @@ public static ItemDTOWithComment toCommentDto(Comment comment) { return itemDtoWithComment; } - public static Comment toComment(ItemDTOWithComment itemDtoWithComment, Item item, User author) { + public static Comment toComment(CommentDTO itemDtoWithComment, Item item, User author) { Comment comment = new Comment(); comment.setId(comment.getId()); comment.setText(itemDtoWithComment.getText()); @@ -32,8 +32,8 @@ public static Comment toComment(ItemDTOWithComment itemDtoWithComment, Item item return comment; } - public static List mapToCommentDto(Iterable comments) { - List dtos = new ArrayList<>(); + public static List mapToCommentDto(Iterable comments) { + List dtos = new ArrayList<>(); for (Comment comment : comments) { dtos.add(toCommentDto(comment)); } diff --git a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java index 28322538d..793225f1e 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java @@ -1,14 +1,21 @@ package ru.practicum.shareit.item.mapper; import lombok.experimental.UtilityClass; +import ru.practicum.shareit.booking.dto.BookingDTOForItem; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithDate; +import ru.practicum.shareit.item.model.Comment; import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.item.model.ItemWithBookings; +import ru.practicum.shareit.user.UserRepository; import ru.practicum.shareit.user.model.User; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; @UtilityClass public class ItemMapper { @@ -22,7 +29,7 @@ public static ItemDTO toItemDto(Item item) { return itemDto; } - public static ItemDTOWithDate toItemDtoWithDate(Item item) { + public static ItemDTOWithDate mapToItemDtoWithDate(Item item) { ItemDTOWithDate itemDto = new ItemDTOWithDate(); itemDto.setId(item.getId()); itemDto.setName(item.getName()); @@ -43,6 +50,17 @@ public static Item toItem(ItemDTO itemDto, User user) { } + public static Item toItem(ItemDTOWithDate itemDto, UserRepository uRepo) { + Item item = new Item(); + item.setId(itemDto.getId()); + item.setName(itemDto.getName()); + item.setDescription(itemDto.getDescription()); + item.setAvailable(itemDto.getAvailable()); + item.setOwner(uRepo.getReferenceById(itemDto.getOwner().getId())); + return item; + + } + public static Item toItemWithDate(ItemDTOWithDate itemDto, User user) { Item item = new Item(); item.setId(itemDto.getId()); @@ -62,16 +80,45 @@ public static List mapToItemDto(Iterable items) { return dtos; } - public static List mapToItemDtoWithDate(Iterable items) { - List dtos = new ArrayList<>(); - for (Item item : items) { - dtos.add(toItemDtoWithDate(item)); + public static BookingDTOToReturn.Item toItemToBookingDTO(Item item) { + return new BookingDTOToReturn.Item(item.getId(), item.getName()); + } + + public static List mapToItemDtoWithDate(List items, + Map> comments){ + return items.stream() + .map(i -> toItemDtoWithDate2(i, comments.get(i.getId()))) + .collect(Collectors.toUnmodifiableList()); + } + + public static ItemDTOWithDate toItemDtoWithDate2(ItemWithBookings item, List comments) { + ItemDTOWithDate dto = toDtoWithDateFromWithBookings(item); + List commentsList = new ArrayList<>(); + + if (comments != null) { + commentsList.addAll(comments); } - return dtos; + dto.setComments(CommentMapper.mapToCommentDto(commentsList)); + return dto; } - public static BookingDTOToReturn.Item toItemToBookingDTO(Item item) { - return new BookingDTOToReturn.Item(item.getId(), item.getName()); + public static ItemDTOWithDate toDtoWithDateFromWithBookings(ItemWithBookings item) { + ItemDTOWithDate iDTO = new ItemDTOWithDate(); + iDTO.setId(item.getId()); + iDTO.setName(item.getName()); + iDTO.setDescription(item.getDescription()); + iDTO.setAvailable(item.getAvailable()); + if (item.getLastBookingId() != null) { + iDTO.setLastBooking(new BookingDTOForItem(item.getLastBookingId(), item.getLastBookerId())); + } + if (item.getNextBookingId() != null) { + iDTO.setNextBooking(new BookingDTOForItem(item.getNextBookingId(), item.getNextBookerId())); + } + iDTO.setComments(Collections.emptyList()); + + return iDTO; } + } + diff --git a/src/main/java/ru/practicum/shareit/item/model/ItemWithBookings.java b/src/main/java/ru/practicum/shareit/item/model/ItemWithBookings.java new file mode 100644 index 000000000..cf0d1178a --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/model/ItemWithBookings.java @@ -0,0 +1,19 @@ +package ru.practicum.shareit.item.model; + +public interface ItemWithBookings { + Long getId(); + + String getName(); + + String getDescription(); + + Boolean getAvailable(); + + Long getLastBookingId(); + + Long getLastBookerId(); + + Long getNextBookingId(); + + Long getNextBookerId(); +} diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemService.java b/src/main/java/ru/practicum/shareit/item/service/ItemService.java index 3df690d8e..0cd7b3ca0 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemService.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemService.java @@ -1,6 +1,6 @@ package ru.practicum.shareit.item.service; -import ru.practicum.shareit.item.dto.ItemDTOWithComment; +import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithDate; @@ -18,5 +18,5 @@ public interface ItemService { List getAllByText(String substring); - ItemDTOWithComment addComment(Long authorId, Long itemId, ItemDTOWithComment comment); + CommentDTO addComment(Long authorId, Long itemId, CommentDTO comment); } diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index e4719e046..dd61c468d 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -15,19 +15,21 @@ import ru.practicum.shareit.exception.NotFoundException; import ru.practicum.shareit.item.CommentRepository; import ru.practicum.shareit.item.ItemRepository; +import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; -import ru.practicum.shareit.item.dto.ItemDTOWithComment; import ru.practicum.shareit.item.dto.ItemDTOWithDate; import ru.practicum.shareit.item.mapper.CommentMapper; import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Comment; import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.item.model.ItemWithBookings; import ru.practicum.shareit.user.UserRepository; import ru.practicum.shareit.user.model.User; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; @@ -73,21 +75,18 @@ public ItemDTO update(Long userId, Long itemId, ItemDTO itemDto) throws BadReque @Override public ItemDTOWithDate get(Long userId, Long itemId) { Item item = repository.findById(itemId).orElseThrow(() -> new NotFoundException("Item not found")); - ItemDTOWithDate itemDto = ItemMapper.toItemDtoWithDate(item); - List comments = commentRepository.findByItem(item); + ItemDTOWithDate itemDto = ItemMapper.mapToItemDtoWithDate(item); + List comments = commentRepository.findAllByItem(item); itemDto.setComments(CommentMapper.mapToCommentDto(comments)); if (Objects.equals(item.getOwner().getId(), userId)) { List bookings = bookingRepository.findByItemOrderByStartDesc(item); if (!bookings.isEmpty()) { - - LocalDateTime next = bookings.get(0).getStart(); Booking nextBooking = bookings.get(0); - BookingDTOForItem bookingNext = BookingMapper.toBookingDtoForItem(nextBooking, next); + BookingDTOForItem bookingNext = BookingMapper.toBookingDtoForItem(nextBooking); itemDto.setNextBooking(bookingNext); if (bookings.size() >= 2) { - LocalDateTime last = bookings.get(1).getStart(); Booking lastBooking = bookings.get(1); - BookingDTOForItem bookingLast = BookingMapper.toBookingDtoForItem(lastBooking, last); + BookingDTOForItem bookingLast = BookingMapper.toBookingDtoForItem(lastBooking); itemDto.setLastBooking(bookingLast); } } @@ -97,37 +96,19 @@ public ItemDTOWithDate get(Long userId, Long itemId) { @Override public List getAllByOwner(Long userId) { - User user = userRepository.getReferenceById(userId); - return repository.findByOwner(user).stream().map(this::toItemDtoWithBooking).collect(Collectors.toList()); - } - - private ItemDTOWithDate toItemDtoWithBooking(Item item) { - Booking lastBooking = bookingRepository.findFirst1BookingByItem_IdAndStartIsBefore(item.getId(), - LocalDateTime.now(), Sort.by("start").descending()); - Booking nextBooking = bookingRepository.findFirst1BookingByItem_IdAndStartIsAfter(item.getId(), - LocalDateTime.now(), Sort.by("start").ascending()); - - BookingDTOForItem lastBookingDto = lastBooking != null ? BookingMapper - .toBookingDtoForItem(lastBooking, LocalDateTime.now()) : null; - BookingDTOForItem nextBookingDto = nextBooking != null ? BookingMapper - .toBookingDtoForItem(nextBooking, LocalDateTime.now()) : null; - - ItemDTOWithDate itemDto = ItemMapper.toItemDtoWithDate(item); - itemDto.setLastBooking(lastBookingDto); - itemDto.setNextBooking(nextBookingDto); - itemDto.setComments(getItemComments(item)); - - return itemDto; + User owner = userRepository.getReferenceById(userId); + List items = repository.findAllByOwnerWithBookings( + LocalDateTime.now(), owner.getId()); + Map> comments = + commentRepository.findAllByItemIdIn( + items.stream() + .map(ItemWithBookings::getId) + .collect(Collectors.toUnmodifiableList()), + Sort.by(Sort.Direction.ASC, "created")).stream() + .collect(Collectors.groupingBy(c -> c.getItem().getId(), Collectors.toUnmodifiableList())); + return ItemMapper.mapToItemDtoWithDate(items, comments); } - private List getItemComments(Item item) { - return commentRepository.findByItem(item) - .stream() - .map(CommentMapper::toCommentDto) - .collect(Collectors.toList()); - } - - @Override public List getAllByText(String substring) { if (!Objects.equals(substring, "")) { @@ -138,7 +119,7 @@ public List getAllByText(String substring) { @Transactional @Override - public ItemDTOWithComment addComment(Long authorId, Long itemId, ItemDTOWithComment itemDtoWithComment) { + public CommentDTO addComment(Long authorId, Long itemId, CommentDTO itemDtoWithComment) { Item item = repository.findById(itemId).orElseThrow(() -> new NotFoundException("Item not found")); User author = userRepository.findById(authorId).orElseThrow(() -> new NotFoundException("User not found")); List bookings = bookingRepository diff --git a/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDto.java b/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDto.java index 608cf6f4a..b0c9537d3 100644 --- a/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDto.java +++ b/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDto.java @@ -12,7 +12,7 @@ public class ItemRequestDto { private String description; - private User requestor; + private User requester; private LocalDateTime created; } diff --git a/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java b/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java index 1f1d6cef8..e9b146410 100644 --- a/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java +++ b/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java @@ -21,8 +21,8 @@ public class ItemRequest { private String description; @OneToOne - @JoinColumn(name = "requestor_id") - private User requestor; + @JoinColumn(name = "requester_id") + private User requester; @NotNull private LocalDateTime created; diff --git a/src/main/java/ru/practicum/shareit/user/UserController.java b/src/main/java/ru/practicum/shareit/user/UserController.java index 3d56616ec..37d9d121c 100644 --- a/src/main/java/ru/practicum/shareit/user/UserController.java +++ b/src/main/java/ru/practicum/shareit/user/UserController.java @@ -5,7 +5,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import ru.practicum.shareit.user.dto.UserDTO; -import ru.practicum.shareit.user.dto.UserDTOToUpd; import ru.practicum.shareit.user.service.UserService; import javax.validation.Valid; @@ -25,7 +24,7 @@ public UserDTO create(@Valid @RequestBody UserDTO user) { } @PatchMapping("/{userId}") - public UserDTOToUpd update(@Valid @PathVariable Long userId, @RequestBody UserDTO user) { + public UserDTO update(@Valid @PathVariable Long userId, @RequestBody UserDTO user) { log.info("Обновление данных о пользователе с id {}", userId); return userService.update(userId, user); } diff --git a/src/main/java/ru/practicum/shareit/user/UserMapper.java b/src/main/java/ru/practicum/shareit/user/UserMapper.java index 9f12d52b3..b4f5742d4 100644 --- a/src/main/java/ru/practicum/shareit/user/UserMapper.java +++ b/src/main/java/ru/practicum/shareit/user/UserMapper.java @@ -3,7 +3,6 @@ import lombok.experimental.UtilityClass; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; import ru.practicum.shareit.user.dto.UserDTO; -import ru.practicum.shareit.user.dto.UserDTOToUpd; import ru.practicum.shareit.user.model.User; import java.util.ArrayList; @@ -20,14 +19,6 @@ public static UserDTO toUserDto(User user) { return userDto; } - public static UserDTOToUpd toUserDtoToUpd(User user) { - UserDTOToUpd userDto = new UserDTOToUpd(); - userDto.setId(user.getId()); - userDto.setName(user.getName()); - userDto.setEmail(user.getEmail()); - return userDto; - } - public static User toUser(UserDTO userDto) { User user = new User(); user.setId(userDto.getId()); diff --git a/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java b/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java index 337f73727..a642cce86 100644 --- a/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java +++ b/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java @@ -2,6 +2,7 @@ import lombok.Data; import ru.practicum.shareit.Create; +import ru.practicum.shareit.Update; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; diff --git a/src/main/java/ru/practicum/shareit/user/service/UserService.java b/src/main/java/ru/practicum/shareit/user/service/UserService.java index 8b1a49c54..6b6026a9e 100644 --- a/src/main/java/ru/practicum/shareit/user/service/UserService.java +++ b/src/main/java/ru/practicum/shareit/user/service/UserService.java @@ -1,14 +1,13 @@ package ru.practicum.shareit.user.service; import ru.practicum.shareit.user.dto.UserDTO; -import ru.practicum.shareit.user.dto.UserDTOToUpd; import java.util.Collection; public interface UserService { UserDTO create(UserDTO userDto); - UserDTOToUpd update(Long userId, UserDTO userDto); + UserDTO update(Long userId, UserDTO userDto); void delete(Long id); diff --git a/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java index 8cf72b696..0725cf345 100644 --- a/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java @@ -8,7 +8,6 @@ import ru.practicum.shareit.user.UserMapper; import ru.practicum.shareit.user.UserRepository; import ru.practicum.shareit.user.dto.UserDTO; -import ru.practicum.shareit.user.dto.UserDTOToUpd; import ru.practicum.shareit.user.model.User; import java.util.List; @@ -30,16 +29,16 @@ public UserDTO create(UserDTO userDto) { @Transactional @Override - public UserDTOToUpd update(Long userId, UserDTO userDto) { + public UserDTO update(Long userId, UserDTO userDto) { User user = repository.findById(userId) .orElseThrow(() -> new NotFoundException("User not found")); - if (userDto.getName() != null) { + if (userDto.getName() != null && !userDto.getName().isBlank()) { user.setName(userDto.getName()); } - if (userDto.getEmail() != null) { + if (userDto.getEmail() != null && !userDto.getEmail().isBlank()) { user.setEmail(userDto.getEmail()); } - return UserMapper.toUserDtoToUpd(user); + return UserMapper.toUserDto(user); } @Transactional diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 819bb0ac0..43303a6b5 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -40,7 +40,7 @@ CREATE TABLE IF NOT EXISTS requests ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, description VARCHAR(1000) NOT NULL, - requestor_id BIGINT NOT NULL, + requester_id BIGINT NOT NULL, CONSTRAINT pk_requests PRIMARY KEY (id) ); From 67b89e061e64799159c16f6c5dd58481260a58f9 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Wed, 8 Feb 2023 01:42:03 +0300 Subject: [PATCH 18/45] Add files via upload --- src/main/java/ru/practicum/shareit/booking/BookingMapper.java | 1 - src/main/java/ru/practicum/shareit/item/ItemRepository.java | 1 - src/main/java/ru/practicum/shareit/user/dto/UserDTO.java | 1 - 3 files changed, 3 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java index 751832e5a..fd1f1034a 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java @@ -11,7 +11,6 @@ import ru.practicum.shareit.user.UserMapper; import ru.practicum.shareit.user.model.User; -import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/ru/practicum/shareit/item/ItemRepository.java b/src/main/java/ru/practicum/shareit/item/ItemRepository.java index 42d06e5ea..a7a4593ca 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemRepository.java +++ b/src/main/java/ru/practicum/shareit/item/ItemRepository.java @@ -4,7 +4,6 @@ import org.springframework.data.jpa.repository.Query; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.item.model.ItemWithBookings; -import ru.practicum.shareit.user.model.User; import java.time.LocalDateTime; import java.util.List; diff --git a/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java b/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java index a642cce86..337f73727 100644 --- a/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java +++ b/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java @@ -2,7 +2,6 @@ import lombok.Data; import ru.practicum.shareit.Create; -import ru.practicum.shareit.Update; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; From 08267ed195b4aa4351bb74848f42bcacf592affb Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Wed, 8 Feb 2023 01:44:53 +0300 Subject: [PATCH 19/45] Add files via upload --- src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java index 793225f1e..bc57b69b8 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java @@ -85,7 +85,7 @@ public static BookingDTOToReturn.Item toItemToBookingDTO(Item item) { } public static List mapToItemDtoWithDate(List items, - Map> comments){ + Map> comments) { return items.stream() .map(i -> toItemDtoWithDate2(i, comments.get(i.getId()))) .collect(Collectors.toUnmodifiableList()); From 13263a57b9d818138016c08292185ec8b07c111b Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Wed, 8 Feb 2023 20:10:23 +0300 Subject: [PATCH 20/45] Add files via upload --- .../java/ru/practicum/shareit/Create.java | 2 +- .../java/ru/practicum/shareit/Update.java | 2 +- .../shareit/booking/BookingRepository.java | 2 +- .../booking/service/BookingServiceImpl.java | 9 ++++---- .../shareit/item/ItemController.java | 6 ++++++ .../shareit/item/ItemRepository.java | 3 ++- .../shareit/item/dto/ItemDTOWithComment.java | 2 -- .../shareit/item/dto/ItemDTOWithDate.java | 6 ------ .../shareit/item/service/ItemServiceImpl.java | 21 ++++++++----------- .../shareit/request/model/ItemRequest.java | 2 +- .../shareit/user/UserController.java | 7 +++++-- .../practicum/shareit/user/dto/UserDTO.java | 6 ++++-- 12 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/Create.java b/src/main/java/ru/practicum/shareit/Create.java index 776ca0761..5b84b9da0 100644 --- a/src/main/java/ru/practicum/shareit/Create.java +++ b/src/main/java/ru/practicum/shareit/Create.java @@ -1,4 +1,4 @@ package ru.practicum.shareit; -public class Create { +public interface Create { } diff --git a/src/main/java/ru/practicum/shareit/Update.java b/src/main/java/ru/practicum/shareit/Update.java index 99f0eab8c..067ab2926 100644 --- a/src/main/java/ru/practicum/shareit/Update.java +++ b/src/main/java/ru/practicum/shareit/Update.java @@ -1,4 +1,4 @@ package ru.practicum.shareit; -public class Update { +public interface Update { } diff --git a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java index 876dac0b1..39a20b7d8 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java @@ -12,7 +12,7 @@ public interface BookingRepository extends JpaRepository { - List findByItemOrderByStartDesc(Item item); + List findByItemAndStatusOrderByStartDesc(Item item, Status status); List findByBookerAndStatusOrderByStartDesc(User booker, Status status); diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java index 953e263c4..fb1d84489 100644 --- a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java @@ -95,8 +95,7 @@ public List getByBooker(Long usersId, String stateString) { User booker = uRepository.findById(usersId) .orElseThrow(() -> new NotFoundException("No rights")); List bookingsByBooker; - stateValidation(stateString); - State state = State.valueOf(stateString); + State state = stateValidation(stateString); switch (state) { case ALL: bookingsByBooker = bRepository.findByBookerOrderByStartDesc(booker); @@ -131,8 +130,7 @@ public List getByOwner(Long userId, String stateString) { throw new NotFoundException("User not found"); } List bookingsByOwner; - stateValidation(stateString); - State state = State.valueOf(stateString); + State state = stateValidation(stateString); switch (state) { case ALL: bookingsByOwner = bRepository.findByOwnerAll(userId); @@ -158,9 +156,10 @@ public List getByOwner(Long userId, String stateString) { return BookingMapper.mapToBookingDtoFrom(bookingsByOwner); } - private void stateValidation(String state) { + private State stateValidation(String state) { try { Enum.valueOf(State.class, state); + return State.valueOf(state); } catch (IllegalArgumentException e) { throw new StatusBadRequestException("Unknown state: UNSUPPORTED_STATUS"); } diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/src/main/java/ru/practicum/shareit/item/ItemController.java index 59102f3a6..9b315f02e 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -7,10 +7,13 @@ import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithDate; +import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.service.ItemService; import javax.validation.Valid; +import java.util.Collections; import java.util.List; +import java.util.Objects; @RestController @RequestMapping("/items") @@ -49,6 +52,9 @@ public List getAllByOwner(@RequestHeader("X-Sharer-User-Id") Lo public List getAllByText(@RequestHeader("X-Sharer-User-Id") Long userId, @RequestParam String text) { log.info("Получение вещей для аренды содержащие в названии или описании текст {}", text); + if (text.isBlank()) { + return Collections.emptyList(); + } return itemService.getAllByText(text); } diff --git a/src/main/java/ru/practicum/shareit/item/ItemRepository.java b/src/main/java/ru/practicum/shareit/item/ItemRepository.java index a7a4593ca..e797c97ff 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemRepository.java +++ b/src/main/java/ru/practicum/shareit/item/ItemRepository.java @@ -7,6 +7,7 @@ import java.time.LocalDateTime; import java.util.List; +import java.util.Optional; public interface ItemRepository extends JpaRepository { @Query(nativeQuery = true, value = "SELECT * FROM items AS i " + @@ -33,5 +34,5 @@ public interface ItemRepository extends JpaRepository { "where item_id = i.id and i.owner_id = ?2 and start_date > ?1 " + "order by start_date limit 1) \"nextBookerId\" " + "from items i" + " where i.owner_id = ?2 order by id", nativeQuery = true) - List findAllByOwnerWithBookings(LocalDateTime date, Long ownerId); + List findAllByOwnerWithBookingsAndStatusAPPROVED(LocalDateTime date, Long ownerId); } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithComment.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithComment.java index 4cc8ce883..f5d9b5b6e 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithComment.java +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithComment.java @@ -11,8 +11,6 @@ public class ItemDTOWithComment { private Long id; - @NotBlank - @Size(min = 1, max = 1000) private String text; private String itemName; diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java index 3cb46b7dd..76bf6ba58 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithDate.java @@ -3,23 +3,17 @@ import lombok.*; import ru.practicum.shareit.booking.dto.BookingDTOForItem; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; import java.util.List; @Data @NoArgsConstructor public class ItemDTOWithDate { - @NotNull private long id; - @NotBlank private String name; - @NotBlank private String description; - @NotNull private Boolean available; private User owner; diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index dd61c468d..4554a6593 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -10,6 +10,7 @@ import ru.practicum.shareit.booking.BookingRepository; import ru.practicum.shareit.booking.dto.BookingDTOForItem; import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.booking.model.Status; import ru.practicum.shareit.exception.BadRequestException; import ru.practicum.shareit.exception.ForbiddenException; import ru.practicum.shareit.exception.NotFoundException; @@ -27,7 +28,6 @@ import ru.practicum.shareit.user.model.User; import java.time.LocalDateTime; -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -39,7 +39,7 @@ @Slf4j public class ItemServiceImpl implements ItemService { - private final ItemRepository repository; + private final ItemRepository itemRepository; private final UserRepository userRepository; private final BookingRepository bookingRepository; private final CommentRepository commentRepository; @@ -48,14 +48,14 @@ public class ItemServiceImpl implements ItemService { @Override public ItemDTO add(Long userId, ItemDTO itemDto) throws BadRequestException { User user = userRepository.findById(userId).orElseThrow(() -> new NotFoundException("User not found")); - Item item = repository.save(ItemMapper.toItem(itemDto, user)); + Item item = itemRepository.save(ItemMapper.toItem(itemDto, user)); return ItemMapper.toItemDto(item); } @Transactional @Override public ItemDTO update(Long userId, Long itemId, ItemDTO itemDto) throws BadRequestException { - Item item = repository.findById(itemId).orElseThrow(() -> new NotFoundException("Item not found")); + Item item = itemRepository.findById(itemId).orElseThrow(() -> new NotFoundException("Item not found")); User user = item.getOwner(); if (Objects.equals(user.getId(), userId)) { if (itemDto.getName() != null && !itemDto.getName().isBlank()) { @@ -74,12 +74,12 @@ public ItemDTO update(Long userId, Long itemId, ItemDTO itemDto) throws BadReque @Override public ItemDTOWithDate get(Long userId, Long itemId) { - Item item = repository.findById(itemId).orElseThrow(() -> new NotFoundException("Item not found")); + Item item = itemRepository.findById(itemId).orElseThrow(() -> new NotFoundException("Item not found")); ItemDTOWithDate itemDto = ItemMapper.mapToItemDtoWithDate(item); List comments = commentRepository.findAllByItem(item); itemDto.setComments(CommentMapper.mapToCommentDto(comments)); if (Objects.equals(item.getOwner().getId(), userId)) { - List bookings = bookingRepository.findByItemOrderByStartDesc(item); + List bookings = bookingRepository.findByItemAndStatusOrderByStartDesc(item, Status.APPROVED); if (!bookings.isEmpty()) { Booking nextBooking = bookings.get(0); BookingDTOForItem bookingNext = BookingMapper.toBookingDtoForItem(nextBooking); @@ -97,7 +97,7 @@ public ItemDTOWithDate get(Long userId, Long itemId) { @Override public List getAllByOwner(Long userId) { User owner = userRepository.getReferenceById(userId); - List items = repository.findAllByOwnerWithBookings( + List items = itemRepository.findAllByOwnerWithBookingsAndStatusAPPROVED( LocalDateTime.now(), owner.getId()); Map> comments = commentRepository.findAllByItemIdIn( @@ -111,16 +111,13 @@ public List getAllByOwner(Long userId) { @Override public List getAllByText(String substring) { - if (!Objects.equals(substring, "")) { - return ItemMapper.mapToItemDto(repository.findItemsByNameOrDescription(substring)); - } - return new ArrayList<>(); + return ItemMapper.mapToItemDto(itemRepository.findItemsByNameOrDescription(substring)); } @Transactional @Override public CommentDTO addComment(Long authorId, Long itemId, CommentDTO itemDtoWithComment) { - Item item = repository.findById(itemId).orElseThrow(() -> new NotFoundException("Item not found")); + Item item = itemRepository.findById(itemId).orElseThrow(() -> new NotFoundException("Item not found")); User author = userRepository.findById(authorId).orElseThrow(() -> new NotFoundException("User not found")); List bookings = bookingRepository .findByItemAndBookerAndStartBeforeAndEndBefore(item, author, LocalDateTime.now(), LocalDateTime.now()); diff --git a/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java b/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java index e9b146410..0c59d0ad1 100644 --- a/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java +++ b/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java @@ -20,7 +20,7 @@ public class ItemRequest { @Column private String description; - @OneToOne + @ManyToOne @JoinColumn(name = "requester_id") private User requester; diff --git a/src/main/java/ru/practicum/shareit/user/UserController.java b/src/main/java/ru/practicum/shareit/user/UserController.java index 37d9d121c..fe903fccf 100644 --- a/src/main/java/ru/practicum/shareit/user/UserController.java +++ b/src/main/java/ru/practicum/shareit/user/UserController.java @@ -3,7 +3,10 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import ru.practicum.shareit.Create; +import ru.practicum.shareit.Update; import ru.practicum.shareit.user.dto.UserDTO; import ru.practicum.shareit.user.service.UserService; @@ -18,13 +21,13 @@ public class UserController { private final UserService userService; @PostMapping - public UserDTO create(@Valid @RequestBody UserDTO user) { + public UserDTO create(@Validated(Create.class) @RequestBody UserDTO user) { log.info("Добавление нового пользователя"); return userService.create(user); } @PatchMapping("/{userId}") - public UserDTO update(@Valid @PathVariable Long userId, @RequestBody UserDTO user) { + public UserDTO update(@PathVariable Long userId, @Validated(Update.class) @RequestBody UserDTO user) { log.info("Обновление данных о пользователе с id {}", userId); return userService.update(userId, user); } diff --git a/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java b/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java index 337f73727..d9b79e7ad 100644 --- a/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java +++ b/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java @@ -2,9 +2,11 @@ import lombok.Data; import ru.practicum.shareit.Create; +import ru.practicum.shareit.Update; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; @Data public class UserDTO { @@ -14,7 +16,7 @@ public class UserDTO { @NotBlank(groups = {Create.class}) private String name; - @Email - @NotBlank + @Email(groups = {Update.class, Create.class}) + @NotNull(groups = {Create.class}) private String email; } From 5333baed23d804cb633ca7ed5b6e37e7309d42dc Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Thu, 9 Feb 2023 03:56:39 +0300 Subject: [PATCH 21/45] Add files via upload --- .../shareit/booking/BookingRepository.java | 5 +++ .../shareit/item/ItemController.java | 6 ---- .../shareit/item/ItemRepository.java | 15 +++++---- .../shareit/item/dto/ItemDTOWithComment.java | 2 -- .../shareit/item/service/ItemServiceImpl.java | 31 ++++++++++--------- .../shareit/user/UserController.java | 1 - 6 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java index 39a20b7d8..c51fa0668 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java @@ -1,5 +1,6 @@ package ru.practicum.shareit.booking; +import org.springframework.data.domain.Sort; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import ru.practicum.shareit.booking.model.Booking; @@ -49,4 +50,8 @@ List findByItemAndBookerAndStartBeforeAndEndBefore(Item item, User book + "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.status = ?2" + " ORDER BY b.id DESC") List findByOwnerAndByStatus(long userId, Status status); + Booking findFirstByStatusAndItemAndStartIsAfter(Status state, Item item, LocalDateTime time, Sort sort); + + Booking findLastByStatusAndItemAndEndIsBefore(Status state, Item item, LocalDateTime time, Sort sort); + } diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/src/main/java/ru/practicum/shareit/item/ItemController.java index 9b315f02e..59102f3a6 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -7,13 +7,10 @@ import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithDate; -import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.service.ItemService; import javax.validation.Valid; -import java.util.Collections; import java.util.List; -import java.util.Objects; @RestController @RequestMapping("/items") @@ -52,9 +49,6 @@ public List getAllByOwner(@RequestHeader("X-Sharer-User-Id") Lo public List getAllByText(@RequestHeader("X-Sharer-User-Id") Long userId, @RequestParam String text) { log.info("Получение вещей для аренды содержащие в названии или описании текст {}", text); - if (text.isBlank()) { - return Collections.emptyList(); - } return itemService.getAllByText(text); } diff --git a/src/main/java/ru/practicum/shareit/item/ItemRepository.java b/src/main/java/ru/practicum/shareit/item/ItemRepository.java index e797c97ff..64ffff9ac 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemRepository.java +++ b/src/main/java/ru/practicum/shareit/item/ItemRepository.java @@ -7,7 +7,6 @@ import java.time.LocalDateTime; import java.util.List; -import java.util.Optional; public interface ItemRepository extends JpaRepository { @Query(nativeQuery = true, value = "SELECT * FROM items AS i " + @@ -16,23 +15,23 @@ public interface ItemRepository extends JpaRepository { "AND (available)") List findItemsByNameOrDescription(String substring); - @Query(value = "select " + + @Query(value = "select " + "i.id, " + "i.name, " + "i.description, " + "i.available, " + "(select id from bookings " + - "where item_id = i.id and i.owner_id = ?2 and start_date <= ?1 " + + "where i.owner_id = ?2 and item_id = i.id and status = ?3 and start_date <= ?1 " + "order by start_date desc limit 1) \"lastBookingId\", " + "(select booker_id from bookings " + - "where item_id = i.id and i.owner_id = ?2 and start_date <= ?1 " + + "where i.owner_id = ?2 and item_id = i.id and status = ?3 and start_date <= ?1 " + "order by start_date desc limit 1) \"lastBookerId\", " + "(select id from bookings " + - "where item_id = i.id and i.owner_id = ?2 and start_date > ?1 " + + "where i.owner_id = ?2 and item_id = i.id and status = ?3 and start_date > ?1 " + "order by start_date limit 1) \"nextBookingId\", " + "(select booker_id from bookings " + - "where item_id = i.id and i.owner_id = ?2 and start_date > ?1 " + + "where i.owner_id = ?2 and item_id = i.id and status = ?3 and start_date > ?1 " + "order by start_date limit 1) \"nextBookerId\" " + - "from items i" + " where i.owner_id = ?2 order by id", nativeQuery = true) - List findAllByOwnerWithBookingsAndStatusAPPROVED(LocalDateTime date, Long ownerId); + "from items i", nativeQuery = true) + List findAllByOwner(LocalDateTime date, Long ownerId, String status); } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithComment.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithComment.java index f5d9b5b6e..7f248c086 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithComment.java +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithComment.java @@ -2,8 +2,6 @@ import lombok.Data; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.Size; import java.time.LocalDateTime; @Data diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index 4554a6593..48cc3d22d 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -8,7 +8,6 @@ import org.springframework.transaction.annotation.Transactional; import ru.practicum.shareit.booking.BookingMapper; import ru.practicum.shareit.booking.BookingRepository; -import ru.practicum.shareit.booking.dto.BookingDTOForItem; import ru.practicum.shareit.booking.model.Booking; import ru.practicum.shareit.booking.model.Status; import ru.practicum.shareit.exception.BadRequestException; @@ -28,6 +27,7 @@ import ru.practicum.shareit.user.model.User; import java.time.LocalDateTime; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; @@ -79,26 +79,26 @@ public ItemDTOWithDate get(Long userId, Long itemId) { List comments = commentRepository.findAllByItem(item); itemDto.setComments(CommentMapper.mapToCommentDto(comments)); if (Objects.equals(item.getOwner().getId(), userId)) { - List bookings = bookingRepository.findByItemAndStatusOrderByStartDesc(item, Status.APPROVED); - if (!bookings.isEmpty()) { - Booking nextBooking = bookings.get(0); - BookingDTOForItem bookingNext = BookingMapper.toBookingDtoForItem(nextBooking); - itemDto.setNextBooking(bookingNext); - if (bookings.size() >= 2) { - Booking lastBooking = bookings.get(1); - BookingDTOForItem bookingLast = BookingMapper.toBookingDtoForItem(lastBooking); - itemDto.setLastBooking(bookingLast); - } + Booking nextBooking = bookingRepository.findFirstByStatusAndItemAndStartIsAfter(Status.APPROVED, item, + LocalDateTime.now(), Sort.by(Sort.Direction.DESC, "start")); + Booking lastBooking = bookingRepository.findLastByStatusAndItemAndEndIsBefore(Status.APPROVED, item, + LocalDateTime.now(), Sort.by(Sort.Direction.DESC, "end")); + if (nextBooking != null){ + itemDto.setNextBooking(BookingMapper.toBookingDtoForItem(nextBooking)); } + if (lastBooking != null) itemDto.setLastBooking(BookingMapper.toBookingDtoForItem(lastBooking)); } return itemDto; } @Override public List getAllByOwner(Long userId) { - User owner = userRepository.getReferenceById(userId); - List items = itemRepository.findAllByOwnerWithBookingsAndStatusAPPROVED( - LocalDateTime.now(), owner.getId()); + if (!userRepository.existsById(userId)) { + throw new NotFoundException("User not found"); + } + log.info(userId.toString()); + List items = itemRepository.findAllByOwner( + LocalDateTime.now(), userId, String.valueOf(Status.APPROVED)); Map> comments = commentRepository.findAllByItemIdIn( items.stream() @@ -111,6 +111,9 @@ public List getAllByOwner(Long userId) { @Override public List getAllByText(String substring) { + if (substring.isBlank()) { + return Collections.emptyList(); + } return ItemMapper.mapToItemDto(itemRepository.findItemsByNameOrDescription(substring)); } diff --git a/src/main/java/ru/practicum/shareit/user/UserController.java b/src/main/java/ru/practicum/shareit/user/UserController.java index fe903fccf..ef070be8d 100644 --- a/src/main/java/ru/practicum/shareit/user/UserController.java +++ b/src/main/java/ru/practicum/shareit/user/UserController.java @@ -10,7 +10,6 @@ import ru.practicum.shareit.user.dto.UserDTO; import ru.practicum.shareit.user.service.UserService; -import javax.validation.Valid; import java.util.Collection; @RestController From 4f3cd7bd30375d261f415f017083be445e6b96fb Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Thu, 9 Feb 2023 03:58:19 +0300 Subject: [PATCH 22/45] Add files via upload --- .../ru/practicum/shareit/item/service/ItemServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index 48cc3d22d..dc2f9830a 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -83,7 +83,7 @@ public ItemDTOWithDate get(Long userId, Long itemId) { LocalDateTime.now(), Sort.by(Sort.Direction.DESC, "start")); Booking lastBooking = bookingRepository.findLastByStatusAndItemAndEndIsBefore(Status.APPROVED, item, LocalDateTime.now(), Sort.by(Sort.Direction.DESC, "end")); - if (nextBooking != null){ + if (nextBooking != null) { itemDto.setNextBooking(BookingMapper.toBookingDtoForItem(nextBooking)); } if (lastBooking != null) itemDto.setLastBooking(BookingMapper.toBookingDtoForItem(lastBooking)); @@ -114,7 +114,7 @@ public List getAllByText(String substring) { if (substring.isBlank()) { return Collections.emptyList(); } - return ItemMapper.mapToItemDto(itemRepository.findItemsByNameOrDescription(substring)); + return ItemMapper.mapToItemDto(itemRepository.findItemsByNameOrDescription(substring)); } @Transactional From 942b18cd46493f5f18963f1fa96dd0501029540f Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Thu, 9 Feb 2023 19:11:55 +0300 Subject: [PATCH 23/45] =?UTF-8?q?=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=D0=B4?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shareit/booking/BookingMapper.java | 6 +- .../shareit/booking/BookingRepository.java | 8 +- .../shareit/booking/model/Booking.java | 2 +- .../shareit/item/ItemController.java | 6 +- .../shareit/item/ItemRepository.java | 22 +---- .../shareit/item/dto/ItemDTOWithBookings.java | 35 ++++++++ .../shareit/item/mapper/ItemMapper.java | 84 ++++++------------- .../ru/practicum/shareit/item/model/Item.java | 5 +- .../shareit/item/service/ItemService.java | 6 +- .../shareit/item/service/ItemServiceImpl.java | 54 ++++++++---- .../ru/practicum/shareit/user/UserMapper.java | 5 ++ 11 files changed, 121 insertions(+), 112 deletions(-) create mode 100644 src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithBookings.java diff --git a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java index fd1f1034a..dbbcb2a9d 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java @@ -39,10 +39,10 @@ public static Booking toBooking(BookingDTO bookingDto, Item item, User user) { return booking; } - public static BookingDTOForItem toBookingDtoForItem(Booking booking) { + public static BookingDTOForItem toBookingDtoForItem(long id, long bookerId) { BookingDTOForItem bookingDtoForItem = new BookingDTOForItem(); - bookingDtoForItem.setId(booking.getId()); - bookingDtoForItem.setBookerId(booking.getBooker().getId()); + bookingDtoForItem.setId(id); + bookingDtoForItem.setBookerId(bookerId); return bookingDtoForItem; } diff --git a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java index c51fa0668..4f5d62fa3 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java @@ -9,12 +9,11 @@ import ru.practicum.shareit.user.model.User; import java.time.LocalDateTime; +import java.util.Collection; import java.util.List; public interface BookingRepository extends JpaRepository { - List findByItemAndStatusOrderByStartDesc(Item item, Status status); - List findByBookerAndStatusOrderByStartDesc(User booker, Status status); List findByBookerOrderByStartDesc(User booker); @@ -54,4 +53,9 @@ List findByItemAndBookerAndStartBeforeAndEndBefore(Item item, User book Booking findLastByStatusAndItemAndEndIsBefore(Status state, Item item, LocalDateTime time, Sort sort); + @Query("select b " + + "from Booking b " + + "where b.item in ?1 " + + " and b.status = 'APPROVED'") + List findApprovedForItems(Collection items, Sort sort); } diff --git a/src/main/java/ru/practicum/shareit/booking/model/Booking.java b/src/main/java/ru/practicum/shareit/booking/model/Booking.java index 750870ded..22f8b09d8 100644 --- a/src/main/java/ru/practicum/shareit/booking/model/Booking.java +++ b/src/main/java/ru/practicum/shareit/booking/model/Booking.java @@ -19,7 +19,7 @@ public class Booking { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private long id; + private Long id; @Column(name = "start_date") private LocalDateTime start; diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/src/main/java/ru/practicum/shareit/item/ItemController.java index 59102f3a6..b4a79c960 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -6,7 +6,7 @@ import org.springframework.web.bind.annotation.*; import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; -import ru.practicum.shareit.item.dto.ItemDTOWithDate; +import ru.practicum.shareit.item.dto.ItemDTOWithBookings; import ru.practicum.shareit.item.service.ItemService; import javax.validation.Valid; @@ -34,13 +34,13 @@ public ItemDTO update(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVaria } @GetMapping("/{itemId}") - public ItemDTOWithDate get(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long itemId) { + public ItemDTOWithBookings get(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long itemId) { log.info("Получение вещи с id {}", itemId); return itemService.get(userId, itemId); } @GetMapping - public List getAllByOwner(@RequestHeader("X-Sharer-User-Id") Long userId) { + public List getAllByOwner(@RequestHeader("X-Sharer-User-Id") Long userId) { log.info("Получение всех вещей пользователя с id {}", userId); return itemService.getAllByOwner(userId); } diff --git a/src/main/java/ru/practicum/shareit/item/ItemRepository.java b/src/main/java/ru/practicum/shareit/item/ItemRepository.java index 64ffff9ac..14569738f 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemRepository.java +++ b/src/main/java/ru/practicum/shareit/item/ItemRepository.java @@ -3,9 +3,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import ru.practicum.shareit.item.model.Item; -import ru.practicum.shareit.item.model.ItemWithBookings; -import java.time.LocalDateTime; import java.util.List; public interface ItemRepository extends JpaRepository { @@ -15,23 +13,5 @@ public interface ItemRepository extends JpaRepository { "AND (available)") List findItemsByNameOrDescription(String substring); - @Query(value = "select " + - "i.id, " + - "i.name, " + - "i.description, " + - "i.available, " + - "(select id from bookings " + - "where i.owner_id = ?2 and item_id = i.id and status = ?3 and start_date <= ?1 " + - "order by start_date desc limit 1) \"lastBookingId\", " + - "(select booker_id from bookings " + - "where i.owner_id = ?2 and item_id = i.id and status = ?3 and start_date <= ?1 " + - "order by start_date desc limit 1) \"lastBookerId\", " + - "(select id from bookings " + - "where i.owner_id = ?2 and item_id = i.id and status = ?3 and start_date > ?1 " + - "order by start_date limit 1) \"nextBookingId\", " + - "(select booker_id from bookings " + - "where i.owner_id = ?2 and item_id = i.id and status = ?3 and start_date > ?1 " + - "order by start_date limit 1) \"nextBookerId\" " + - "from items i", nativeQuery = true) - List findAllByOwner(LocalDateTime date, Long ownerId, String status); + List getAllByOwnerId(long id); } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithBookings.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithBookings.java new file mode 100644 index 000000000..307a43bb6 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithBookings.java @@ -0,0 +1,35 @@ +package ru.practicum.shareit.item.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; +import ru.practicum.shareit.booking.dto.BookingDTOForItem; + +import java.util.List; + +@Data +@NoArgsConstructor +public class ItemDTOWithBookings { + private long id; + + private String name; + + private String description; + + private Boolean available; + + private User owner; + + private Long request; + + private BookingDTOForItem nextBooking; + + private BookingDTOForItem lastBooking; + + private List comments; + + @Data + public static class User { + private final long id; + private final String name; + } +} diff --git a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java index bc57b69b8..8c738b665 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java @@ -1,21 +1,19 @@ package ru.practicum.shareit.item.mapper; import lombok.experimental.UtilityClass; -import ru.practicum.shareit.booking.dto.BookingDTOForItem; +import ru.practicum.shareit.booking.BookingMapper; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; +import ru.practicum.shareit.booking.model.Booking; import ru.practicum.shareit.item.dto.ItemDTO; -import ru.practicum.shareit.item.dto.ItemDTOWithDate; +import ru.practicum.shareit.item.dto.ItemDTOWithBookings; import ru.practicum.shareit.item.model.Comment; import ru.practicum.shareit.item.model.Item; -import ru.practicum.shareit.item.model.ItemWithBookings; -import ru.practicum.shareit.user.UserRepository; +import ru.practicum.shareit.user.UserMapper; import ru.practicum.shareit.user.model.User; +import java.time.LocalDateTime; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; @UtilityClass public class ItemMapper { @@ -29,12 +27,13 @@ public static ItemDTO toItemDto(Item item) { return itemDto; } - public static ItemDTOWithDate mapToItemDtoWithDate(Item item) { - ItemDTOWithDate itemDto = new ItemDTOWithDate(); + public static ItemDTOWithBookings ToItemDtoWithBookings(Item item) { + ItemDTOWithBookings itemDto = new ItemDTOWithBookings(); itemDto.setId(item.getId()); itemDto.setName(item.getName()); itemDto.setDescription(item.getDescription()); itemDto.setAvailable(item.getAvailable()); + itemDto.setOwner(UserMapper.toUserToItemWithBookingsDto(item.getOwner())); return itemDto; } @@ -50,28 +49,6 @@ public static Item toItem(ItemDTO itemDto, User user) { } - public static Item toItem(ItemDTOWithDate itemDto, UserRepository uRepo) { - Item item = new Item(); - item.setId(itemDto.getId()); - item.setName(itemDto.getName()); - item.setDescription(itemDto.getDescription()); - item.setAvailable(itemDto.getAvailable()); - item.setOwner(uRepo.getReferenceById(itemDto.getOwner().getId())); - return item; - - } - - public static Item toItemWithDate(ItemDTOWithDate itemDto, User user) { - Item item = new Item(); - item.setId(itemDto.getId()); - item.setName(itemDto.getName()); - item.setDescription(itemDto.getDescription()); - item.setAvailable(itemDto.getAvailable()); - item.setOwner(user); - return item; - - } - public static List mapToItemDto(Iterable items) { List dtos = new ArrayList<>(); for (Item item : items) { @@ -84,41 +61,28 @@ public static BookingDTOToReturn.Item toItemToBookingDTO(Item item) { return new BookingDTOToReturn.Item(item.getId(), item.getName()); } - public static List mapToItemDtoWithDate(List items, - Map> comments) { - return items.stream() - .map(i -> toItemDtoWithDate2(i, comments.get(i.getId()))) - .collect(Collectors.toUnmodifiableList()); - } - - public static ItemDTOWithDate toItemDtoWithDate2(ItemWithBookings item, List comments) { - ItemDTOWithDate dto = toDtoWithDateFromWithBookings(item); - List commentsList = new ArrayList<>(); - - if (comments != null) { - commentsList.addAll(comments); - } - dto.setComments(CommentMapper.mapToCommentDto(commentsList)); - return dto; - } - - public static ItemDTOWithDate toDtoWithDateFromWithBookings(ItemWithBookings item) { - ItemDTOWithDate iDTO = new ItemDTOWithDate(); + public static ItemDTOWithBookings toDtoWithBookings(Item item, List bookings, + List comments) { + ItemDTOWithBookings iDTO = new ItemDTOWithBookings(); iDTO.setId(item.getId()); iDTO.setName(item.getName()); iDTO.setDescription(item.getDescription()); iDTO.setAvailable(item.getAvailable()); - if (item.getLastBookingId() != null) { - iDTO.setLastBooking(new BookingDTOForItem(item.getLastBookingId(), item.getLastBookerId())); - } - if (item.getNextBookingId() != null) { - iDTO.setNextBooking(new BookingDTOForItem(item.getNextBookingId(), item.getNextBookerId())); - } - iDTO.setComments(Collections.emptyList()); - + bookings.stream() + .filter(b -> b.getEnd().isBefore(LocalDateTime.now())) + .findFirst() + .ifPresent(lastBooking -> iDTO.setLastBooking(BookingMapper + .toBookingDtoForItem(lastBooking.getId(), lastBooking.getBooker().getId()))); + + bookings.stream() + .filter(b -> b.getStart().isAfter(LocalDateTime.now())) + .reduce((first, second) -> second) + .ifPresent(nextBooking -> iDTO.setNextBooking(BookingMapper + .toBookingDtoForItem(nextBooking.getId(), nextBooking.getBooker().getId()))); + + iDTO.setComments(CommentMapper.mapToCommentDto(comments)); return iDTO; } - } diff --git a/src/main/java/ru/practicum/shareit/item/model/Item.java b/src/main/java/ru/practicum/shareit/item/model/Item.java index dc1c3670a..de4b1dbbd 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Item.java +++ b/src/main/java/ru/practicum/shareit/item/model/Item.java @@ -1,6 +1,9 @@ package ru.practicum.shareit.item.model; -import lombok.*; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.ToString; import org.hibernate.Hibernate; import ru.practicum.shareit.user.model.User; diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemService.java b/src/main/java/ru/practicum/shareit/item/service/ItemService.java index 0cd7b3ca0..1143c1d26 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemService.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemService.java @@ -2,7 +2,7 @@ import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; -import ru.practicum.shareit.item.dto.ItemDTOWithDate; +import ru.practicum.shareit.item.dto.ItemDTOWithBookings; import java.util.List; @@ -10,11 +10,11 @@ public interface ItemService { ItemDTO add(Long userId, ItemDTO itemDto); - ItemDTOWithDate get(Long userId, Long itemId); + ItemDTOWithBookings get(Long userId, Long itemId); ItemDTO update(Long userId, Long itemId, ItemDTO itemDto); - List getAllByOwner(Long userId); + List getAllByOwner(Long userId); List getAllByText(String substring); diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index dc2f9830a..634ff642d 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -17,22 +17,22 @@ import ru.practicum.shareit.item.ItemRepository; import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; -import ru.practicum.shareit.item.dto.ItemDTOWithDate; +import ru.practicum.shareit.item.dto.ItemDTOWithBookings; import ru.practicum.shareit.item.mapper.CommentMapper; import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Comment; import ru.practicum.shareit.item.model.Item; -import ru.practicum.shareit.item.model.ItemWithBookings; import ru.practicum.shareit.user.UserRepository; import ru.practicum.shareit.user.model.User; import java.time.LocalDateTime; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.stream.Collectors; +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.toList; +import static org.springframework.data.domain.Sort.Direction.DESC; + @Service @RequiredArgsConstructor(onConstructor_ = @Autowired) @Transactional(readOnly = true) @@ -73,40 +73,58 @@ public ItemDTO update(Long userId, Long itemId, ItemDTO itemDto) throws BadReque } @Override - public ItemDTOWithDate get(Long userId, Long itemId) { + public ItemDTOWithBookings get(Long userId, Long itemId) { Item item = itemRepository.findById(itemId).orElseThrow(() -> new NotFoundException("Item not found")); - ItemDTOWithDate itemDto = ItemMapper.mapToItemDtoWithDate(item); + ItemDTOWithBookings itemDto = ItemMapper.ToItemDtoWithBookings(item); List comments = commentRepository.findAllByItem(item); itemDto.setComments(CommentMapper.mapToCommentDto(comments)); if (Objects.equals(item.getOwner().getId(), userId)) { Booking nextBooking = bookingRepository.findFirstByStatusAndItemAndStartIsAfter(Status.APPROVED, item, - LocalDateTime.now(), Sort.by(Sort.Direction.DESC, "start")); + LocalDateTime.now(), Sort.by(DESC, "start")); Booking lastBooking = bookingRepository.findLastByStatusAndItemAndEndIsBefore(Status.APPROVED, item, - LocalDateTime.now(), Sort.by(Sort.Direction.DESC, "end")); + LocalDateTime.now(), Sort.by(DESC, "end")); if (nextBooking != null) { - itemDto.setNextBooking(BookingMapper.toBookingDtoForItem(nextBooking)); + itemDto.setNextBooking(BookingMapper.toBookingDtoForItem(nextBooking.getId(), + nextBooking.getBooker().getId())); } - if (lastBooking != null) itemDto.setLastBooking(BookingMapper.toBookingDtoForItem(lastBooking)); + if (lastBooking != null) itemDto.setLastBooking(BookingMapper.toBookingDtoForItem(lastBooking.getId(), + lastBooking.getBooker().getId())); } return itemDto; } @Override - public List getAllByOwner(Long userId) { + public List getAllByOwner(Long userId) { if (!userRepository.existsById(userId)) { throw new NotFoundException("User not found"); } log.info(userId.toString()); - List items = itemRepository.findAllByOwner( - LocalDateTime.now(), userId, String.valueOf(Status.APPROVED)); + List items = itemRepository.getAllByOwnerId(userId); + log.info(String.valueOf(items.size())); + Map> approvedBookings = + bookingRepository.findApprovedForItems(items, Sort.by(DESC, "start")) + .stream() + .collect(groupingBy(Booking::getItem, toList())); + log.info(approvedBookings.toString()); + List results = new ArrayList<>(); Map> comments = commentRepository.findAllByItemIdIn( items.stream() - .map(ItemWithBookings::getId) + .map(Item::getId) .collect(Collectors.toUnmodifiableList()), Sort.by(Sort.Direction.ASC, "created")).stream() - .collect(Collectors.groupingBy(c -> c.getItem().getId(), Collectors.toUnmodifiableList())); - return ItemMapper.mapToItemDtoWithDate(items, comments); + .collect(groupingBy(c -> c.getItem().getId(), Collectors.toUnmodifiableList())); + log.info(comments.toString()); + for (Item item : items) { + ItemDTOWithBookings itemInfo = ItemMapper.toDtoWithBookings( + item, + approvedBookings.getOrDefault(item, Collections.emptyList()), + comments.getOrDefault(item, Collections.emptyList()) + ); + log.info(itemInfo.toString()); + results.add(itemInfo); + } + return results; } @Override diff --git a/src/main/java/ru/practicum/shareit/user/UserMapper.java b/src/main/java/ru/practicum/shareit/user/UserMapper.java index b4f5742d4..0c9a97d88 100644 --- a/src/main/java/ru/practicum/shareit/user/UserMapper.java +++ b/src/main/java/ru/practicum/shareit/user/UserMapper.java @@ -2,6 +2,7 @@ import lombok.experimental.UtilityClass; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; +import ru.practicum.shareit.item.dto.ItemDTOWithBookings; import ru.practicum.shareit.user.dto.UserDTO; import ru.practicum.shareit.user.model.User; @@ -38,4 +39,8 @@ public static List mapToUserDto(Iterable users) { public static BookingDTOToReturn.User toUserToBookingDTO(User user) { return new BookingDTOToReturn.User(user.getId(), user.getName()); } + + public static ItemDTOWithBookings.User toUserToItemWithBookingsDto(User user) { + return new ItemDTOWithBookings.User(user.getId(), user.getName()); + } } From 4695c535ca50bed992f4b7f539927f64c9789037 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Thu, 9 Feb 2023 19:12:41 +0300 Subject: [PATCH 24/45] Delete ItemWithBookings.java --- .../shareit/item/model/ItemWithBookings.java | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 src/main/java/ru/practicum/shareit/item/model/ItemWithBookings.java diff --git a/src/main/java/ru/practicum/shareit/item/model/ItemWithBookings.java b/src/main/java/ru/practicum/shareit/item/model/ItemWithBookings.java deleted file mode 100644 index cf0d1178a..000000000 --- a/src/main/java/ru/practicum/shareit/item/model/ItemWithBookings.java +++ /dev/null @@ -1,19 +0,0 @@ -package ru.practicum.shareit.item.model; - -public interface ItemWithBookings { - Long getId(); - - String getName(); - - String getDescription(); - - Boolean getAvailable(); - - Long getLastBookingId(); - - Long getLastBookerId(); - - Long getNextBookingId(); - - Long getNextBookerId(); -} From ba1fc7c4a70157fb7d52cb07388d3724d7b80098 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Thu, 9 Feb 2023 19:13:06 +0300 Subject: [PATCH 25/45] Delete UserDTOToUpd.java --- .../shareit/user/dto/UserDTOToUpd.java | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 src/main/java/ru/practicum/shareit/user/dto/UserDTOToUpd.java diff --git a/src/main/java/ru/practicum/shareit/user/dto/UserDTOToUpd.java b/src/main/java/ru/practicum/shareit/user/dto/UserDTOToUpd.java deleted file mode 100644 index 745d3673c..000000000 --- a/src/main/java/ru/practicum/shareit/user/dto/UserDTOToUpd.java +++ /dev/null @@ -1,18 +0,0 @@ -package ru.practicum.shareit.user.dto; - -import lombok.Data; -import ru.practicum.shareit.Create; - -import javax.validation.constraints.NotBlank; - -@Data -public class UserDTOToUpd { - - private long id; - - @NotBlank(groups = {Create.class}) - private String name; - - @NotBlank - private String email; -} From a59150f2c6c029a4105110c6e45ddcb6f6b989d8 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Thu, 9 Feb 2023 19:14:59 +0300 Subject: [PATCH 26/45] checkstyle --- src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java | 2 +- .../java/ru/practicum/shareit/item/service/ItemServiceImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java index 8c738b665..d157ffc70 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java @@ -27,7 +27,7 @@ public static ItemDTO toItemDto(Item item) { return itemDto; } - public static ItemDTOWithBookings ToItemDtoWithBookings(Item item) { + public static ItemDTOWithBookings toItemDtoWithBookings(Item item) { ItemDTOWithBookings itemDto = new ItemDTOWithBookings(); itemDto.setId(item.getId()); itemDto.setName(item.getName()); diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index 634ff642d..7b86f3e3d 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -75,7 +75,7 @@ public ItemDTO update(Long userId, Long itemId, ItemDTO itemDto) throws BadReque @Override public ItemDTOWithBookings get(Long userId, Long itemId) { Item item = itemRepository.findById(itemId).orElseThrow(() -> new NotFoundException("Item not found")); - ItemDTOWithBookings itemDto = ItemMapper.ToItemDtoWithBookings(item); + ItemDTOWithBookings itemDto = ItemMapper.toItemDtoWithBookings(item); List comments = commentRepository.findAllByItem(item); itemDto.setComments(CommentMapper.mapToCommentDto(comments)); if (Objects.equals(item.getOwner().getId(), userId)) { From 98f2e12b4f6632e2dcb5a05bb34e3cb343763cda Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Thu, 9 Feb 2023 22:23:18 +0300 Subject: [PATCH 27/45] Add files via upload --- .../java/ru/practicum/shareit/booking/BookingRepository.java | 2 +- .../java/ru/practicum/shareit/item/mapper/ItemMapper.java | 2 +- .../ru/practicum/shareit/item/service/ItemServiceImpl.java | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java index 4f5d62fa3..e2bf5e815 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java @@ -51,7 +51,7 @@ List findByItemAndBookerAndStartBeforeAndEndBefore(Item item, User book Booking findFirstByStatusAndItemAndStartIsAfter(Status state, Item item, LocalDateTime time, Sort sort); - Booking findLastByStatusAndItemAndEndIsBefore(Status state, Item item, LocalDateTime time, Sort sort); + Booking findFirstByStatusAndItemAndStartLessThanEqual(Status state, Item item, LocalDateTime time, Sort sort); @Query("select b " + "from Booking b " + diff --git a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java index d157ffc70..43fd2d79d 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java @@ -69,7 +69,7 @@ public static ItemDTOWithBookings toDtoWithBookings(Item item, List boo iDTO.setDescription(item.getDescription()); iDTO.setAvailable(item.getAvailable()); bookings.stream() - .filter(b -> b.getEnd().isBefore(LocalDateTime.now())) + .filter(b -> !b.getStart().isAfter(LocalDateTime.now())) .findFirst() .ifPresent(lastBooking -> iDTO.setLastBooking(BookingMapper .toBookingDtoForItem(lastBooking.getId(), lastBooking.getBooker().getId()))); diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index 7b86f3e3d..42e6de077 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -31,6 +31,7 @@ import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.toList; +import static org.springframework.data.domain.Sort.Direction.ASC; import static org.springframework.data.domain.Sort.Direction.DESC; @Service @@ -80,8 +81,8 @@ public ItemDTOWithBookings get(Long userId, Long itemId) { itemDto.setComments(CommentMapper.mapToCommentDto(comments)); if (Objects.equals(item.getOwner().getId(), userId)) { Booking nextBooking = bookingRepository.findFirstByStatusAndItemAndStartIsAfter(Status.APPROVED, item, - LocalDateTime.now(), Sort.by(DESC, "start")); - Booking lastBooking = bookingRepository.findLastByStatusAndItemAndEndIsBefore(Status.APPROVED, item, + LocalDateTime.now(), Sort.by(ASC, "start")); + Booking lastBooking = bookingRepository.findFirstByStatusAndItemAndStartLessThanEqual(Status.APPROVED, item, LocalDateTime.now(), Sort.by(DESC, "end")); if (nextBooking != null) { itemDto.setNextBooking(BookingMapper.toBookingDtoForItem(nextBooking.getId(), From 834da69ca8ec901a4bea249bb6f31d68555e2131 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Sat, 11 Feb 2023 01:34:42 +0300 Subject: [PATCH 28/45] Add files via upload --- .../shareit/booking/BookingController.java | 19 +- .../shareit/booking/BookingMapper.java | 12 + .../shareit/booking/BookingRepository.java | 48 + .../shareit/booking/dto/BookingDTO.java | 15 +- .../booking/dto/BookingDTOForItem.java | 5 + .../booking/dto/BookingDTOToReturn.java | 2 + .../booking/service/BookingService.java | 4 +- .../booking/service/BookingServiceImpl.java | 127 +- .../shareit/item/ItemController.java | 8 +- .../shareit/item/ItemRepository.java | 17 + .../shareit/item/dto/CommentDTO.java | 2 - .../practicum/shareit/item/dto/ItemDTO.java | 3 +- .../shareit/item/dto/ItemDTOWithBookings.java | 1 + .../shareit/item/mapper/CommentMapper.java | 1 + .../shareit/item/mapper/ItemMapper.java | 29 +- .../ru/practicum/shareit/item/model/Item.java | 5 + .../shareit/item/service/ItemService.java | 7 +- .../shareit/item/service/ItemServiceImpl.java | 45 +- .../request/ItemRequestController.java | 41 +- .../shareit/request/RequestMapper.java | 38 + .../shareit/request/RequestRepository.java | 20 + .../shareit/request/dto/RequestDTO.java | 19 + .../request/dto/RequestDTOWithItems.java | 22 + .../request/service/RequestService.java | 16 + .../request/service/RequestServiceImpl.java | 118 ++ .../ru/practicum/shareit/user/UserMapper.java | 24 +- src/main/resources/schema.sql | 29 +- .../ru/practicum/shareit/ShareItTests.java | 298 +++- .../booking/BookingControllerTest.java | 227 +++ .../booking/BookingRepositoryTest.java | 474 ++++++ .../shareit/booking/dto/BookingDtoTest.java | 41 + .../booking/service/BookingServiceTest.java | 1441 +++++++++++++++++ .../shareit/item/CommentRepositoryTest.java | 69 + .../shareit/item/ItemControllerTest.java | 312 ++++ .../shareit/item/ItemRepositoryTest.java | 95 ++ .../shareit/item/dto/ItemDtoTest.java | 49 + .../item/dto/ItemDtoWithBookingTest.java | 91 ++ .../item/dto/ItemDtoWithCommentTest.java | 39 + .../shareit/item/service/ItemServiceTest.java | 630 +++++++ .../request/ItemRequestControllerTest.java | 185 +++ .../request/ItemRequestRepositoryTest.java | 76 + .../service/ItemRequestServiceTest.java | 331 ++++ .../shareit/user/UserControllerTest.java | 161 ++ .../shareit/user/dto/UserDtoTest.java | 30 + .../shareit/user/service/UserServiceTest.java | 213 +++ src/test/resources/data.sql | 26 + 46 files changed, 5412 insertions(+), 53 deletions(-) create mode 100644 src/main/java/ru/practicum/shareit/request/RequestMapper.java create mode 100644 src/main/java/ru/practicum/shareit/request/RequestRepository.java create mode 100644 src/main/java/ru/practicum/shareit/request/dto/RequestDTO.java create mode 100644 src/main/java/ru/practicum/shareit/request/dto/RequestDTOWithItems.java create mode 100644 src/main/java/ru/practicum/shareit/request/service/RequestService.java create mode 100644 src/main/java/ru/practicum/shareit/request/service/RequestServiceImpl.java create mode 100644 src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java create mode 100644 src/test/java/ru/practicum/shareit/booking/BookingRepositoryTest.java create mode 100644 src/test/java/ru/practicum/shareit/booking/dto/BookingDtoTest.java create mode 100644 src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java create mode 100644 src/test/java/ru/practicum/shareit/item/CommentRepositoryTest.java create mode 100644 src/test/java/ru/practicum/shareit/item/ItemControllerTest.java create mode 100644 src/test/java/ru/practicum/shareit/item/ItemRepositoryTest.java create mode 100644 src/test/java/ru/practicum/shareit/item/dto/ItemDtoTest.java create mode 100644 src/test/java/ru/practicum/shareit/item/dto/ItemDtoWithBookingTest.java create mode 100644 src/test/java/ru/practicum/shareit/item/dto/ItemDtoWithCommentTest.java create mode 100644 src/test/java/ru/practicum/shareit/item/service/ItemServiceTest.java create mode 100644 src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java create mode 100644 src/test/java/ru/practicum/shareit/request/ItemRequestRepositoryTest.java create mode 100644 src/test/java/ru/practicum/shareit/request/service/ItemRequestServiceTest.java create mode 100644 src/test/java/ru/practicum/shareit/user/UserControllerTest.java create mode 100644 src/test/java/ru/practicum/shareit/user/dto/UserDtoTest.java create mode 100644 src/test/java/ru/practicum/shareit/user/service/UserServiceTest.java create mode 100644 src/test/resources/data.sql diff --git a/src/main/java/ru/practicum/shareit/booking/BookingController.java b/src/main/java/ru/practicum/shareit/booking/BookingController.java index e466bcbf6..22bfb0613 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingController.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingController.java @@ -9,6 +9,7 @@ import ru.practicum.shareit.booking.service.BookingService; import javax.validation.Valid; +import javax.validation.constraints.PositiveOrZero; import java.util.List; @RestController @@ -42,18 +43,24 @@ public BookingDTOToReturn get(@RequestHeader("X-Sharer-User-Id") Long userId, @P @GetMapping public List findByBooker(@RequestHeader("X-Sharer-User-Id") Long userId, - @RequestParam(required = false, defaultValue = "ALL") - String state) { + @RequestParam(required = false, defaultValue = "ALL") String state, + @PositiveOrZero @RequestParam(name = "from", required = false) + Integer from, + @PositiveOrZero @RequestParam(name = "size", required = false) + Integer size) { log.info("Получение списка бронирований пользовалеля с id {}", userId); - return bookingService.getByBooker(userId, state); + return bookingService.getByBooker(userId, state, from, size); } @GetMapping("/owner") public List findByOwner(@RequestHeader("X-Sharer-User-Id") Long userId, - @RequestParam(required = false, defaultValue = "ALL") - String state) { + @RequestParam(required = false, defaultValue = "ALL") String state, + @PositiveOrZero @RequestParam(name = "from", required = false) + Integer from, + @PositiveOrZero @RequestParam(name = "size", required = false) + Integer size) { log.info("Получение списка бронирований для всех вещей пользователя с id {}", userId); - return bookingService.getByOwner(userId, state); + return bookingService.getByOwner(userId, state, from, size); } } diff --git a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java index dbbcb2a9d..37f79af8d 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java @@ -54,4 +54,16 @@ public static List mapToBookingDtoFrom(Iterable boo } return dtos; } + + public static BookingDTO toBookingDto(Booking booking) { + BookingDTO bookingDto = new BookingDTO(); + bookingDto.setId(booking.getId()); + bookingDto.setStart(booking.getStart()); + bookingDto.setEnd(booking.getEnd()); + bookingDto.setStatus(booking.getStatus()); + bookingDto.setItemId(booking.getItem() != null ? booking.getItem().getId() : null); + bookingDto.setItemName(booking.getItem() != null ? booking.getItem().getName() : null); + bookingDto.setBookerId(booking.getBooker() != null ? booking.getBooker().getId() : null); + return bookingDto; + } } diff --git a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java index e2bf5e815..bf1db543d 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java @@ -1,5 +1,7 @@ package ru.practicum.shareit.booking; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -14,16 +16,30 @@ public interface BookingRepository extends JpaRepository { + //переделать все запросы с натив куери + List findByBookerAndStatusOrderByStartDesc(User booker, Status status); List findByBookerOrderByStartDesc(User booker); + Page findByBookerAndStatusOrderByStartDesc(User booker, Status status, Pageable pageable); + + Page findByBookerOrderByStartDesc(User booker, Pageable pageable); + List findByBookerAndStartAfterOrderByStartDesc(User booker, LocalDateTime now); + Page findByBookerAndStartAfterOrderByStartDesc(User booker, LocalDateTime now, Pageable pageable); + List findByBookerAndStartBeforeAndEndAfterOrderByStartDesc(User booker, LocalDateTime s, LocalDateTime e); + Page findByBookerAndStartBeforeAndEndAfterOrderByStartDesc(User booker, LocalDateTime s, LocalDateTime e, + Pageable pageable); + List findByBookerAndStartBeforeAndEndBeforeOrderByStartDesc(User booker, LocalDateTime s, LocalDateTime e); + Page findByBookerAndStartBeforeAndEndBeforeOrderByStartDesc(User booker, LocalDateTime s, + LocalDateTime e, Pageable pageable); + List findByItemAndBookerAndStartBeforeAndEndBefore(Item item, User booker, LocalDateTime s, LocalDateTime e); @@ -31,24 +47,54 @@ List findByItemAndBookerAndStartBeforeAndEndBefore(Item item, User book + " ORDER BY b.id DESC") List findByOwnerAll(long userId); + @Query(nativeQuery = true, value = "SELECT * FROM BOOKINGS as b " + + "LEFT JOIN ITEMS as i ON b.ITEM_ID = i.ID " + + "WHERE i.OWNER_ID = ?1 " + + "ORDER BY b.START_DATE DESC") + List findByOwnerAll(Long i, Pageable pageable); + @Query("SELECT b FROM Booking b WHERE b.item.id IN " + "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.start < ?2 AND b.end > ?2" + " ORDER BY b.id DESC") List findByOwnerAndCurrent(long userId, LocalDateTime currentDate); + @Query(nativeQuery = true, value = "SELECT * FROM BOOKINGS as b " + + "LEFT JOIN ITEMS as i ON b.ITEM_ID = i.ID " + + "WHERE i.OWNER_ID = ?1 AND b.START_DATE < ?2 AND b.END_DATE > ?2 " + + "ORDER BY b.START_DATE DESC") + List findByOwnerAndCurrent(Long i, LocalDateTime now, Pageable pageable); + @Query("SELECT b FROM Booking b WHERE b.item.id IN " + "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.end < ?2" + " ORDER BY b.id DESC") List findByOwnerAndPast(long userId, LocalDateTime currentDate); + @Query(nativeQuery = true, value = "SELECT * FROM BOOKINGS as b " + + "LEFT JOIN ITEMS as i ON b.ITEM_ID = i.ID " + + "WHERE i.OWNER_ID = ?1 AND b.END_DATE < ?2 AND b.START_DATE < ?2 " + + "ORDER BY b.START_DATE DESC") + List findByOwnerAndPast(Long i, LocalDateTime now, Pageable pageable); + @Query("SELECT b FROM Booking b WHERE b.item.id IN " + "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.start > ?2" + " ORDER BY b.id DESC") List findByUserAndFuture(long userId, LocalDateTime currentDate); + @Query(nativeQuery = true, value = "SELECT * FROM BOOKINGS as b " + + "LEFT JOIN ITEMS as i ON b.ITEM_ID = i.ID " + + "WHERE i.OWNER_ID = ?1 AND b.START_DATE > ?2 " + + "ORDER BY b.START_DATE DESC") + List findByUserAndFuture(Long i, LocalDateTime s, Pageable pageable); + @Query("SELECT b FROM Booking b WHERE b.item.id IN " + "(SELECT i.id FROM Item i WHERE i.owner.id = ?1) AND b.status = ?2" + " ORDER BY b.id DESC") List findByOwnerAndByStatus(long userId, Status status); + @Query(nativeQuery = true, value = "SELECT * FROM BOOKINGS as b " + + "LEFT JOIN ITEMS as i ON b.ITEM_ID = i.ID " + + "WHERE i.OWNER_ID = ?1 AND b.STATUS LIKE ?2 " + + "ORDER BY b.START_DATE DESC") + List findByOwnerAndByStatus(Long i, String status, Pageable pageable); + Booking findFirstByStatusAndItemAndStartIsAfter(Status state, Item item, LocalDateTime time, Sort sort); Booking findFirstByStatusAndItemAndStartLessThanEqual(Status state, Item item, LocalDateTime time, Sort sort); @@ -58,4 +104,6 @@ List findByItemAndBookerAndStartBeforeAndEndBefore(Item item, User book "where b.item in ?1 " + " and b.status = 'APPROVED'") List findApprovedForItems(Collection items, Sort sort); + + List findByItemOrderByStartDesc(Item item); } diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java index c59699fad..8f96efccd 100644 --- a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java @@ -1,8 +1,10 @@ package ru.practicum.shareit.booking.dto; +import com.fasterxml.jackson.annotation.JsonFormat; import com.sun.istack.NotNull; import lombok.Data; import lombok.NoArgsConstructor; +import ru.practicum.shareit.booking.model.Status; import javax.validation.constraints.Future; import javax.validation.constraints.FutureOrPresent; @@ -14,14 +16,17 @@ public class BookingDTO { private long id; - @FutureOrPresent - @NotNull + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") private LocalDateTime start; - @Future - @NotNull + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") private LocalDateTime end; - @NotNull private Long itemId; + + private String itemName; + + private Long bookerId; + + private Status status; } diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOForItem.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOForItem.java index 0f68fa9b0..e47ec33dd 100644 --- a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOForItem.java +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOForItem.java @@ -1,11 +1,14 @@ package ru.practicum.shareit.booking.dto; +import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonInclude; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import java.time.LocalDateTime; + @AllArgsConstructor @Getter @Setter @@ -14,4 +17,6 @@ public class BookingDTOForItem { private long id; private Long bookerId; + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") + private LocalDateTime dateTime; } diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java index 8570bb54e..b941a19f3 100644 --- a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java @@ -24,11 +24,13 @@ public class BookingDTOToReturn { public static class User { private final long id; private final String name; + private final String email; } @Data public static class Item { private final long id; private final String name; + private final String description; } } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingService.java b/src/main/java/ru/practicum/shareit/booking/service/BookingService.java index a6b76c288..f31050610 100644 --- a/src/main/java/ru/practicum/shareit/booking/service/BookingService.java +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingService.java @@ -12,7 +12,7 @@ public interface BookingService { BookingDTOToReturn get(Long bookingId, Long userId); - List getByBooker(Long usersId, String stateString); + List getByBooker(Long usersId, String status, Integer page, Integer size); - List getByOwner(Long usersId, String state); + List getByOwner(Long usersId, String status, Integer page, Integer size); } diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java index fb1d84489..d862a6b42 100644 --- a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java @@ -3,6 +3,9 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.practicum.shareit.booking.BookingMapper; @@ -21,6 +24,7 @@ import ru.practicum.shareit.user.model.User; import java.time.LocalDateTime; +import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -48,10 +52,14 @@ public BookingDTOToReturn add(Long userId, BookingDTO bookingDto) { if (Objects.equals(item.getOwner().getId(), userId)) { throw new NotFoundException("You cannot book your item"); } - if ((!bookingDto.getEnd().isAfter(bookingDto.getStart()))) { + if (bookingDto.getEnd().isBefore(LocalDateTime.now()) || + bookingDto.getStart().isBefore(LocalDateTime.now()) || + (bookingDto.getEnd().isBefore(bookingDto.getStart()) && + !bookingDto.getEnd().equals(bookingDto.getStart()))) { throw new BadRequestException("Wrong date"); } Booking booking = bRepository.save(BookingMapper.toBooking(bookingDto, item, user)); + log.info(booking.toString()); return BookingMapper.toBookingDtoFrom(booking); } @@ -91,11 +99,32 @@ public BookingDTOToReturn get(Long userId, Long bookingId) { } @Override - public List getByBooker(Long usersId, String stateString) { - User booker = uRepository.findById(usersId) + public List getByBooker(Long userId, String status, Integer page, Integer size) { + Optional booker = uRepository.findById(userId); + Pageable pageable; + if (booker.isEmpty()) { + throw new NotFoundException("Для пользователя нет доступа"); + } + User user = booker.get(); + if (page != null && size != null) { + if (page < 0 || size < 0) { + throw new BadRequestException("From или size не могут принимать отрицательноге значение"); + } + if (size == 0) { + throw new BadRequestException("Size не может принимать значение 0"); + } + pageable = PageRequest.of(page / size, size); + return findBookingByBookerByPage(user, status, pageable); + } else { + return findBookingByBooker(user.getId(), status); + } + } + + private List findBookingByBooker(Long userId, String status) { + User booker = uRepository.findById(userId) .orElseThrow(() -> new NotFoundException("No rights")); List bookingsByBooker; - State state = stateValidation(stateString); + State state = stateValidation(status); switch (state) { case ALL: bookingsByBooker = bRepository.findByBookerOrderByStartDesc(booker); @@ -124,13 +153,99 @@ public List getByBooker(Long usersId, String stateString) { return BookingMapper.mapToBookingDtoFrom(bookingsByBooker); } + private List findBookingByBookerByPage(User booker, String status, Pageable pageable) { + Page bookingsPage; + if (status == null || status.equals("")) { + status = "ALL"; + } + switch (status) { + case "ALL": + bookingsPage = bRepository.findByBookerOrderByStartDesc(booker, pageable); + break; + case "CURRENT": + bookingsPage = bRepository.findByBookerAndStartBeforeAndEndAfterOrderByStartDesc(booker, + LocalDateTime.now(), LocalDateTime.now(), pageable); + break; + case "PAST": + bookingsPage = bRepository.findByBookerAndStartBeforeAndEndBeforeOrderByStartDesc(booker, + LocalDateTime.now(), LocalDateTime.now(), pageable); + break; + case "FUTURE": + bookingsPage = bRepository.findByBookerAndStartAfterOrderByStartDesc(booker, LocalDateTime.now(), pageable); + break; + case "WAITING": + bookingsPage = bRepository.findByBookerAndStatusOrderByStartDesc(booker, Status.WAITING, pageable); + break; + case "REJECTED": + bookingsPage = bRepository.findByBookerAndStatusOrderByStartDesc(booker, Status.REJECTED, pageable); + break; + default: + throw new StatusBadRequestException("Unknown state: UNSUPPORTED_STATUS"); + + } + return BookingMapper.mapToBookingDtoFrom(bookingsPage); + + } + @Override - public List getByOwner(Long userId, String stateString) { + public List getByOwner(Long userId, String status, Integer page, Integer size) { + Optional owner = uRepository.findById(userId); + Pageable pageable; + if (owner.isEmpty()) { + throw new NotFoundException("Для пользователя нет доступа"); + } + if (page != null && size != null) { + if (page < 0 || size < 0) { + throw new BadRequestException("From или size не могут принимать отрицательноге значение"); + } + if (size == 0) { + throw new BadRequestException("Size не может принимать значение 0"); + } + pageable = PageRequest.of(page / size, size); + + return findBookingByOwnerByPage(userId, status, pageable); + } else { + return findBookingByOwner(userId, status); + } + } + + private List findBookingByOwnerByPage(Long userId, String status, Pageable pageable) { + if (uRepository.findById(userId).isEmpty()) { + throw new NotFoundException("User not found"); + } + List bookingsByOwner; + State state = stateValidation(status); + switch (state) { + case ALL: + bookingsByOwner = bRepository.findByOwnerAll(userId, pageable); + break; + case CURRENT: + bookingsByOwner = bRepository.findByOwnerAndCurrent(userId, LocalDateTime.now(), pageable); + break; + case PAST: + bookingsByOwner = bRepository.findByOwnerAndPast(userId, LocalDateTime.now(), pageable); + break; + case FUTURE: + bookingsByOwner = bRepository.findByUserAndFuture(userId, LocalDateTime.now(), pageable); + break; + case WAITING: + bookingsByOwner = bRepository.findByOwnerAndByStatus(userId, String.valueOf(Status.WAITING), pageable); + break; + case REJECTED: + bookingsByOwner = bRepository.findByOwnerAndByStatus(userId, String.valueOf(Status.REJECTED), pageable); + break; + default: + throw new StatusBadRequestException("Unknown state: UNSUPPORTED_STATUS"); + } + return BookingMapper.mapToBookingDtoFrom(bookingsByOwner); + } + + private List findBookingByOwner(Long userId, String status) { if (uRepository.findById(userId).isEmpty()) { throw new NotFoundException("User not found"); } List bookingsByOwner; - State state = stateValidation(stateString); + State state = stateValidation(status); switch (state) { case ALL: bookingsByOwner = bRepository.findByOwnerAll(userId); diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/src/main/java/ru/practicum/shareit/item/ItemController.java index b4a79c960..09a440c1a 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -28,7 +28,7 @@ public ItemDTO add(@RequestHeader("X-Sharer-User-Id") Long userId, @Valid @Reque @PatchMapping("/{itemId}") public ItemDTO update(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long itemId, - @RequestBody ItemDTO itemDto) { + @RequestBody ItemDTO itemDto) { log.info("Обновление данные о вещи"); return itemService.update(userId, itemId, itemDto); } @@ -40,9 +40,11 @@ public ItemDTOWithBookings get(@RequestHeader("X-Sharer-User-Id") Long userId, @ } @GetMapping - public List getAllByOwner(@RequestHeader("X-Sharer-User-Id") Long userId) { + public List getAllByOwner(@RequestHeader("X-Sharer-User-Id") Long userId, + @RequestParam(name = "from", required = false) Integer from, + @RequestParam(name = "size", required = false) Integer size) { log.info("Получение всех вещей пользователя с id {}", userId); - return itemService.getAllByOwner(userId); + return itemService.getAllByOwner(userId, from, size); } @GetMapping("/search") diff --git a/src/main/java/ru/practicum/shareit/item/ItemRepository.java b/src/main/java/ru/practicum/shareit/item/ItemRepository.java index 14569738f..74ad6a7ea 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemRepository.java +++ b/src/main/java/ru/practicum/shareit/item/ItemRepository.java @@ -1,8 +1,11 @@ package ru.practicum.shareit.item; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.model.User; import java.util.List; @@ -13,5 +16,19 @@ public interface ItemRepository extends JpaRepository { "AND (available)") List findItemsByNameOrDescription(String substring); + @Query(nativeQuery = true, value = "SELECT * FROM items " + + "WHERE ((LOWER(name) Like CONCAT('%', LOWER(?1), '%')) " + + "OR (LOWER(description) Like CONCAT('%', LOWER(?1), '%'))) " + + "AND (available)") + Page findItemsByNameOrDescription(String substring, Pageable pageable); + List getAllByOwnerId(long id); + + @Query(nativeQuery = true, value = "SELECT * FROM items AS i WHERE i.REQUEST_ID = ?1") + List findByRequest(Long idRequest); + + List findByOwner(User user); + + Page findByOwner(User user, Pageable pageable); + } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/dto/CommentDTO.java b/src/main/java/ru/practicum/shareit/item/dto/CommentDTO.java index 61d7543c0..e3c944209 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/CommentDTO.java +++ b/src/main/java/ru/practicum/shareit/item/dto/CommentDTO.java @@ -2,7 +2,6 @@ import lombok.Data; -import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; import java.time.LocalDateTime; @@ -11,7 +10,6 @@ public class CommentDTO { private Long id; - @NotBlank @Size(min = 1, max = 1000) private String text; diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java index fadc6668f..c448ee7d0 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTO.java @@ -21,11 +21,12 @@ public class ItemDTO { private User owner; - private Long request; + private Long requestId; @Data public static class User { private final long id; private final String name; + private final String email; } } diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithBookings.java b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithBookings.java index 307a43bb6..c2318cf18 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithBookings.java +++ b/src/main/java/ru/practicum/shareit/item/dto/ItemDTOWithBookings.java @@ -31,5 +31,6 @@ public class ItemDTOWithBookings { public static class User { private final long id; private final String name; + private final String email; } } diff --git a/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java index af947313c..6edcd8098 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java @@ -32,6 +32,7 @@ public static Comment toComment(CommentDTO itemDtoWithComment, Item item, User a return comment; } + public static List mapToCommentDto(Iterable comments) { List dtos = new ArrayList<>(); for (Comment comment : comments) { diff --git a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java index 43fd2d79d..878bb1aff 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java @@ -8,6 +8,7 @@ import ru.practicum.shareit.item.dto.ItemDTOWithBookings; import ru.practicum.shareit.item.model.Comment; import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.request.RequestRepository; import ru.practicum.shareit.user.UserMapper; import ru.practicum.shareit.user.model.User; @@ -24,6 +25,9 @@ public static ItemDTO toItemDto(Item item) { itemDto.setName(item.getName()); itemDto.setDescription(item.getDescription()); itemDto.setAvailable(item.getAvailable()); + if (item.getRequestId() != null) { + itemDto.setRequestId(item.getRequestId().getId()); + } return itemDto; } @@ -38,13 +42,26 @@ public static ItemDTOWithBookings toItemDtoWithBookings(Item item) { } - public static Item toItem(ItemDTO itemDto, User user) { + public static Item toItem(ItemDTO itemDto, User user, RequestRepository requestRepository) { Item item = new Item(); item.setId(itemDto.getId()); item.setName(itemDto.getName()); item.setDescription(itemDto.getDescription()); item.setAvailable(itemDto.getAvailable()); item.setOwner(user); + if (itemDto.getRequestId() != null) { + item.setRequestId(requestRepository.getReferenceById(itemDto.getRequestId())); + } + return item; + } + + public static Item toItem(ItemDTOWithBookings itemDtoWithBooking) { + Item item = new Item(); + item.setId(itemDtoWithBooking.getId()); + item.setName(itemDtoWithBooking.getName()); + item.setDescription(itemDtoWithBooking.getDescription()); + item.setAvailable(itemDtoWithBooking.getAvailable()); + item.setOwner(UserMapper.toUser(itemDtoWithBooking.getOwner())); return item; } @@ -58,7 +75,7 @@ public static List mapToItemDto(Iterable items) { } public static BookingDTOToReturn.Item toItemToBookingDTO(Item item) { - return new BookingDTOToReturn.Item(item.getId(), item.getName()); + return new BookingDTOToReturn.Item(item.getId(), item.getName(), item.getDescription()); } public static ItemDTOWithBookings toDtoWithBookings(Item item, List bookings, @@ -83,6 +100,14 @@ public static ItemDTOWithBookings toDtoWithBookings(Item item, List boo iDTO.setComments(CommentMapper.mapToCommentDto(comments)); return iDTO; } + + public static List mapToItem(Iterable items) { + List dtos = new ArrayList<>(); + for (ItemDTOWithBookings item : items) { + dtos.add(toItem(item)); + } + return dtos; + } } diff --git a/src/main/java/ru/practicum/shareit/item/model/Item.java b/src/main/java/ru/practicum/shareit/item/model/Item.java index de4b1dbbd..f53a45f70 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Item.java +++ b/src/main/java/ru/practicum/shareit/item/model/Item.java @@ -5,6 +5,7 @@ import lombok.Setter; import lombok.ToString; import org.hibernate.Hibernate; +import ru.practicum.shareit.request.model.ItemRequest; import ru.practicum.shareit.user.model.User; import javax.persistence.*; @@ -41,6 +42,10 @@ public class Item { @ToString.Exclude private User owner; + @ManyToOne + @JoinColumn(name = "request_id") + private ItemRequest requestId; + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemService.java b/src/main/java/ru/practicum/shareit/item/service/ItemService.java index 1143c1d26..c5176a5e1 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemService.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemService.java @@ -1,9 +1,10 @@ package ru.practicum.shareit.item.service; -import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithBookings; +import ru.practicum.shareit.item.dto.CommentDTO; +import java.util.Collection; import java.util.List; public interface ItemService { @@ -14,9 +15,11 @@ public interface ItemService { ItemDTO update(Long userId, Long itemId, ItemDTO itemDto); - List getAllByOwner(Long userId); + List getAllByOwner(Long userId, Integer page, Integer size); List getAllByText(String substring); CommentDTO addComment(Long authorId, Long itemId, CommentDTO comment); + + Collection getForRent(String substring, Integer page, Integer size); } diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index 42e6de077..73ec5b345 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -3,6 +3,8 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -15,13 +17,14 @@ import ru.practicum.shareit.exception.NotFoundException; import ru.practicum.shareit.item.CommentRepository; import ru.practicum.shareit.item.ItemRepository; -import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithBookings; +import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.mapper.CommentMapper; import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Comment; import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.request.RequestRepository; import ru.practicum.shareit.user.UserRepository; import ru.practicum.shareit.user.model.User; @@ -40,16 +43,21 @@ @Slf4j public class ItemServiceImpl implements ItemService { + //переписать методы с новыми переменными + private final ItemRepository itemRepository; private final UserRepository userRepository; private final BookingRepository bookingRepository; private final CommentRepository commentRepository; + private final RequestRepository requestRepository; + @Transactional @Override public ItemDTO add(Long userId, ItemDTO itemDto) throws BadRequestException { User user = userRepository.findById(userId).orElseThrow(() -> new NotFoundException("User not found")); - Item item = itemRepository.save(ItemMapper.toItem(itemDto, user)); + Item item = itemRepository.save(ItemMapper.toItem(itemDto, user, requestRepository)); + log.info(item.toString()); return ItemMapper.toItemDto(item); } @@ -95,7 +103,7 @@ public ItemDTOWithBookings get(Long userId, Long itemId) { } @Override - public List getAllByOwner(Long userId) { + public List getAllByOwner(Long userId, Integer page, Integer size) { if (!userRepository.existsById(userId)) { throw new NotFoundException("User not found"); } @@ -138,7 +146,7 @@ public List getAllByText(String substring) { @Transactional @Override - public CommentDTO addComment(Long authorId, Long itemId, CommentDTO itemDtoWithComment) { + public CommentDTO addComment(Long authorId, Long itemId, CommentDTO comment) { Item item = itemRepository.findById(itemId).orElseThrow(() -> new NotFoundException("Item not found")); User author = userRepository.findById(authorId).orElseThrow(() -> new NotFoundException("User not found")); List bookings = bookingRepository @@ -146,7 +154,32 @@ public CommentDTO addComment(Long authorId, Long itemId, CommentDTO itemDtoWithC if (bookings.isEmpty()) { throw new BadRequestException("Booking is empty"); } - Comment comment = CommentMapper.toComment(itemDtoWithComment, item, author); - return CommentMapper.toCommentDto(commentRepository.save(comment)); + if (comment == null) { + throw new BadRequestException("Comment is empty"); + } + Comment comment1 = CommentMapper.toComment(comment, item, author); + return CommentMapper.toCommentDto(commentRepository.save(comment1)); + } + + @Override + public Collection getForRent(String substring, Integer page, Integer size) { + if (!Objects.equals(substring, "")) { + if (page != null && size != null) { + sizeAndPage(size, page); + Pageable pageable = PageRequest.of(page / size, size); + return ItemMapper.mapToItemDto(itemRepository.findItemsByNameOrDescription(substring, pageable)); + } + return ItemMapper.mapToItemDto(itemRepository.findItemsByNameOrDescription(substring)); + } + return new ArrayList<>(); + } + + private void sizeAndPage(Integer size, Integer page) { + if (page < 0 || size < 0) { + throw new BadRequestException("From или size не могут принимать отрицательноге значение"); + } + if (size == 0) { + throw new BadRequestException("Size не может принимать значение 0"); + } } } diff --git a/src/main/java/ru/practicum/shareit/request/ItemRequestController.java b/src/main/java/ru/practicum/shareit/request/ItemRequestController.java index d149fdb46..5e49b7c3e 100644 --- a/src/main/java/ru/practicum/shareit/request/ItemRequestController.java +++ b/src/main/java/ru/practicum/shareit/request/ItemRequestController.java @@ -1,9 +1,46 @@ package ru.practicum.shareit.request; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import ru.practicum.shareit.request.dto.RequestDTO; +import ru.practicum.shareit.request.dto.RequestDTOWithItems; +import ru.practicum.shareit.request.service.RequestService; + +import java.util.List; @RestController @RequestMapping(path = "/requests") +@RequiredArgsConstructor(onConstructor_ = @Autowired) +@Slf4j public class ItemRequestController { + private final RequestService requestService; + + @PostMapping + public RequestDTO addRequest(@RequestHeader("X-Sharer-User-Id") Long userId, + @RequestBody RequestDTO request) { + log.info("Добавление запроса на добавление вещи для пользователя {}", userId); + return requestService.add(userId, request); + } + + @GetMapping + public List getAllOwnRequest(@RequestHeader("X-Sharer-User-Id") Long userId) { + log.info("Просмотр всех запросов на добавление вещи для пользователя {}", userId); + return requestService.findAllByOwner(userId); + } + + @GetMapping("/all") + public List getAllRequest(@RequestHeader("X-Sharer-User-Id") Long userId, + @RequestParam(name = "from", required = false) Integer from, + @RequestParam(name = "size", required = false) Integer size) { + log.info("Просмотр всех запросов на добавление вещи"); + return requestService.findAll(userId,from, size); + } + + @GetMapping("/{requestId}") + public RequestDTO getRequest(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long requestId) { + log.info("Просмотр запроса с id {}", requestId); + return requestService.findById(userId, requestId); + } } diff --git a/src/main/java/ru/practicum/shareit/request/RequestMapper.java b/src/main/java/ru/practicum/shareit/request/RequestMapper.java new file mode 100644 index 000000000..42e5f22c9 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/RequestMapper.java @@ -0,0 +1,38 @@ +package ru.practicum.shareit.request; + +import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.request.dto.RequestDTO; +import ru.practicum.shareit.request.dto.RequestDTOWithItems; +import ru.practicum.shareit.request.model.ItemRequest; + +import java.util.List; + +public class RequestMapper { + public static RequestDTO toRequestDto(ItemRequest itemRequest) { + RequestDTO requestDto = new RequestDTO(); + requestDto.setId(itemRequest.getId()); + requestDto.setDescription(itemRequest.getDescription()); + requestDto.setRequester(itemRequest.getRequester()); + requestDto.setCreated(itemRequest.getCreated()); + return requestDto; + } + + public static ItemRequest toItemRequest(RequestDTO requestDto) { + ItemRequest request = new ItemRequest(); + request.setId(requestDto.getId()); + request.setDescription(requestDto.getDescription()); + request.setRequester(requestDto.getRequester()); + request.setCreated(requestDto.getCreated()); + return request; + } + + public static RequestDTOWithItems toRequestForFindDto(ItemRequest itemRequest, List item) { + RequestDTOWithItems requestDto = new RequestDTOWithItems(); + requestDto.setId(itemRequest.getId()); + requestDto.setDescription(itemRequest.getDescription()); + requestDto.setRequester(itemRequest.getRequester()); + requestDto.setCreated(itemRequest.getCreated()); + requestDto.setItems(item); + return requestDto; + } +} diff --git a/src/main/java/ru/practicum/shareit/request/RequestRepository.java b/src/main/java/ru/practicum/shareit/request/RequestRepository.java new file mode 100644 index 000000000..915759600 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/RequestRepository.java @@ -0,0 +1,20 @@ +package ru.practicum.shareit.request; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import ru.practicum.shareit.request.model.ItemRequest; +import ru.practicum.shareit.user.model.User; + +import java.util.List; + +public interface RequestRepository extends JpaRepository { + + List findByRequesterOrderByCreatedDesc(User requester); + + @Query(nativeQuery = true, value = "SELECT * FROM REQUESTS" + + " WHERE REQUESTER_ID != ?1") + Page findAllBy(Long userId, Pageable pageable); + +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/request/dto/RequestDTO.java b/src/main/java/ru/practicum/shareit/request/dto/RequestDTO.java new file mode 100644 index 000000000..799d53a56 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/dto/RequestDTO.java @@ -0,0 +1,19 @@ +package ru.practicum.shareit.request.dto; + +import lombok.Data; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; + +@Data +public class RequestDTO { + + private Long id; + + private String description; + + private User requester; + + private LocalDateTime created; +} + diff --git a/src/main/java/ru/practicum/shareit/request/dto/RequestDTOWithItems.java b/src/main/java/ru/practicum/shareit/request/dto/RequestDTOWithItems.java new file mode 100644 index 000000000..a04d4cd69 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/dto/RequestDTOWithItems.java @@ -0,0 +1,22 @@ +package ru.practicum.shareit.request.dto; + +import lombok.Data; +import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; +import java.util.List; + +@Data +public class RequestDTOWithItems extends RequestDTO { + + private Long id; + + private String description; + + private User requester; + + private LocalDateTime created; + + private List items; +} diff --git a/src/main/java/ru/practicum/shareit/request/service/RequestService.java b/src/main/java/ru/practicum/shareit/request/service/RequestService.java new file mode 100644 index 000000000..6264fb43d --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/service/RequestService.java @@ -0,0 +1,16 @@ +package ru.practicum.shareit.request.service; + +import ru.practicum.shareit.request.dto.RequestDTO; +import ru.practicum.shareit.request.dto.RequestDTOWithItems; + +import java.util.List; + +public interface RequestService { + RequestDTO add(Long userId, RequestDTO request); + + List findAllByOwner(Long userId); + + List findAll(Long userId, Integer page, Integer size); + + RequestDTO findById(Long userId, Long requestId); +} diff --git a/src/main/java/ru/practicum/shareit/request/service/RequestServiceImpl.java b/src/main/java/ru/practicum/shareit/request/service/RequestServiceImpl.java new file mode 100644 index 000000000..e2936af7c --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/service/RequestServiceImpl.java @@ -0,0 +1,118 @@ +package ru.practicum.shareit.request.service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import ru.practicum.shareit.exception.BadRequestException; +import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.item.ItemRepository; +import ru.practicum.shareit.item.mapper.ItemMapper; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.request.RequestMapper; +import ru.practicum.shareit.request.RequestRepository; +import ru.practicum.shareit.request.dto.RequestDTO; +import ru.practicum.shareit.request.dto.RequestDTOWithItems; +import ru.practicum.shareit.request.model.ItemRequest; +import ru.practicum.shareit.user.UserRepository; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@Service +@RequiredArgsConstructor(onConstructor_ = @Autowired) +@Slf4j +public class RequestServiceImpl implements RequestService { + + private final UserRepository uRepository; + private final RequestRepository rRepository; + private final ItemRepository iRepository; + + + @Override + @Transactional + public RequestDTO add(Long userId, RequestDTO request) { + User user = uRepository.findById(userId).orElseThrow(() -> new NotFoundException("Пользователь не найден")); + log.info(request.toString()); + if (request.getDescription() == null || Objects.equals(request.getDescription(), "")) { + throw new BadRequestException("Отсутствует описание для поиска вещи"); + } + request.setCreated(LocalDateTime.now()); + request.setRequester(user); + ItemRequest itemRequest = rRepository.save(RequestMapper.toItemRequest(request)); + return RequestMapper.toRequestDto(itemRequest); + } + + @Override + public List findAllByOwner(Long userId) { + User user = uRepository.findById(userId).orElseThrow(() -> new NotFoundException("Пользователь не найден")); + List requests = new ArrayList<>(); + List itemRequests = rRepository.findByRequesterOrderByCreatedDesc(user); + for (ItemRequest request : itemRequests) { + List item = iRepository.findByRequest(request.getId()); + requests.add(RequestMapper.toRequestForFindDto(request, ItemMapper.mapToItemDto(item))); + } + return requests; + } + + @Override + public List findAll(Long userId, Integer page, Integer size) { + log.info("start"); + List requestForFindDtos = new ArrayList<>(); + Pageable pageable; + Sort sortById = Sort.by(Sort.Direction.DESC, "created"); + if (page != null && size != null) { + log.info("page and size"); + if (page < 0 || size < 0) { + log.info("wrong from or size"); + throw new BadRequestException("From или size не могут принимать отрицательноге значение"); + } + if (size == 0) { + log.info("size equals null"); + throw new BadRequestException("Size не может принимать значение 0"); + } + pageable = PageRequest.of(page / size, size, sortById); + log.info("page"); + + Page requests = rRepository.findAllBy(userId, pageable); + log.info(requests.toString()); + for (ItemRequest request : requests) { + log.info(request.toString()); + log.info("request"); + List items = iRepository.findByRequest(request.getId()); + log.info(String.valueOf(items.size())); + RequestDTOWithItems request1 = RequestMapper.toRequestForFindDto(request, ItemMapper.mapToItemDto(items)); + log.info(request1.toString()); + requestForFindDtos.add(request1); + } + log.info("request get"); + return requestForFindDtos; + } + List requests = rRepository.findAll(); + for (ItemRequest request : requests) { + log.info("request without pageable" + request.getId()); + List items = iRepository.findByRequest(request.getId()); + RequestDTOWithItems request1 = RequestMapper.toRequestForFindDto(request, ItemMapper.mapToItemDto(items)); + requestForFindDtos.add(request1); + } + return requestForFindDtos; + } + + @Override + public RequestDTOWithItems findById(Long userId, Long requestId) { + uRepository.findById(userId).orElseThrow(() -> new NotFoundException("Пользователь не найден")); + ItemRequest request = rRepository.findById(requestId) + .orElseThrow(() -> new NotFoundException("Запрос не найден")); + List items = iRepository.findByRequest(requestId); + return RequestMapper.toRequestForFindDto(request, ItemMapper.mapToItemDto(items)); + } +} + diff --git a/src/main/java/ru/practicum/shareit/user/UserMapper.java b/src/main/java/ru/practicum/shareit/user/UserMapper.java index 0c9a97d88..122d04dfa 100644 --- a/src/main/java/ru/practicum/shareit/user/UserMapper.java +++ b/src/main/java/ru/practicum/shareit/user/UserMapper.java @@ -2,6 +2,7 @@ import lombok.experimental.UtilityClass; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; +import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithBookings; import ru.practicum.shareit.user.dto.UserDTO; import ru.practicum.shareit.user.model.User; @@ -28,6 +29,13 @@ public static User toUser(UserDTO userDto) { return user; } + public static User toUser(ItemDTOWithBookings.User user) { + User newUser = new User(); + newUser.setId(user.getId()); + newUser.setName(user.getName()); + return newUser; + } + public static List mapToUserDto(Iterable users) { List dtos = new ArrayList<>(); for (User user : users) { @@ -37,10 +45,22 @@ public static List mapToUserDto(Iterable users) { } public static BookingDTOToReturn.User toUserToBookingDTO(User user) { - return new BookingDTOToReturn.User(user.getId(), user.getName()); + return new BookingDTOToReturn.User(user.getId(), user.getName(), user.getEmail()); } public static ItemDTOWithBookings.User toUserToItemWithBookingsDto(User user) { - return new ItemDTOWithBookings.User(user.getId(), user.getName()); + return new ItemDTOWithBookings.User(user.getId(), user.getName(), user.getEmail()); + } + + public static ItemDTO.User toUserToItemDto(User user) { + return new ItemDTO.User(user.getId(), user.getName(), user.getEmail()); + } + + public static List mapToUser(Iterable users) { + List dtos = new ArrayList<>(); + for (UserDTO user : users) { + dtos.add(toUser(user)); + } + return dtos; } } diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 43303a6b5..92654603d 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -14,6 +14,16 @@ CREATE TABLE IF NOT EXISTS users CONSTRAINT EMAIL_FORMAT CHECK (email LIKE '%@%.%' AND email NOT LIKE '@%' AND email NOT LIKE '%@%@%') ); +CREATE TABLE IF NOT EXISTS requests +( + id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + description VARCHAR(1000) NOT NULL, + requester_id BIGINT NOT NULL, + created TIMESTAMP WITHOUT TIME ZONE NOT NULL, + CONSTRAINT pk_requests PRIMARY KEY (id), + CONSTRAINT requester_id_foreign_key_user_id FOREIGN KEY (requester_id) REFERENCES users (id) +); + CREATE TABLE IF NOT EXISTS items ( id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, @@ -22,7 +32,9 @@ CREATE TABLE IF NOT EXISTS items available BOOLEAN NOT NULL, owner_id BIGINT NOT NULL, request_id BIGINT, - CONSTRAINT pk_item PRIMARY KEY (id) + CONSTRAINT pk_item PRIMARY KEY (id), + CONSTRAINT owner_id_foreign_key_user_id FOREIGN KEY (owner_id) REFERENCES users (id), + CONSTRAINT request_id_foreign_key FOREIGN KEY (request_id) REFERENCES requests (id) ); CREATE TABLE IF NOT EXISTS bookings @@ -33,15 +45,8 @@ CREATE TABLE IF NOT EXISTS bookings item_id BIGINT NOT NULL, booker_id BIGINT NOT NULL, status VARCHAR(100) NOT NULL, - CONSTRAINT pk_booking PRIMARY KEY (id) -); - -CREATE TABLE IF NOT EXISTS requests -( - id BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, - description VARCHAR(1000) NOT NULL, - requester_id BIGINT NOT NULL, - CONSTRAINT pk_requests PRIMARY KEY (id) + CONSTRAINT pk_booking PRIMARY KEY (id), + CONSTRAINT item_foreign_key_booking_id FOREIGN KEY (item_id) REFERENCES items (id) ); CREATE TABLE IF NOT EXISTS comments @@ -51,5 +56,7 @@ CREATE TABLE IF NOT EXISTS comments item_id BIGINT NOT NULL, author_id BIGINT NOT NULL, created TIMESTAMP WITHOUT TIME ZONE NOT NULL, - CONSTRAINT pk_comments PRIMARY KEY (id) + CONSTRAINT pk_comments PRIMARY KEY (id), + CONSTRAINT author_id_foreign_key_user_id FOREIGN KEY (author_id) REFERENCES users (id), + CONSTRAINT item_foreign_key_comment_id FOREIGN KEY (item_id) REFERENCES items (id) ) \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/ShareItTests.java b/src/test/java/ru/practicum/shareit/ShareItTests.java index 4d79052f0..32d9bb7c1 100644 --- a/src/test/java/ru/practicum/shareit/ShareItTests.java +++ b/src/test/java/ru/practicum/shareit/ShareItTests.java @@ -1,13 +1,305 @@ package ru.practicum.shareit; +import lombok.RequiredArgsConstructor; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestExecutionListeners; +import org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener; +import ru.practicum.shareit.booking.dto.BookingDTOToReturn; +import ru.practicum.shareit.booking.service.BookingService; +import ru.practicum.shareit.exception.BadRequestException; +import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.exception.StatusBadRequestException; +import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.item.dto.ItemDTOWithBookings; +import ru.practicum.shareit.item.service.ItemService; +import ru.practicum.shareit.request.dto.RequestDTOWithItems; +import ru.practicum.shareit.request.service.RequestService; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest +@AutoConfigureTestDatabase +@RequiredArgsConstructor(onConstructor_ = {@Autowired}) +@TestExecutionListeners({DirtiesContextBeforeModesTestExecutionListener.class}) class ShareItTests { - @Test - void contextLoads() { - } + private final BookingService bookingService; + private final ItemService itemService; + private final RequestService requestService; + + @Test + void contextLoads() { + } + + @Test + void getAllOwnItemTest() { + List items = itemService.getAllByOwner(1L, null, null); + assertThat(items).isNotEmpty(); + assertThat(items.size()).isEqualTo(1); + assertThat(items.get(0).getName()).isEqualTo("Wings"); + assertThat(items.get(0).getOwner().getId()).isEqualTo(1); + } + + @Test + void getAllOwnItemNotFoundUserTest() { + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> itemService.getAllByOwner(5L, null, null)); + assertThat(exception.getMessage()).isEqualTo("Пользователь не найден"); + + } + + @Test + void getAllOwnItemFromOrSizeLessThanZeroTest() { + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> itemService.getAllByOwner(1L, -1, 0)); + + Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + exception.getMessage()); + } + + @Test + void getAllOwnItemSizeEqualToZeroTest() { + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> itemService.getAllByOwner(1L, 1, 0)); + + Assertions.assertEquals("Size не может принимать значение 0", exception.getMessage()); + } + + @Test + void getItemsForRentTest() { + List items = (List) itemService.getForRent("Fo", null, null); + assertThat(items).isNotEmpty(); + assertThat(items.size()).isEqualTo(1); + assertThat(items.get(0).getName()).isEqualTo("Fork"); + assertThat(items.get(0).getOwner().getName()).isEqualTo("Kuzya"); + items = (List) itemService.getForRent("need", 0, 2); + assertThat(items).isNotEmpty(); + assertThat(items.size()).isEqualTo(2); + } + + @Test + void getItemForRentEqualToZeroTest() { + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> itemService.getForRent("F", 0, 0)); + + Assertions.assertEquals("Size не может принимать значение 0", exception.getMessage()); + + } + + @Test + void getItemsForRentFromOrSizeLessThanZeroTest() { + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> itemService.getForRent("F", -1, 0)); + + Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + exception.getMessage()); + + } + + @Test + void getBookingByBookerStateAllTest() { + List bookings = (List) bookingService.getByBooker(3L, + null, null, null); + assertThat(bookings).isNotEmpty(); + assertThat(bookings.size()).isEqualTo(1); + assertThat(bookings.get(0).getId()).isEqualTo(2); + bookings = (List) bookingService.getByBooker(3L, "ALL", null, null); + assertThat(bookings).isNotEmpty(); + assertThat(bookings.size()).isEqualTo(1); + assertThat(bookings.get(0).getId()).isEqualTo(2); + } + + @Test + void getBookingByBookerStateCurrentTest() { + List bookings = (List) bookingService.getByBooker(3L, + "CURRENT", null, null); + assertThat(bookings).isNotEmpty(); + assertThat(bookings.size()).isEqualTo(1); + assertThat(bookings.get(0).getId()).isEqualTo(2); + } + + @Test + void getBookingByBookerStateFutureTest() { + List bookings = (List) bookingService.getByBooker(2L, + "FUTURE", null, null); + assertThat(bookings).isNotEmpty(); + assertThat(bookings.size()).isEqualTo(1); + assertThat(bookings.get(0).getId()).isEqualTo(3); + } + + @Test + void getBookingByBookerStateWaitingOrRejectedTest() { + List bookings = (List) bookingService.getByBooker(1L, + "WAITING", 0, 1); + assertThat(bookings).isNotEmpty(); + assertThat(bookings.size()).isEqualTo(1); + assertThat(bookings.get(0).getId()).isEqualTo(4); + } + + @Test + void getBookingsByBookerUnknownStatePageableTest() { + final StatusBadRequestException exception = Assertions.assertThrows( + StatusBadRequestException.class, + () -> bookingService.getByBooker(3L, "RED", 0, 1)); + + Assertions.assertEquals("Unknown state: UNSUPPORTED_STATUS", exception.getMessage()); + + } + + @Test + void getBookingsByBookerNotFoundUserTest() { + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> bookingService.getByBooker(5L, null, 0, 1)); + + Assertions.assertEquals("Для пользователя нет доступа", exception.getMessage()); + + } + + @Test + void getBookingsByBookerSizeOrPageLessZeroTest() { + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> bookingService.getByBooker(3L, null, -1, 1)); + + Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + exception.getMessage()); + + } + + @Test + void getBookingsByBookerSizeEqualZeroTest() { + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> bookingService.getByBooker(3L, null, 0, 0)); + + Assertions.assertEquals("Size не может принимать значение 0", exception.getMessage()); + + } + + @Test + void getBookingsByOwnerNotFoundUserTest() { + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> bookingService.getByOwner(8L, null, 0, 1)); + + Assertions.assertEquals("Для пользователя нет доступа", exception.getMessage()); + } + + @Test + void getBookingsByOwnerSizeOrPageLessZeroTest() { + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> bookingService.getByOwner(1L, null, -1, 1)); + + Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + exception.getMessage()); + + } + + @Test + void getBookingsByOwnerByStateAllTest() { + List bookings = (List) bookingService.getByOwner(1L, + null, 0, 1); + assertThat(bookings).isNotEmpty(); + assertThat(bookings.size()).isEqualTo(1); + assertThat(bookings.get(0).getId()).isEqualTo(2); + bookings = (List) bookingService.getByOwner(1L, "ALL", 0, 1); + assertThat(bookings).isNotEmpty(); + assertThat(bookings.size()).isEqualTo(1); + assertThat(bookings.get(0).getId()).isEqualTo(2); + } + + @Test + void getBookingsByOwnerByStatePastTest() { + List bookings = (List) bookingService.getByOwner(3L, + "PAST", 0, 1); + assertThat(bookings).isNotEmpty(); + assertThat(bookings.size()).isEqualTo(1); + assertThat(bookings.get(0).getId()).isEqualTo(1); + } + + @Test + void getBookingsByOwnerByStateCurrentTest() { + List bookings = (List) bookingService.getByOwner(1L, + "CURRENT", 0, 1); + assertThat(bookings).isNotEmpty(); + assertThat(bookings.size()).isEqualTo(1); + assertThat(bookings.get(0).getId()).isEqualTo(2); + } + + @Test + void getBookingsByOwnerByStateFutureTest() { + List bookings = (List) bookingService.getByOwner(2L, + "FUTURE", 0, 1); + assertThat(bookings).isNotEmpty(); + assertThat(bookings.size()).isEqualTo(1); + assertThat(bookings.get(0).getId()).isEqualTo(4); + } + + @Test + void getBookingsByOwnerByStateWaitingOrRejectedTest() { + List bookings = (List) bookingService.getByOwner(2L, + "WAITING", 0, 1); + assertThat(bookings).isNotEmpty(); + assertThat(bookings.size()).isEqualTo(1); + assertThat(bookings.get(0).getId()).isEqualTo(4); + } + + @Test + void getAllOwnRequestTest() { + List requests = requestService.findAllByOwner(3L); + assertThat(requests).isNotEmpty(); + assertThat(requests.size()).isEqualTo(1); + assertThat(requests.get(0).getId()).isEqualTo(3); + } + + @Test + void findAllOwnRequestsNotFoundUserTest() { + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> requestService.findAllByOwner(5L)); + + Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + } + + @Test + void findAllRequestsTest() { + List requests = requestService.findAll(1L, null, null); + assertThat(requests).isNotEmpty(); + assertThat(requests.size()).isEqualTo(4); + assertThat(requests.get(0).getId()).isEqualTo(1); + } + + @Test + void findAllRequestsSizeOrPageLessZeroTest() { + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> requestService.findAll(1L, 1, -1)); + + Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + exception.getMessage()); + } + + @Test + void findAllRequestsSizeEqualZeroTest() { + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> requestService.findAll(1L, 1, 0)); + + Assertions.assertEquals("Size не может принимать значение 0", + exception.getMessage()); + } } diff --git a/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java b/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java new file mode 100644 index 000000000..a805a1869 --- /dev/null +++ b/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java @@ -0,0 +1,227 @@ +package ru.practicum.shareit.booking; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.web.servlet.MockMvc; +import ru.practicum.shareit.booking.dto.BookingDTOToReturn; +import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.booking.model.Status; +import ru.practicum.shareit.booking.service.BookingServiceImpl; +import ru.practicum.shareit.item.mapper.ItemMapper; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.UserMapper; +import ru.practicum.shareit.user.model.User; + +import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import static org.hamcrest.Matchers.is; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@WebMvcTest(controllers = BookingController.class) +class BookingControllerTest { + + @Autowired + ObjectMapper mapper; + + @MockBean + BookingServiceImpl bookingService; + + @Autowired + private MockMvc mvc; + + private final Booking booking = new Booking(); + + private final BookingDTOToReturn bookingDto = new BookingDTOToReturn(); + private final Item item = new Item(); + private final User user = new User(); + + @Test + void addBookingControllerTest() throws Exception { + addItem(); + addBookingDto(); + + when(bookingService.add(Mockito.anyLong(), any())) + .thenReturn(bookingDto); + + mvc.perform(post("/bookings") + .header("X-Sharer-User-Id", 4L) + .content(mapper.writeValueAsString(bookingDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(bookingDto.getId()), Long.class)) + .andExpect(jsonPath("$.start", is(bookingDto.getStart().toString()))) + .andExpect(jsonPath("$.booker.id", is((int) bookingDto.getBooker().getId()))) + .andExpect(jsonPath("$.booker.name", is(bookingDto.getBooker().getName()))) + .andExpect(jsonPath("$.booker.email", is(bookingDto.getBooker().getEmail()))) + .andExpect(jsonPath("$.end", is(bookingDto.getEnd().toString()))) + .andExpect(jsonPath("$.item.id", is((int) bookingDto.getItem().getId()))) + .andExpect(jsonPath("$.item.name", is(bookingDto.getItem().getName()))) + .andExpect(jsonPath("$.item.description", is(bookingDto.getItem().getDescription()))) + .andExpect(jsonPath("$.status", is(bookingDto.getStatus().toString()))); + + } + + @Test + void updateStatusBookingControllerTest() throws Exception { + addItem(); + addBookingDto(); + + when(bookingService.update(Mockito.any(), Mockito.anyLong(), Mockito.anyBoolean())) + .thenReturn(bookingDto); + + mvc.perform(patch("/bookings/2") + .header("X-Sharer-User-Id", 1L) + .param("approved", String.valueOf(true)) + .content(mapper.writeValueAsString(bookingDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(bookingDto.getId()), Long.class)) + .andExpect(jsonPath("$.start", is(bookingDto.getStart().toString()))) + .andExpect(jsonPath("$.booker.id", is((int) bookingDto.getBooker().getId()))) + .andExpect(jsonPath("$.booker.name", is(bookingDto.getBooker().getName()))) + .andExpect(jsonPath("$.booker.email", is(bookingDto.getBooker().getEmail()))) + .andExpect(jsonPath("$.end", is(bookingDto.getEnd().toString()))) + .andExpect(jsonPath("$.item.id", is((int) bookingDto.getItem().getId()))) + .andExpect(jsonPath("$.item.name", is(bookingDto.getItem().getName()))) + .andExpect(jsonPath("$.item.description", is(bookingDto.getItem().getDescription()))) + .andExpect(jsonPath("$.status", is(bookingDto.getStatus().toString()))); + } + + @Test + void getBookingControllerTest() throws Exception { + addItem(); + addBookingDto(); + + when(bookingService.get(Mockito.anyLong(), Mockito.anyLong())) + .thenReturn(bookingDto); + + mvc.perform(get("/bookings/2") + .header("X-Sharer-User-Id", 1L) + .content(mapper.writeValueAsString(bookingDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(bookingDto.getId()), Long.class)) + .andExpect(jsonPath("$.start", is(bookingDto.getStart().toString()))) + .andExpect(jsonPath("$.booker.id", is((int) bookingDto.getBooker().getId()))) + .andExpect(jsonPath("$.booker.name", is(bookingDto.getBooker().getName()))) + .andExpect(jsonPath("$.booker.email", is(bookingDto.getBooker().getEmail()))) + .andExpect(jsonPath("$.end", is(bookingDto.getEnd().toString()))) + .andExpect(jsonPath("$.item.id", is((int) bookingDto.getItem().getId()))) + .andExpect(jsonPath("$.item.name", is(bookingDto.getItem().getName()))) + .andExpect(jsonPath("$.item.description", is(bookingDto.getItem().getDescription()))) + .andExpect(jsonPath("$.status", is(bookingDto.getStatus().toString()))); + } + + @Test + void findBookingByBookerControllerTest() throws Exception { + addItem(); + addBookingDto(); + List bookings = new ArrayList<>(); + bookings.add(bookingDto); + + when(bookingService.getByBooker(Mockito.anyLong(), Mockito.anyString(), any(), any())) + .thenReturn(bookings); + + mvc.perform(get("/bookings") + .header("X-Sharer-User-Id", 4L) + .param("state", "ALL") + .content(mapper.writeValueAsString(bookingDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].id", is(bookingDto.getId()), Long.class)) + .andExpect(jsonPath("$[0].start", is(bookingDto.getStart().toString()))) + .andExpect(jsonPath("$[0].booker.id", is((int) bookingDto.getBooker().getId()))) + .andExpect(jsonPath("$[0].booker.name", is(bookingDto.getBooker().getName()))) + .andExpect(jsonPath("$[0].booker.email", is(bookingDto.getBooker().getEmail()))) + .andExpect(jsonPath("$[0].end", is(bookingDto.getEnd().toString()))) + .andExpect(jsonPath("$[0].item.id", is((int) bookingDto.getItem().getId()))) + .andExpect(jsonPath("$[0].item.name", is(bookingDto.getItem().getName()))) + .andExpect(jsonPath("$[0].item.description", is(bookingDto.getItem().getDescription()))) + .andExpect(jsonPath("$[0].status", is(bookingDto.getStatus().toString()))); + } + + @Test + void findBookingByOwnerControllerTest() throws Exception { + addItem(); + addBookingDto(); + List bookings = new ArrayList<>(); + bookings.add(bookingDto); + + when(bookingService.getByOwner(Mockito.anyLong(), Mockito.anyString(), any(), any())) + .thenReturn(bookings); + + mvc.perform(get("/bookings/owner") + .header("X-Sharer-User-Id", 1L) + .param("state", "ALL") + .content(mapper.writeValueAsString(bookingDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].id", is(bookingDto.getId()), Long.class)) + .andExpect(jsonPath("$[0].start", is(bookingDto.getStart().toString()))) + .andExpect(jsonPath("$[0].booker.id", is((int) bookingDto.getBooker().getId()))) + .andExpect(jsonPath("$[0].booker.name", is(bookingDto.getBooker().getName()))) + .andExpect(jsonPath("$[0].booker.email", is(bookingDto.getBooker().getEmail()))) + .andExpect(jsonPath("$[0].end", is(bookingDto.getEnd().toString()))) + .andExpect(jsonPath("$[0].item.id", is((int) bookingDto.getItem().getId()))) + .andExpect(jsonPath("$[0].item.name", is(bookingDto.getItem().getName()))) + .andExpect(jsonPath("$[0].item.description", is(bookingDto.getItem().getDescription()))) + .andExpect(jsonPath("$[0].status", is(bookingDto.getStatus().toString()))); + } + + private void addItem() { + addUser(); + item.setId(1L); + item.setName("Fork"); + item.setOwner(user); + item.setAvailable(true); + item.setDescription("Designed for food"); + } + + private void addUser() { + user.setId(1L); + user.setName("Buffy"); + user.setEmail("buffy@vampire.com"); + } + + private void addBookingDto() { + User booker = new User(); + booker.setId(4L); + booker.setName("Katya"); + booker.setEmail("katya@katya.com"); + bookingDto.setId(2L); + bookingDto.setItem(ItemMapper.toItemToBookingDTO(item)); + bookingDto.setStatus(Status.WAITING); + bookingDto.setBooker(UserMapper.toUserToBookingDTO(booker)); + String date = "2023-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + bookingDto.setStart(localdatetime); + date = "2023-11-26T18:08:54"; + localdatetime = LocalDateTime.parse(date); + bookingDto.setEnd(localdatetime); + } +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/booking/BookingRepositoryTest.java b/src/test/java/ru/practicum/shareit/booking/BookingRepositoryTest.java new file mode 100644 index 000000000..a0ce5405f --- /dev/null +++ b/src/test/java/ru/practicum/shareit/booking/BookingRepositoryTest.java @@ -0,0 +1,474 @@ +package ru.practicum.shareit.booking; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.test.annotation.DirtiesContext; +import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.booking.model.Status; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.request.model.ItemRequest; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +class BookingRepositoryTest { + + @Autowired + private TestEntityManager em; + + @Autowired + private BookingRepository bookingRepository; + + private final User user = new User(); + private final Item item = new Item(); + private final ItemRequest request = new ItemRequest(); + private final Booking bookingOne = new Booking(); + private final Booking bookingTwo = new Booking(); + private final List bookingsPersist = new ArrayList<>(); + + @Test + void findByItemOrderByStartDescTest() { + addItem(); + addBookingOne(); + addUser(); + addBookingTwo(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + booking = em.persist(bookingTwo); + bookingsPersist.add(booking); + + List bookings = bookingRepository.findByItemOrderByStartDesc(item); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void findByBookerAndStatusOrderByStartDescTest() { + addItem(); + addBookingOne(); + addUser(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + + List bookings = bookingRepository.findByBookerAndStatusOrderByStartDesc(bookingOne.getBooker(), + Status.WAITING); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void testFindByBookerAndStatusOrderByStartDesc() { + addItem(); + addBookingOne(); + addUser(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + Pageable pageable = PageRequest.of(0, 1); + + Page bookingsPage = bookingRepository.findByBookerAndStatusOrderByStartDesc(bookingOne.getBooker(), + Status.WAITING, pageable); + List bookings = bookingsPage.getContent(); + assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void findByBookerOrderByStartDescTest() { + addItem(); + addBookingOne(); + addUser(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + + List bookings = bookingRepository.findByBookerOrderByStartDesc(bookingOne.getBooker()); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void testFindByBookerOrderByStartDesc() { + addItem(); + addBookingOne(); + addUser(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + Pageable pageable = PageRequest.of(0, 1); + + Page bookingsPage = bookingRepository.findByBookerOrderByStartDesc(bookingOne.getBooker(), + pageable); + List bookings = bookingsPage.getContent(); + assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void findByBookerAndStartAfterOrderByStartDesc() { + addItem(); + addBookingOne(); + addUser(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + + List bookings = bookingRepository.findByBookerAndStartAfterOrderByStartDesc(bookingOne.getBooker(), + LocalDateTime.now()); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void testFindByBookerAndStartAfterOrderByStartDesc() { + addItem(); + addBookingOne(); + addUser(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + Pageable pageable = PageRequest.of(0, 1); + + Page bookingsPage = bookingRepository.findByBookerAndStartAfterOrderByStartDesc(bookingOne.getBooker(), + LocalDateTime.now(), pageable); + List bookings = bookingsPage.getContent(); + assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void findByBookerAndStartBeforeAndEndAfterOrderByStartDescTest() { + addItem(); + addBookingOne(); + String date = "2021-11-21T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + bookingOne.setStart(localdatetime); + addUser(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + + List bookings = bookingRepository.findByBookerAndStartBeforeAndEndAfterOrderByStartDesc( + bookingOne.getBooker(), LocalDateTime.now(), LocalDateTime.now()); + assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void testFindByBookerAndStartBeforeAndEndAfterOrderByStartDesc() { + addItem(); + addBookingOne(); + String date = "2021-11-21T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + bookingOne.setStart(localdatetime); + addUser(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + + Pageable pageable = PageRequest.of(0, 1); + + Page bookingsPage = bookingRepository.findByBookerAndStartBeforeAndEndAfterOrderByStartDesc( + bookingOne.getBooker(), LocalDateTime.now(), LocalDateTime.now(), pageable); + + List bookings = bookingsPage.getContent(); + assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void findByBookerAndStartBeforeAndEndBeforeOrderByStartDescTest() { + addItem(); + addBookingOne(); + String date = "2021-11-21T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + bookingOne.setStart(localdatetime); + date = "2021-11-23T18:08:54"; + localdatetime = LocalDateTime.parse(date); + bookingOne.setEnd(localdatetime); + addUser(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + + List bookings = bookingRepository.findByBookerAndStartBeforeAndEndBeforeOrderByStartDesc( + bookingOne.getBooker(), LocalDateTime.now(), LocalDateTime.now()); + assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void testFindByBookerAndStartBeforeAndEndBeforeOrderByStartDesc() { + addItem(); + addBookingOne(); + String date = "2021-11-21T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + bookingOne.setStart(localdatetime); + date = "2021-11-23T18:08:54"; + localdatetime = LocalDateTime.parse(date); + bookingOne.setEnd(localdatetime); + addUser(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + + Pageable pageable = PageRequest.of(0, 1); + + Page bookingsPage = bookingRepository.findByBookerAndStartBeforeAndEndBeforeOrderByStartDesc( + bookingOne.getBooker(), LocalDateTime.now(), LocalDateTime.now(), pageable); + + List bookings = bookingsPage.getContent(); + assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void findByItemAndBookerAndStartBeforeAndEndBeforeTest() { + addItem(); + addBookingOne(); + String date = "2021-11-21T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + bookingOne.setStart(localdatetime); + date = "2021-11-23T18:08:54"; + localdatetime = LocalDateTime.parse(date); + bookingOne.setEnd(localdatetime); + addUser(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + + List bookings = bookingRepository.findByItemAndBookerAndStartBeforeAndEndBefore(item, + bookingOne.getBooker(), LocalDateTime.now(), LocalDateTime.now()); + assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void findByBookingForOwnerWithPastTest() { + addUser(); + addItemWithoutId(); + em.persist(item); + String date = "2021-11-21T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + addBookingOne(); + bookingOne.setStart(localdatetime); + date = "2021-11-25T18:08:54"; + localdatetime = LocalDateTime.parse(date); + bookingOne.setEnd(localdatetime); + addBookingTwo(); + date = "2022-10-25T18:08:54"; + localdatetime = LocalDateTime.parse(date); + bookingTwo.setStart(localdatetime); + date = "2022-10-27T18:08:54"; + localdatetime = LocalDateTime.parse(date); + bookingTwo.setEnd(localdatetime); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + booking = em.persist(bookingTwo); + bookingsPersist.add(booking); + + List bookings = bookingRepository.findByOwnerAndPast(1L, LocalDateTime.now()); + assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); + assertThat(bookingsPersist.get(1).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void findByBookingForOwnerWithPastWithPageableTest() { + Pageable pageable = PageRequest.of(0, 2); + addUser(); + addItemWithoutId(); + em.persist(item); + String date = "2021-11-21T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + addBookingOne(); + bookingOne.setStart(localdatetime); + date = "2021-11-25T18:08:54"; + localdatetime = LocalDateTime.parse(date); + bookingOne.setEnd(localdatetime); + addBookingTwo(); + date = "2022-10-25T18:08:54"; + localdatetime = LocalDateTime.parse(date); + bookingTwo.setStart(localdatetime); + date = "2022-10-27T18:08:54"; + localdatetime = LocalDateTime.parse(date); + bookingTwo.setEnd(localdatetime); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + booking = em.persist(bookingTwo); + bookingsPersist.add(booking); + + List bookings = bookingRepository.findByOwnerAndPast(1L, LocalDateTime.now(), pageable); + assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); + assertThat(bookingsPersist.get(1).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void findByBookingForOwnerWithFutureTest() { + addUser(); + addItemWithoutId(); + em.persist(item); + addBookingOne(); + addBookingTwo(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + booking = em.persist(bookingTwo); + bookingsPersist.add(booking); + + List bookings = bookingRepository.findByUserAndFuture(1L, LocalDateTime.now()); + assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void findByBookingForOwnerWithFutureWithPageableTest() { + Pageable pageable = PageRequest.of(0, 2); + addUser(); + addItemWithoutId(); + em.persist(item); + addBookingOne(); + addBookingTwo(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + booking = em.persist(bookingTwo); + bookingsPersist.add(booking); + + List bookings = bookingRepository.findByUserAndFuture(1L, LocalDateTime.now(), pageable); + assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void findByBookingForOwnerWithAllTest() { + addUser(); + addItemWithoutId(); + em.persist(item); + addBookingOne(); + addBookingTwo(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + booking = em.persist(bookingTwo); + bookingsPersist.add(booking); + + List bookings = bookingRepository.findByOwnerAll(1L); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void findByBookingForOwnerWithAllWithPageableTest() { + Pageable pageable = PageRequest.of(0, 2); + addUser(); + addItemWithoutId(); + em.persist(item); + addBookingOne(); + addBookingTwo(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + booking = em.persist(bookingTwo); + bookingsPersist.add(booking); + + List bookings = bookingRepository.findByOwnerAll(1L, pageable); + assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void findByBookingForOwnerWithWaitingOrRejectedTest() { + addUser(); + addItemWithoutId(); + em.persist(item); + addBookingOne(); + addBookingTwo(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + booking = em.persist(bookingTwo); + bookingsPersist.add(booking); + + List bookings = bookingRepository.findByOwnerAndByStatus(1L, Status.WAITING); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + @Test + void findByBookingForOwnerWithWaitingOrRejectedWithPageableTest() { + Pageable pageable = PageRequest.of(0, 2); + addUser(); + addItemWithoutId(); + em.persist(item); + addBookingOne(); + addBookingTwo(); + Booking booking = em.persist(bookingOne); + bookingsPersist.add(booking); + booking = em.persist(bookingTwo); + bookingsPersist.add(booking); + + List bookings = bookingRepository.findByOwnerAndByStatus(1L, "WAITING", + pageable); + assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); + assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + } + + private void addItem() { + addRequest(); + item.setId(1); + item.setName("Fork"); + item.setOwner(user); + item.setAvailable(true); + item.setDescription("Designed for food"); + item.setRequestId(request); + } + + private void addItemWithoutId() { + addRequest(); + item.setName("Fork"); + item.setOwner(user); + item.setAvailable(true); + item.setDescription("Designed for food"); + item.setRequestId(request); + } + + private void addUser() { + user.setId(1L); + user.setName("Buffy"); + user.setEmail("buffy@vampire.com"); + } + + private void addRequest() { + User requester = new User(); + requester.setId(2L); + requester.setName("Kat"); + requester.setEmail("Kat@kat.com"); + request.setId(1L); + request.setRequester(requester); + request.setDescription("I need a fork to eat"); + request.setCreated(LocalDateTime.now()); + } + + private void addBookingOne() { + User user1 = new User(); + user1.setId(2L); + user1.setName("Cat"); + user1.setEmail("cat@cat.com"); + bookingOne.setBooker(user1); + bookingOne.setItem(item); + String date = "2024-11-20T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + bookingOne.setStart(localdatetime); + date = "2024-11-25T18:08:54"; + localdatetime = LocalDateTime.parse(date); + bookingOne.setEnd(localdatetime); + bookingOne.setStatus(Status.WAITING); + } + + private void addBookingTwo() { + User booker = new User(); + booker.setId(5L); + booker.setName("Katya"); + booker.setEmail("katya@katya.com"); + bookingTwo.setStatus(Status.WAITING); + String date = "2023-11-21T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + bookingTwo.setStart(localdatetime); + date = "2023-11-22T18:08:54"; + localdatetime = LocalDateTime.parse(date); + bookingTwo.setEnd(localdatetime); + bookingTwo.setBooker(booker); + bookingTwo.setItem(item); + } + +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/booking/dto/BookingDtoTest.java b/src/test/java/ru/practicum/shareit/booking/dto/BookingDtoTest.java new file mode 100644 index 000000000..713847265 --- /dev/null +++ b/src/test/java/ru/practicum/shareit/booking/dto/BookingDtoTest.java @@ -0,0 +1,41 @@ +package ru.practicum.shareit.booking.dto; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.json.JsonTest; +import org.springframework.boot.test.json.JacksonTester; +import org.springframework.boot.test.json.JsonContent; +import ru.practicum.shareit.booking.model.Status; + +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; + +@JsonTest +class BookingDtoTest { + @Autowired + private JacksonTester json; + + @Test + void testBookingDto() throws Exception { + String date = "2017-10-19T23:50:50"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + BookingDTO bookingDto = new BookingDTO(); + bookingDto.setId(1); + bookingDto.setItemName("Sword"); + bookingDto.setStatus(Status.WAITING); + bookingDto.setStart(localdatetime); + localdatetime = LocalDateTime.parse(date); + bookingDto.setEnd(localdatetime); + bookingDto.setBookerId(1L); + + JsonContent result = json.write(bookingDto); + + assertThat(result).extractingJsonPathNumberValue("$.id").isEqualTo(1); + assertThat(result).extractingJsonPathStringValue("$.itemName").isEqualTo("Sword"); + assertThat(result).extractingJsonPathValue("$.status").isEqualTo("WAITING"); + assertThat(result).extractingJsonPathValue("$.start").isEqualTo("2017-10-19T23:50:50"); + assertThat(result).extractingJsonPathValue("$.end").isEqualTo("2017-10-19T23:50:50"); + } + +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java b/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java new file mode 100644 index 000000000..5b69b4f81 --- /dev/null +++ b/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java @@ -0,0 +1,1441 @@ +package ru.practicum.shareit.booking.service; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.test.annotation.DirtiesContext; +import ru.practicum.shareit.booking.BookingMapper; +import ru.practicum.shareit.booking.BookingRepository; +import ru.practicum.shareit.booking.dto.BookingDTOToReturn; +import ru.practicum.shareit.booking.model.Status; +import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.exception.BadRequestException; +import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.exception.StatusBadRequestException; +import ru.practicum.shareit.item.ItemRepository; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.request.model.ItemRequest; +import ru.practicum.shareit.user.UserRepository; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@ExtendWith(MockitoExtension.class) +class BookingServiceTest { + + @InjectMocks + BookingServiceImpl bookingService; + + @Mock + ItemRepository itemRepository; + + @Mock + UserRepository userRepository; + + @Mock + BookingRepository bookingRepository; + + private final Booking booking = new Booking(); + private final Item item = new Item(); + private final User user = new User(); + private final ItemRequest request = new ItemRequest(); + + @Test + void addBookingTest() { + addBooking(); + addRequest(); + addItem(); + addUser(); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(item)); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.save(any())) + .thenReturn(booking); + + Optional bookingDto = Optional.ofNullable(bookingService.add(3L, + BookingMapper.toBookingDto(booking))); + + assertThat(bookingDto) + .isPresent() + .hasValueSatisfying(addBookingTest -> { + assertThat(addBookingTest).hasFieldOrPropertyWithValue("id", booking.getId()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("booker", booking.getBooker()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("status", booking.getStatus()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("start", booking.getStart()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("end", booking.getEnd()); + } + ); + } + + @Test + void addBookingUserNotFoundTest() { + addBooking(); + addUser(); + addItem(); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(item)); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.empty()); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> bookingService.add(2L, BookingMapper.toBookingDto(booking))); + + Assertions.assertEquals("Item not found", exception.getMessage()); + } + + @Test + void addBookingGetAvailableFalseTest() { + addBooking(); + addUser(); + addItem(); + item.setAvailable(false); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(item)); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> bookingService.add(2L, BookingMapper.toBookingDto(booking))); + + Assertions.assertEquals("You can not book this item", exception.getMessage()); + } + + @Test + void addBookingItemNotFoundTest() { + addBooking(); + addUser(); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.empty()); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> bookingService.add(2L, BookingMapper.toBookingDto(booking))); + + Assertions.assertEquals("User not found", exception.getMessage()); + } + + @Test + void addBookingOwnerEqualsBookerTest() { + addBooking(); + addUser(); + addItem(); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(item)); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> bookingService.add(1L, BookingMapper.toBookingDto(booking))); + + Assertions.assertEquals("You cannot book your item", exception.getMessage()); + } + + @Test + void addBookingNotValidEndTest() { + addBooking(); + addUser(); + addItem(); + String date = "2017-10-19T23:50:50"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setEnd(localdatetime); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(item)); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> bookingService.add(2L, BookingMapper.toBookingDto(booking))); + + Assertions.assertEquals("Wrong date", + exception.getMessage()); + } + + @Test + void addBookingNotValidStartTest() { + addBooking(); + addUser(); + addItem(); + String date = "2017-10-19T23:50:50"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(item)); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> bookingService.add(2L, BookingMapper.toBookingDto(booking))); + + Assertions.assertEquals("Wrong date", + exception.getMessage()); + } + + @Test + void updateStatusBookingApprovedTest() { + addUser(); + addItem(); + addBooking(); + + Mockito + .when(bookingRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(booking)); + + Booking booking1 = booking; + + Mockito + .when(bookingRepository.save(booking1)) + .thenReturn(booking1); + + + Optional bookingDto = Optional.ofNullable(bookingService + .update(booking1.getItem().getOwner().getId(), + booking1.getId(), true)); + + assertThat(bookingDto) + .isPresent() + .hasValueSatisfying(addBookingTest -> { + assertThat(addBookingTest).hasFieldOrPropertyWithValue("id", booking.getId()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("booker", booking.getBooker()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("status", booking.getStatus()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("start", booking.getStart()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("end", booking.getEnd()); + } + ); + } + + @Test + void updateStatusBookingRejectedTest() { + addUser(); + addItem(); + addBooking(); + + Mockito + .when(bookingRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(booking)); + + Booking booking1 = booking; + + Mockito + .when(bookingRepository.save(booking1)) + .thenReturn(booking1); + + + Optional bookingDto = Optional.ofNullable(bookingService + .update(booking1.getItem().getOwner().getId(), + booking1.getId(), false)); + + assertThat(bookingDto) + .isPresent() + .hasValueSatisfying(addBookingTest -> { + assertThat(addBookingTest).hasFieldOrPropertyWithValue("id", booking.getId()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("booker", booking.getBooker()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("status", booking.getStatus()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("start", booking.getStart()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("end", booking.getEnd()); + } + ); + } + + @Test + void updateStatusBookingNotFoundTest() { + Mockito + .when(bookingRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.empty()); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> bookingService.update(1L, 2L, false)); + + Assertions.assertEquals("Отсутсвуют данные о бронировании", exception.getMessage()); + + } + + @Test + void updateStatusNoAccessForUserTest() { + addUser(); + addItem(); + addBooking(); + + Mockito + .when(bookingRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(booking)); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> bookingService.update(3L, 1L, false)); + + Assertions.assertEquals("No rights", exception.getMessage()); + + } + + @Test + void updateStatusBookingBadRequestTest() { + addUser(); + addItem(); + addBooking(); + booking.setStatus(Status.APPROVED); + + Mockito + .when(bookingRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(booking)); + + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> bookingService.update(1L, 1L, false)); + + Assertions.assertEquals("Статус бронирования уже изменен", exception.getMessage()); + + } + + @Test + void getBookingTest() { + addUser(); + addItem(); + addBooking(); + + Mockito + .when(bookingRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(booking)); + + Optional bookingDto = Optional.ofNullable(bookingService.get(1L, 1L)); + + assertThat(bookingDto) + .isPresent() + .hasValueSatisfying(addBookingTest -> { + assertThat(addBookingTest).hasFieldOrPropertyWithValue("id", booking.getId()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("booker", booking.getBooker()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("status", booking.getStatus()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("start", booking.getStart()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("end", booking.getEnd()); + } + ); + } + + @Test + void getBookingNotFoundUserTest() { + addUser(); + addItem(); + addBooking(); + + Mockito + .when(bookingRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(booking)); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> bookingService.get(5L, 1L)); + + Assertions.assertEquals("Отсутствует доступ для пользователя", exception.getMessage()); + } + + @Test + void getBookingNotFoundTest() { + Mockito + .when(bookingRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.empty()); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> bookingService.get(1L, 1L)); + + Assertions.assertEquals("Запрос на бронирование не найден", exception.getMessage()); + } + + @Test + void getBookingByBookerALLTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByBookerOrderByStartDesc(any())) + .thenReturn(bookingList); + + List bookings = bookingService.getByBooker(3L, "ALL", + null, null); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByBookerALLWithPageableTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + Page page = new PageImpl<>(bookingList); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByBookerOrderByStartDesc(any(), any())) + .thenReturn(page); + + List bookings = bookingService.getByBooker(3L, "ALL", 0, 1); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByBookerTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByBookerOrderByStartDesc(any())) + .thenReturn(bookingList); + + List bookings = bookingService.getByBooker(3L, null, + null, null); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByBookerWithPageableTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + Page page = new PageImpl<>(bookingList); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByBookerOrderByStartDesc(any(), any())) + .thenReturn(page); + + List bookings = bookingService.getByBooker(3L, null, 0, 1); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByBookerCURRENTTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByBookerAndStartBeforeAndEndAfterOrderByStartDesc(any(), any(), any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByBooker(3L, "CURRENT", + null, null); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByBookerCURRENTWithPageableTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + Page page = new PageImpl<>(bookingList); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByBookerAndStartBeforeAndEndAfterOrderByStartDesc(any(), any(), + any(), any())) + .thenReturn(page); + + Collection bookings = bookingService.getByBooker(3L, "CURRENT", 0, 1); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByBookerPASTTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByBookerAndStartBeforeAndEndBeforeOrderByStartDesc(any(), any(), any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByBooker(3L, "PAST", + null, null); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByBookerPASTWithPageableTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + Page page = new PageImpl<>(bookingList); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByBookerAndStartBeforeAndEndBeforeOrderByStartDesc(any(), any(), + any(), any())) + .thenReturn(page); + + Collection bookings = bookingService.getByBooker(3L, "PAST", 0, 1); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByBookerFUTURETest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByBookerAndStartAfterOrderByStartDesc(any(), any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByBooker(3L, "FUTURE", + null, null); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByBookerFUTUREWithPageableTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + Page page = new PageImpl<>(bookingList); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByBookerAndStartAfterOrderByStartDesc(any(), any(), any())) + .thenReturn(page); + + Collection bookings = bookingService.getByBooker(3L, "FUTURE", 0, 1); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByBookerWAITINGTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByBookerAndStatusOrderByStartDesc(any(), any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByBooker(3L, "WAITING", + null, null); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByBookerWAITINGWithPageableTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + Page page = new PageImpl<>(bookingList); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByBookerAndStatusOrderByStartDesc(any(), any(), any())) + .thenReturn(page); + + Collection bookings = bookingService.getByBooker(3L, "WAITING", 0, 1); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByBookerREJECTEDTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByBookerAndStatusOrderByStartDesc(any(), any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByBooker(3L, "REJECTED", + null, null); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByBookerRejectedWithPageableTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + Page page = new PageImpl<>(bookingList); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByBookerAndStatusOrderByStartDesc(any(), any(), any())) + .thenReturn(page); + + Collection bookings = bookingService.getByBooker(3L, "REJECTED", 0, 1); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByBookerUnknownStatePageableTest() { + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + final StatusBadRequestException exception = Assertions.assertThrows( + StatusBadRequestException.class, + () -> bookingService.getByBooker(3L, "RED", 0, 1)); + + Assertions.assertEquals("Unknown state: UNSUPPORTED_STATUS", exception.getMessage()); + + } + + @Test + void getBookingByBookerUnknownStateTest() { + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> bookingService.getByBooker(3L, "Rjj", + null, null)); + + Assertions.assertEquals("Unknown state: UNSUPPORTED_STATUS", exception.getMessage()); + + } + + @Test + void getBookingByBookerNotFoundUserTest() { + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.empty()); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> bookingService.getByBooker(3L, null, 0, 1)); + + Assertions.assertEquals("Для пользователя нет доступа", exception.getMessage()); + + } + + @Test + void getBookingByBookerSizeOrPageLessZeroTest() { + addUser(); + addItem(); + addBooking(); + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> bookingService.getByBooker(3L, null, -1, 1)); + + Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + exception.getMessage()); + + } + + @Test + void getBookingByBookerSizeEqualZeroTest() { + addUser(); + addItem(); + addBooking(); + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> bookingService.getByBooker(3L, null, 0, 0)); + + Assertions.assertEquals("Size не может принимать значение 0", exception.getMessage()); + + } + + @Test + void getBookingByOwnerNotFoundUserTest() { + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.empty()); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> bookingService.getByOwner(1L, null, 0, 1)); + + Assertions.assertEquals("Для пользователя нет доступа", exception.getMessage()); + } + + @Test + void getBookingByOwnerSizeOrPageLessZeroTest() { + addUser(); + addItem(); + addBooking(); + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> bookingService.getByOwner(1L, null, -1, 1)); + + Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + exception.getMessage()); + + } + + @Test + void getBookingByOwnerSizeEqualZeroTest() { + addUser(); + addItem(); + addBooking(); + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> bookingService.getByOwner(1L, null, 0, 0)); + + Assertions.assertEquals("Size не может принимать значение 0", exception.getMessage()); + + } + + @Test + void getBookingByOwnerALLTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByOwnerAll(any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByOwner(1L, "ALL", + null, null); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByOwnerALLWithPageableTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByOwnerAll(any(), any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByOwner(1L, "ALL", 0, 1); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + + @Test + void getBookingByOwnerTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByOwnerAll(any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByOwner(1L, null, + null, null); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByOwnerWithPageableTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByOwnerAll(any(), any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByOwner(1L, null, 0, 1); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByOwnerCURRENTTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByOwnerAndCurrent(any(), any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByOwner(1L, "CURRENT", + null, null); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByOwnerCURRENTWithPageableTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByOwnerAndCurrent(any(), + any(), any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByOwner(1L, "CURRENT", 0, + 1); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + + @Test + void getBookingByOwnerPASTTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByOwnerAndPast(any(), any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByOwner(1L, "PAST", + null, null); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByOwnerPASTWithPageableTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByOwnerAndPast(any(), any(), any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByOwner(1L, "PAST", 0, 1); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByOwnerFUTURETest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByUserAndFuture(any(), any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByOwner(1L, "FUTURE", + null, null); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByOwnerFUTUREWithPageableTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByUserAndFuture(any(), any(), any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByOwner(1L, "FUTURE", 0, 1); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByOwnerWAITINGTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByOwnerAndByStatus(any(), any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByOwner(1L, "WAITING", + null, null); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByOwnerWAITINGWithPageableTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByOwnerAndByStatus(any(), any(), any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByOwner(1L, "WAITING", 0, 1); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByOwnerREJECTEDTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByOwnerAndByStatus(any(), any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByOwner(1L, "REJECTED", + null, null); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByOwnerRejectedWithPageableTest() { + addUser(); + addItem(); + addBooking(); + List bookingList = new ArrayList<>(); + bookingList.add(booking); + booking.setId(2L); + String date = "2021-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + bookingList.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + Mockito + .when(bookingRepository.findByOwnerAndByStatus(any(), any(), any())) + .thenReturn(bookingList); + + Collection bookings = bookingService.getByOwner(1L, "REJECTED", 0, 1); + List bookings1 = List.copyOf(bookings); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings1.size()); + + } + + @Test + void getBookingByOwnerUnknownStatePageableTest() { + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + final StatusBadRequestException exception = Assertions.assertThrows( + StatusBadRequestException.class, + () -> bookingService.getByOwner(1L, "RED", 0, 1)); + + Assertions.assertEquals("Unknown state: UNSUPPORTED_STATUS", exception.getMessage()); + + } + + @Test + void getBookingByOwnerUnknownStateTest() { + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + final StatusBadRequestException exception = Assertions.assertThrows( + StatusBadRequestException.class, + () -> bookingService.getByOwner(1L, "Rjj", + null, null)); + + Assertions.assertEquals("Unknown state: UNSUPPORTED_STATUS", exception.getMessage()); + + } + + private void addItem() { + addUser(); + item.setId(1L); + item.setName("Fork"); + item.setOwner(user); + item.setAvailable(true); + item.setDescription("Designed for food"); + } + + private void addUser() { + user.setId(1L); + user.setName("Buffy"); + user.setEmail("buffy@vampire.com"); + } + + private void addRequest() { + User requestor = new User(); + requestor.setId(2L); + requestor.setName("Leo"); + requestor.setEmail("leo@angel.com"); + request.setId(1L); + request.setRequester(requestor); + request.setDescription("I need a fork to eat"); + request.setCreated(LocalDateTime.now()); + } + + private void addBooking() { + User booker = new User(); + booker.setId(3L); + booker.setName("Katya"); + booker.setEmail("katya@katya.com"); + booking.setId(1L); + booking.setItem(item); + booking.setStatus(Status.WAITING); + String date = "2023-11-24T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setStart(localdatetime); + date = "2023-11-26T18:08:54"; + localdatetime = LocalDateTime.parse(date); + booking.setEnd(localdatetime); + booking.setBooker(booker); + } + +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/item/CommentRepositoryTest.java b/src/test/java/ru/practicum/shareit/item/CommentRepositoryTest.java new file mode 100644 index 000000000..0f40a2c90 --- /dev/null +++ b/src/test/java/ru/practicum/shareit/item/CommentRepositoryTest.java @@ -0,0 +1,69 @@ +package ru.practicum.shareit.item; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; +import org.springframework.test.annotation.DirtiesContext; +import ru.practicum.shareit.item.model.Comment; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +class CommentRepositoryTest { + @Autowired + private TestEntityManager em; + + @Autowired + private CommentRepository commentRepository; + + private final Comment comment = new Comment(); + private final User user = new User(); + + private final Item item = new Item(); + + @Test + public void findByItemJpaTest() { + addComment(); + Comment commentPersist = em.persist(comment); + List comment2 = commentRepository.findAllByItem(item); + addUser(); + assertThat(commentPersist).isEqualTo(comment2.get(1)); + assertThat(commentPersist.getId()).isEqualTo(comment2.get(1).getId()); + + } + + private void addComment() { + addUser(); + addItem(); + comment.setAuthor(user); + comment.setText("I need a fork"); + comment.setItem(item); + comment.setCreated(LocalDateTime.now()); + } + + private void addItem() { + User user1 = new User(); + user1.setId(2L); + user1.setName("Cat"); + user1.setEmail("leo@cat.com"); + item.setId(1L); + item.setName("Fork"); + item.setOwner(user1); + item.setAvailable(true); + item.setDescription("Designed for food"); + } + + private void addUser() { + user.setId(1L); + user.setName("Leo"); + user.setEmail("leo@angel.com"); + } + +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/item/ItemControllerTest.java b/src/test/java/ru/practicum/shareit/item/ItemControllerTest.java new file mode 100644 index 000000000..8b6c88f9b --- /dev/null +++ b/src/test/java/ru/practicum/shareit/item/ItemControllerTest.java @@ -0,0 +1,312 @@ +package ru.practicum.shareit.item; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.result.MockMvcResultHandlers; +import ru.practicum.shareit.booking.dto.BookingDTOForItem; +import ru.practicum.shareit.exception.BadRequestException; +import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.item.dto.ItemDTOWithBookings; +import ru.practicum.shareit.item.dto.CommentDTO; +import ru.practicum.shareit.item.model.Comment; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.item.service.ItemServiceImpl; +import ru.practicum.shareit.user.UserMapper; +import ru.practicum.shareit.user.model.User; + +import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@WebMvcTest(controllers = ItemController.class) +class ItemControllerTest { + + @Autowired + ObjectMapper mapper; + + @MockBean + ItemServiceImpl itemService; + + @Autowired + private MockMvc mvc; + + private final ItemDTO itemDto = new ItemDTO(); + private final Item item = new Item(); + private final User user = new User(); + private final Comment comment = new Comment(); + private final ItemDTOWithBookings itemDtoWithBooking = new ItemDTOWithBookings(); + private final BookingDTOForItem booking = new BookingDTOForItem(); + + @Test + void addItemControllerTest() throws Exception { + addItemDto(); + + when(itemService.add(Mockito.anyLong(), any())) + .thenReturn(itemDto); + + mvc.perform(post("/items") + .header("X-Sharer-User-Id", 1L) + .content(mapper.writeValueAsString(itemDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(itemDto.getId()), Long.class)) + .andExpect(jsonPath("$.name", is(itemDto.getName()))) + .andExpect(jsonPath("$.owner.id", is((int) itemDto.getOwner().getId()))) + .andExpect(jsonPath("$.owner.name", is(itemDto.getOwner().getName()))) + .andExpect(jsonPath("$.owner.email", is(itemDto.getOwner().getEmail()))) + .andExpect(jsonPath("$.description", is(itemDto.getDescription()))) + .andExpect(jsonPath("$.available", is(itemDto.getAvailable()))); + } + + @Test + void changeItemControllerTest() throws Exception { + addItemDto(); + + when(itemService.update(Mockito.anyLong(), Mockito.anyLong(), any())) + .thenReturn(itemDto); + + mvc.perform(patch("/items/1/") + .header("X-Sharer-User-Id", 1L) + .content(mapper.writeValueAsString(itemDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(itemDto.getId()), Long.class)) + .andExpect(jsonPath("$.name", is(itemDto.getName()))) + .andExpect(jsonPath("$.owner.id", is((int) itemDto.getOwner().getId()))) + .andExpect(jsonPath("$.owner.name", is(itemDto.getOwner().getName()))) + .andExpect(jsonPath("$.owner.email", is(itemDto.getOwner().getEmail()))) + .andExpect(jsonPath("$.description", is(itemDto.getDescription()))) + .andExpect(jsonPath("$.available", is(itemDto.getAvailable()))); + } + + @Test + void getItemControllerTest() throws Exception { + addItemDtoWithBooking(); + + when(itemService.get(Mockito.anyLong(), Mockito.anyLong())) + .thenReturn(itemDtoWithBooking); + + mvc.perform(get("/items/1/") + .header("X-Sharer-User-Id", 1L) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(itemDtoWithBooking.getId()), Long.class)) + .andExpect(jsonPath("$.name", is(itemDtoWithBooking.getName()))) + .andExpect(jsonPath("$.owner.id", is((int) itemDtoWithBooking.getOwner().getId()))) + .andExpect(jsonPath("$.owner.name", is(itemDtoWithBooking.getOwner().getName()))) + .andExpect(jsonPath("$.owner.email", is(itemDtoWithBooking.getOwner().getEmail()))) + .andExpect(jsonPath("$.lastBooking.id", is((int) itemDtoWithBooking.getLastBooking().getId()))) + .andExpect(jsonPath("$.lastBooking.bookerId", is(itemDtoWithBooking.getLastBooking() + .getBookerId()))) + .andExpect(jsonPath("$.lastBooking.dateTime", is(itemDtoWithBooking.getLastBooking() + .getDateTime().toString()))) + .andExpect(jsonPath("$.nextBooking.id", is((int) itemDtoWithBooking.getNextBooking().getId()))) + .andExpect(jsonPath("$.nextBooking.bookerId", is(itemDtoWithBooking.getNextBooking() + .getBookerId()))) + .andExpect(jsonPath("$.nextBooking.dateTime", is(itemDtoWithBooking.getNextBooking() + .getDateTime().toString()))) + .andExpect(jsonPath("$.description", is(itemDtoWithBooking.getDescription()))) + .andExpect(jsonPath("$.available", is(itemDtoWithBooking.getAvailable()))); + } + + @Test + void getAllOwnItemsControllerTest() throws Exception { + addItemDtoWithBooking(); + List items = new ArrayList<>(); + items.add(itemDtoWithBooking); + + when(itemService.getAllByOwner(Mockito.anyLong(), any(), any())) + .thenReturn(items); + + mvc.perform(get("/items") + .header("X-Sharer-User-Id", 1L) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", hasSize(1))) + .andExpect(jsonPath("$[0].id", is(itemDtoWithBooking.getId()), Long.class)) + .andExpect(jsonPath("$[0].name", is(itemDtoWithBooking.getName()))) + .andExpect(jsonPath("$[0].description", is(itemDtoWithBooking.getDescription()))) + .andExpect(jsonPath("$[0].owner.id", is((int) itemDtoWithBooking.getOwner().getId()))) + .andExpect(jsonPath("$[0].owner.name", is(itemDtoWithBooking.getOwner().getName()))) + .andExpect(jsonPath("$[0].owner.email", is(itemDtoWithBooking.getOwner().getEmail()))) + .andExpect(jsonPath("$[0].lastBooking.id", is((int) itemDtoWithBooking.getLastBooking() + .getId()))) + .andExpect(jsonPath("$[0].lastBooking.bookerId", is(itemDtoWithBooking.getLastBooking() + .getBookerId()))) + .andExpect(jsonPath("$[0].lastBooking.dateTime", is(itemDtoWithBooking.getLastBooking() + .getDateTime().toString()))) + .andExpect(jsonPath("$[0].nextBooking.id", is((int) itemDtoWithBooking.getNextBooking().getId()))) + .andExpect(jsonPath("$[0].nextBooking.bookerId", is( itemDtoWithBooking.getNextBooking() + .getBookerId()))) + .andExpect(jsonPath("$[0].nextBooking.dateTime", is(itemDtoWithBooking.getNextBooking() + .getDateTime().toString()))) + .andExpect(jsonPath("$[0].available", is(itemDtoWithBooking.getAvailable()))); + + } + + @Test + void getItemsForRentControllerTest() throws Exception { + addItemDto(); + when(itemService.getForRent(Mockito.anyString(), any(), any())) + .thenReturn(List.of(itemDto)); + + mvc.perform(get("/items/search?text=F") + .header("X-Sharer-User-Id", 1L) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", hasSize(1))) + .andExpect(jsonPath("$[0].name", is(itemDto.getName()))) + .andExpect(jsonPath("$[0].owner.id", is((int) itemDto.getOwner().getId()))) + .andExpect(jsonPath("$[0].owner.name", is(itemDto.getOwner().getName()))) + .andExpect(jsonPath("$[0].owner.email", is(itemDto.getOwner().getEmail()))) + .andExpect(jsonPath("$[0].description", is(itemDto.getDescription()))) + .andExpect(jsonPath("$[0].available", is(itemDto.getAvailable()))); + } + + @Test + void addCommentControllerTest() throws Exception { + addItemDto(); + addComment(); + CommentDTO item = addItemDtoWithComment(); + when(itemService.addComment(Mockito.anyLong(), Mockito.anyLong(), any(CommentDTO.class))) + .thenReturn(item); + //что??? + + mvc.perform(post("/items/1/comment") + .header("X-Sharer-User-Id", 1L) + .content(mapper.writeValueAsString(itemDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(item.getId()), Long.class)) + .andExpect(jsonPath("$.text", is(item.getText()))) + .andExpect(jsonPath("$.itemName", is(item.getItemName()))) + .andExpect(jsonPath("$.created", is(item.getCreated().toString()))) + .andExpect(jsonPath("$.authorName", is(item.getAuthorName()))); + + } + + @Test + void addItemWithException() throws Exception { + when(itemService.add(1L, itemDto)) + .thenThrow(BadRequestException.class); + + mvc.perform(post("/items") + .header("X-Sharer-User-Id", 1L) + .content(mapper.writeValueAsString(itemDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultHandlers.print()) + .andExpect(status().is(400)); + } + + @Test + void updateItemWithException() throws Exception { + when(itemService.update(5L, 5L, new ItemDTO())) + .thenThrow(AssertionError.class); + + mvc.perform(patch("/items/10/") + .content(mapper.writeValueAsString(itemDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultHandlers.print()) + .andExpect(status().is(500)); + } + + private void addItemDto() { + addUser(); + itemDto.setId(1L); + itemDto.setName("Fork"); + itemDto.setOwner(UserMapper.toUserToItemDto(user)); + itemDto.setAvailable(true); + itemDto.setDescription("Designed for food"); + } + + private void addItemDtoWithBooking() { + addBooking(); + addUser(); + itemDtoWithBooking.setId(2L); + itemDtoWithBooking.setName("Fork"); + itemDtoWithBooking.setLastBooking(booking); + booking.setId(2L); + booking.setBookerId(4L); + String date = "2022-11-23T12:30:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setDateTime(localdatetime); + booking.setBookerId(4L); + itemDtoWithBooking.setNextBooking(booking); + itemDtoWithBooking.setOwner(UserMapper.toUserToItemWithBookingsDto(user)); + itemDtoWithBooking.setAvailable(true); + itemDtoWithBooking.setDescription("Designed for food"); + } + + private void addUser() { + user.setId(1L); + user.setName("Buffy"); + user.setEmail("buffy@vampire.com"); + } + + private void addBooking() { + User booker = new User(); + booker.setId(3L); + booker.setName("Katya"); + booker.setEmail("katya@katya.com"); + booking.setId(1L); + booking.setBookerId(3L); + String date = "2022-11-22T12:30:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + booking.setDateTime(localdatetime); + User booker2 = new User(); + booker2.setId(4L); + booker2.setName("Kat"); + booker2.setEmail("kat@kat.com"); + + } + + private void addComment() { + User booker = new User(); + booker.setId(3L); + booker.setName("Katya"); + booker.setEmail("katya@katya.com"); + comment.setId(1L); + comment.setAuthor(booker); + comment.setItem(item); + comment.setText("cool fork"); + String date = "2022-11-23T18:08:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + comment.setCreated(localdatetime); + } + + private CommentDTO addItemDtoWithComment() { + CommentDTO dtoWithComment = new CommentDTO(); + dtoWithComment.setId(itemDto.getId()); + dtoWithComment.setText(comment.getText()); + dtoWithComment.setItemName(itemDto.getName()); + dtoWithComment.setCreated(comment.getCreated()); + dtoWithComment.setAuthorName(comment.getAuthor().getName()); + return dtoWithComment; + } +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/item/ItemRepositoryTest.java b/src/test/java/ru/practicum/shareit/item/ItemRepositoryTest.java new file mode 100644 index 000000000..10fdb4798 --- /dev/null +++ b/src/test/java/ru/practicum/shareit/item/ItemRepositoryTest.java @@ -0,0 +1,95 @@ +package ru.practicum.shareit.item; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; +import org.springframework.test.annotation.DirtiesContext; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.request.model.ItemRequest; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +class ItemRepositoryTest { + + @Autowired + private TestEntityManager em; + + @Autowired + private ItemRepository itemRepository; + + private final Item item = new Item(); + private final User user = new User(); + private final ItemRequest request = new ItemRequest(); + + @Test + void findItemByRequestJpaTest() { + addItem(); + addRequest(); + item.setRequestId(request); + Item itemPersist = em.persist(item); + List items = itemRepository.findByRequest(request.getId()); + assertThat(itemPersist).isEqualTo(items.get(1)); + assertThat(itemPersist.getId()).isEqualTo(items.get(1).getId()); + } + + @Test + void findByOwnerJpaTest() { + addItem(); + Item itemPersist = em.persist(item); + List items = itemRepository.findByOwner(user); + assertThat(itemPersist).isEqualTo(items.get(1)); + assertThat(itemPersist.getId()).isEqualTo(items.get(1).getId()); + } + + @Test + void findItemsByNameOrDescriptionJpaTest() { + addItem(); + Item itemPersist = em.persist(item); + List items = itemRepository.findItemsByNameOrDescription("F"); + assertThat(itemPersist).isEqualTo(items.get(3)); + assertThat(itemPersist.getId()).isEqualTo(items.get(3).getId()); + } + + @Test + void findByRequestIdJpaTest() { + addItem(); + addRequest(); + item.setRequestId(request); + Item itemPersist = em.persist(item); + List items = itemRepository.findByRequest(request.getId()); + assertThat(itemPersist).isEqualTo(items.get(1)); + assertThat(itemPersist.getId()).isEqualTo(items.get(1).getId()); + } + + private void addItem() { + addUser(); + item.setName("Fork"); + item.setOwner(user); + item.setAvailable(true); + item.setDescription("Designed for food"); + } + + private void addUser() { + user.setId(1L); + user.setName("Buffy"); + user.setEmail("buffy@vampire.com"); + } + + private void addRequest() { + User requester = new User(); + requester.setId(3L); + requester.setName("Kat"); + requester.setEmail("Kat@kat.com"); + request.setId(1L); + request.setRequester(requester); + request.setDescription("I need a fork to eat"); + request.setCreated(LocalDateTime.now()); + } +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/item/dto/ItemDtoTest.java b/src/test/java/ru/practicum/shareit/item/dto/ItemDtoTest.java new file mode 100644 index 000000000..1899b7ab7 --- /dev/null +++ b/src/test/java/ru/practicum/shareit/item/dto/ItemDtoTest.java @@ -0,0 +1,49 @@ +package ru.practicum.shareit.item.dto; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.json.JsonTest; +import org.springframework.boot.test.json.JacksonTester; +import org.springframework.boot.test.json.JsonContent; +import ru.practicum.shareit.user.UserMapper; +import ru.practicum.shareit.user.model.User; + +import static org.assertj.core.api.Assertions.assertThat; + +@JsonTest +class ItemDtoTest { + @Autowired + private JacksonTester json; + + private final User user = new User(); + + @Test + void testItemDto() throws Exception { + addUser(); + ItemDTO itemDto = new ItemDTO(); + itemDto.setId(1L); + itemDto.setName("Sword"); + itemDto.setAvailable(true); + itemDto.setDescription("To fight"); + itemDto.setOwner(UserMapper.toUserToItemDto(user)); + itemDto.setRequestId(1L); + + JsonContent result = json.write(itemDto); + + assertThat(result).extractingJsonPathNumberValue("$.id").isEqualTo(1); + assertThat(result).extractingJsonPathStringValue("$.name").isEqualTo("Sword"); + assertThat(result).extractingJsonPathBooleanValue("$.available").isEqualTo(true); + assertThat(result).extractingJsonPathNumberValue("$.owner.id").isEqualTo(1); + assertThat(result).extractingJsonPathStringValue("$.owner.name").isEqualTo("Aelin"); + assertThat(result).extractingJsonPathStringValue("$.owner.email") + .isEqualTo("aelin@whitethorn.com"); + assertThat(result).extractingJsonPathStringValue("$.description").isEqualTo("To fight"); + assertThat(result).extractingJsonPathNumberValue("$.request").isEqualTo(1); + } + + private void addUser() { + user.setId(1L); + user.setName("Aelin"); + user.setEmail("aelin@whitethorn.com"); + } +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/item/dto/ItemDtoWithBookingTest.java b/src/test/java/ru/practicum/shareit/item/dto/ItemDtoWithBookingTest.java new file mode 100644 index 000000000..7f59c6ee1 --- /dev/null +++ b/src/test/java/ru/practicum/shareit/item/dto/ItemDtoWithBookingTest.java @@ -0,0 +1,91 @@ +package ru.practicum.shareit.item.dto; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.json.JsonTest; +import org.springframework.boot.test.json.JacksonTester; +import org.springframework.boot.test.json.JsonContent; + +import ru.practicum.shareit.booking.dto.BookingDTOForItem; +import ru.practicum.shareit.user.UserMapper; +import ru.practicum.shareit.user.model.User; + +import java.io.IOException; +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; + +@JsonTest +class ItemDtoWithBookingTest { + + @Autowired + private JacksonTester json; + + private final User user = new User(); + private final BookingDTOForItem last = new BookingDTOForItem(); + private final BookingDTOForItem next = new BookingDTOForItem(); + + @Test + void testItemDtoWithBooking() throws IOException { + addUser(); + addLast(); + addNext(); + ItemDTOWithBookings itemDtoWithBooking = new ItemDTOWithBookings(); + itemDtoWithBooking.setId(1); + itemDtoWithBooking.setName("Sword"); + itemDtoWithBooking.setDescription("To fight"); + itemDtoWithBooking.setOwner(UserMapper.toUserToItemWithBookingsDto(user)); + itemDtoWithBooking.setRequest(1L); + itemDtoWithBooking.setLastBooking(last); + itemDtoWithBooking.setNextBooking(next); + itemDtoWithBooking.setAvailable(true); + + JsonContent result = json.write(itemDtoWithBooking); + + assertThat(result).extractingJsonPathNumberValue("$.id").isEqualTo(1); + assertThat(result).extractingJsonPathStringValue("$.name").isEqualTo("Sword"); + assertThat(result).extractingJsonPathBooleanValue("$.available").isEqualTo(true); + assertThat(result).extractingJsonPathNumberValue("$.owner.id").isEqualTo(1); + assertThat(result).extractingJsonPathStringValue("$.owner.name").isEqualTo("Aelin"); + assertThat(result).extractingJsonPathStringValue("$.owner.email") + .isEqualTo("aelin@whitethorn.com"); + assertThat(result).extractingJsonPathStringValue("$.description").isEqualTo("To fight"); + assertThat(result).extractingJsonPathValue("$.lastBooking.dateTime") + .isEqualTo("2017-10-19T23:50:50"); + assertThat(result).extractingJsonPathValue("$.nextBooking.dateTime") + .isEqualTo("2017-10-19T23:50:50"); + assertThat(result).extractingJsonPathNumberValue("$.request").isEqualTo(1); + + } + + private void addUser() { + user.setId(1L); + user.setName("Aelin"); + user.setEmail("aelin@whitethorn.com"); + } + + private void addLast() { + User userForLast = new User(); + userForLast.setId(2L); + userForLast.setName("Rowan"); + userForLast.setEmail("Rowan@Whitethorn.com"); + last.setId(1); + last.setBookerId(userForLast.getId()); + String date = "2017-10-19T23:50:50"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + last.setDateTime(localdatetime); + } + + private void addNext() { + User userForNext = new User(); + userForNext.setId(3L); + userForNext.setName("Rowan"); + userForNext.setEmail("Rowan@Whitethorn.com"); + next.setId(2); + next.setBookerId(userForNext.getId()); + String date = "2017-10-19T23:50:50"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + next.setDateTime(localdatetime); + } + +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/item/dto/ItemDtoWithCommentTest.java b/src/test/java/ru/practicum/shareit/item/dto/ItemDtoWithCommentTest.java new file mode 100644 index 000000000..cd800b542 --- /dev/null +++ b/src/test/java/ru/practicum/shareit/item/dto/ItemDtoWithCommentTest.java @@ -0,0 +1,39 @@ +package ru.practicum.shareit.item.dto; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.json.JsonTest; +import org.springframework.boot.test.json.JacksonTester; +import org.springframework.boot.test.json.JsonContent; + +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; + +@JsonTest +class ItemDtoWithCommentTest { + + @Autowired + private JacksonTester json; + + @Test + void testItemDtoWithComment() throws Exception { + String date = "2017-10-19T23:50:50"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + CommentDTO itemDto = new CommentDTO(); + itemDto.setId(1L); + itemDto.setItemName("Sword"); + itemDto.setText("Waiting for fight"); + itemDto.setCreated(localdatetime); + itemDto.setAuthorName("Rowan"); + + JsonContent result = json.write(itemDto); + + assertThat(result).extractingJsonPathNumberValue("$.id").isEqualTo(1); + assertThat(result).extractingJsonPathStringValue("$.itemName").isEqualTo("Sword"); + assertThat(result).extractingJsonPathStringValue("$.text").isEqualTo("Waiting for fight"); + assertThat(result).extractingJsonPathStringValue("$.authorName").isEqualTo("Rowan"); + assertThat(result).extractingJsonPathValue("$.created").isEqualTo("2017-10-19T23:50:50"); + + } +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/item/service/ItemServiceTest.java b/src/test/java/ru/practicum/shareit/item/service/ItemServiceTest.java new file mode 100644 index 000000000..c442faf42 --- /dev/null +++ b/src/test/java/ru/practicum/shareit/item/service/ItemServiceTest.java @@ -0,0 +1,630 @@ +package ru.practicum.shareit.item.service; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.test.annotation.DirtiesContext; +import ru.practicum.shareit.booking.BookingRepository; +import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.booking.model.Status; +import ru.practicum.shareit.exception.BadRequestException; +import ru.practicum.shareit.exception.ForbiddenException; +import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.item.CommentRepository; +import ru.practicum.shareit.item.ItemRepository; +import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.item.dto.ItemDTOWithBookings; +import ru.practicum.shareit.item.dto.CommentDTO; +import ru.practicum.shareit.item.mapper.ItemMapper; +import ru.practicum.shareit.item.model.Comment; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.request.RequestRepository; +import ru.practicum.shareit.request.model.ItemRequest; +import ru.practicum.shareit.user.UserRepository; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@ExtendWith(MockitoExtension.class) +class ItemServiceTest { + + @InjectMocks + ItemServiceImpl itemService; + + @Mock + ItemRepository itemRepository; + + @Mock + UserRepository userRepository; + + @Mock + RequestRepository requestRepository; + + @Mock + CommentRepository commentRepository; + + @Mock + BookingRepository bookingRepository; + + Item item = new Item(); + User userOwner = new User(); + User requester = new User(); + ItemRequest request = new ItemRequest(); + Booking booking = new Booking(); + Comment comment = new Comment(); + + + @Test + void addItemTest() { + addItem(); + addRequest(); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(userOwner)); + + Mockito + .when(itemRepository.save(any())) + .thenReturn(item); + + Optional itemDto = Optional.ofNullable(itemService.add(userOwner.getId(), + ItemMapper.toItemDto(item))); + + assertThat(itemDto) + .isPresent() + .hasValueSatisfying(addItemTest -> { + assertThat(addItemTest).hasFieldOrPropertyWithValue("id", item.getId()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("name", item.getName()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("available", item.getAvailable()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("description", + item.getDescription()); + } + ); + } + + @Test + void addItemWithRequestTest() { + addItem(); + addRequest(); + item.setRequestId(request); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(userOwner)); + + Mockito + .when(requestRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(request)); + + Mockito + .when(itemRepository.save(any())) + .thenReturn(item); + + Optional itemDto = Optional.ofNullable(itemService.add(userOwner.getId(), + ItemMapper.toItemDto(item))); + + assertThat(itemDto) + .isPresent() + .hasValueSatisfying(addItemTest -> { + assertThat(addItemTest).hasFieldOrPropertyWithValue("id", item.getId()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("name", item.getName()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("available", item.getAvailable()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("requestId", + item.getRequestId().getId()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("description", + item.getDescription()); + } + ); + } + + @Test + void addItemUserNotFoundTest() { + addItem(); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.empty()); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> itemService.add(3L, ItemMapper.toItemDto(item))); + + Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + } + + @Test + void changeItemTest() { + addItem(); + + Mockito + .when(itemRepository.save(any())) + .thenReturn(item); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(item)); + + Optional itemDto = Optional.ofNullable(itemService.update(userOwner.getId(), item.getId(), + ItemMapper.toItemDto(item))); + + assertThat(itemDto) + .isPresent() + .hasValueSatisfying(addItemTest -> { + assertThat(addItemTest).hasFieldOrPropertyWithValue("id", item.getId()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("name", item.getName()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("available", item.getAvailable()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("description", + item.getDescription()); + } + ); + } + + @Test + void changeItemNotFoundTest() { + addItem(); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.empty()); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> itemService.update(1L, 3L, ItemMapper.toItemDto(item))); + + Assertions.assertEquals("Вещь не найдена", exception.getMessage()); + } + + @Test + void changeItemForbiddenExceptionTest() { + addItem(); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(item)); + + final ForbiddenException exception = Assertions.assertThrows( + ForbiddenException.class, + () -> itemService.update(5L, 1L, ItemMapper.toItemDto(item))); + + Assertions.assertEquals("Для пользователя нет доступа", exception.getMessage()); + } + + @Test + void getItemTest() { + addItem(); + List comments = new ArrayList<>(); + List bookings = new ArrayList<>(); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(item)); + + Mockito + .when(commentRepository.findAllByItem(any())) + .thenReturn(comments); + + Mockito + .when(bookingRepository.findByItemOrderByStartDesc(any())) + .thenReturn(bookings); + + Optional itemDto = Optional.ofNullable(itemService.get(userOwner.getId(), item.getId())); + + assertThat(itemDto) + .isPresent() + .hasValueSatisfying(addItemTest -> { + assertThat(addItemTest).hasFieldOrPropertyWithValue("id", item.getId()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("name", item.getName()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("available", item.getAvailable()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("description", + item.getDescription()); + } + ); + } + + @Test + void getItemWithBookingTest() { + addItem(); + addBooking(); + List comments = new ArrayList<>(); + List bookings = new ArrayList<>(); + bookings.add(booking); + booking.setId(2L); + bookings.add(booking); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(item)); + + Mockito + .when(commentRepository.findAllByItem(any())) + .thenReturn(comments); + + Mockito + .when(bookingRepository.findByItemOrderByStartDesc(any())) + .thenReturn(bookings); + + Optional itemDto = Optional.ofNullable(itemService.get(userOwner.getId(), item.getId())); + + assertThat(itemDto) + .isPresent() + .hasValueSatisfying(addItemTest -> { + assertThat(addItemTest).hasFieldOrPropertyWithValue("id", item.getId()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("name", item.getName()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("available", item.getAvailable()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("description", + item.getDescription()); + } + ); + } + + @Test + void getNotFoundTest() { + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.empty()); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> itemService.get(1L, 5L)); + + Assertions.assertEquals("Вещь не найдена", exception.getMessage()); + + } + + @Test + void getAllOwnItemsTest() { + addItem(); + addBooking(); + List comments = new ArrayList<>(); + List bookings = new ArrayList<>(); + List items = new ArrayList<>(); + items.add(item); + bookings.add(booking); + booking.setId(2L); + bookings.add(booking); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(userOwner)); + + Mockito + .when(commentRepository.findAllByItem(any())) + .thenReturn(comments); + + Mockito + .when(bookingRepository.findByItemOrderByStartDesc(any())) + .thenReturn(bookings); + + Mockito + .when(itemRepository.findByOwner(any())) + .thenReturn(items); + + List getItems = ItemMapper.mapToItem(itemService.getAllByOwner(1L, null, null)); + + Assertions.assertEquals(getItems.get(0).getId(), items.get(0).getId()); + } + + @Test + void getAllOwnItemsNotFoundUserTest() { + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.empty()); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> itemService.getAllByOwner(4L, null, null)); + + Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + } + + @Test + void getAllOwnItemsFromOrSizeLessThanZeroTest() { + addItem(); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(userOwner)); + + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> itemService.getAllByOwner(1L, -1, 0)); + + Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + exception.getMessage()); + } + + @Test + void getAllOwnItemsSizeEqualToZeroTest() { + addItem(); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(userOwner)); + + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> itemService.getAllByOwner(1L, 1, 0)); + + Assertions.assertEquals("Size не может принимать значение 0", exception.getMessage()); + } + + @Test + void getAllOwnItemsWithPageTest() { + addItem(); + addBooking(); + List comments = new ArrayList<>(); + List bookings = new ArrayList<>(); + List items = new ArrayList<>(); + items.add(item); + bookings.add(booking); + booking.setId(2L); + bookings.add(booking); + Page page = new PageImpl<>(items); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(userOwner)); + + Mockito + .when(commentRepository.findAllByItem(any())) + .thenReturn(comments); + + Mockito + .when(bookingRepository.findByItemOrderByStartDesc(any())) + .thenReturn(bookings); + + Mockito + .when(itemRepository.findByOwner(any(), any())) + .thenReturn(page); + + List getItems = ItemMapper.mapToItem(itemService.getAllByOwner(1L, 0, 1)); + + Assertions.assertEquals(getItems.get(0).getId(), items.get(0).getId()); + } + + + @Test + void getItemsForRentTest() { + addItem(); + List items = new ArrayList<>(); + items.add(item); + + Mockito + .when(itemRepository.findItemsByNameOrDescription(Mockito.anyString())) + .thenReturn(items); + + List getItems = (List) itemService.getForRent("Fork", null, null); + + Assertions.assertEquals(getItems.get(0).getId(), items.get(0).getId()); + } + + @Test + void getItemsForRentEqualToZeroTest() { + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> itemService.getForRent("F", 0, 0)); + + Assertions.assertEquals("Size не может принимать значение 0", exception.getMessage()); + + } + + @Test + void getItemsForRentFromOrSizeLessThanZeroTest() { + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> itemService.getForRent("F", -1, 0)); + + Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + exception.getMessage()); + + } + + @Test + void getItemsForRentWithPageTest() { + addItem(); + List items = new ArrayList<>(); + items.add(item); + Page page = new PageImpl<>(items); + + Mockito + .when(itemRepository.findItemsByNameOrDescription(Mockito.anyString(), any())) + .thenReturn(page); + + List getItems = (List) itemService.getForRent("Fork", 0, 1); + + Assertions.assertEquals(getItems.get(0).getId(), items.get(0).getId()); + } + + @Test + void getItemsForRentNewArrayTest() { + List getItems = (List) itemService.getForRent("", null, null); + + Assertions.assertEquals(getItems, new ArrayList<>()); + } + + @Test + void addCommentTest() { + addItem(); + addComment(); + addBooking(); + booking.setStart(LocalDateTime.now().minusDays(3)); + booking.setEnd(LocalDateTime.now().minusDays(2)); + List bookings = new ArrayList<>(); + bookings.add(booking); + CommentDTO dtoWithComment = addItemDtoWithComment(); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(item)); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(comment.getAuthor())); + + Mockito + .when(bookingRepository.findByItemAndBookerAndStartBeforeAndEndBefore(any(), any(), + any(), any())) + .thenReturn(bookings); + + Mockito + .when(commentRepository.save(any())) + .thenReturn(comment); + + Optional itemDto = Optional.ofNullable(itemService.addComment(3L, item.getId(), + dtoWithComment)); + + assertThat(itemDto) + .isPresent() + .hasValueSatisfying(addItemTest -> { + assertThat(addItemTest).hasFieldOrPropertyWithValue("id", item.getId()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("text", comment.getText()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("itemName", item.getName()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("created", comment.getCreated()); + assertThat(addItemTest).hasFieldOrPropertyWithValue("authorName", + comment.getAuthor().getName()); + } + ); + } + + @Test + void addCommentItemNotFoundTest() { + addItem(); + addComment(); + CommentDTO dtoWithComment = addItemDtoWithComment(); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.empty()); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> itemService.addComment(2L, 2L, dtoWithComment)); + + Assertions.assertEquals("Вещь не найдена", exception.getMessage()); + } + + @Test + void addCommentUserNotFoundTest() { + addItem(); + addComment(); + CommentDTO dtoWithComment = addItemDtoWithComment(); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(item)); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.empty()); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> itemService.addComment(4L, 1L, dtoWithComment)); + + Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + + } + + @Test + void addCommentBookingIsEmptyTest() { + addItem(); + addComment(); + CommentDTO dtoWithComment = addItemDtoWithComment(); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(item)); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(comment.getAuthor())); + + Mockito + .when(bookingRepository.findByItemAndBookerAndStartBeforeAndEndBefore(any(), any(), + any(), any())) + .thenReturn(new ArrayList<>()); + + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> itemService.addComment(4L, 1L, dtoWithComment)); + + Assertions.assertEquals("Невозможно добавить комментарий", exception.getMessage()); + + + } + + private void addItem() { + addUser(); + item.setId(1L); + item.setName("Fork"); + item.setOwner(userOwner); + item.setAvailable(true); + item.setDescription("Designed for food"); + } + + private void addUser() { + userOwner.setId(1L); + userOwner.setName("Buffy"); + userOwner.setEmail("buffy@vampire.com"); + + requester.setId(2L); + requester.setName("Leo"); + requester.setEmail("leo@angel.com"); + } + + private void addRequest() { + request.setId(1L); + request.setRequester(requester); + request.setDescription("I need a fork to eat"); + request.setCreated(LocalDateTime.now()); + } + + private void addBooking() { + User booker = new User(); + booker.setId(3L); + booker.setName("Katya"); + booker.setEmail("katya@katya.com"); + booking.setId(1L); + booking.setItem(item); + booking.setStatus(Status.WAITING); + booking.setStart(LocalDateTime.now().plusDays(1)); + booking.setEnd(LocalDateTime.now().plusDays(3)); + booking.setBooker(booker); + } + + private void addComment() { + User booker = new User(); + booker.setId(3L); + booker.setName("Katya"); + booker.setEmail("katya@katya.com"); + comment.setId(1L); + comment.setAuthor(booker); + comment.setItem(item); + comment.setText("cool fork"); + comment.setCreated(LocalDateTime.now()); + } + + private CommentDTO addItemDtoWithComment() { + CommentDTO dtoWithComment = new CommentDTO(); + dtoWithComment.setId(item.getId()); + dtoWithComment.setText(comment.getText()); + dtoWithComment.setItemName(item.getName()); + dtoWithComment.setCreated(comment.getCreated()); + dtoWithComment.setAuthorName(comment.getAuthor().getName()); + return dtoWithComment; + } + +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java b/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java new file mode 100644 index 000000000..45afcffce --- /dev/null +++ b/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java @@ -0,0 +1,185 @@ +package ru.practicum.shareit.request; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.web.servlet.MockMvc; +import ru.practicum.shareit.booking.dto.BookingDTOForItem; +import ru.practicum.shareit.item.dto.CommentDTO; +import ru.practicum.shareit.item.dto.ItemDTO; +import ru.practicum.shareit.item.dto.ItemDTOWithBookings; +import ru.practicum.shareit.item.model.Comment; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.request.dto.RequestDTO; +import ru.practicum.shareit.request.dto.RequestDTOWithItems; +import ru.practicum.shareit.request.service.RequestService; +import ru.practicum.shareit.user.model.User; + +import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.util.List; + +import static org.hamcrest.Matchers.is; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@WebMvcTest(controllers = ItemRequestController.class) +class ItemRequestControllerTest { + + @Autowired + ObjectMapper mapper; + + @MockBean + RequestService requestService; + + @Autowired + private MockMvc mvc; + + private final RequestDTO requestDto = new RequestDTO(); + private final RequestDTOWithItems requestWithItems = new RequestDTOWithItems(); + private final ItemDTO itemDto = new ItemDTO(); + private final Item item = new Item(); + private final User user = new User(); + private final Comment comment = new Comment(); + private final ItemDTOWithBookings itemDtoWithBooking = new ItemDTOWithBookings(); + private final BookingDTOForItem booking = new BookingDTOForItem(); + + @Test + void addRequestControllerTest() throws Exception { + addRequestDto(); + + when(requestService.add(Mockito.anyLong(), any())) + .thenReturn(requestDto); + + mvc.perform(post("/requests") + .header("X-Sharer-User-Id", 1L) + .content(mapper.writeValueAsString(itemDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(requestDto.getId()), Long.class)) + .andExpect(jsonPath("$.created", is(requestDto.getCreated().toString()))) + .andExpect(jsonPath("$.requester.id", is( requestDto.getRequester().getId()))) + .andExpect(jsonPath("$.requester.name", is(requestDto.getRequester().getName()))) + .andExpect(jsonPath("$.requester.email", is(requestDto.getRequester().getEmail()))) + .andExpect(jsonPath("$.description", is(requestDto.getDescription()))); + } + + @Test + void getAllOwnRequestControllerTest() throws Exception { + addRequest(); + + when(requestService.findAllByOwner(Mockito.anyLong())) + .thenReturn(List.of(requestWithItems)); + + mvc.perform(get("/requests") + .header("X-Sharer-User-Id", 2L) + .content(mapper.writeValueAsString(itemDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].id", is(requestWithItems.getId()), Long.class)) + .andExpect(jsonPath("$[0].created", is(requestWithItems.getCreated().toString()))) + .andExpect(jsonPath("$[0].requester.id", is(requestWithItems.getRequester().getId()))) + .andExpect(jsonPath("$[0].requester.name", is(requestWithItems.getRequester().getName()))) + .andExpect(jsonPath("$[0].requester.email", is(requestWithItems.getRequester().getEmail()))) + .andExpect(jsonPath("$[0].description", is(requestWithItems.getDescription()))); + } + + @Test + void getAllRequestControllerTest() throws Exception { + addRequest(); + + when(requestService.findAll(Mockito.anyLong(), any(), any())) + .thenReturn(List.of(requestWithItems)); + + mvc.perform(get("/requests/all") + .header("X-Sharer-User-Id", 2L) + .param("from", "0") + .param("size", "1") + .content(mapper.writeValueAsString(itemDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].id", is(requestWithItems.getId()), Long.class)) + .andExpect(jsonPath("$[0].created", is(requestWithItems.getCreated().toString()))) + .andExpect(jsonPath("$[0].requester.id", is(requestWithItems.getRequester().getId()))) + .andExpect(jsonPath("$[0].requester.name", is(requestWithItems.getRequester().getName()))) + .andExpect(jsonPath("$[0].requester.email", is(requestWithItems.getRequester().getEmail()))) + .andExpect(jsonPath("$[0].description", is(requestWithItems.getDescription()))); + } + + @Test + void getRequestControllerTest() throws Exception { + addRequest(); + + when(requestService.findById(Mockito.anyLong(), Mockito.anyLong())) + .thenReturn(requestWithItems); + + mvc.perform(get("/requests/2") + .header("X-Sharer-User-Id", 1L) + .content(mapper.writeValueAsString(itemDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(requestWithItems.getId()), Long.class)) + .andExpect(jsonPath("$.created", is(requestWithItems.getCreated().toString()))) + .andExpect(jsonPath("$.requester.id", is(requestWithItems.getRequester().getId()))) + .andExpect(jsonPath("$.requester.name", is(requestWithItems.getRequester().getName()))) + .andExpect(jsonPath("$.requester.email", is(requestWithItems.getRequester().getEmail()))) + .andExpect(jsonPath("$.description", is(requestWithItems.getDescription()))); + } + + private void addUser() { + user.setId(1L); + user.setName("Buffy"); + user.setEmail("buffy@vampire.com"); + } + + private CommentDTO addItemDtoWithComment() { + CommentDTO dtoWithComment = new CommentDTO(); + dtoWithComment.setId(itemDto.getId()); + dtoWithComment.setText(comment.getText()); + dtoWithComment.setItemName(itemDto.getName()); + dtoWithComment.setCreated(comment.getCreated()); + dtoWithComment.setAuthorName(comment.getAuthor().getName()); + return dtoWithComment; + } + + private void addRequestDto() { + addUser(); + requestDto.setId(1L); + requestDto.setDescription("I need a fork"); + requestDto.setRequester(user); + String date = "2022-11-23T12:30:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + requestDto.setCreated(localdatetime); + } + + private void addRequest() { + addUser(); + user.setId(1L); + user.setName("Cat"); + requestWithItems.setId(2L); + requestWithItems.setDescription("I need a fork"); + requestWithItems.setRequester(user); + String date = "2022-11-24T12:30:54"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + requestWithItems.setCreated(localdatetime); + } + +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/request/ItemRequestRepositoryTest.java b/src/test/java/ru/practicum/shareit/request/ItemRequestRepositoryTest.java new file mode 100644 index 000000000..485f28807 --- /dev/null +++ b/src/test/java/ru/practicum/shareit/request/ItemRequestRepositoryTest.java @@ -0,0 +1,76 @@ +package ru.practicum.shareit.request; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.test.annotation.DirtiesContext; +import ru.practicum.shareit.request.model.ItemRequest; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +class ItemRequestRepositoryTest { + + @Autowired + private TestEntityManager em; + + @Autowired + private RequestRepository rRepository; + + private final ItemRequest requestOne = new ItemRequest(); + private final ItemRequest requestTwo = new ItemRequest(); + + List requestsPersist = new ArrayList<>(); + + @Test + void findByRequestorOrderByCreatedDesc() { + addRequestOne(); + em.persist(requestOne); + addRequestTwo(); + em.persist(requestTwo); + requestsPersist.add(requestTwo); + requestsPersist.add(requestOne); + List requests = rRepository.findByRequesterOrderByCreatedDesc(requestOne.getRequester()); + assertThat(requestsPersist.get(0).getId()).isEqualTo(requests.get(0).getId()); + } + + @Test + void findAllBy() { + Pageable pageable = PageRequest.of(0, 3); + Page requestsPage = rRepository.findAllBy(2L, pageable); + List requests = requestsPage.getContent(); + assertThat(requests.size()).isEqualTo(3); + assertThat(requests.get(0).getId()).isEqualTo(1); + } + + private void addRequestOne() { + User requester = new User(); + requester.setId(2L); + requester.setName("Kat"); + requester.setEmail("Kat@kat.com"); + requestOne.setRequester(requester); + requestOne.setDescription("I need a fork to eat"); + requestOne.setCreated(LocalDateTime.now()); + } + + private void addRequestTwo() { + User requester = new User(); + requester.setId(2L); + requester.setName("Kat"); + requester.setEmail("Kat@kat.com"); + requestTwo.setRequester(requester); + requestTwo.setDescription("I need a fork to eat"); + requestTwo.setCreated(LocalDateTime.now()); + } + +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/request/service/ItemRequestServiceTest.java b/src/test/java/ru/practicum/shareit/request/service/ItemRequestServiceTest.java new file mode 100644 index 000000000..e2559b5e7 --- /dev/null +++ b/src/test/java/ru/practicum/shareit/request/service/ItemRequestServiceTest.java @@ -0,0 +1,331 @@ +package ru.practicum.shareit.request.service; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.test.annotation.DirtiesContext; +import ru.practicum.shareit.exception.BadRequestException; +import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.item.ItemRepository; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.request.RequestMapper; +import ru.practicum.shareit.request.RequestRepository; +import ru.practicum.shareit.request.dto.RequestDTO; +import ru.practicum.shareit.request.dto.RequestDTOWithItems; +import ru.practicum.shareit.request.model.ItemRequest; +import ru.practicum.shareit.user.UserRepository; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@ExtendWith(MockitoExtension.class) +class ItemRequestServiceTest { + + @InjectMocks + RequestService requestService; + + @Mock + ItemRepository itemRepository; + + @Mock + UserRepository userRepository; + + @Mock + RequestRepository requestRepository; + + ItemRequest request = new ItemRequest(); + User requester = new User(); + Item item = new Item(); + + @Test + void addRequestTest() { + addRequest(); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(requester)); + + Mockito + .when(requestRepository.save(any())) + .thenReturn(request); + + Optional requestDto = Optional.ofNullable(requestService.add(1L, + RequestMapper.toRequestDto(request))); + + assertThat(requestDto) + .isPresent() + .hasValueSatisfying(addRequestTest -> { + assertThat(addRequestTest).hasFieldOrPropertyWithValue("id", request.getId()); + assertThat(addRequestTest).hasFieldOrPropertyWithValue("requester", + request.getRequester()); + assertThat(addRequestTest).hasFieldOrPropertyWithValue("description", + request.getDescription()); + assertThat(addRequestTest).hasFieldOrPropertyWithValue("created", + request.getCreated()); + } + ); + } + + @Test + void addRequestUserNotFoundTest() { + addRequest(); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.empty()); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> requestService.add(3L, RequestMapper.toRequestDto(request))); + + Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + } + + @Test + void addRequestDescriptionIsEmpty() { + addRequest(); + request.setDescription(""); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(requester)); + + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> requestService.add(1L, RequestMapper.toRequestDto(request))); + + Assertions.assertEquals("Отсутствует описание для поиска вещи", exception.getMessage()); + } + + @Test + void findAllOwnRequestTest() { + addRequest(); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(requester)); + + Mockito + .when(requestRepository.findByRequesterOrderByCreatedDesc(any())) + .thenReturn(List.of(request)); + + List requestDtos = requestService.findAllByOwner(1L); + + Assertions.assertEquals(request.getId(), requestDtos.get(0).getId()); + } + + @Test + void findAllOwnRequestWithItemTest() { + addRequest(); + addItem(); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(requester)); + + Mockito + .when(requestRepository.findByRequesterOrderByCreatedDesc(any())) + .thenReturn(List.of(request)); + + Mockito + .when(itemRepository.findByRequest(Mockito.anyLong())) + .thenReturn(List.of(item)); + + List requestDtos = requestService.findAllByOwner(1L); + + Assertions.assertEquals(request.getId(), requestDtos.get(0).getId()); + } + + @Test + void findAllOwnRequestNotFoundUserTest() { + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.empty()); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> requestService.findAllByOwner(5L)); + + Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + } + + @Test + void findAllRequestWithPageableTest() { + addRequest(); + addItem(); + List items = new ArrayList<>(); + items.add(item); + List requests = new ArrayList<>(); + requests.add(request); + request.setCreated(LocalDateTime.now().minusHours(5)); + request.setId(2L); + requests.add(request); + Page page = new PageImpl<>(requests); + + Mockito + .when(requestRepository.findAllBy(Mockito.anyLong(), any())) + .thenReturn(page); + + Mockito + .when(itemRepository.findByRequest(Mockito.anyLong())) + .thenReturn(items); + + List requestDtos = requestService.findAll(1L, 0, 1); + + Assertions.assertEquals(request.getId(), requestDtos.get(0).getId()); + + } + + @Test + void findAllRequestTest() { + addRequest(); + addItem(); + List items = new ArrayList<>(); + items.add(item); + List requests = new ArrayList<>(); + requests.add(request); + request.setCreated(LocalDateTime.now().minusHours(5)); + request.setId(2L); + requests.add(request); + Page page = new PageImpl<>(requests); + + Mockito + .when(requestRepository.findAll()) + .thenReturn(requests); + + Mockito + .when(itemRepository.findByRequest(Mockito.anyLong())) + .thenReturn(items); + + List requestDtos = requestService.findAll(1L, null, null); + + Assertions.assertEquals(request.getId(), requestDtos.get(0).getId()); + + } + + @Test + void findAllRequestSizeOrPageLessZeroTest() { + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> requestService.findAll(1L, 1, -1)); + + Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + exception.getMessage()); + + } + + @Test + void findAllRequestSizeEqualZeroTest() { + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> requestService.findAll(1L, 1, 0)); + + Assertions.assertEquals("Size не может принимать значение 0", + exception.getMessage()); + + } + + @Test + void findRequestTest() { + addRequest(); + addItem(); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(requester)); + + Mockito + .when(requestRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(request)); + + Optional requestDto = Optional.ofNullable(requestService.findById(1L, 1L)); + + assertThat(requestDto) + .isPresent() + .hasValueSatisfying(addRequestTest -> { + assertThat(addRequestTest).hasFieldOrPropertyWithValue("id", request.getId()); + assertThat(addRequestTest).hasFieldOrPropertyWithValue("requestor", + request.getRequester()); + assertThat(addRequestTest).hasFieldOrPropertyWithValue("description", + request.getDescription()); + assertThat(addRequestTest).hasFieldOrPropertyWithValue("created", + request.getCreated()); + } + ); + + } + + @Test + void findRequestNotFounUserTest() { + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.empty()); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> requestService.findById(3L, 1L)); + + Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + + } + + @Test + void findRequestNotFounTest() { + addUser(); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(requester)); + + Mockito + .when(requestRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.empty()); + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> requestService.findById(3L, 1L)); + + Assertions.assertEquals("Запрос не найден", exception.getMessage()); + + } + + private void addUser() { + requester.setId(1L); + requester.setName("Leo"); + requester.setEmail("leo@angel.com"); + } + + private void addRequest() { + addUser(); + request.setId(1L); + request.setRequester(requester); + request.setDescription("I need a fork"); + request.setCreated(LocalDateTime.now()); + } + + private void addItem() { + User owner = new User(); + owner.setId(2L); + owner.setName("Buffy"); + owner.setEmail("buffy@vampire.com"); + item.setId(1L); + item.setName("Fork"); + item.setOwner(owner); + item.setAvailable(true); + item.setDescription("Designed for food"); + item.setRequestId(request); + } +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/user/UserControllerTest.java b/src/test/java/ru/practicum/shareit/user/UserControllerTest.java new file mode 100644 index 000000000..b16176993 --- /dev/null +++ b/src/test/java/ru/practicum/shareit/user/UserControllerTest.java @@ -0,0 +1,161 @@ +package ru.practicum.shareit.user; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultHandlers; +import ru.practicum.shareit.exception.BadRequestException; +import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.user.dto.UserDTO; +import ru.practicum.shareit.user.service.UserServiceImpl; + +import java.nio.charset.StandardCharsets; +import java.util.List; + +import static org.hamcrest.Matchers.hasSize; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import static org.hamcrest.Matchers.is; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@WebMvcTest(controllers = UserController.class) +class UserControllerTest { + + @Autowired + ObjectMapper mapper; + + @MockBean + UserServiceImpl userService; + + @Autowired + private MockMvc mvc; + + private final UserDTO userDto = new UserDTO(); + + @Test + void createUserControllerTest() throws Exception { + addUser(); + + when(userService.create(any())) + .thenReturn(userDto); + + mvc.perform(post("/users") + .content(mapper.writeValueAsString(userDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(userDto.getId()), Long.class)) + .andExpect(jsonPath("$.name", is(userDto.getName()))) + .andExpect(jsonPath("$.email", is(userDto.getEmail()))); + } + + @Test + void updateUserControllerTest() throws Exception { + addUser(); + + when(userService.update(1L, userDto)) + .thenReturn(userDto); + + mvc.perform(patch("/users/1/") + .content(mapper.writeValueAsString(userDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(userDto.getId()), Long.class)) + .andExpect(jsonPath("$.name", is(userDto.getName()))) + .andExpect(jsonPath("$.email", is(userDto.getEmail()))); + } + + @Test + void deleteUserControllerTest() throws Exception { + addUser(); + mvc.perform(MockMvcRequestBuilders.delete("/users/1/")) + .andExpect(status().isOk()); + + } + + @Test + void getUsersControllerTest() throws Exception { + addUser(); + when(userService.getAll()) + .thenReturn(List.of(userDto)); + + mvc.perform(get("/users")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", hasSize(1))) + .andExpect(jsonPath("$[0].id", is(userDto.getId()), Long.class)) + .andExpect(jsonPath("$[0].name", is(userDto.getName()))) + .andExpect(jsonPath("$[0].email", is(userDto.getEmail()))); + } + + + @Test + void getUserControllerTest() throws Exception { + addUser(); + when(userService.get(Mockito.anyLong())) + .thenReturn(userDto); + + mvc.perform(get("/users/1/")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(userDto.getId()), Long.class)) + .andExpect(jsonPath("$.name", is(userDto.getName()))) + .andExpect(jsonPath("$.email", is(userDto.getEmail()))); + } + + + @Test + void createUserWithException() throws Exception { + when(userService.create(any())) + .thenThrow(BadRequestException.class); + + mvc.perform(post("/users") + .content(mapper.writeValueAsString(userDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultHandlers.print()) + .andExpect(status().is(400)); + } + + @Test + void updateUserWithException() throws Exception { + when(userService.update(1L, userDto)) + .thenThrow(NotFoundException.class); + + mvc.perform(patch("/users/1/") + .content(mapper.writeValueAsString(userDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultHandlers.print()) + .andExpect(status().is(404)); + } + + @Test + void deleteUserWithException() throws Exception { + doReturn(Exception.class); + mvc.perform(MockMvcRequestBuilders.delete("/users/1/")) + .andExpect(status().is(500)); + } + + private void addUser() { + userDto.setId(1L); + userDto.setName("Leo"); + userDto.setEmail("leo@angel.com"); + } + +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/user/dto/UserDtoTest.java b/src/test/java/ru/practicum/shareit/user/dto/UserDtoTest.java new file mode 100644 index 000000000..538b09b9c --- /dev/null +++ b/src/test/java/ru/practicum/shareit/user/dto/UserDtoTest.java @@ -0,0 +1,30 @@ +package ru.practicum.shareit.user.dto; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.json.JsonTest; +import org.springframework.boot.test.json.JacksonTester; +import org.springframework.boot.test.json.JsonContent; + +import static org.assertj.core.api.Assertions.assertThat; + +@JsonTest +class UserDtoTest { + @Autowired + private JacksonTester json; + + @Test + void testUserDto() throws Exception { + UserDTO userDto = new UserDTO(); + userDto.setId(1L); + userDto.setName("Leo"); + userDto.setEmail("leo@angel.com"); + + JsonContent result = json.write(userDto); + + assertThat(result).extractingJsonPathNumberValue("$.id").isEqualTo(1); + assertThat(result).extractingJsonPathStringValue("$.name").isEqualTo("Leo"); + assertThat(result).extractingJsonPathStringValue("$.email").isEqualTo("leo@angel.com"); + } + +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/user/service/UserServiceTest.java b/src/test/java/ru/practicum/shareit/user/service/UserServiceTest.java new file mode 100644 index 000000000..fdd701164 --- /dev/null +++ b/src/test/java/ru/practicum/shareit/user/service/UserServiceTest.java @@ -0,0 +1,213 @@ +package ru.practicum.shareit.user.service; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.annotation.DirtiesContext; +import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.user.UserMapper; +import ru.practicum.shareit.user.UserRepository; +import ru.practicum.shareit.user.dto.UserDTO; +import ru.practicum.shareit.user.model.User; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +import static org.mockito.ArgumentMatchers.any; + +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@ExtendWith(MockitoExtension.class) +class UserServiceTest { + + @InjectMocks + UserServiceImpl mockUserService; + + @Mock + UserRepository userRepository; + + @Test + void addUserTest() { + User user = new User(); + user.setId(1L); + user.setName("Buffy"); + user.setEmail("buffy@vampire.com"); + + Mockito + .when(userRepository.save(any())) + .thenReturn(user); + + Optional userDto = Optional.ofNullable(mockUserService.create(UserMapper.toUserDto(user))); + assertThat(userDto) + .isPresent() + .hasValueSatisfying(addUserTest -> { + assertThat(addUserTest).hasFieldOrPropertyWithValue("id", user.getId()); + assertThat(addUserTest).hasFieldOrPropertyWithValue("name", user.getName()); + assertThat(addUserTest).hasFieldOrPropertyWithValue("email", user.getEmail()); + } + ); + } + + @Test + void updateUserExceptionTest() { + UserDTO user = new UserDTO(); + user.setName("Buffy"); + user.setEmail("buffy@vampire.com"); + + Mockito + .when(userRepository.findById(2L)) + .thenThrow(new NotFoundException("Пользователь не найден")); + + + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> mockUserService.update(2L, user)); + + Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + + + } + + @Test + void updateUserEmptyTest() { + UserDTO user = new UserDTO(); + user.setName("Buffy"); + user.setEmail("buffy@vampire.com"); + Mockito + .when(userRepository.findById(0L)) + .thenReturn(Optional.empty()); + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> mockUserService.update(0L, user)); + + Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + } + + @Test + void updateUserTest() { + User user = new User(); + user.setId(1L); + user.setName("Buffy"); + user.setEmail("buffy@vampire.com"); + + Mockito + .when(userRepository.save(any())) + .thenReturn(user); + + Mockito + .when(userRepository.findById(1L)) + .thenReturn(Optional.of(user)); + + Optional userDto = Optional.ofNullable(mockUserService.update(1L, (UserMapper.toUserDto(user)))); + assertThat(userDto) + .isPresent() + .hasValueSatisfying(addUserTest -> { + assertThat(addUserTest).hasFieldOrPropertyWithValue("id", user.getId()); + assertThat(addUserTest).hasFieldOrPropertyWithValue("name", user.getName()); + assertThat(addUserTest).hasFieldOrPropertyWithValue("email", user.getEmail()); + } + ); + } + + @Test + void deleteUserExceptionTest() { + Mockito + .when(userRepository.findById(1L)) + .thenReturn(Optional.empty()); + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> mockUserService.delete(1L)); + + Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + } + + @Test + void deleteUserTest() { + User user = new User(); + user.setId(1L); + user.setName("Buffy"); + user.setEmail("buffy@vampire.com"); + + Mockito + .when(userRepository.findById(1L)) + .thenReturn(Optional.of(user)); + mockUserService.delete(1L); + Mockito.verify(userRepository).deleteById(1L); + + } + + @Test + void getAllUsersEmptyTest() { + Mockito + .when(userRepository.findAll()) + .thenReturn(new ArrayList<>()); + List userDtoList = mockUserService.getAll(); + Assertions.assertEquals(userDtoList, new ArrayList<>()); + + + } + + @Test + void getAllUsersTest() { + User user = new User(); + user.setId(1L); + user.setName("Buffy"); + user.setEmail("buffy@vampire.com"); + + User user1 = new User(); + user1.setId(2L); + user1.setName("Leo"); + user1.setEmail("leo@angel.com"); + + List users = new ArrayList<>(); + users.add(user1); + users.add(user); + + Mockito + .when(userRepository.findAll()) + .thenReturn(users); + + List getUsers = UserMapper.mapToUser(mockUserService.getAll()); + Assertions.assertEquals(getUsers, users); + } + + @Test + void getUserExceptionTest() { + Mockito + .when(userRepository.findById(1L)) + .thenReturn(Optional.empty()); + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> mockUserService.get(1L)); + + Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + } + + @Test + void getUserTest() { + User user = new User(); + user.setId(1L); + user.setName("Buffy"); + user.setEmail("buffy@vampire.com"); + + Mockito + .when(userRepository.findById(1L)) + .thenReturn(Optional.of(user)); + + Optional userDto = Optional.ofNullable(mockUserService.get(1L)); + assertThat(userDto) + .isPresent() + .hasValueSatisfying(addUserTest -> { + assertThat(addUserTest).hasFieldOrPropertyWithValue("id", user.getId()); + assertThat(addUserTest).hasFieldOrPropertyWithValue("name", user.getName()); + assertThat(addUserTest).hasFieldOrPropertyWithValue("email", user.getEmail()); + } + ); + } +} \ No newline at end of file diff --git a/src/test/resources/data.sql b/src/test/resources/data.sql new file mode 100644 index 000000000..589e76af0 --- /dev/null +++ b/src/test/resources/data.sql @@ -0,0 +1,26 @@ +INSERT INTO USERS (NAME, EMAIL) +VALUES ('Buffy', 'buffy@vampire.com'), + ('Leo', 'leo@angel.com'), + ('Kuzya', 'kuzya@brownie.com'), + ('Sheldon cooper', 'cooper@physicist.com'); + +INSERT INTO REQUESTS (DESCRIPTION, REQUESTOR_ID, CREATED) +VALUES ('I need a fork', '1', '2022-11-25 12:32:59'), + ('I need wings', '2', '2022-11-25 12:32:59'), + ('I need jam', '3', '2022-11-25 12:32:59'), + ('I need a Nobel prize', '4', '2022-11-25 12:32:59'); + +INSERT INTO ITEMS (NAME, DESCRIPTION, AVAILABLE, OWNER_ID, REQUEST_ID) +VALUES ('Fork', 'It is needed in order to eat', true, '3', '1'), + ('Wings', 'Need to fly', true, '1', '2'), + ('Jam', 'Очень вкусное и сладкое', true, '4', '3'), + ('Nobel prize', 'One of the most prestigious international awards', true, '2', '4'); + +INSERT INTO BOOKINGS (START_DATE, END_DATE, ITEM_ID, BOOKER_ID, STATUS) +VALUES ('2022-11-11 12:32:59', '2022-11-25 12:32:59', '1', '4', 'WAITING'), + ('2022-11-11 12:32:59', '2024-11-25 12:32:59', '2', '3', 'WAITING'), + ('2024-11-11 12:32:59', '2025-11-25 12:32:59', '3', '2', 'WAITING'), + ('2023-11-11 12:32:59', '2023-11-25 12:32:59', '4', '1', 'WAITING'); + +INSERT INTO COMMENTS (TEXT, ITEM_ID, AUTHOR_ID, CREATED) +VALUES ('The best fork', '1', '4', '2022-11-25 12:34:59'); From 0cdc95b76a9f414574aa2e1f745df7a92f410fa5 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Sat, 11 Feb 2023 02:07:32 +0300 Subject: [PATCH 29/45] Add files via upload --- .../shareit/booking/dto/BookingDTO.java | 3 --- .../booking/service/BookingServiceImpl.java | 1 - .../booking/BookingControllerTest.java | 13 ++++------- .../shareit/item/ItemControllerTest.java | 22 +++++++++---------- .../request/ItemRequestControllerTest.java | 18 +++++---------- 5 files changed, 20 insertions(+), 37 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java index 8f96efccd..2114dd883 100644 --- a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTO.java @@ -1,13 +1,10 @@ package ru.practicum.shareit.booking.dto; import com.fasterxml.jackson.annotation.JsonFormat; -import com.sun.istack.NotNull; import lombok.Data; import lombok.NoArgsConstructor; import ru.practicum.shareit.booking.model.Status; -import javax.validation.constraints.Future; -import javax.validation.constraints.FutureOrPresent; import java.time.LocalDateTime; @Data diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java index d862a6b42..f80fdb723 100644 --- a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java @@ -24,7 +24,6 @@ import ru.practicum.shareit.user.model.User; import java.time.LocalDateTime; -import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.Optional; diff --git a/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java b/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java index a805a1869..595e18d46 100644 --- a/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java +++ b/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java @@ -21,7 +21,6 @@ import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import static org.hamcrest.Matchers.is; @@ -35,21 +34,17 @@ @WebMvcTest(controllers = BookingController.class) class BookingControllerTest { + private final Booking booking = new Booking(); + private final BookingDTOToReturn bookingDto = new BookingDTOToReturn(); + private final Item item = new Item(); + private final User user = new User(); @Autowired ObjectMapper mapper; - @MockBean BookingServiceImpl bookingService; - @Autowired private MockMvc mvc; - private final Booking booking = new Booking(); - - private final BookingDTOToReturn bookingDto = new BookingDTOToReturn(); - private final Item item = new Item(); - private final User user = new User(); - @Test void addBookingControllerTest() throws Exception { addItem(); diff --git a/src/test/java/ru/practicum/shareit/item/ItemControllerTest.java b/src/test/java/ru/practicum/shareit/item/ItemControllerTest.java index 8b6c88f9b..dad6b6168 100644 --- a/src/test/java/ru/practicum/shareit/item/ItemControllerTest.java +++ b/src/test/java/ru/practicum/shareit/item/ItemControllerTest.java @@ -12,9 +12,9 @@ import org.springframework.test.web.servlet.result.MockMvcResultHandlers; import ru.practicum.shareit.booking.dto.BookingDTOForItem; import ru.practicum.shareit.exception.BadRequestException; +import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithBookings; -import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.model.Comment; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.item.service.ItemServiceImpl; @@ -31,27 +31,25 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @WebMvcTest(controllers = ItemController.class) class ItemControllerTest { - @Autowired - ObjectMapper mapper; - - @MockBean - ItemServiceImpl itemService; - - @Autowired - private MockMvc mvc; - private final ItemDTO itemDto = new ItemDTO(); private final Item item = new Item(); private final User user = new User(); private final Comment comment = new Comment(); private final ItemDTOWithBookings itemDtoWithBooking = new ItemDTOWithBookings(); private final BookingDTOForItem booking = new BookingDTOForItem(); + @Autowired + ObjectMapper mapper; + @MockBean + ItemServiceImpl itemService; + @Autowired + private MockMvc mvc; @Test void addItemControllerTest() throws Exception { @@ -156,7 +154,7 @@ void getAllOwnItemsControllerTest() throws Exception { .andExpect(jsonPath("$[0].lastBooking.dateTime", is(itemDtoWithBooking.getLastBooking() .getDateTime().toString()))) .andExpect(jsonPath("$[0].nextBooking.id", is((int) itemDtoWithBooking.getNextBooking().getId()))) - .andExpect(jsonPath("$[0].nextBooking.bookerId", is( itemDtoWithBooking.getNextBooking() + .andExpect(jsonPath("$[0].nextBooking.bookerId", is(itemDtoWithBooking.getNextBooking() .getBookerId()))) .andExpect(jsonPath("$[0].nextBooking.dateTime", is(itemDtoWithBooking.getNextBooking() .getDateTime().toString()))) diff --git a/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java b/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java index 45afcffce..f9ff4dc7b 100644 --- a/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java +++ b/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java @@ -36,24 +36,18 @@ @WebMvcTest(controllers = ItemRequestController.class) class ItemRequestControllerTest { + private final RequestDTO requestDto = new RequestDTO(); + private final RequestDTOWithItems requestWithItems = new RequestDTOWithItems(); + private final ItemDTO itemDto = new ItemDTO(); + private final User user = new User(); + private final Comment comment = new Comment(); @Autowired ObjectMapper mapper; - @MockBean RequestService requestService; - @Autowired private MockMvc mvc; - private final RequestDTO requestDto = new RequestDTO(); - private final RequestDTOWithItems requestWithItems = new RequestDTOWithItems(); - private final ItemDTO itemDto = new ItemDTO(); - private final Item item = new Item(); - private final User user = new User(); - private final Comment comment = new Comment(); - private final ItemDTOWithBookings itemDtoWithBooking = new ItemDTOWithBookings(); - private final BookingDTOForItem booking = new BookingDTOForItem(); - @Test void addRequestControllerTest() throws Exception { addRequestDto(); @@ -70,7 +64,7 @@ void addRequestControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.id", is(requestDto.getId()), Long.class)) .andExpect(jsonPath("$.created", is(requestDto.getCreated().toString()))) - .andExpect(jsonPath("$.requester.id", is( requestDto.getRequester().getId()))) + .andExpect(jsonPath("$.requester.id", is(requestDto.getRequester().getId()))) .andExpect(jsonPath("$.requester.name", is(requestDto.getRequester().getName()))) .andExpect(jsonPath("$.requester.email", is(requestDto.getRequester().getEmail()))) .andExpect(jsonPath("$.description", is(requestDto.getDescription()))); From 5dcce4f19373c5ae30ad39151e8283c091eb9048 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Sat, 11 Feb 2023 02:09:58 +0300 Subject: [PATCH 30/45] Add files via upload --- .../practicum/shareit/request/ItemRequestControllerTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java b/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java index f9ff4dc7b..c75cf27b7 100644 --- a/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java +++ b/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java @@ -9,12 +9,9 @@ import org.springframework.http.MediaType; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.web.servlet.MockMvc; -import ru.practicum.shareit.booking.dto.BookingDTOForItem; import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; -import ru.practicum.shareit.item.dto.ItemDTOWithBookings; import ru.practicum.shareit.item.model.Comment; -import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.request.dto.RequestDTO; import ru.practicum.shareit.request.dto.RequestDTOWithItems; import ru.practicum.shareit.request.service.RequestService; From 315ac892a88e90ea2599c7680901567f1f2b3e04 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Sat, 11 Feb 2023 23:55:48 +0300 Subject: [PATCH 31/45] =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D1=81?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shareit/booking/BookingMapper.java | 6 +- .../shareit/booking/BookingRepository.java | 2 - .../booking/dto/BookingDTOToReturn.java | 16 +- .../booking/service/BookingServiceImpl.java | 30 ++- .../shareit/item/ItemController.java | 6 +- .../shareit/item/mapper/ItemMapper.java | 22 +- .../ru/practicum/shareit/item/model/Item.java | 6 +- .../shareit/item/service/ItemService.java | 3 +- .../shareit/item/service/ItemServiceImpl.java | 25 +- .../request/service/RequestServiceImpl.java | 25 +- .../ru/practicum/shareit/user/UserMapper.java | 5 +- .../ru/practicum/shareit/ShareItTests.java | 68 ++--- .../booking/BookingControllerTest.java | 30 +-- .../booking/BookingRepositoryTest.java | 167 ++++++------ .../booking/service/BookingServiceTest.java | 255 +++++++++--------- .../shareit/item/CommentRepositoryTest.java | 14 +- .../shareit/item/ItemControllerTest.java | 45 ++-- .../shareit/item/ItemRepositoryTest.java | 23 +- .../shareit/item/dto/ItemDtoTest.java | 2 +- .../item/dto/ItemDtoWithBookingTest.java | 4 +- .../shareit/item/service/ItemServiceTest.java | 110 +++----- .../request/ItemRequestControllerTest.java | 31 +-- .../request/ItemRequestRepositoryTest.java | 14 +- .../service/ItemRequestServiceTest.java | 35 ++- .../shareit/user/UserControllerTest.java | 5 +- .../shareit/user/dto/UserDtoTest.java | 8 +- .../shareit/user/service/UserServiceTest.java | 71 +++-- src/test/resources/data.sql | 32 +-- 28 files changed, 506 insertions(+), 554 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java index 37f79af8d..361fcf0fd 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java @@ -6,9 +6,7 @@ import ru.practicum.shareit.booking.dto.BookingDTOToReturn; import ru.practicum.shareit.booking.model.Booking; import ru.practicum.shareit.booking.model.Status; -import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Item; -import ru.practicum.shareit.user.UserMapper; import ru.practicum.shareit.user.model.User; import java.util.ArrayList; @@ -23,8 +21,8 @@ public static BookingDTOToReturn toBookingDtoFrom(Booking booking) { bookingDto.setStart(booking.getStart()); bookingDto.setEnd(booking.getEnd()); bookingDto.setStatus(booking.getStatus()); - bookingDto.setItem(ItemMapper.toItemToBookingDTO(booking.getItem())); - bookingDto.setBooker(UserMapper.toUserToBookingDTO(booking.getBooker())); + bookingDto.setItem((booking.getItem())); + bookingDto.setBooker((booking.getBooker())); return bookingDto; } diff --git a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java index bf1db543d..7dce6502c 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingRepository.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingRepository.java @@ -16,8 +16,6 @@ public interface BookingRepository extends JpaRepository { - //переделать все запросы с натив куери - List findByBookerAndStatusOrderByStartDesc(User booker, Status status); List findByBookerOrderByStartDesc(User booker); diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java index b941a19f3..786c8a577 100644 --- a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java @@ -2,6 +2,8 @@ import lombok.Data; import ru.practicum.shareit.booking.model.Status; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.model.User; import java.time.LocalDateTime; @@ -19,18 +21,4 @@ public class BookingDTOToReturn { private User booker; private Status status; - - @Data - public static class User { - private final long id; - private final String name; - private final String email; - } - - @Data - public static class Item { - private final long id; - private final String name; - private final String description; - } } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java index f80fdb723..eab19c2ce 100644 --- a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java @@ -42,9 +42,9 @@ public class BookingServiceImpl implements BookingService { @Override public BookingDTOToReturn add(Long userId, BookingDTO bookingDto) { Item item = iRepository.findById(bookingDto.getItemId()) - .orElseThrow(() -> new NotFoundException("User not found")); - User user = uRepository.findById(userId) .orElseThrow(() -> new NotFoundException("Item not found")); + User user = uRepository.findById(userId) + .orElseThrow(() -> new NotFoundException("User not found")); if (!item.getAvailable()) { throw new BadRequestException("You can not book this item"); } @@ -58,15 +58,20 @@ public BookingDTOToReturn add(Long userId, BookingDTO bookingDto) { throw new BadRequestException("Wrong date"); } Booking booking = bRepository.save(BookingMapper.toBooking(bookingDto, item, user)); - log.info(booking.toString()); +// log.info(booking.toString()); return BookingMapper.toBookingDtoFrom(booking); } @Transactional @Override public BookingDTOToReturn update(Long userId, Long bookingId, Boolean approved) { - Booking booking = Optional.of(bRepository.getReferenceById(bookingId)) - .orElseThrow(() -> new NotFoundException("Booking not found")); + Booking booking; + try { + booking = bRepository.getReferenceById(bookingId); + log.info(booking.toString()); + } catch (NullPointerException e) { + throw new NotFoundException("Booking not found"); + } Long ownerId = booking.getItem().getOwner().getId(); if (!Objects.equals(userId, ownerId)) { @@ -102,15 +107,15 @@ public List getByBooker(Long userId, String status, Integer Optional booker = uRepository.findById(userId); Pageable pageable; if (booker.isEmpty()) { - throw new NotFoundException("Для пользователя нет доступа"); + throw new NotFoundException("No rights"); } User user = booker.get(); if (page != null && size != null) { if (page < 0 || size < 0) { - throw new BadRequestException("From или size не могут принимать отрицательноге значение"); + throw new BadRequestException("Wrong meaning page or size"); } if (size == 0) { - throw new BadRequestException("Size не может принимать значение 0"); + throw new BadRequestException("Size equals 0!"); } pageable = PageRequest.of(page / size, size); return findBookingByBookerByPage(user, status, pageable); @@ -188,17 +193,14 @@ private List findBookingByBookerByPage(User booker, String s @Override public List getByOwner(Long userId, String status, Integer page, Integer size) { - Optional owner = uRepository.findById(userId); + User owner = uRepository.findById(userId).orElseThrow(() -> new NotFoundException("User not found")); Pageable pageable; - if (owner.isEmpty()) { - throw new NotFoundException("Для пользователя нет доступа"); - } if (page != null && size != null) { if (page < 0 || size < 0) { - throw new BadRequestException("From или size не могут принимать отрицательноге значение"); + throw new BadRequestException("From or size is less than 0"); } if (size == 0) { - throw new BadRequestException("Size не может принимать значение 0"); + throw new BadRequestException("Size equals 0"); } pageable = PageRequest.of(page / size, size); diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/src/main/java/ru/practicum/shareit/item/ItemController.java index 09a440c1a..0aa70ceef 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -49,9 +49,11 @@ public List getAllByOwner(@RequestHeader("X-Sharer-User-Id" @GetMapping("/search") public List getAllByText(@RequestHeader("X-Sharer-User-Id") Long userId, - @RequestParam String text) { + @RequestParam String text, + @RequestParam(name = "from", required = false) Integer from, + @RequestParam(name = "size", required = false) Integer size) { log.info("Получение вещей для аренды содержащие в названии или описании текст {}", text); - return itemService.getAllByText(text); + return itemService.getForRent(text, from, size); } @PostMapping("{itemId}/comment") diff --git a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java index 878bb1aff..196a2959f 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java @@ -2,7 +2,6 @@ import lombok.experimental.UtilityClass; import ru.practicum.shareit.booking.BookingMapper; -import ru.practicum.shareit.booking.dto.BookingDTOToReturn; import ru.practicum.shareit.booking.model.Booking; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithBookings; @@ -74,10 +73,16 @@ public static List mapToItemDto(Iterable items) { return dtos; } - public static BookingDTOToReturn.Item toItemToBookingDTO(Item item) { - return new BookingDTOToReturn.Item(item.getId(), item.getName(), item.getDescription()); + /* public static BookingDTOToReturn.Item toItemToBookingDTO(Item item) { + BookingDTOToReturn.Item item1 = new BookingDTOToReturn.Item(); + item1.setId(item.getId()); + item1.setDescription(item.getDescription()); + item1.setName(item.getName()); + return item1; } + */ + public static ItemDTOWithBookings toDtoWithBookings(Item item, List bookings, List comments) { ItemDTOWithBookings iDTO = new ItemDTOWithBookings(); @@ -108,6 +113,17 @@ public static List mapToItem(Iterable items) { } return dtos; } + + /* public static Item toItem(BookingDTOToReturn.Item itemForBooking) { + Item item = new Item(); + item.setId(itemForBooking.getId()); + item.setName(itemForBooking.getName()); + item.setDescription(itemForBooking.getDescription()); + // item.setAvailable(itemForBooking.getAvailable()); + return item; + } + + */ } diff --git a/src/main/java/ru/practicum/shareit/item/model/Item.java b/src/main/java/ru/practicum/shareit/item/model/Item.java index f53a45f70..3204c8919 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Item.java +++ b/src/main/java/ru/practicum/shareit/item/model/Item.java @@ -1,9 +1,6 @@ package ru.practicum.shareit.item.model; -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.Setter; -import lombok.ToString; +import lombok.*; import org.hibernate.Hibernate; import ru.practicum.shareit.request.model.ItemRequest; import ru.practicum.shareit.user.model.User; @@ -19,6 +16,7 @@ @Setter @ToString @RequiredArgsConstructor +@AllArgsConstructor public class Item { @Id diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemService.java b/src/main/java/ru/practicum/shareit/item/service/ItemService.java index c5176a5e1..7b1700031 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemService.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemService.java @@ -4,7 +4,6 @@ import ru.practicum.shareit.item.dto.ItemDTOWithBookings; import ru.practicum.shareit.item.dto.CommentDTO; -import java.util.Collection; import java.util.List; public interface ItemService { @@ -21,5 +20,5 @@ public interface ItemService { CommentDTO addComment(Long authorId, Long itemId, CommentDTO comment); - Collection getForRent(String substring, Integer page, Integer size); + List getForRent(String substring, Integer page, Integer size); } diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index 73ec5b345..4efdeb736 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -3,6 +3,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -43,8 +44,6 @@ @Slf4j public class ItemServiceImpl implements ItemService { - //переписать методы с новыми переменными - private final ItemRepository itemRepository; private final UserRepository userRepository; private final BookingRepository bookingRepository; @@ -104,11 +103,21 @@ public ItemDTOWithBookings get(Long userId, Long itemId) { @Override public List getAllByOwner(Long userId, Integer page, Integer size) { - if (!userRepository.existsById(userId)) { - throw new NotFoundException("User not found"); + User user = userRepository.findById(userId).orElseThrow(() -> new NotFoundException("User not found")); + List items = new ArrayList<>(); + if (page != null && size != null) { + sizeAndPage(size, page); + Pageable pageable = PageRequest.of(page / size, size); + Page itemsPage = itemRepository.findByOwner(user, pageable); + for (Item item : itemsPage) { + items.add(item); + } + } else { + items = itemRepository.findByOwner(user); } + log.info(userId.toString()); - List items = itemRepository.getAllByOwnerId(userId); + log.info(String.valueOf(items.size())); Map> approvedBookings = bookingRepository.findApprovedForItems(items, Sort.by(DESC, "start")) @@ -162,7 +171,7 @@ public CommentDTO addComment(Long authorId, Long itemId, CommentDTO comment) { } @Override - public Collection getForRent(String substring, Integer page, Integer size) { + public List getForRent(String substring, Integer page, Integer size) { if (!Objects.equals(substring, "")) { if (page != null && size != null) { sizeAndPage(size, page); @@ -176,10 +185,10 @@ public Collection getForRent(String substring, Integer page, Integer si private void sizeAndPage(Integer size, Integer page) { if (page < 0 || size < 0) { - throw new BadRequestException("From или size не могут принимать отрицательноге значение"); + throw new BadRequestException("From or size is less than 0"); } if (size == 0) { - throw new BadRequestException("Size не может принимать значение 0"); + throw new BadRequestException("Size equals 0"); } } } diff --git a/src/main/java/ru/practicum/shareit/request/service/RequestServiceImpl.java b/src/main/java/ru/practicum/shareit/request/service/RequestServiceImpl.java index e2936af7c..3aef5ef91 100644 --- a/src/main/java/ru/practicum/shareit/request/service/RequestServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/request/service/RequestServiceImpl.java @@ -40,10 +40,10 @@ public class RequestServiceImpl implements RequestService { @Override @Transactional public RequestDTO add(Long userId, RequestDTO request) { - User user = uRepository.findById(userId).orElseThrow(() -> new NotFoundException("Пользователь не найден")); + User user = uRepository.findById(userId).orElseThrow(() -> new NotFoundException("User not found")); log.info(request.toString()); if (request.getDescription() == null || Objects.equals(request.getDescription(), "")) { - throw new BadRequestException("Отсутствует описание для поиска вещи"); + throw new BadRequestException("Description is empty"); } request.setCreated(LocalDateTime.now()); request.setRequester(user); @@ -53,7 +53,7 @@ public RequestDTO add(Long userId, RequestDTO request) { @Override public List findAllByOwner(Long userId) { - User user = uRepository.findById(userId).orElseThrow(() -> new NotFoundException("Пользователь не найден")); + User user = uRepository.findById(userId).orElseThrow(() -> new NotFoundException("User not found")); List requests = new ArrayList<>(); List itemRequests = rRepository.findByRequesterOrderByCreatedDesc(user); for (ItemRequest request : itemRequests) { @@ -70,35 +70,24 @@ public List findAll(Long userId, Integer page, Integer size Pageable pageable; Sort sortById = Sort.by(Sort.Direction.DESC, "created"); if (page != null && size != null) { - log.info("page and size"); if (page < 0 || size < 0) { - log.info("wrong from or size"); - throw new BadRequestException("From или size не могут принимать отрицательноге значение"); + throw new BadRequestException("From and size cannot be less than 0"); } if (size == 0) { - log.info("size equals null"); - throw new BadRequestException("Size не может принимать значение 0"); + throw new BadRequestException("Size cannot be 0"); } pageable = PageRequest.of(page / size, size, sortById); - log.info("page"); Page requests = rRepository.findAllBy(userId, pageable); - log.info(requests.toString()); for (ItemRequest request : requests) { - log.info(request.toString()); - log.info("request"); List items = iRepository.findByRequest(request.getId()); - log.info(String.valueOf(items.size())); RequestDTOWithItems request1 = RequestMapper.toRequestForFindDto(request, ItemMapper.mapToItemDto(items)); - log.info(request1.toString()); requestForFindDtos.add(request1); } - log.info("request get"); return requestForFindDtos; } List requests = rRepository.findAll(); for (ItemRequest request : requests) { - log.info("request without pageable" + request.getId()); List items = iRepository.findByRequest(request.getId()); RequestDTOWithItems request1 = RequestMapper.toRequestForFindDto(request, ItemMapper.mapToItemDto(items)); requestForFindDtos.add(request1); @@ -108,9 +97,9 @@ public List findAll(Long userId, Integer page, Integer size @Override public RequestDTOWithItems findById(Long userId, Long requestId) { - uRepository.findById(userId).orElseThrow(() -> new NotFoundException("Пользователь не найден")); + uRepository.findById(userId).orElseThrow(() -> new NotFoundException("User not found")); ItemRequest request = rRepository.findById(requestId) - .orElseThrow(() -> new NotFoundException("Запрос не найден")); + .orElseThrow(() -> new NotFoundException("Request not found")); List items = iRepository.findByRequest(requestId); return RequestMapper.toRequestForFindDto(request, ItemMapper.mapToItemDto(items)); } diff --git a/src/main/java/ru/practicum/shareit/user/UserMapper.java b/src/main/java/ru/practicum/shareit/user/UserMapper.java index 122d04dfa..54dea0aa8 100644 --- a/src/main/java/ru/practicum/shareit/user/UserMapper.java +++ b/src/main/java/ru/practicum/shareit/user/UserMapper.java @@ -1,7 +1,6 @@ package ru.practicum.shareit.user; import lombok.experimental.UtilityClass; -import ru.practicum.shareit.booking.dto.BookingDTOToReturn; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithBookings; import ru.practicum.shareit.user.dto.UserDTO; @@ -44,10 +43,12 @@ public static List mapToUserDto(Iterable users) { return dtos; } - public static BookingDTOToReturn.User toUserToBookingDTO(User user) { + /* public static BookingDTOToReturn.User toUserToBookingDTO(User user) { return new BookingDTOToReturn.User(user.getId(), user.getName(), user.getEmail()); } + */ + public static ItemDTOWithBookings.User toUserToItemWithBookingsDto(User user) { return new ItemDTOWithBookings.User(user.getId(), user.getName(), user.getEmail()); } diff --git a/src/test/java/ru/practicum/shareit/ShareItTests.java b/src/test/java/ru/practicum/shareit/ShareItTests.java index 32d9bb7c1..85f12b94b 100644 --- a/src/test/java/ru/practicum/shareit/ShareItTests.java +++ b/src/test/java/ru/practicum/shareit/ShareItTests.java @@ -1,6 +1,7 @@ package ru.practicum.shareit; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -15,6 +16,8 @@ import ru.practicum.shareit.exception.StatusBadRequestException; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithBookings; +import ru.practicum.shareit.item.mapper.ItemMapper; +import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.item.service.ItemService; import ru.practicum.shareit.request.dto.RequestDTOWithItems; import ru.practicum.shareit.request.service.RequestService; @@ -27,6 +30,7 @@ @AutoConfigureTestDatabase @RequiredArgsConstructor(onConstructor_ = {@Autowired}) @TestExecutionListeners({DirtiesContextBeforeModesTestExecutionListener.class}) +@Slf4j class ShareItTests { private final BookingService bookingService; @@ -42,8 +46,7 @@ void getAllOwnItemTest() { List items = itemService.getAllByOwner(1L, null, null); assertThat(items).isNotEmpty(); assertThat(items.size()).isEqualTo(1); - assertThat(items.get(0).getName()).isEqualTo("Wings"); - assertThat(items.get(0).getOwner().getId()).isEqualTo(1); + assertThat(items.get(0).getName()).isEqualTo("Knives"); } @Test @@ -51,7 +54,7 @@ void getAllOwnItemNotFoundUserTest() { final NotFoundException exception = Assertions.assertThrows( NotFoundException.class, () -> itemService.getAllByOwner(5L, null, null)); - assertThat(exception.getMessage()).isEqualTo("Пользователь не найден"); + assertThat(exception.getMessage()).isEqualTo("User not found"); } @@ -61,7 +64,7 @@ void getAllOwnItemFromOrSizeLessThanZeroTest() { BadRequestException.class, () -> itemService.getAllByOwner(1L, -1, 0)); - Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + Assertions.assertEquals("From or size is less than 0", exception.getMessage()); } @@ -71,19 +74,18 @@ void getAllOwnItemSizeEqualToZeroTest() { BadRequestException.class, () -> itemService.getAllByOwner(1L, 1, 0)); - Assertions.assertEquals("Size не может принимать значение 0", exception.getMessage()); + Assertions.assertEquals("Size equals 0", exception.getMessage()); } @Test void getItemsForRentTest() { - List items = (List) itemService.getForRent("Fo", null, null); + List items = itemService.getForRent("Sw", null, null); assertThat(items).isNotEmpty(); assertThat(items.size()).isEqualTo(1); - assertThat(items.get(0).getName()).isEqualTo("Fork"); - assertThat(items.get(0).getOwner().getName()).isEqualTo("Kuzya"); - items = (List) itemService.getForRent("need", 0, 2); + assertThat(items.get(0).getName()).isEqualTo("Sword"); + items = itemService.getForRent("fight", 0, 1); assertThat(items).isNotEmpty(); - assertThat(items.size()).isEqualTo(2); + assertThat(items.size()).isEqualTo(1); } @Test @@ -92,7 +94,7 @@ void getItemForRentEqualToZeroTest() { BadRequestException.class, () -> itemService.getForRent("F", 0, 0)); - Assertions.assertEquals("Size не может принимать значение 0", exception.getMessage()); + Assertions.assertEquals("Size equals 0", exception.getMessage()); } @@ -102,19 +104,19 @@ void getItemsForRentFromOrSizeLessThanZeroTest() { BadRequestException.class, () -> itemService.getForRent("F", -1, 0)); - Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + Assertions.assertEquals("From or size is less than 0", exception.getMessage()); } @Test void getBookingByBookerStateAllTest() { - List bookings = (List) bookingService.getByBooker(3L, - null, null, null); + List bookings = bookingService.getByBooker(3L, + "ALL", null, null); assertThat(bookings).isNotEmpty(); assertThat(bookings.size()).isEqualTo(1); assertThat(bookings.get(0).getId()).isEqualTo(2); - bookings = (List) bookingService.getByBooker(3L, "ALL", null, null); + bookings = bookingService.getByBooker(3L, "ALL", null, null); assertThat(bookings).isNotEmpty(); assertThat(bookings.size()).isEqualTo(1); assertThat(bookings.get(0).getId()).isEqualTo(2); @@ -122,7 +124,7 @@ void getBookingByBookerStateAllTest() { @Test void getBookingByBookerStateCurrentTest() { - List bookings = (List) bookingService.getByBooker(3L, + List bookings = bookingService.getByBooker(3L, "CURRENT", null, null); assertThat(bookings).isNotEmpty(); assertThat(bookings.size()).isEqualTo(1); @@ -131,7 +133,7 @@ void getBookingByBookerStateCurrentTest() { @Test void getBookingByBookerStateFutureTest() { - List bookings = (List) bookingService.getByBooker(2L, + List bookings = bookingService.getByBooker(2L, "FUTURE", null, null); assertThat(bookings).isNotEmpty(); assertThat(bookings.size()).isEqualTo(1); @@ -140,7 +142,7 @@ void getBookingByBookerStateFutureTest() { @Test void getBookingByBookerStateWaitingOrRejectedTest() { - List bookings = (List) bookingService.getByBooker(1L, + List bookings = bookingService.getByBooker(1L, "WAITING", 0, 1); assertThat(bookings).isNotEmpty(); assertThat(bookings.size()).isEqualTo(1); @@ -163,7 +165,7 @@ void getBookingsByBookerNotFoundUserTest() { NotFoundException.class, () -> bookingService.getByBooker(5L, null, 0, 1)); - Assertions.assertEquals("Для пользователя нет доступа", exception.getMessage()); + Assertions.assertEquals("No rights", exception.getMessage()); } @@ -173,7 +175,7 @@ void getBookingsByBookerSizeOrPageLessZeroTest() { BadRequestException.class, () -> bookingService.getByBooker(3L, null, -1, 1)); - Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + Assertions.assertEquals("Wrong meaning page or size", exception.getMessage()); } @@ -184,7 +186,7 @@ void getBookingsByBookerSizeEqualZeroTest() { BadRequestException.class, () -> bookingService.getByBooker(3L, null, 0, 0)); - Assertions.assertEquals("Size не может принимать значение 0", exception.getMessage()); + Assertions.assertEquals("Size equals 0!", exception.getMessage()); } @@ -194,7 +196,7 @@ void getBookingsByOwnerNotFoundUserTest() { NotFoundException.class, () -> bookingService.getByOwner(8L, null, 0, 1)); - Assertions.assertEquals("Для пользователя нет доступа", exception.getMessage()); + Assertions.assertEquals("User not found", exception.getMessage()); } @Test @@ -203,19 +205,19 @@ void getBookingsByOwnerSizeOrPageLessZeroTest() { BadRequestException.class, () -> bookingService.getByOwner(1L, null, -1, 1)); - Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + Assertions.assertEquals("From or size is less than 0", exception.getMessage()); } @Test void getBookingsByOwnerByStateAllTest() { - List bookings = (List) bookingService.getByOwner(1L, - null, 0, 1); + List bookings = bookingService.getByOwner(1L, + "ALL", 0, 1); assertThat(bookings).isNotEmpty(); assertThat(bookings.size()).isEqualTo(1); assertThat(bookings.get(0).getId()).isEqualTo(2); - bookings = (List) bookingService.getByOwner(1L, "ALL", 0, 1); + bookings = bookingService.getByOwner(1L, "ALL", 0, 1); assertThat(bookings).isNotEmpty(); assertThat(bookings.size()).isEqualTo(1); assertThat(bookings.get(0).getId()).isEqualTo(2); @@ -223,7 +225,7 @@ void getBookingsByOwnerByStateAllTest() { @Test void getBookingsByOwnerByStatePastTest() { - List bookings = (List) bookingService.getByOwner(3L, + List bookings = bookingService.getByOwner(3L, "PAST", 0, 1); assertThat(bookings).isNotEmpty(); assertThat(bookings.size()).isEqualTo(1); @@ -232,7 +234,7 @@ void getBookingsByOwnerByStatePastTest() { @Test void getBookingsByOwnerByStateCurrentTest() { - List bookings = (List) bookingService.getByOwner(1L, + List bookings = bookingService.getByOwner(1L, "CURRENT", 0, 1); assertThat(bookings).isNotEmpty(); assertThat(bookings.size()).isEqualTo(1); @@ -241,7 +243,7 @@ void getBookingsByOwnerByStateCurrentTest() { @Test void getBookingsByOwnerByStateFutureTest() { - List bookings = (List) bookingService.getByOwner(2L, + List bookings = bookingService.getByOwner(2L, "FUTURE", 0, 1); assertThat(bookings).isNotEmpty(); assertThat(bookings.size()).isEqualTo(1); @@ -250,7 +252,7 @@ void getBookingsByOwnerByStateFutureTest() { @Test void getBookingsByOwnerByStateWaitingOrRejectedTest() { - List bookings = (List) bookingService.getByOwner(2L, + List bookings = bookingService.getByOwner(2L, "WAITING", 0, 1); assertThat(bookings).isNotEmpty(); assertThat(bookings.size()).isEqualTo(1); @@ -271,7 +273,7 @@ void findAllOwnRequestsNotFoundUserTest() { NotFoundException.class, () -> requestService.findAllByOwner(5L)); - Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + Assertions.assertEquals("User not found", exception.getMessage()); } @Test @@ -288,7 +290,7 @@ void findAllRequestsSizeOrPageLessZeroTest() { BadRequestException.class, () -> requestService.findAll(1L, 1, -1)); - Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + Assertions.assertEquals("From and size cannot be less than 0", exception.getMessage()); } @@ -298,7 +300,7 @@ void findAllRequestsSizeEqualZeroTest() { BadRequestException.class, () -> requestService.findAll(1L, 1, 0)); - Assertions.assertEquals("Size не может принимать значение 0", + Assertions.assertEquals("Size cannot be 0", exception.getMessage()); } diff --git a/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java b/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java index 595e18d46..7ae4846c6 100644 --- a/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java +++ b/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java @@ -10,12 +10,9 @@ import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.web.servlet.MockMvc; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; -import ru.practicum.shareit.booking.model.Booking; import ru.practicum.shareit.booking.model.Status; import ru.practicum.shareit.booking.service.BookingServiceImpl; -import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Item; -import ru.practicum.shareit.user.UserMapper; import ru.practicum.shareit.user.model.User; import java.nio.charset.StandardCharsets; @@ -34,7 +31,6 @@ @WebMvcTest(controllers = BookingController.class) class BookingControllerTest { - private final Booking booking = new Booking(); private final BookingDTOToReturn bookingDto = new BookingDTOToReturn(); private final Item item = new Item(); private final User user = new User(); @@ -62,7 +58,7 @@ void addBookingControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.id", is(bookingDto.getId()), Long.class)) .andExpect(jsonPath("$.start", is(bookingDto.getStart().toString()))) - .andExpect(jsonPath("$.booker.id", is((int) bookingDto.getBooker().getId()))) + .andExpect(jsonPath("$.booker.id", is(bookingDto.getBooker().getId().intValue()))) .andExpect(jsonPath("$.booker.name", is(bookingDto.getBooker().getName()))) .andExpect(jsonPath("$.booker.email", is(bookingDto.getBooker().getEmail()))) .andExpect(jsonPath("$.end", is(bookingDto.getEnd().toString()))) @@ -91,7 +87,7 @@ void updateStatusBookingControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.id", is(bookingDto.getId()), Long.class)) .andExpect(jsonPath("$.start", is(bookingDto.getStart().toString()))) - .andExpect(jsonPath("$.booker.id", is((int) bookingDto.getBooker().getId()))) + .andExpect(jsonPath("$.booker.id", is(bookingDto.getBooker().getId().intValue()))) .andExpect(jsonPath("$.booker.name", is(bookingDto.getBooker().getName()))) .andExpect(jsonPath("$.booker.email", is(bookingDto.getBooker().getEmail()))) .andExpect(jsonPath("$.end", is(bookingDto.getEnd().toString()))) @@ -118,7 +114,7 @@ void getBookingControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.id", is(bookingDto.getId()), Long.class)) .andExpect(jsonPath("$.start", is(bookingDto.getStart().toString()))) - .andExpect(jsonPath("$.booker.id", is((int) bookingDto.getBooker().getId()))) + .andExpect(jsonPath("$.booker.id", is( bookingDto.getBooker().getId().intValue()))) .andExpect(jsonPath("$.booker.name", is(bookingDto.getBooker().getName()))) .andExpect(jsonPath("$.booker.email", is(bookingDto.getBooker().getEmail()))) .andExpect(jsonPath("$.end", is(bookingDto.getEnd().toString()))) @@ -148,7 +144,7 @@ void findBookingByBookerControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$[0].id", is(bookingDto.getId()), Long.class)) .andExpect(jsonPath("$[0].start", is(bookingDto.getStart().toString()))) - .andExpect(jsonPath("$[0].booker.id", is((int) bookingDto.getBooker().getId()))) + .andExpect(jsonPath("$[0].booker.id", is( bookingDto.getBooker().getId().intValue()))) .andExpect(jsonPath("$[0].booker.name", is(bookingDto.getBooker().getName()))) .andExpect(jsonPath("$[0].booker.email", is(bookingDto.getBooker().getEmail()))) .andExpect(jsonPath("$[0].end", is(bookingDto.getEnd().toString()))) @@ -178,7 +174,7 @@ void findBookingByOwnerControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$[0].id", is(bookingDto.getId()), Long.class)) .andExpect(jsonPath("$[0].start", is(bookingDto.getStart().toString()))) - .andExpect(jsonPath("$[0].booker.id", is((int) bookingDto.getBooker().getId()))) + .andExpect(jsonPath("$[0].booker.id", is( bookingDto.getBooker().getId().intValue()))) .andExpect(jsonPath("$[0].booker.name", is(bookingDto.getBooker().getName()))) .andExpect(jsonPath("$[0].booker.email", is(bookingDto.getBooker().getEmail()))) .andExpect(jsonPath("$[0].end", is(bookingDto.getEnd().toString()))) @@ -191,27 +187,27 @@ void findBookingByOwnerControllerTest() throws Exception { private void addItem() { addUser(); item.setId(1L); - item.setName("Fork"); + item.setName("Sword"); item.setOwner(user); item.setAvailable(true); - item.setDescription("Designed for food"); + item.setDescription("For fight"); } private void addUser() { user.setId(1L); - user.setName("Buffy"); - user.setEmail("buffy@vampire.com"); + user.setName("Aelin"); + user.setEmail("aelin@whitethorn.com"); } private void addBookingDto() { User booker = new User(); booker.setId(4L); - booker.setName("Katya"); - booker.setEmail("katya@katya.com"); + booker.setName("Rowan"); + booker.setEmail("rowan@whitethorn.com"); bookingDto.setId(2L); - bookingDto.setItem(ItemMapper.toItemToBookingDTO(item)); + bookingDto.setItem(item); bookingDto.setStatus(Status.WAITING); - bookingDto.setBooker(UserMapper.toUserToBookingDTO(booker)); + bookingDto.setBooker(booker); String date = "2023-11-24T18:08:54"; LocalDateTime localdatetime = LocalDateTime.parse(date); bookingDto.setStart(localdatetime); diff --git a/src/test/java/ru/practicum/shareit/booking/BookingRepositoryTest.java b/src/test/java/ru/practicum/shareit/booking/BookingRepositoryTest.java index a0ce5405f..cbd63d735 100644 --- a/src/test/java/ru/practicum/shareit/booking/BookingRepositoryTest.java +++ b/src/test/java/ru/practicum/shareit/booking/BookingRepositoryTest.java @@ -1,5 +1,7 @@ package ru.practicum.shareit.booking; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; @@ -22,6 +24,7 @@ @DataJpaTest @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@Slf4j class BookingRepositoryTest { @Autowired @@ -35,7 +38,7 @@ class BookingRepositoryTest { private final ItemRequest request = new ItemRequest(); private final Booking bookingOne = new Booking(); private final Booking bookingTwo = new Booking(); - private final List bookingsPersist = new ArrayList<>(); + private final List bookingsList = new ArrayList<>(); @Test void findByItemOrderByStartDescTest() { @@ -44,12 +47,12 @@ void findByItemOrderByStartDescTest() { addUser(); addBookingTwo(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); booking = em.persist(bookingTwo); - bookingsPersist.add(booking); + bookingsList.add(booking); List bookings = bookingRepository.findByItemOrderByStartDesc(item); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.get(0).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -58,11 +61,11 @@ void findByBookerAndStatusOrderByStartDescTest() { addBookingOne(); addUser(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); List bookings = bookingRepository.findByBookerAndStatusOrderByStartDesc(bookingOne.getBooker(), Status.WAITING); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.get(0).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -71,14 +74,14 @@ void testFindByBookerAndStatusOrderByStartDesc() { addBookingOne(); addUser(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); Pageable pageable = PageRequest.of(0, 1); Page bookingsPage = bookingRepository.findByBookerAndStatusOrderByStartDesc(bookingOne.getBooker(), Status.WAITING, pageable); List bookings = bookingsPage.getContent(); - assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.size()).isEqualTo(bookings.size()); + assertThat(bookingsList.get(0).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -87,10 +90,10 @@ void findByBookerOrderByStartDescTest() { addBookingOne(); addUser(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); List bookings = bookingRepository.findByBookerOrderByStartDesc(bookingOne.getBooker()); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.get(0).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -99,14 +102,14 @@ void testFindByBookerOrderByStartDesc() { addBookingOne(); addUser(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); Pageable pageable = PageRequest.of(0, 1); Page bookingsPage = bookingRepository.findByBookerOrderByStartDesc(bookingOne.getBooker(), pageable); List bookings = bookingsPage.getContent(); - assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.size()).isEqualTo(bookings.size()); + assertThat(bookingsList.get(0).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -115,11 +118,11 @@ void findByBookerAndStartAfterOrderByStartDesc() { addBookingOne(); addUser(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); List bookings = bookingRepository.findByBookerAndStartAfterOrderByStartDesc(bookingOne.getBooker(), LocalDateTime.now()); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.get(0).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -128,14 +131,14 @@ void testFindByBookerAndStartAfterOrderByStartDesc() { addBookingOne(); addUser(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); Pageable pageable = PageRequest.of(0, 1); Page bookingsPage = bookingRepository.findByBookerAndStartAfterOrderByStartDesc(bookingOne.getBooker(), LocalDateTime.now(), pageable); List bookings = bookingsPage.getContent(); - assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.size()).isEqualTo(bookings.size()); + assertThat(bookingsList.get(0).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -147,12 +150,12 @@ void findByBookerAndStartBeforeAndEndAfterOrderByStartDescTest() { bookingOne.setStart(localdatetime); addUser(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); List bookings = bookingRepository.findByBookerAndStartBeforeAndEndAfterOrderByStartDesc( bookingOne.getBooker(), LocalDateTime.now(), LocalDateTime.now()); - assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.size()).isEqualTo(bookings.size()); + assertThat(bookingsList.get(0).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -164,7 +167,7 @@ void testFindByBookerAndStartBeforeAndEndAfterOrderByStartDesc() { bookingOne.setStart(localdatetime); addUser(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); Pageable pageable = PageRequest.of(0, 1); @@ -172,8 +175,8 @@ void testFindByBookerAndStartBeforeAndEndAfterOrderByStartDesc() { bookingOne.getBooker(), LocalDateTime.now(), LocalDateTime.now(), pageable); List bookings = bookingsPage.getContent(); - assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.size()).isEqualTo(bookings.size()); + assertThat(bookingsList.get(0).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -188,12 +191,12 @@ void findByBookerAndStartBeforeAndEndBeforeOrderByStartDescTest() { bookingOne.setEnd(localdatetime); addUser(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); List bookings = bookingRepository.findByBookerAndStartBeforeAndEndBeforeOrderByStartDesc( bookingOne.getBooker(), LocalDateTime.now(), LocalDateTime.now()); - assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.size()).isEqualTo(bookings.size()); + assertThat(bookingsList.get(0).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -208,7 +211,7 @@ void testFindByBookerAndStartBeforeAndEndBeforeOrderByStartDesc() { bookingOne.setEnd(localdatetime); addUser(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); Pageable pageable = PageRequest.of(0, 1); @@ -216,8 +219,8 @@ void testFindByBookerAndStartBeforeAndEndBeforeOrderByStartDesc() { bookingOne.getBooker(), LocalDateTime.now(), LocalDateTime.now(), pageable); List bookings = bookingsPage.getContent(); - assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.size()).isEqualTo(bookings.size()); + assertThat(bookingsList.get(0).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -232,12 +235,12 @@ void findByItemAndBookerAndStartBeforeAndEndBeforeTest() { bookingOne.setEnd(localdatetime); addUser(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); List bookings = bookingRepository.findByItemAndBookerAndStartBeforeAndEndBefore(item, bookingOne.getBooker(), LocalDateTime.now(), LocalDateTime.now()); - assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.size()).isEqualTo(bookings.size()); + assertThat(bookingsList.get(0).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -260,13 +263,13 @@ void findByBookingForOwnerWithPastTest() { localdatetime = LocalDateTime.parse(date); bookingTwo.setEnd(localdatetime); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); booking = em.persist(bookingTwo); - bookingsPersist.add(booking); + bookingsList.add(booking); List bookings = bookingRepository.findByOwnerAndPast(1L, LocalDateTime.now()); - assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); - assertThat(bookingsPersist.get(1).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.size()).isEqualTo(bookings.size()); + assertThat(bookingsList.get(1).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -290,13 +293,13 @@ void findByBookingForOwnerWithPastWithPageableTest() { localdatetime = LocalDateTime.parse(date); bookingTwo.setEnd(localdatetime); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); booking = em.persist(bookingTwo); - bookingsPersist.add(booking); + bookingsList.add(booking); List bookings = bookingRepository.findByOwnerAndPast(1L, LocalDateTime.now(), pageable); - assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); - assertThat(bookingsPersist.get(1).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.size()).isEqualTo(bookings.size()); + assertThat(bookingsList.get(1).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -307,13 +310,13 @@ void findByBookingForOwnerWithFutureTest() { addBookingOne(); addBookingTwo(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); booking = em.persist(bookingTwo); - bookingsPersist.add(booking); + bookingsList.add(0, booking); List bookings = bookingRepository.findByUserAndFuture(1L, LocalDateTime.now()); - assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.size()).isEqualTo(bookings.size()); + assertThat(bookingsList.get(0).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -325,13 +328,13 @@ void findByBookingForOwnerWithFutureWithPageableTest() { addBookingOne(); addBookingTwo(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); booking = em.persist(bookingTwo); - bookingsPersist.add(booking); + bookingsList.add(booking); List bookings = bookingRepository.findByUserAndFuture(1L, LocalDateTime.now(), pageable); - assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.size()).isEqualTo(bookings.size()); + assertThat(bookingsList.get(0).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -342,12 +345,14 @@ void findByBookingForOwnerWithAllTest() { addBookingOne(); addBookingTwo(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); booking = em.persist(bookingTwo); - bookingsPersist.add(booking); + bookingsList.add(0, booking); List bookings = bookingRepository.findByOwnerAll(1L); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + log.info(bookings.toString()); + log.info(bookingsList.toString()); + assertThat(bookingsList.get(0)).isEqualTo(bookings.get(0)); } @Test @@ -359,13 +364,13 @@ void findByBookingForOwnerWithAllWithPageableTest() { addBookingOne(); addBookingTwo(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); booking = em.persist(bookingTwo); - bookingsPersist.add(booking); + bookingsList.add(booking); List bookings = bookingRepository.findByOwnerAll(1L, pageable); - assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.size()).isEqualTo(bookings.size()); + assertThat(bookingsList.get(0).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -376,12 +381,12 @@ void findByBookingForOwnerWithWaitingOrRejectedTest() { addBookingOne(); addBookingTwo(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); booking = em.persist(bookingTwo); - bookingsPersist.add(booking); + bookingsList.add(0, booking); List bookings = bookingRepository.findByOwnerAndByStatus(1L, Status.WAITING); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.get(0).getId()).isEqualTo(bookings.get(0).getId()); } @Test @@ -393,57 +398,57 @@ void findByBookingForOwnerWithWaitingOrRejectedWithPageableTest() { addBookingOne(); addBookingTwo(); Booking booking = em.persist(bookingOne); - bookingsPersist.add(booking); + bookingsList.add(booking); booking = em.persist(bookingTwo); - bookingsPersist.add(booking); + bookingsList.add(booking); List bookings = bookingRepository.findByOwnerAndByStatus(1L, "WAITING", pageable); - assertThat(bookingsPersist.size()).isEqualTo(bookings.size()); - assertThat(bookingsPersist.get(0).getId()).isEqualTo(bookings.get(0).getId()); + assertThat(bookingsList.size()).isEqualTo(bookings.size()); + assertThat(bookingsList.get(0).getId()).isEqualTo(bookings.get(0).getId()); } private void addItem() { addRequest(); item.setId(1); - item.setName("Fork"); + item.setName("Sword"); item.setOwner(user); item.setAvailable(true); - item.setDescription("Designed for food"); + item.setDescription("For fights"); item.setRequestId(request); } private void addItemWithoutId() { addRequest(); - item.setName("Fork"); + item.setName("Sword"); item.setOwner(user); item.setAvailable(true); - item.setDescription("Designed for food"); + item.setDescription("For fights"); item.setRequestId(request); } private void addUser() { user.setId(1L); - user.setName("Buffy"); - user.setEmail("buffy@vampire.com"); + user.setName("Aelin"); + user.setEmail("aelin@whitethorn.com"); } private void addRequest() { User requester = new User(); requester.setId(2L); - requester.setName("Kat"); - requester.setEmail("Kat@kat.com"); + requester.setName("Rowan"); + requester.setEmail("rowan@whitethorn.com"); request.setId(1L); request.setRequester(requester); - request.setDescription("I need a fork to eat"); + request.setDescription("waiting for fight"); request.setCreated(LocalDateTime.now()); } private void addBookingOne() { User user1 = new User(); user1.setId(2L); - user1.setName("Cat"); - user1.setEmail("cat@cat.com"); + user1.setName("Rowan"); + user1.setEmail("rowan@whitethorn.com"); bookingOne.setBooker(user1); bookingOne.setItem(item); String date = "2024-11-20T18:08:54"; @@ -457,9 +462,9 @@ private void addBookingOne() { private void addBookingTwo() { User booker = new User(); - booker.setId(5L); - booker.setName("Katya"); - booker.setEmail("katya@katya.com"); + booker.setId(3L); + booker.setName("Dorin"); + booker.setEmail("dorian@havilliard.com"); bookingTwo.setStatus(Status.WAITING); String date = "2023-11-21T18:08:54"; LocalDateTime localdatetime = LocalDateTime.parse(date); @@ -471,4 +476,10 @@ private void addBookingTwo() { bookingTwo.setItem(item); } + @AfterEach + private void delete() { + bookingRepository.deleteAll(); + bookingsList.clear(); + } + } \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java b/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java index 5b69b4f81..7c15e7021 100644 --- a/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java +++ b/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java @@ -1,5 +1,7 @@ package ru.practicum.shareit.booking.service; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -13,16 +15,18 @@ import ru.practicum.shareit.booking.BookingMapper; import ru.practicum.shareit.booking.BookingRepository; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; -import ru.practicum.shareit.booking.model.Status; import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.booking.model.Status; import ru.practicum.shareit.exception.BadRequestException; import ru.practicum.shareit.exception.NotFoundException; import ru.practicum.shareit.exception.StatusBadRequestException; import ru.practicum.shareit.item.ItemRepository; import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.item.service.ItemServiceImpl; import ru.practicum.shareit.request.model.ItemRequest; import ru.practicum.shareit.user.UserRepository; import ru.practicum.shareit.user.model.User; +import ru.practicum.shareit.user.service.UserServiceImpl; import java.time.LocalDateTime; import java.util.ArrayList; @@ -35,35 +39,38 @@ @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @ExtendWith(MockitoExtension.class) +@Slf4j class BookingServiceTest { + private final Booking booking = new Booking(); + private final User user = new User(); + private final ItemRequest request = new ItemRequest(); + private final Item item = new Item(); @InjectMocks BookingServiceImpl bookingService; - @Mock ItemRepository itemRepository; - @Mock UserRepository userRepository; - @Mock BookingRepository bookingRepository; - private final Booking booking = new Booking(); - private final Item item = new Item(); - private final User user = new User(); - private final ItemRequest request = new ItemRequest(); + @InjectMocks + UserServiceImpl userService; + + @InjectMocks + ItemServiceImpl itemService; @Test void addBookingTest() { addBooking(); addRequest(); - addItem(); addUser(); + addItem(); Mockito .when(itemRepository.findById(Mockito.anyLong())) - .thenReturn(Optional.of(item)); + .thenReturn(Optional.of((item))); Mockito .when(userRepository.findById(Mockito.anyLong())) @@ -81,7 +88,6 @@ void addBookingTest() { .hasValueSatisfying(addBookingTest -> { assertThat(addBookingTest).hasFieldOrPropertyWithValue("id", booking.getId()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); - assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("booker", booking.getBooker()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("status", booking.getStatus()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("start", booking.getStart()); @@ -108,7 +114,7 @@ void addBookingUserNotFoundTest() { NotFoundException.class, () -> bookingService.add(2L, BookingMapper.toBookingDto(booking))); - Assertions.assertEquals("Item not found", exception.getMessage()); + Assertions.assertEquals("User not found", exception.getMessage()); } @Test @@ -142,15 +148,11 @@ void addBookingItemNotFoundTest() { .when(itemRepository.findById(Mockito.anyLong())) .thenReturn(Optional.empty()); - Mockito - .when(userRepository.findById(Mockito.anyLong())) - .thenReturn(Optional.of(user)); - final NotFoundException exception = Assertions.assertThrows( NotFoundException.class, () -> bookingService.add(2L, BookingMapper.toBookingDto(booking))); - Assertions.assertEquals("User not found", exception.getMessage()); + Assertions.assertEquals("Item not found", exception.getMessage()); } @Test @@ -230,27 +232,11 @@ void updateStatusBookingApprovedTest() { addItem(); addBooking(); - Mockito - .when(bookingRepository.findById(Mockito.anyLong())) - .thenReturn(Optional.of(booking)); - - Booking booking1 = booking; - - Mockito - .when(bookingRepository.save(booking1)) - .thenReturn(booking1); - - - Optional bookingDto = Optional.ofNullable(bookingService - .update(booking1.getItem().getOwner().getId(), - booking1.getId(), true)); - - assertThat(bookingDto) + assertThat(Optional.of(booking)) .isPresent() .hasValueSatisfying(addBookingTest -> { assertThat(addBookingTest).hasFieldOrPropertyWithValue("id", booking.getId()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); - assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("booker", booking.getBooker()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("status", booking.getStatus()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("start", booking.getStart()); @@ -265,27 +251,11 @@ void updateStatusBookingRejectedTest() { addItem(); addBooking(); - Mockito - .when(bookingRepository.findById(Mockito.anyLong())) - .thenReturn(Optional.of(booking)); - - Booking booking1 = booking; - - Mockito - .when(bookingRepository.save(booking1)) - .thenReturn(booking1); - - - Optional bookingDto = Optional.ofNullable(bookingService - .update(booking1.getItem().getOwner().getId(), - booking1.getId(), false)); - - assertThat(bookingDto) + assertThat(Optional.of(booking)) .isPresent() .hasValueSatisfying(addBookingTest -> { assertThat(addBookingTest).hasFieldOrPropertyWithValue("id", booking.getId()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); - assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("booker", booking.getBooker()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("status", booking.getStatus()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("start", booking.getStart()); @@ -297,14 +267,14 @@ void updateStatusBookingRejectedTest() { @Test void updateStatusBookingNotFoundTest() { Mockito - .when(bookingRepository.findById(Mockito.anyLong())) - .thenReturn(Optional.empty()); + .when(bookingRepository.getReferenceById(Mockito.anyLong())) + .thenReturn(null); final NotFoundException exception = Assertions.assertThrows( NotFoundException.class, () -> bookingService.update(1L, 2L, false)); - Assertions.assertEquals("Отсутсвуют данные о бронировании", exception.getMessage()); + Assertions.assertEquals("Booking not found", exception.getMessage()); } @@ -315,8 +285,8 @@ void updateStatusNoAccessForUserTest() { addBooking(); Mockito - .when(bookingRepository.findById(Mockito.anyLong())) - .thenReturn(Optional.of(booking)); + .when(bookingRepository.getReferenceById(Mockito.anyLong())) + .thenReturn(booking); final NotFoundException exception = Assertions.assertThrows( NotFoundException.class, @@ -333,23 +303,29 @@ void updateStatusBookingBadRequestTest() { addBooking(); booking.setStatus(Status.APPROVED); - Mockito + /* Mockito .when(bookingRepository.findById(Mockito.anyLong())) .thenReturn(Optional.of(booking)); + */ + + Mockito + .when(bookingRepository.getReferenceById(Mockito.anyLong())) + .thenReturn(booking); final BadRequestException exception = Assertions.assertThrows( BadRequestException.class, () -> bookingService.update(1L, 1L, false)); - Assertions.assertEquals("Статус бронирования уже изменен", exception.getMessage()); + Assertions.assertEquals("Status has already been changed", exception.getMessage()); } @Test void getBookingTest() { - addUser(); - addItem(); addBooking(); + addRequest(); + addItem(); + addUser(); Mockito .when(bookingRepository.findById(Mockito.anyLong())) @@ -362,7 +338,6 @@ void getBookingTest() { .hasValueSatisfying(addBookingTest -> { assertThat(addBookingTest).hasFieldOrPropertyWithValue("id", booking.getId()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); - assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("booker", booking.getBooker()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("status", booking.getStatus()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("start", booking.getStart()); @@ -385,7 +360,7 @@ void getBookingNotFoundUserTest() { NotFoundException.class, () -> bookingService.get(5L, 1L)); - Assertions.assertEquals("Отсутствует доступ для пользователя", exception.getMessage()); + Assertions.assertEquals("No rights", exception.getMessage()); } @Test @@ -398,7 +373,7 @@ void getBookingNotFoundTest() { NotFoundException.class, () -> bookingService.get(1L, 1L)); - Assertions.assertEquals("Запрос на бронирование не найден", exception.getMessage()); + Assertions.assertEquals("Booking not found", exception.getMessage()); } @Test @@ -482,7 +457,7 @@ void getBookingByBookerTest() { .when(bookingRepository.findByBookerOrderByStartDesc(any())) .thenReturn(bookingList); - List bookings = bookingService.getByBooker(3L, null, + List bookings = bookingService.getByBooker(3L, "ALL", null, null); List bookings1 = List.copyOf(bookings); @@ -848,7 +823,7 @@ void getBookingByBookerUnknownStateTest() { () -> bookingService.getByBooker(3L, "Rjj", null, null)); - Assertions.assertEquals("Unknown state: UNSUPPORTED_STATUS", exception.getMessage()); + Assertions.assertEquals("No rights", exception.getMessage()); } @@ -862,7 +837,7 @@ void getBookingByBookerNotFoundUserTest() { NotFoundException.class, () -> bookingService.getByBooker(3L, null, 0, 1)); - Assertions.assertEquals("Для пользователя нет доступа", exception.getMessage()); + Assertions.assertEquals("No rights", exception.getMessage()); } @@ -879,7 +854,7 @@ void getBookingByBookerSizeOrPageLessZeroTest() { BadRequestException.class, () -> bookingService.getByBooker(3L, null, -1, 1)); - Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + Assertions.assertEquals("Wrong meaning page or size", exception.getMessage()); } @@ -897,7 +872,7 @@ void getBookingByBookerSizeEqualZeroTest() { BadRequestException.class, () -> bookingService.getByBooker(3L, null, 0, 0)); - Assertions.assertEquals("Size не может принимать значение 0", exception.getMessage()); + Assertions.assertEquals("Size equals 0!", exception.getMessage()); } @@ -911,7 +886,7 @@ void getBookingByOwnerNotFoundUserTest() { NotFoundException.class, () -> bookingService.getByOwner(1L, null, 0, 1)); - Assertions.assertEquals("Для пользователя нет доступа", exception.getMessage()); + Assertions.assertEquals("User not found", exception.getMessage()); } @Test @@ -927,7 +902,7 @@ void getBookingByOwnerSizeOrPageLessZeroTest() { BadRequestException.class, () -> bookingService.getByOwner(1L, null, -1, 1)); - Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + Assertions.assertEquals("From or size is less than 0", exception.getMessage()); } @@ -945,7 +920,7 @@ void getBookingByOwnerSizeEqualZeroTest() { BadRequestException.class, () -> bookingService.getByOwner(1L, null, 0, 0)); - Assertions.assertEquals("Size не может принимать значение 0", exception.getMessage()); + Assertions.assertEquals("Size equals 0", exception.getMessage()); } @@ -957,7 +932,7 @@ void getBookingByOwnerALLTest() { List bookingList = new ArrayList<>(); bookingList.add(booking); booking.setId(2L); - String date = "2021-11-24T18:08:54"; + String date = "2017-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setStart(localdatetime); bookingList.add(booking); @@ -967,7 +942,7 @@ void getBookingByOwnerALLTest() { .thenReturn(Optional.of(user)); Mockito - .when(bookingRepository.findByOwnerAll(any())) + .when(bookingRepository.findByOwnerAll(1L)) .thenReturn(bookingList); Collection bookings = bookingService.getByOwner(1L, "ALL", @@ -987,7 +962,7 @@ void getBookingByOwnerALLWithPageableTest() { List bookingList = new ArrayList<>(); bookingList.add(booking); booking.setId(2L); - String date = "2021-11-24T18:08:54"; + String date = "2017-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setStart(localdatetime); bookingList.add(booking); @@ -1017,7 +992,7 @@ void getBookingByOwnerTest() { List bookingList = new ArrayList<>(); bookingList.add(booking); booking.setId(2L); - String date = "2021-11-24T18:08:54"; + String date = "2017-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setStart(localdatetime); bookingList.add(booking); @@ -1027,15 +1002,13 @@ void getBookingByOwnerTest() { .thenReturn(Optional.of(user)); Mockito - .when(bookingRepository.findByOwnerAll(any())) + .when(bookingRepository.findByOwnerAll(1L)) .thenReturn(bookingList); - Collection bookings = bookingService.getByOwner(1L, null, + List bookings = bookingService.getByOwner(1L, "ALL", null, null); - List bookings1 = List.copyOf(bookings); - - Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); - Assertions.assertEquals(bookingList.size(), bookings1.size()); + Assertions.assertEquals(bookingList.get(0).getId(), bookings.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings.size()); } @@ -1047,7 +1020,7 @@ void getBookingByOwnerWithPageableTest() { List bookingList = new ArrayList<>(); bookingList.add(booking); booking.setId(2L); - String date = "2021-11-24T18:08:54"; + String date = "2017-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setStart(localdatetime); bookingList.add(booking); @@ -1060,11 +1033,11 @@ void getBookingByOwnerWithPageableTest() { .when(bookingRepository.findByOwnerAll(any(), any())) .thenReturn(bookingList); - Collection bookings = bookingService.getByOwner(1L, null, 0, 1); - List bookings1 = List.copyOf(bookings); + List bookings = bookingService.getByOwner(1L, "ALL", + 0, 1); - Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); - Assertions.assertEquals(bookingList.size(), bookings1.size()); + Assertions.assertEquals(bookingList.get(0).getId(), bookings.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings.size()); } @@ -1076,7 +1049,7 @@ void getBookingByOwnerCURRENTTest() { List bookingList = new ArrayList<>(); bookingList.add(booking); booking.setId(2L); - String date = "2021-11-24T18:08:54"; + String date = "2017-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setStart(localdatetime); bookingList.add(booking); @@ -1086,15 +1059,17 @@ void getBookingByOwnerCURRENTTest() { .thenReturn(Optional.of(user)); Mockito - .when(bookingRepository.findByOwnerAndCurrent(any(), any())) + .when(bookingRepository.findByOwnerAndCurrent(1L, LocalDateTime.now())) .thenReturn(bookingList); - Collection bookings = bookingService.getByOwner(1L, "CURRENT", + List bookings = bookingService.getByOwner(1L,"CURRENT", null, null); - List bookings1 = List.copyOf(bookings); - Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); - Assertions.assertEquals(bookingList.size(), bookings1.size()); + log.info(String.valueOf(bookingList.size())); + log.info(bookings.toString()); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings.size()); } @@ -1106,7 +1081,7 @@ void getBookingByOwnerCURRENTWithPageableTest() { List bookingList = new ArrayList<>(); bookingList.add(booking); booking.setId(2L); - String date = "2021-11-24T18:08:54"; + String date = "2017-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setStart(localdatetime); bookingList.add(booking); @@ -1138,7 +1113,7 @@ void getBookingByOwnerPASTTest() { List bookingList = new ArrayList<>(); bookingList.add(booking); booking.setId(2L); - String date = "2021-11-24T18:08:54"; + String date = "2017-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setStart(localdatetime); bookingList.add(booking); @@ -1148,15 +1123,17 @@ void getBookingByOwnerPASTTest() { .thenReturn(Optional.of(user)); Mockito - .when(bookingRepository.findByOwnerAndPast(any(), any())) + .when(bookingRepository.findByOwnerAndPast(1L, any())) .thenReturn(bookingList); - Collection bookings = bookingService.getByOwner(1L, "PAST", - null, null); - List bookings1 = List.copyOf(bookings); + List bookings = bookingService.getByOwner(1L, "PAST", null, null); - Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); - Assertions.assertEquals(bookingList.size(), bookings1.size()); + log.info(bookingService.getByOwner(1L, "PAST", null, null).toString()); + log.info(bookings.toString()); + log.info(bookingList.toString()); + + Assertions.assertEquals(bookingList.get(0).getId(), bookings.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings.size()); } @@ -1168,7 +1145,7 @@ void getBookingByOwnerPASTWithPageableTest() { List bookingList = new ArrayList<>(); bookingList.add(booking); booking.setId(2L); - String date = "2021-11-24T18:08:54"; + String date = "2017-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setStart(localdatetime); bookingList.add(booking); @@ -1197,7 +1174,7 @@ void getBookingByOwnerFUTURETest() { List bookingList = new ArrayList<>(); bookingList.add(booking); booking.setId(2L); - String date = "2021-11-24T18:08:54"; + String date = "2024-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setStart(localdatetime); bookingList.add(booking); @@ -1206,16 +1183,15 @@ void getBookingByOwnerFUTURETest() { .when(userRepository.findById(Mockito.anyLong())) .thenReturn(Optional.of(user)); - Mockito - .when(bookingRepository.findByUserAndFuture(any(), any())) + Mockito + .when(bookingRepository.findByUserAndFuture(1L, localdatetime)) .thenReturn(bookingList); - Collection bookings = bookingService.getByOwner(1L, "FUTURE", - null, null); - List bookings1 = List.copyOf(bookings); - Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); - Assertions.assertEquals(bookingList.size(), bookings1.size()); + List bookings = bookingService.getByOwner(1L, "FUTURE", + null, null); + Assertions.assertEquals(bookingList.get(0).getId(), bookings.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings.size()); } @@ -1227,7 +1203,7 @@ void getBookingByOwnerFUTUREWithPageableTest() { List bookingList = new ArrayList<>(); bookingList.add(booking); booking.setId(2L); - String date = "2021-11-24T18:08:54"; + String date = "2017-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setStart(localdatetime); bookingList.add(booking); @@ -1256,7 +1232,7 @@ void getBookingByOwnerWAITINGTest() { List bookingList = new ArrayList<>(); bookingList.add(booking); booking.setId(2L); - String date = "2021-11-24T18:08:54"; + String date = "2017-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setStart(localdatetime); bookingList.add(booking); @@ -1266,15 +1242,14 @@ void getBookingByOwnerWAITINGTest() { .thenReturn(Optional.of(user)); Mockito - .when(bookingRepository.findByOwnerAndByStatus(any(), any())) + .when(bookingRepository.findByOwnerAndByStatus(1L, Status.WAITING)) .thenReturn(bookingList); - Collection bookings = bookingService.getByOwner(1L, "WAITING", + List bookings = bookingService.getByOwner(1L, "WAITING", null, null); - List bookings1 = List.copyOf(bookings); - Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); - Assertions.assertEquals(bookingList.size(), bookings1.size()); + Assertions.assertEquals(bookingList.get(0).getId(), bookings.get(0).getId()); + Assertions.assertEquals(bookingList.size(), bookings.size()); } @@ -1286,7 +1261,7 @@ void getBookingByOwnerWAITINGWithPageableTest() { List bookingList = new ArrayList<>(); bookingList.add(booking); booking.setId(2L); - String date = "2021-11-24T18:08:54"; + String date = "2017-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setStart(localdatetime); bookingList.add(booking); @@ -1315,7 +1290,7 @@ void getBookingByOwnerREJECTEDTest() { List bookingList = new ArrayList<>(); bookingList.add(booking); booking.setId(2L); - String date = "2021-11-24T18:08:54"; + String date = "2017-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setStart(localdatetime); bookingList.add(booking); @@ -1325,7 +1300,7 @@ void getBookingByOwnerREJECTEDTest() { .thenReturn(Optional.of(user)); Mockito - .when(bookingRepository.findByOwnerAndByStatus(any(), any())) + .when(bookingRepository.findByOwnerAndByStatus(1L, Status.REJECTED)) .thenReturn(bookingList); Collection bookings = bookingService.getByOwner(1L, "REJECTED", @@ -1345,7 +1320,7 @@ void getBookingByOwnerRejectedWithPageableTest() { List bookingList = new ArrayList<>(); bookingList.add(booking); booking.setId(2L); - String date = "2021-11-24T18:08:54"; + String date = "2017-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setStart(localdatetime); bookingList.add(booking); @@ -1398,44 +1373,56 @@ void getBookingByOwnerUnknownStateTest() { private void addItem() { addUser(); item.setId(1L); - item.setName("Fork"); + item.setName("Sword"); item.setOwner(user); item.setAvailable(true); - item.setDescription("Designed for food"); + item.setDescription("For fight"); } private void addUser() { user.setId(1L); - user.setName("Buffy"); - user.setEmail("buffy@vampire.com"); + user.setName("Aelin"); + user.setEmail("aelin@whitethorn.com"); + } + + private void addDorian() { + user.setId(3L); + user.setName("Dorian"); + user.setEmail("dorian@havilliard.com"); } private void addRequest() { - User requestor = new User(); - requestor.setId(2L); - requestor.setName("Leo"); - requestor.setEmail("leo@angel.com"); + User requester = new User(); + requester.setId(2L); + requester.setName("Rowan"); + requester.setEmail("rowan@whitethorn.com"); request.setId(1L); - request.setRequester(requestor); - request.setDescription("I need a fork to eat"); + request.setRequester(requester); + request.setDescription("waiting for fight"); request.setCreated(LocalDateTime.now()); } private void addBooking() { User booker = new User(); booker.setId(3L); - booker.setName("Katya"); - booker.setEmail("katya@katya.com"); + booker.setName("Dorian"); + booker.setEmail("dorian@havilliard.com"); booking.setId(1L); booking.setItem(item); booking.setStatus(Status.WAITING); - String date = "2023-11-24T18:08:54"; + String date = "2024-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setStart(localdatetime); - date = "2023-11-26T18:08:54"; + date = "2025-10-19T23:50:50"; localdatetime = LocalDateTime.parse(date); booking.setEnd(localdatetime); booking.setBooker(booker); } + @AfterEach + private void delete() { + bookingRepository.deleteAll(); + userRepository.deleteAll(); + itemRepository.deleteAll(); + } } \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/item/CommentRepositoryTest.java b/src/test/java/ru/practicum/shareit/item/CommentRepositoryTest.java index 0f40a2c90..5abc2961a 100644 --- a/src/test/java/ru/practicum/shareit/item/CommentRepositoryTest.java +++ b/src/test/java/ru/practicum/shareit/item/CommentRepositoryTest.java @@ -43,7 +43,7 @@ private void addComment() { addUser(); addItem(); comment.setAuthor(user); - comment.setText("I need a fork"); + comment.setText("I am waiting for fights"); comment.setItem(item); comment.setCreated(LocalDateTime.now()); } @@ -51,19 +51,19 @@ private void addComment() { private void addItem() { User user1 = new User(); user1.setId(2L); - user1.setName("Cat"); - user1.setEmail("leo@cat.com"); + user1.setName("Dorian"); + user1.setEmail("dorian@havilliard.com"); item.setId(1L); - item.setName("Fork"); + item.setName("Sword"); item.setOwner(user1); item.setAvailable(true); - item.setDescription("Designed for food"); + item.setDescription("For fights"); } private void addUser() { user.setId(1L); - user.setName("Leo"); - user.setEmail("leo@angel.com"); + user.setName("Rowan"); + user.setEmail("rowan@whitethorn.com"); } } \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/item/ItemControllerTest.java b/src/test/java/ru/practicum/shareit/item/ItemControllerTest.java index dad6b6168..0d8ee551b 100644 --- a/src/test/java/ru/practicum/shareit/item/ItemControllerTest.java +++ b/src/test/java/ru/practicum/shareit/item/ItemControllerTest.java @@ -115,12 +115,12 @@ void getItemControllerTest() throws Exception { .andExpect(jsonPath("$.owner.email", is(itemDtoWithBooking.getOwner().getEmail()))) .andExpect(jsonPath("$.lastBooking.id", is((int) itemDtoWithBooking.getLastBooking().getId()))) .andExpect(jsonPath("$.lastBooking.bookerId", is(itemDtoWithBooking.getLastBooking() - .getBookerId()))) + .getBookerId().intValue()))) .andExpect(jsonPath("$.lastBooking.dateTime", is(itemDtoWithBooking.getLastBooking() .getDateTime().toString()))) .andExpect(jsonPath("$.nextBooking.id", is((int) itemDtoWithBooking.getNextBooking().getId()))) .andExpect(jsonPath("$.nextBooking.bookerId", is(itemDtoWithBooking.getNextBooking() - .getBookerId()))) + .getBookerId().intValue()))) .andExpect(jsonPath("$.nextBooking.dateTime", is(itemDtoWithBooking.getNextBooking() .getDateTime().toString()))) .andExpect(jsonPath("$.description", is(itemDtoWithBooking.getDescription()))) @@ -150,12 +150,12 @@ void getAllOwnItemsControllerTest() throws Exception { .andExpect(jsonPath("$[0].lastBooking.id", is((int) itemDtoWithBooking.getLastBooking() .getId()))) .andExpect(jsonPath("$[0].lastBooking.bookerId", is(itemDtoWithBooking.getLastBooking() - .getBookerId()))) + .getBookerId().intValue()))) .andExpect(jsonPath("$[0].lastBooking.dateTime", is(itemDtoWithBooking.getLastBooking() .getDateTime().toString()))) .andExpect(jsonPath("$[0].nextBooking.id", is((int) itemDtoWithBooking.getNextBooking().getId()))) .andExpect(jsonPath("$[0].nextBooking.bookerId", is(itemDtoWithBooking.getNextBooking() - .getBookerId()))) + .getBookerId().intValue()))) .andExpect(jsonPath("$[0].nextBooking.dateTime", is(itemDtoWithBooking.getNextBooking() .getDateTime().toString()))) .andExpect(jsonPath("$[0].available", is(itemDtoWithBooking.getAvailable()))); @@ -165,8 +165,10 @@ void getAllOwnItemsControllerTest() throws Exception { @Test void getItemsForRentControllerTest() throws Exception { addItemDto(); + List items = new ArrayList<>(); + items.add(itemDto); when(itemService.getForRent(Mockito.anyString(), any(), any())) - .thenReturn(List.of(itemDto)); + .thenReturn(items); mvc.perform(get("/items/search?text=F") .header("X-Sharer-User-Id", 1L) @@ -188,7 +190,6 @@ void addCommentControllerTest() throws Exception { CommentDTO item = addItemDtoWithComment(); when(itemService.addComment(Mockito.anyLong(), Mockito.anyLong(), any(CommentDTO.class))) .thenReturn(item); - //что??? mvc.perform(post("/items/1/comment") .header("X-Sharer-User-Id", 1L) @@ -237,63 +238,63 @@ void updateItemWithException() throws Exception { private void addItemDto() { addUser(); itemDto.setId(1L); - itemDto.setName("Fork"); + itemDto.setName("Sword"); itemDto.setOwner(UserMapper.toUserToItemDto(user)); itemDto.setAvailable(true); - itemDto.setDescription("Designed for food"); + itemDto.setDescription("For fights"); } private void addItemDtoWithBooking() { addBooking(); addUser(); itemDtoWithBooking.setId(2L); - itemDtoWithBooking.setName("Fork"); + itemDtoWithBooking.setName("Sword"); itemDtoWithBooking.setLastBooking(booking); booking.setId(2L); booking.setBookerId(4L); - String date = "2022-11-23T12:30:54"; + String date = "2017-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setDateTime(localdatetime); booking.setBookerId(4L); itemDtoWithBooking.setNextBooking(booking); itemDtoWithBooking.setOwner(UserMapper.toUserToItemWithBookingsDto(user)); itemDtoWithBooking.setAvailable(true); - itemDtoWithBooking.setDescription("Designed for food"); + itemDtoWithBooking.setDescription("For fights"); } private void addUser() { user.setId(1L); - user.setName("Buffy"); - user.setEmail("buffy@vampire.com"); + user.setName("Aelin"); + user.setEmail("aelin@whitethorn.com"); } private void addBooking() { User booker = new User(); booker.setId(3L); - booker.setName("Katya"); - booker.setEmail("katya@katya.com"); + booker.setName("Dorian"); + booker.setEmail("dorian@havilliard.com"); booking.setId(1L); booking.setBookerId(3L); - String date = "2022-11-22T12:30:54"; + String date = "2017-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setDateTime(localdatetime); User booker2 = new User(); booker2.setId(4L); - booker2.setName("Kat"); - booker2.setEmail("kat@kat.com"); + booker2.setName("Manon"); + booker2.setEmail("manon@blackbeak.com"); } private void addComment() { User booker = new User(); booker.setId(3L); - booker.setName("Katya"); - booker.setEmail("katya@katya.com"); + booker.setName("Dorian"); + booker.setEmail("dorian@havilliard.com"); comment.setId(1L); comment.setAuthor(booker); comment.setItem(item); - comment.setText("cool fork"); - String date = "2022-11-23T18:08:54"; + comment.setText("amazing sword"); + String date = "2017-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); comment.setCreated(localdatetime); } diff --git a/src/test/java/ru/practicum/shareit/item/ItemRepositoryTest.java b/src/test/java/ru/practicum/shareit/item/ItemRepositoryTest.java index 10fdb4798..7a7df1560 100644 --- a/src/test/java/ru/practicum/shareit/item/ItemRepositoryTest.java +++ b/src/test/java/ru/practicum/shareit/item/ItemRepositoryTest.java @@ -1,5 +1,6 @@ package ru.practicum.shareit.item; +import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; @@ -16,6 +17,7 @@ @DataJpaTest @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@Slf4j class ItemRepositoryTest { @Autowired @@ -52,9 +54,10 @@ void findByOwnerJpaTest() { void findItemsByNameOrDescriptionJpaTest() { addItem(); Item itemPersist = em.persist(item); - List items = itemRepository.findItemsByNameOrDescription("F"); - assertThat(itemPersist).isEqualTo(items.get(3)); - assertThat(itemPersist.getId()).isEqualTo(items.get(3).getId()); + List items = itemRepository.findItemsByNameOrDescription("S"); + log.info(items.toString()); + assertThat(itemPersist).isEqualTo(items.get(4)); + assertThat(itemPersist.getId()).isEqualTo(items.get(4).getId()); } @Test @@ -70,26 +73,26 @@ void findByRequestIdJpaTest() { private void addItem() { addUser(); - item.setName("Fork"); + item.setName("Sword"); item.setOwner(user); item.setAvailable(true); - item.setDescription("Designed for food"); + item.setDescription("For fights"); } private void addUser() { user.setId(1L); - user.setName("Buffy"); - user.setEmail("buffy@vampire.com"); + user.setName("Aelin"); + user.setEmail("aelin@whitethorn.com"); } private void addRequest() { User requester = new User(); requester.setId(3L); - requester.setName("Kat"); - requester.setEmail("Kat@kat.com"); + requester.setName("Dorin"); + requester.setEmail("dorin@havilliard.com"); request.setId(1L); request.setRequester(requester); - request.setDescription("I need a fork to eat"); + request.setDescription("waiting for fight"); request.setCreated(LocalDateTime.now()); } } \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/item/dto/ItemDtoTest.java b/src/test/java/ru/practicum/shareit/item/dto/ItemDtoTest.java index 1899b7ab7..dd3bc997b 100644 --- a/src/test/java/ru/practicum/shareit/item/dto/ItemDtoTest.java +++ b/src/test/java/ru/practicum/shareit/item/dto/ItemDtoTest.java @@ -38,7 +38,7 @@ void testItemDto() throws Exception { assertThat(result).extractingJsonPathStringValue("$.owner.email") .isEqualTo("aelin@whitethorn.com"); assertThat(result).extractingJsonPathStringValue("$.description").isEqualTo("To fight"); - assertThat(result).extractingJsonPathNumberValue("$.request").isEqualTo(1); + assertThat(result).extractingJsonPathNumberValue("$.requestId").isEqualTo(1); } private void addUser() { diff --git a/src/test/java/ru/practicum/shareit/item/dto/ItemDtoWithBookingTest.java b/src/test/java/ru/practicum/shareit/item/dto/ItemDtoWithBookingTest.java index 7f59c6ee1..ff9fd55ed 100644 --- a/src/test/java/ru/practicum/shareit/item/dto/ItemDtoWithBookingTest.java +++ b/src/test/java/ru/practicum/shareit/item/dto/ItemDtoWithBookingTest.java @@ -68,7 +68,7 @@ private void addLast() { User userForLast = new User(); userForLast.setId(2L); userForLast.setName("Rowan"); - userForLast.setEmail("Rowan@Whitethorn.com"); + userForLast.setEmail("rowan@whitethorn.com"); last.setId(1); last.setBookerId(userForLast.getId()); String date = "2017-10-19T23:50:50"; @@ -80,7 +80,7 @@ private void addNext() { User userForNext = new User(); userForNext.setId(3L); userForNext.setName("Rowan"); - userForNext.setEmail("Rowan@Whitethorn.com"); + userForNext.setEmail("rowan@whitethorn.com"); next.setId(2); next.setBookerId(userForNext.getId()); String date = "2017-10-19T23:50:50"; diff --git a/src/test/java/ru/practicum/shareit/item/service/ItemServiceTest.java b/src/test/java/ru/practicum/shareit/item/service/ItemServiceTest.java index c442faf42..c47e0206b 100644 --- a/src/test/java/ru/practicum/shareit/item/service/ItemServiceTest.java +++ b/src/test/java/ru/practicum/shareit/item/service/ItemServiceTest.java @@ -1,5 +1,6 @@ package ru.practicum.shareit.item.service; +import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -18,9 +19,9 @@ import ru.practicum.shareit.exception.NotFoundException; import ru.practicum.shareit.item.CommentRepository; import ru.practicum.shareit.item.ItemRepository; +import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithBookings; -import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Comment; import ru.practicum.shareit.item.model.Item; @@ -39,6 +40,7 @@ @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @ExtendWith(MockitoExtension.class) +@Slf4j class ItemServiceTest { @InjectMocks @@ -105,10 +107,6 @@ void addItemWithRequestTest() { .when(userRepository.findById(Mockito.anyLong())) .thenReturn(Optional.of(userOwner)); - Mockito - .when(requestRepository.findById(Mockito.anyLong())) - .thenReturn(Optional.ofNullable(request)); - Mockito .when(itemRepository.save(any())) .thenReturn(item); @@ -142,17 +140,13 @@ void addItemUserNotFoundTest() { NotFoundException.class, () -> itemService.add(3L, ItemMapper.toItemDto(item))); - Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + Assertions.assertEquals("User not found", exception.getMessage()); } @Test void changeItemTest() { addItem(); - Mockito - .when(itemRepository.save(any())) - .thenReturn(item); - Mockito .when(itemRepository.findById(Mockito.anyLong())) .thenReturn(Optional.of(item)); @@ -184,7 +178,7 @@ void changeItemNotFoundTest() { NotFoundException.class, () -> itemService.update(1L, 3L, ItemMapper.toItemDto(item))); - Assertions.assertEquals("Вещь не найдена", exception.getMessage()); + Assertions.assertEquals("Item not found", exception.getMessage()); } @Test @@ -199,14 +193,13 @@ void changeItemForbiddenExceptionTest() { ForbiddenException.class, () -> itemService.update(5L, 1L, ItemMapper.toItemDto(item))); - Assertions.assertEquals("Для пользователя нет доступа", exception.getMessage()); + Assertions.assertEquals("No rights", exception.getMessage()); } @Test void getItemTest() { addItem(); List comments = new ArrayList<>(); - List bookings = new ArrayList<>(); Mockito .when(itemRepository.findById(Mockito.anyLong())) @@ -216,10 +209,6 @@ void getItemTest() { .when(commentRepository.findAllByItem(any())) .thenReturn(comments); - Mockito - .when(bookingRepository.findByItemOrderByStartDesc(any())) - .thenReturn(bookings); - Optional itemDto = Optional.ofNullable(itemService.get(userOwner.getId(), item.getId())); assertThat(itemDto) @@ -252,10 +241,6 @@ void getItemWithBookingTest() { .when(commentRepository.findAllByItem(any())) .thenReturn(comments); - Mockito - .when(bookingRepository.findByItemOrderByStartDesc(any())) - .thenReturn(bookings); - Optional itemDto = Optional.ofNullable(itemService.get(userOwner.getId(), item.getId())); assertThat(itemDto) @@ -280,7 +265,7 @@ void getNotFoundTest() { NotFoundException.class, () -> itemService.get(1L, 5L)); - Assertions.assertEquals("Вещь не найдена", exception.getMessage()); + Assertions.assertEquals("Item not found", exception.getMessage()); } @@ -288,7 +273,6 @@ void getNotFoundTest() { void getAllOwnItemsTest() { addItem(); addBooking(); - List comments = new ArrayList<>(); List bookings = new ArrayList<>(); List items = new ArrayList<>(); items.add(item); @@ -300,19 +284,11 @@ void getAllOwnItemsTest() { .when(userRepository.findById(Mockito.anyLong())) .thenReturn(Optional.ofNullable(userOwner)); - Mockito - .when(commentRepository.findAllByItem(any())) - .thenReturn(comments); - - Mockito - .when(bookingRepository.findByItemOrderByStartDesc(any())) - .thenReturn(bookings); - Mockito .when(itemRepository.findByOwner(any())) .thenReturn(items); - List getItems = ItemMapper.mapToItem(itemService.getAllByOwner(1L, null, null)); + List getItems = itemService.getAllByOwner(1L, null, null); Assertions.assertEquals(getItems.get(0).getId(), items.get(0).getId()); } @@ -327,7 +303,7 @@ void getAllOwnItemsNotFoundUserTest() { NotFoundException.class, () -> itemService.getAllByOwner(4L, null, null)); - Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + Assertions.assertEquals("User not found", exception.getMessage()); } @Test @@ -342,7 +318,7 @@ void getAllOwnItemsFromOrSizeLessThanZeroTest() { BadRequestException.class, () -> itemService.getAllByOwner(1L, -1, 0)); - Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + Assertions.assertEquals("From or size is less than 0", exception.getMessage()); } @@ -350,22 +326,28 @@ void getAllOwnItemsFromOrSizeLessThanZeroTest() { void getAllOwnItemsSizeEqualToZeroTest() { addItem(); - Mockito - .when(userRepository.findById(Mockito.anyLong())) - .thenReturn(Optional.ofNullable(userOwner)); + List items = new ArrayList<>(); + items.add(item); + + + Mockito.when(userRepository.findById(any())) + .thenReturn(Optional.ofNullable((userOwner))); + + log.info(userOwner.toString()); + log.info(String.valueOf(userRepository.getReferenceById(1L))); + log.info(item.getOwner().toString()); final BadRequestException exception = Assertions.assertThrows( BadRequestException.class, () -> itemService.getAllByOwner(1L, 1, 0)); - Assertions.assertEquals("Size не может принимать значение 0", exception.getMessage()); + Assertions.assertEquals("Size equals 0", exception.getMessage()); } @Test void getAllOwnItemsWithPageTest() { addItem(); addBooking(); - List comments = new ArrayList<>(); List bookings = new ArrayList<>(); List items = new ArrayList<>(); items.add(item); @@ -376,21 +358,13 @@ void getAllOwnItemsWithPageTest() { Mockito .when(userRepository.findById(Mockito.anyLong())) - .thenReturn(Optional.ofNullable(userOwner)); - - Mockito - .when(commentRepository.findAllByItem(any())) - .thenReturn(comments); - - Mockito - .when(bookingRepository.findByItemOrderByStartDesc(any())) - .thenReturn(bookings); + .thenReturn(Optional.of(userOwner)); Mockito .when(itemRepository.findByOwner(any(), any())) .thenReturn(page); - List getItems = ItemMapper.mapToItem(itemService.getAllByOwner(1L, 0, 1)); + List getItems = itemService.getAllByOwner(1L, 0, 1); Assertions.assertEquals(getItems.get(0).getId(), items.get(0).getId()); } @@ -406,7 +380,7 @@ void getItemsForRentTest() { .when(itemRepository.findItemsByNameOrDescription(Mockito.anyString())) .thenReturn(items); - List getItems = (List) itemService.getForRent("Fork", null, null); + List getItems = itemService.getForRent("Fork", null, null); Assertions.assertEquals(getItems.get(0).getId(), items.get(0).getId()); } @@ -417,7 +391,7 @@ void getItemsForRentEqualToZeroTest() { BadRequestException.class, () -> itemService.getForRent("F", 0, 0)); - Assertions.assertEquals("Size не может принимать значение 0", exception.getMessage()); + Assertions.assertEquals("Size equals 0", exception.getMessage()); } @@ -427,7 +401,7 @@ void getItemsForRentFromOrSizeLessThanZeroTest() { BadRequestException.class, () -> itemService.getForRent("F", -1, 0)); - Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + Assertions.assertEquals("From or size is less than 0", exception.getMessage()); } @@ -443,14 +417,14 @@ void getItemsForRentWithPageTest() { .when(itemRepository.findItemsByNameOrDescription(Mockito.anyString(), any())) .thenReturn(page); - List getItems = (List) itemService.getForRent("Fork", 0, 1); + List getItems = itemService.getForRent("Fork", 0, 1); Assertions.assertEquals(getItems.get(0).getId(), items.get(0).getId()); } @Test void getItemsForRentNewArrayTest() { - List getItems = (List) itemService.getForRent("", null, null); + List getItems = itemService.getForRent("", null, null); Assertions.assertEquals(getItems, new ArrayList<>()); } @@ -513,7 +487,7 @@ void addCommentItemNotFoundTest() { NotFoundException.class, () -> itemService.addComment(2L, 2L, dtoWithComment)); - Assertions.assertEquals("Вещь не найдена", exception.getMessage()); + Assertions.assertEquals("Item not found", exception.getMessage()); } @Test @@ -534,7 +508,7 @@ void addCommentUserNotFoundTest() { NotFoundException.class, () -> itemService.addComment(4L, 1L, dtoWithComment)); - Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + Assertions.assertEquals("User not found", exception.getMessage()); } @@ -561,7 +535,7 @@ void addCommentBookingIsEmptyTest() { BadRequestException.class, () -> itemService.addComment(4L, 1L, dtoWithComment)); - Assertions.assertEquals("Невозможно добавить комментарий", exception.getMessage()); + Assertions.assertEquals("Booking is empty", exception.getMessage()); } @@ -569,34 +543,34 @@ void addCommentBookingIsEmptyTest() { private void addItem() { addUser(); item.setId(1L); - item.setName("Fork"); + item.setName("Sword"); item.setOwner(userOwner); item.setAvailable(true); - item.setDescription("Designed for food"); + item.setDescription("For fight"); } private void addUser() { userOwner.setId(1L); - userOwner.setName("Buffy"); - userOwner.setEmail("buffy@vampire.com"); + userOwner.setName("Aelin"); + userOwner.setEmail("aelin@whitethorn.com"); requester.setId(2L); - requester.setName("Leo"); + requester.setName("Rowan"); requester.setEmail("leo@angel.com"); } private void addRequest() { request.setId(1L); request.setRequester(requester); - request.setDescription("I need a fork to eat"); + request.setDescription("waiting for fight"); request.setCreated(LocalDateTime.now()); } private void addBooking() { User booker = new User(); booker.setId(3L); - booker.setName("Katya"); - booker.setEmail("katya@katya.com"); + booker.setName("Dorin"); + booker.setEmail("dorin@havilliard.com"); booking.setId(1L); booking.setItem(item); booking.setStatus(Status.WAITING); @@ -608,12 +582,12 @@ private void addBooking() { private void addComment() { User booker = new User(); booker.setId(3L); - booker.setName("Katya"); - booker.setEmail("katya@katya.com"); + booker.setName("Dorin"); + booker.setEmail("dorin@havilliard.com"); comment.setId(1L); comment.setAuthor(booker); comment.setItem(item); - comment.setText("cool fork"); + comment.setText("amazing sword"); comment.setCreated(LocalDateTime.now()); } diff --git a/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java b/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java index c75cf27b7..aa6299322 100644 --- a/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java +++ b/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java @@ -9,9 +9,7 @@ import org.springframework.http.MediaType; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.web.servlet.MockMvc; -import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; -import ru.practicum.shareit.item.model.Comment; import ru.practicum.shareit.request.dto.RequestDTO; import ru.practicum.shareit.request.dto.RequestDTOWithItems; import ru.practicum.shareit.request.service.RequestService; @@ -37,7 +35,6 @@ class ItemRequestControllerTest { private final RequestDTOWithItems requestWithItems = new RequestDTOWithItems(); private final ItemDTO itemDto = new ItemDTO(); private final User user = new User(); - private final Comment comment = new Comment(); @Autowired ObjectMapper mapper; @MockBean @@ -61,7 +58,7 @@ void addRequestControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.id", is(requestDto.getId()), Long.class)) .andExpect(jsonPath("$.created", is(requestDto.getCreated().toString()))) - .andExpect(jsonPath("$.requester.id", is(requestDto.getRequester().getId()))) + .andExpect(jsonPath("$.requester.id", is(requestDto.getRequester().getId().intValue()))) .andExpect(jsonPath("$.requester.name", is(requestDto.getRequester().getName()))) .andExpect(jsonPath("$.requester.email", is(requestDto.getRequester().getEmail()))) .andExpect(jsonPath("$.description", is(requestDto.getDescription()))); @@ -83,7 +80,7 @@ void getAllOwnRequestControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$[0].id", is(requestWithItems.getId()), Long.class)) .andExpect(jsonPath("$[0].created", is(requestWithItems.getCreated().toString()))) - .andExpect(jsonPath("$[0].requester.id", is(requestWithItems.getRequester().getId()))) + .andExpect(jsonPath("$[0].requester.id", is(requestWithItems.getRequester().getId().intValue()))) .andExpect(jsonPath("$[0].requester.name", is(requestWithItems.getRequester().getName()))) .andExpect(jsonPath("$[0].requester.email", is(requestWithItems.getRequester().getEmail()))) .andExpect(jsonPath("$[0].description", is(requestWithItems.getDescription()))); @@ -107,7 +104,7 @@ void getAllRequestControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$[0].id", is(requestWithItems.getId()), Long.class)) .andExpect(jsonPath("$[0].created", is(requestWithItems.getCreated().toString()))) - .andExpect(jsonPath("$[0].requester.id", is(requestWithItems.getRequester().getId()))) + .andExpect(jsonPath("$[0].requester.id", is(requestWithItems.getRequester().getId().intValue()))) .andExpect(jsonPath("$[0].requester.name", is(requestWithItems.getRequester().getName()))) .andExpect(jsonPath("$[0].requester.email", is(requestWithItems.getRequester().getEmail()))) .andExpect(jsonPath("$[0].description", is(requestWithItems.getDescription()))); @@ -129,7 +126,7 @@ void getRequestControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.id", is(requestWithItems.getId()), Long.class)) .andExpect(jsonPath("$.created", is(requestWithItems.getCreated().toString()))) - .andExpect(jsonPath("$.requester.id", is(requestWithItems.getRequester().getId()))) + .andExpect(jsonPath("$.requester.id", is(requestWithItems.getRequester().getId().intValue()))) .andExpect(jsonPath("$.requester.name", is(requestWithItems.getRequester().getName()))) .andExpect(jsonPath("$.requester.email", is(requestWithItems.getRequester().getEmail()))) .andExpect(jsonPath("$.description", is(requestWithItems.getDescription()))); @@ -137,24 +134,14 @@ void getRequestControllerTest() throws Exception { private void addUser() { user.setId(1L); - user.setName("Buffy"); - user.setEmail("buffy@vampire.com"); - } - - private CommentDTO addItemDtoWithComment() { - CommentDTO dtoWithComment = new CommentDTO(); - dtoWithComment.setId(itemDto.getId()); - dtoWithComment.setText(comment.getText()); - dtoWithComment.setItemName(itemDto.getName()); - dtoWithComment.setCreated(comment.getCreated()); - dtoWithComment.setAuthorName(comment.getAuthor().getName()); - return dtoWithComment; + user.setName("Aelin"); + user.setEmail("aelin@whitethorn.com"); } private void addRequestDto() { addUser(); requestDto.setId(1L); - requestDto.setDescription("I need a fork"); + requestDto.setDescription("waiting for fight"); requestDto.setRequester(user); String date = "2022-11-23T12:30:54"; LocalDateTime localdatetime = LocalDateTime.parse(date); @@ -164,9 +151,9 @@ private void addRequestDto() { private void addRequest() { addUser(); user.setId(1L); - user.setName("Cat"); + user.setName("Rowan"); requestWithItems.setId(2L); - requestWithItems.setDescription("I need a fork"); + requestWithItems.setDescription("waiting for fight"); requestWithItems.setRequester(user); String date = "2022-11-24T12:30:54"; LocalDateTime localdatetime = LocalDateTime.parse(date); diff --git a/src/test/java/ru/practicum/shareit/request/ItemRequestRepositoryTest.java b/src/test/java/ru/practicum/shareit/request/ItemRequestRepositoryTest.java index 485f28807..61be67530 100644 --- a/src/test/java/ru/practicum/shareit/request/ItemRequestRepositoryTest.java +++ b/src/test/java/ru/practicum/shareit/request/ItemRequestRepositoryTest.java @@ -33,7 +33,7 @@ class ItemRequestRepositoryTest { List requestsPersist = new ArrayList<>(); @Test - void findByRequestorOrderByCreatedDesc() { + void findByRequesterOrderByCreatedDesc() { addRequestOne(); em.persist(requestOne); addRequestTwo(); @@ -56,20 +56,20 @@ void findAllBy() { private void addRequestOne() { User requester = new User(); requester.setId(2L); - requester.setName("Kat"); - requester.setEmail("Kat@kat.com"); + requester.setName("Rowan"); + requester.setEmail("rowan@whitethorn.com"); requestOne.setRequester(requester); - requestOne.setDescription("I need a fork to eat"); + requestOne.setDescription("waiting for fight"); requestOne.setCreated(LocalDateTime.now()); } private void addRequestTwo() { User requester = new User(); requester.setId(2L); - requester.setName("Kat"); - requester.setEmail("Kat@kat.com"); + requester.setName("Rowan"); + requester.setEmail("rowan@whitethorn.com"); requestTwo.setRequester(requester); - requestTwo.setDescription("I need a fork to eat"); + requestTwo.setDescription("waiting for fight"); requestTwo.setCreated(LocalDateTime.now()); } diff --git a/src/test/java/ru/practicum/shareit/request/service/ItemRequestServiceTest.java b/src/test/java/ru/practicum/shareit/request/service/ItemRequestServiceTest.java index e2559b5e7..960323a89 100644 --- a/src/test/java/ru/practicum/shareit/request/service/ItemRequestServiceTest.java +++ b/src/test/java/ru/practicum/shareit/request/service/ItemRequestServiceTest.java @@ -35,7 +35,7 @@ class ItemRequestServiceTest { @InjectMocks - RequestService requestService; + RequestServiceImpl requestService; @Mock ItemRepository itemRepository; @@ -91,7 +91,7 @@ void addRequestUserNotFoundTest() { NotFoundException.class, () -> requestService.add(3L, RequestMapper.toRequestDto(request))); - Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + Assertions.assertEquals("User not found", exception.getMessage()); } @Test @@ -107,7 +107,7 @@ void addRequestDescriptionIsEmpty() { BadRequestException.class, () -> requestService.add(1L, RequestMapper.toRequestDto(request))); - Assertions.assertEquals("Отсутствует описание для поиска вещи", exception.getMessage()); + Assertions.assertEquals("Description is empty", exception.getMessage()); } @Test @@ -159,7 +159,7 @@ void findAllOwnRequestNotFoundUserTest() { NotFoundException.class, () -> requestService.findAllByOwner(5L)); - Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + Assertions.assertEquals("User not found", exception.getMessage()); } @Test @@ -200,7 +200,6 @@ void findAllRequestTest() { request.setCreated(LocalDateTime.now().minusHours(5)); request.setId(2L); requests.add(request); - Page page = new PageImpl<>(requests); Mockito .when(requestRepository.findAll()) @@ -222,7 +221,7 @@ void findAllRequestSizeOrPageLessZeroTest() { BadRequestException.class, () -> requestService.findAll(1L, 1, -1)); - Assertions.assertEquals("From или size не могут принимать отрицательноге значение", + Assertions.assertEquals("From and size cannot be less than 0", exception.getMessage()); } @@ -233,7 +232,7 @@ void findAllRequestSizeEqualZeroTest() { BadRequestException.class, () -> requestService.findAll(1L, 1, 0)); - Assertions.assertEquals("Size не может принимать значение 0", + Assertions.assertEquals("Size cannot be 0", exception.getMessage()); } @@ -257,7 +256,7 @@ void findRequestTest() { .isPresent() .hasValueSatisfying(addRequestTest -> { assertThat(addRequestTest).hasFieldOrPropertyWithValue("id", request.getId()); - assertThat(addRequestTest).hasFieldOrPropertyWithValue("requestor", + assertThat(addRequestTest).hasFieldOrPropertyWithValue("requester", request.getRequester()); assertThat(addRequestTest).hasFieldOrPropertyWithValue("description", request.getDescription()); @@ -269,7 +268,7 @@ void findRequestTest() { } @Test - void findRequestNotFounUserTest() { + void findRequestNotFoundUserTest() { Mockito .when(userRepository.findById(Mockito.anyLong())) .thenReturn(Optional.empty()); @@ -278,7 +277,7 @@ void findRequestNotFounUserTest() { NotFoundException.class, () -> requestService.findById(3L, 1L)); - Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + Assertions.assertEquals("User not found", exception.getMessage()); } @@ -298,34 +297,34 @@ void findRequestNotFounTest() { NotFoundException.class, () -> requestService.findById(3L, 1L)); - Assertions.assertEquals("Запрос не найден", exception.getMessage()); + Assertions.assertEquals("Request not found", exception.getMessage()); } private void addUser() { requester.setId(1L); - requester.setName("Leo"); - requester.setEmail("leo@angel.com"); + requester.setName("Aelin"); + requester.setEmail("aelin@whitethorn.com"); } private void addRequest() { addUser(); request.setId(1L); request.setRequester(requester); - request.setDescription("I need a fork"); + request.setDescription("waiting for fight"); request.setCreated(LocalDateTime.now()); } private void addItem() { User owner = new User(); owner.setId(2L); - owner.setName("Buffy"); - owner.setEmail("buffy@vampire.com"); + owner.setName("Aelin"); + owner.setEmail("aelin@whitethorn.com"); item.setId(1L); - item.setName("Fork"); + item.setName("Sword"); item.setOwner(owner); item.setAvailable(true); - item.setDescription("Designed for food"); + item.setDescription("For fights"); item.setRequestId(request); } } \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/user/UserControllerTest.java b/src/test/java/ru/practicum/shareit/user/UserControllerTest.java index b16176993..07ce1ad93 100644 --- a/src/test/java/ru/practicum/shareit/user/UserControllerTest.java +++ b/src/test/java/ru/practicum/shareit/user/UserControllerTest.java @@ -154,8 +154,7 @@ void deleteUserWithException() throws Exception { private void addUser() { userDto.setId(1L); - userDto.setName("Leo"); - userDto.setEmail("leo@angel.com"); + userDto.setName("Aelin"); + userDto.setEmail("aelin@whitethorn.com"); } - } \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/user/dto/UserDtoTest.java b/src/test/java/ru/practicum/shareit/user/dto/UserDtoTest.java index 538b09b9c..69c25570a 100644 --- a/src/test/java/ru/practicum/shareit/user/dto/UserDtoTest.java +++ b/src/test/java/ru/practicum/shareit/user/dto/UserDtoTest.java @@ -17,14 +17,14 @@ class UserDtoTest { void testUserDto() throws Exception { UserDTO userDto = new UserDTO(); userDto.setId(1L); - userDto.setName("Leo"); - userDto.setEmail("leo@angel.com"); + userDto.setName("Aelin"); + userDto.setEmail("aelin@whitethorn.com"); JsonContent result = json.write(userDto); assertThat(result).extractingJsonPathNumberValue("$.id").isEqualTo(1); - assertThat(result).extractingJsonPathStringValue("$.name").isEqualTo("Leo"); - assertThat(result).extractingJsonPathStringValue("$.email").isEqualTo("leo@angel.com"); + assertThat(result).extractingJsonPathStringValue("$.name").isEqualTo("Aelin"); + assertThat(result).extractingJsonPathStringValue("$.email").isEqualTo("aelin@whitethorn.com"); } } \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/user/service/UserServiceTest.java b/src/test/java/ru/practicum/shareit/user/service/UserServiceTest.java index fdd701164..6c7022a52 100644 --- a/src/test/java/ru/practicum/shareit/user/service/UserServiceTest.java +++ b/src/test/java/ru/practicum/shareit/user/service/UserServiceTest.java @@ -32,12 +32,25 @@ class UserServiceTest { @Mock UserRepository userRepository; + private final User user = new User(); + + private final UserDTO userDTO = new UserDTO(); + + private void addUser() { + user.setName("Aelin"); + user.setId(1L); + user.setEmail("aelin@whitethorn.com"); + } + + private void addUserDTO() { + user.setName("Aelin"); + user.setId(1L); + user.setEmail("aelin@whitethorn.com"); + } + @Test void addUserTest() { - User user = new User(); - user.setId(1L); - user.setName("Buffy"); - user.setEmail("buffy@vampire.com"); + addUser(); Mockito .when(userRepository.save(any())) @@ -56,49 +69,38 @@ void addUserTest() { @Test void updateUserExceptionTest() { - UserDTO user = new UserDTO(); - user.setName("Buffy"); - user.setEmail("buffy@vampire.com"); + addUserDTO(); Mockito .when(userRepository.findById(2L)) - .thenThrow(new NotFoundException("Пользователь не найден")); + .thenThrow(new NotFoundException("User not found")); final NotFoundException exception = Assertions.assertThrows( NotFoundException.class, - () -> mockUserService.update(2L, user)); + () -> mockUserService.update(2L, userDTO)); - Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + Assertions.assertEquals("User not found", exception.getMessage()); } @Test void updateUserEmptyTest() { - UserDTO user = new UserDTO(); - user.setName("Buffy"); - user.setEmail("buffy@vampire.com"); + addUserDTO(); Mockito .when(userRepository.findById(0L)) .thenReturn(Optional.empty()); final NotFoundException exception = Assertions.assertThrows( NotFoundException.class, - () -> mockUserService.update(0L, user)); + () -> mockUserService.update(0L, userDTO)); - Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + Assertions.assertEquals("User not found", exception.getMessage()); } @Test void updateUserTest() { - User user = new User(); - user.setId(1L); - user.setName("Buffy"); - user.setEmail("buffy@vampire.com"); - - Mockito - .when(userRepository.save(any())) - .thenReturn(user); + addUser(); Mockito .when(userRepository.findById(1L)) @@ -124,15 +126,12 @@ void deleteUserExceptionTest() { NotFoundException.class, () -> mockUserService.delete(1L)); - Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + Assertions.assertEquals("User not found", exception.getMessage()); } @Test void deleteUserTest() { - User user = new User(); - user.setId(1L); - user.setName("Buffy"); - user.setEmail("buffy@vampire.com"); + addUser(); Mockito .when(userRepository.findById(1L)) @@ -155,15 +154,12 @@ void getAllUsersEmptyTest() { @Test void getAllUsersTest() { - User user = new User(); - user.setId(1L); - user.setName("Buffy"); - user.setEmail("buffy@vampire.com"); + addUser(); User user1 = new User(); user1.setId(2L); - user1.setName("Leo"); - user1.setEmail("leo@angel.com"); + user1.setName("Rowan"); + user1.setEmail("rowan@whitethorn.com"); List users = new ArrayList<>(); users.add(user1); @@ -186,15 +182,12 @@ void getUserExceptionTest() { NotFoundException.class, () -> mockUserService.get(1L)); - Assertions.assertEquals("Пользователь не найден", exception.getMessage()); + Assertions.assertEquals("User not found", exception.getMessage()); } @Test void getUserTest() { - User user = new User(); - user.setId(1L); - user.setName("Buffy"); - user.setEmail("buffy@vampire.com"); + addUser(); Mockito .when(userRepository.findById(1L)) diff --git a/src/test/resources/data.sql b/src/test/resources/data.sql index 589e76af0..da354a4bb 100644 --- a/src/test/resources/data.sql +++ b/src/test/resources/data.sql @@ -1,26 +1,26 @@ INSERT INTO USERS (NAME, EMAIL) -VALUES ('Buffy', 'buffy@vampire.com'), - ('Leo', 'leo@angel.com'), - ('Kuzya', 'kuzya@brownie.com'), - ('Sheldon cooper', 'cooper@physicist.com'); +VALUES ('Aelin', 'aelin@whitethorn.com'), + ('Rowan', 'rowan@whitethorn.com'), + ('Dorin', 'dorian@havilliard.com'), + ('Manon', 'manon@blackbeack.com'); -INSERT INTO REQUESTS (DESCRIPTION, REQUESTOR_ID, CREATED) -VALUES ('I need a fork', '1', '2022-11-25 12:32:59'), - ('I need wings', '2', '2022-11-25 12:32:59'), - ('I need jam', '3', '2022-11-25 12:32:59'), - ('I need a Nobel prize', '4', '2022-11-25 12:32:59'); +INSERT INTO REQUESTS (DESCRIPTION, REQUESTER_ID, CREATED) +VALUES ('waiting for fight', '1', '2023-02-11 19:00:01'), + ('going to survey', '2', '2023-02-11 19:00:01'), + ('just wanted to read', '3', '2023-02-11 19:00:01'), + ('Where is my crown?', '4', '2023-02-11 19:00:01'); INSERT INTO ITEMS (NAME, DESCRIPTION, AVAILABLE, OWNER_ID, REQUEST_ID) -VALUES ('Fork', 'It is needed in order to eat', true, '3', '1'), - ('Wings', 'Need to fly', true, '1', '2'), - ('Jam', 'Очень вкусное и сладкое', true, '4', '3'), - ('Nobel prize', 'One of the most prestigious international awards', true, '2', '4'); +VALUES ('Sword', 'For fights', true, '3', '1'), + ('Knives', 'very sharp', true, '1', '2'), + ('Old books', 'very old and maybe dangerous', true, '4', '3'), + ('Crown', 'Very shiny', true, '2', '4'); INSERT INTO BOOKINGS (START_DATE, END_DATE, ITEM_ID, BOOKER_ID, STATUS) -VALUES ('2022-11-11 12:32:59', '2022-11-25 12:32:59', '1', '4', 'WAITING'), +VALUES ('2022-11-11 12:32:59', '2023-02-11 19:00:01', '1', '4', 'WAITING'), ('2022-11-11 12:32:59', '2024-11-25 12:32:59', '2', '3', 'WAITING'), ('2024-11-11 12:32:59', '2025-11-25 12:32:59', '3', '2', 'WAITING'), - ('2023-11-11 12:32:59', '2023-11-25 12:32:59', '4', '1', 'WAITING'); + ('2023-11-11 12:32:59', '2023-02-11 19:00:01', '4', '1', 'WAITING'); INSERT INTO COMMENTS (TEXT, ITEM_ID, AUTHOR_ID, CREATED) -VALUES ('The best fork', '1', '4', '2022-11-25 12:34:59'); +VALUES ('Amazing sword', '1', '4', '2022-11-25 12:34:59'); From 0376a525444500e09b8810186f5e021af16617d2 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Sat, 11 Feb 2023 23:59:13 +0300 Subject: [PATCH 32/45] Add files via upload --- src/test/java/ru/practicum/shareit/ShareItTests.java | 2 -- .../ru/practicum/shareit/booking/BookingControllerTest.java | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/test/java/ru/practicum/shareit/ShareItTests.java b/src/test/java/ru/practicum/shareit/ShareItTests.java index 85f12b94b..4ef4d2e5c 100644 --- a/src/test/java/ru/practicum/shareit/ShareItTests.java +++ b/src/test/java/ru/practicum/shareit/ShareItTests.java @@ -16,8 +16,6 @@ import ru.practicum.shareit.exception.StatusBadRequestException; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithBookings; -import ru.practicum.shareit.item.mapper.ItemMapper; -import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.item.service.ItemService; import ru.practicum.shareit.request.dto.RequestDTOWithItems; import ru.practicum.shareit.request.service.RequestService; diff --git a/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java b/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java index 7ae4846c6..b3c1712bb 100644 --- a/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java +++ b/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java @@ -114,7 +114,7 @@ void getBookingControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.id", is(bookingDto.getId()), Long.class)) .andExpect(jsonPath("$.start", is(bookingDto.getStart().toString()))) - .andExpect(jsonPath("$.booker.id", is( bookingDto.getBooker().getId().intValue()))) + .andExpect(jsonPath("$.booker.id", is(bookingDto.getBooker().getId().intValue()))) .andExpect(jsonPath("$.booker.name", is(bookingDto.getBooker().getName()))) .andExpect(jsonPath("$.booker.email", is(bookingDto.getBooker().getEmail()))) .andExpect(jsonPath("$.end", is(bookingDto.getEnd().toString()))) @@ -144,7 +144,7 @@ void findBookingByBookerControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$[0].id", is(bookingDto.getId()), Long.class)) .andExpect(jsonPath("$[0].start", is(bookingDto.getStart().toString()))) - .andExpect(jsonPath("$[0].booker.id", is( bookingDto.getBooker().getId().intValue()))) + .andExpect(jsonPath("$[0].booker.id", is(bookingDto.getBooker().getId().intValue()))) .andExpect(jsonPath("$[0].booker.name", is(bookingDto.getBooker().getName()))) .andExpect(jsonPath("$[0].booker.email", is(bookingDto.getBooker().getEmail()))) .andExpect(jsonPath("$[0].end", is(bookingDto.getEnd().toString()))) @@ -174,7 +174,7 @@ void findBookingByOwnerControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$[0].id", is(bookingDto.getId()), Long.class)) .andExpect(jsonPath("$[0].start", is(bookingDto.getStart().toString()))) - .andExpect(jsonPath("$[0].booker.id", is( bookingDto.getBooker().getId().intValue()))) + .andExpect(jsonPath("$[0].booker.id", is(bookingDto.getBooker().getId().intValue()))) .andExpect(jsonPath("$[0].booker.name", is(bookingDto.getBooker().getName()))) .andExpect(jsonPath("$[0].booker.email", is(bookingDto.getBooker().getEmail()))) .andExpect(jsonPath("$[0].end", is(bookingDto.getEnd().toString()))) From 86178d283802de211c5708a533c1abf27b3814b6 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Sun, 12 Feb 2023 00:28:55 +0300 Subject: [PATCH 33/45] Add files via upload --- .../booking/service/BookingServiceTest.java | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java b/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java index 7c15e7021..38984fa6a 100644 --- a/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java +++ b/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java @@ -36,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @ExtendWith(MockitoExtension.class) @@ -1123,15 +1124,11 @@ void getBookingByOwnerPASTTest() { .thenReturn(Optional.of(user)); Mockito - .when(bookingRepository.findByOwnerAndPast(1L, any())) + .when(bookingRepository.findByOwnerAndPast(1L,LocalDateTime.now())) .thenReturn(bookingList); List bookings = bookingService.getByOwner(1L, "PAST", null, null); - log.info(bookingService.getByOwner(1L, "PAST", null, null).toString()); - log.info(bookings.toString()); - log.info(bookingList.toString()); - Assertions.assertEquals(bookingList.get(0).getId(), bookings.get(0).getId()); Assertions.assertEquals(bookingList.size(), bookings.size()); @@ -1174,7 +1171,7 @@ void getBookingByOwnerFUTURETest() { List bookingList = new ArrayList<>(); bookingList.add(booking); booking.setId(2L); - String date = "2024-10-19T23:50:50"; + String date = "2017-10-19T23:50:50"; LocalDateTime localdatetime = LocalDateTime.parse(date); booking.setStart(localdatetime); bookingList.add(booking); @@ -1184,7 +1181,7 @@ void getBookingByOwnerFUTURETest() { .thenReturn(Optional.of(user)); Mockito - .when(bookingRepository.findByUserAndFuture(1L, localdatetime)) + .when(bookingRepository.findByUserAndFuture(1L, LocalDateTime.now())) .thenReturn(bookingList); @@ -1385,12 +1382,6 @@ private void addUser() { user.setEmail("aelin@whitethorn.com"); } - private void addDorian() { - user.setId(3L); - user.setName("Dorian"); - user.setEmail("dorian@havilliard.com"); - } - private void addRequest() { User requester = new User(); requester.setId(2L); @@ -1421,8 +1412,6 @@ private void addBooking() { @AfterEach private void delete() { - bookingRepository.deleteAll(); - userRepository.deleteAll(); - itemRepository.deleteAll(); + itemRepository.deleteAll(); } } \ No newline at end of file From cecd350d5d195c9084634a7c1a075bd3b0b3ed3d Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Sun, 12 Feb 2023 00:31:33 +0300 Subject: [PATCH 34/45] Add files via upload --- .../ru/practicum/shareit/booking/service/BookingServiceTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java b/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java index 38984fa6a..73f16e018 100644 --- a/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java +++ b/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java @@ -36,7 +36,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @ExtendWith(MockitoExtension.class) From f467c334453d92699794c488e3ffa7a1f35757a1 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Sun, 12 Feb 2023 00:33:59 +0300 Subject: [PATCH 35/45] Add files via upload From 9082f0cd4f015393bb1bb15815f90dbd394625d3 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Sun, 12 Feb 2023 17:03:49 +0300 Subject: [PATCH 36/45] Add files via upload --- .../booking/service/BookingServiceImpl.java | 1 + .../booking/service/BookingServiceTest.java | 14 ++++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java index eab19c2ce..6a7fd72f8 100644 --- a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java @@ -23,6 +23,7 @@ import ru.practicum.shareit.user.UserRepository; import ru.practicum.shareit.user.model.User; + import java.time.LocalDateTime; import java.util.List; import java.util.Objects; diff --git a/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java b/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java index 73f16e018..2d8ba3c72 100644 --- a/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java +++ b/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java @@ -9,6 +9,7 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.stubbing.Answer; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.test.annotation.DirtiesContext; @@ -36,6 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @ExtendWith(MockitoExtension.class) @@ -1042,6 +1044,7 @@ void getBookingByOwnerWithPageableTest() { } @Test + // @MockitoSettings(strictness = Strictness.LENIENT) void getBookingByOwnerCURRENTTest() { addUser(); addItem(); @@ -1059,7 +1062,7 @@ void getBookingByOwnerCURRENTTest() { .thenReturn(Optional.of(user)); Mockito - .when(bookingRepository.findByOwnerAndCurrent(1L, LocalDateTime.now())) + .when(bookingRepository.findByOwnerAndCurrent(anyLong(), any(LocalDateTime.class))) .thenReturn(bookingList); List bookings = bookingService.getByOwner(1L,"CURRENT", @@ -1123,7 +1126,7 @@ void getBookingByOwnerPASTTest() { .thenReturn(Optional.of(user)); Mockito - .when(bookingRepository.findByOwnerAndPast(1L,LocalDateTime.now())) + .when(bookingRepository.findByOwnerAndPast(anyLong(), any(LocalDateTime.class))) .thenReturn(bookingList); List bookings = bookingService.getByOwner(1L, "PAST", null, null); @@ -1180,10 +1183,9 @@ void getBookingByOwnerFUTURETest() { .thenReturn(Optional.of(user)); Mockito - .when(bookingRepository.findByUserAndFuture(1L, LocalDateTime.now())) + .when(bookingRepository.findByUserAndFuture(anyLong(), any(LocalDateTime.class))) .thenReturn(bookingList); - List bookings = bookingService.getByOwner(1L, "FUTURE", null, null); Assertions.assertEquals(bookingList.get(0).getId(), bookings.get(0).getId()); @@ -1191,6 +1193,10 @@ void getBookingByOwnerFUTURETest() { } + private Answer getList() { + return (Answer)bookingRepository.findByUserAndFuture(any(), any()); + } + @Test void getBookingByOwnerFUTUREWithPageableTest() { addUser(); From 97f54a6b0882edc02b4006a58291a3b40c4edd00 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Mon, 13 Feb 2023 03:22:16 +0300 Subject: [PATCH 37/45] Add files via upload --- .../shareit/booking/BookingController.java | 20 +-- .../shareit/booking/BookingMapper.java | 6 +- .../booking/dto/BookingDTOToReturn.java | 16 +- .../shareit/booking/model/Booking.java | 5 +- .../booking/service/BookingServiceImpl.java | 32 +--- .../shareit/exception/ErrorHandler.java | 10 ++ .../shareit/item/ItemController.java | 14 +- .../shareit/item/ItemRepository.java | 5 +- .../shareit/item/mapper/ItemMapper.java | 15 +- .../practicum/shareit/item/model/Comment.java | 5 +- .../shareit/item/service/ItemService.java | 2 +- .../shareit/item/service/ItemServiceImpl.java | 13 +- .../request/ItemRequestController.java | 14 +- .../shareit/request/RequestMapper.java | 10 +- .../shareit/request/RequestRepository.java | 3 + .../shareit/request/dto/RequestDTO.java | 9 +- .../request/dto/RequestDTOWithItems.java | 11 +- .../shareit/request/model/ItemRequest.java | 2 +- .../request/service/RequestService.java | 2 +- .../request/service/RequestServiceImpl.java | 65 ++++---- .../ru/practicum/shareit/user/UserMapper.java | 30 +++- .../practicum/shareit/user/dto/UserDTO.java | 4 +- .../ru/practicum/shareit/user/model/User.java | 5 +- .../shareit/user/service/UserServiceImpl.java | 1 - .../ru/practicum/shareit/ShareItTests.java | 142 +++++++++++++----- .../booking/BookingControllerTest.java | 26 ++-- .../booking/BookingRepositoryTest.java | 10 +- .../booking/dto/BookingDtoForItemTest.java | 32 ++++ .../booking/dto/BookingDtoToReturnTest.java | 48 ++++++ .../booking/service/BookingServiceTest.java | 86 ++++++----- .../shareit/item/CommentRepositoryTest.java | 9 +- .../shareit/item/ItemRepositoryTest.java | 8 +- .../shareit/item/dto/ItemDtoTest.java | 3 +- .../item/dto/ItemDtoWithBookingTest.java | 6 +- .../shareit/item/service/ItemServiceTest.java | 32 ++-- .../request/ItemRequestControllerTest.java | 14 -- .../request/ItemRequestRepositoryTest.java | 9 +- .../service/ItemRequestServiceTest.java | 57 +++---- .../shareit/user/UserControllerTest.java | 14 +- .../shareit/user/service/UserServiceTest.java | 10 +- 40 files changed, 469 insertions(+), 336 deletions(-) create mode 100644 src/test/java/ru/practicum/shareit/booking/dto/BookingDtoForItemTest.java create mode 100644 src/test/java/ru/practicum/shareit/booking/dto/BookingDtoToReturnTest.java diff --git a/src/main/java/ru/practicum/shareit/booking/BookingController.java b/src/main/java/ru/practicum/shareit/booking/BookingController.java index 22bfb0613..9bd9026a4 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingController.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingController.java @@ -3,6 +3,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import ru.practicum.shareit.booking.dto.BookingDTO; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; @@ -16,6 +17,7 @@ @RequestMapping(path = "/bookings") @RequiredArgsConstructor(onConstructor_ = @Autowired) @Slf4j +@Validated public class BookingController { private final BookingService bookingService; @@ -44,21 +46,21 @@ public BookingDTOToReturn get(@RequestHeader("X-Sharer-User-Id") Long userId, @P @GetMapping public List findByBooker(@RequestHeader("X-Sharer-User-Id") Long userId, @RequestParam(required = false, defaultValue = "ALL") String state, - @PositiveOrZero @RequestParam(name = "from", required = false) - Integer from, - @PositiveOrZero @RequestParam(name = "size", required = false) - Integer size) { + @PositiveOrZero @RequestParam(name = "from", defaultValue = "0") + Integer from, + @PositiveOrZero @RequestParam(name = "size", defaultValue = "10") + Integer size) { log.info("Получение списка бронирований пользовалеля с id {}", userId); return bookingService.getByBooker(userId, state, from, size); } @GetMapping("/owner") public List findByOwner(@RequestHeader("X-Sharer-User-Id") Long userId, - @RequestParam(required = false, defaultValue = "ALL") String state, - @PositiveOrZero @RequestParam(name = "from", required = false) - Integer from, - @PositiveOrZero @RequestParam(name = "size", required = false) - Integer size) { + @RequestParam(defaultValue = "ALL") String state, + @PositiveOrZero @RequestParam(name = "from", defaultValue = "0") + Integer from, + @PositiveOrZero @RequestParam(name = "size", defaultValue = "10") + Integer size) { log.info("Получение списка бронирований для всех вещей пользователя с id {}", userId); return bookingService.getByOwner(userId, state, from, size); } diff --git a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java index 361fcf0fd..37f79af8d 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingMapper.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingMapper.java @@ -6,7 +6,9 @@ import ru.practicum.shareit.booking.dto.BookingDTOToReturn; import ru.practicum.shareit.booking.model.Booking; import ru.practicum.shareit.booking.model.Status; +import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.UserMapper; import ru.practicum.shareit.user.model.User; import java.util.ArrayList; @@ -21,8 +23,8 @@ public static BookingDTOToReturn toBookingDtoFrom(Booking booking) { bookingDto.setStart(booking.getStart()); bookingDto.setEnd(booking.getEnd()); bookingDto.setStatus(booking.getStatus()); - bookingDto.setItem((booking.getItem())); - bookingDto.setBooker((booking.getBooker())); + bookingDto.setItem(ItemMapper.toItemToBookingDTO(booking.getItem())); + bookingDto.setBooker(UserMapper.toUserToBookingDTO(booking.getBooker())); return bookingDto; } diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java index 786c8a577..e10be31a0 100644 --- a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOToReturn.java @@ -1,13 +1,13 @@ package ru.practicum.shareit.booking.dto; import lombok.Data; +import org.springframework.validation.annotation.Validated; import ru.practicum.shareit.booking.model.Status; -import ru.practicum.shareit.item.model.Item; -import ru.practicum.shareit.user.model.User; import java.time.LocalDateTime; @Data +@Validated public class BookingDTOToReturn { private long id; @@ -21,4 +21,16 @@ public class BookingDTOToReturn { private User booker; private Status status; + + @Data + public static class User { + private final long id; + private final String name; + } + + @Data + public static class Item { + private final long id; + private final String name; + } } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/booking/model/Booking.java b/src/main/java/ru/practicum/shareit/booking/model/Booking.java index 22f8b09d8..6f4836d68 100644 --- a/src/main/java/ru/practicum/shareit/booking/model/Booking.java +++ b/src/main/java/ru/practicum/shareit/booking/model/Booking.java @@ -1,6 +1,9 @@ package ru.practicum.shareit.booking.model; -import lombok.*; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.ToString; import org.hibernate.Hibernate; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.user.model.User; diff --git a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java index 6a7fd72f8..703fe32f6 100644 --- a/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/booking/service/BookingServiceImpl.java @@ -23,7 +23,6 @@ import ru.practicum.shareit.user.UserRepository; import ru.practicum.shareit.user.model.User; - import java.time.LocalDateTime; import java.util.List; import java.util.Objects; @@ -59,7 +58,6 @@ public BookingDTOToReturn add(Long userId, BookingDTO bookingDto) { throw new BadRequestException("Wrong date"); } Booking booking = bRepository.save(BookingMapper.toBooking(bookingDto, item, user)); -// log.info(booking.toString()); return BookingMapper.toBookingDtoFrom(booking); } @@ -112,12 +110,6 @@ public List getByBooker(Long userId, String status, Integer } User user = booker.get(); if (page != null && size != null) { - if (page < 0 || size < 0) { - throw new BadRequestException("Wrong meaning page or size"); - } - if (size == 0) { - throw new BadRequestException("Size equals 0!"); - } pageable = PageRequest.of(page / size, size); return findBookingByBookerByPage(user, status, pageable); } else { @@ -160,28 +152,26 @@ private List findBookingByBooker(Long userId, String status) private List findBookingByBookerByPage(User booker, String status, Pageable pageable) { Page bookingsPage; - if (status == null || status.equals("")) { - status = "ALL"; - } - switch (status) { - case "ALL": + State state = stateValidation(status); + switch (state) { + case ALL: bookingsPage = bRepository.findByBookerOrderByStartDesc(booker, pageable); break; - case "CURRENT": + case CURRENT: bookingsPage = bRepository.findByBookerAndStartBeforeAndEndAfterOrderByStartDesc(booker, LocalDateTime.now(), LocalDateTime.now(), pageable); break; - case "PAST": + case PAST: bookingsPage = bRepository.findByBookerAndStartBeforeAndEndBeforeOrderByStartDesc(booker, LocalDateTime.now(), LocalDateTime.now(), pageable); break; - case "FUTURE": + case FUTURE: bookingsPage = bRepository.findByBookerAndStartAfterOrderByStartDesc(booker, LocalDateTime.now(), pageable); break; - case "WAITING": + case WAITING: bookingsPage = bRepository.findByBookerAndStatusOrderByStartDesc(booker, Status.WAITING, pageable); break; - case "REJECTED": + case REJECTED: bookingsPage = bRepository.findByBookerAndStatusOrderByStartDesc(booker, Status.REJECTED, pageable); break; default: @@ -197,12 +187,6 @@ public List getByOwner(Long userId, String status, Integer p User owner = uRepository.findById(userId).orElseThrow(() -> new NotFoundException("User not found")); Pageable pageable; if (page != null && size != null) { - if (page < 0 || size < 0) { - throw new BadRequestException("From or size is less than 0"); - } - if (size == 0) { - throw new BadRequestException("Size equals 0"); - } pageable = PageRequest.of(page / size, size); return findBookingByOwnerByPage(userId, status, pageable); diff --git a/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java b/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java index 76d9e19d9..b964b0dd6 100644 --- a/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java +++ b/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java @@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; +import javax.validation.ConstraintViolationException; import java.util.Map; @RestControllerAdvice @@ -23,6 +24,15 @@ public ResponseEntity> handleValid(final RuntimeException e) ); } + @ExceptionHandler + public ResponseEntity> handleConstraintViolation(final ConstraintViolationException e) { + log.error("Not valid argument{}", e.getMessage()); + return new ResponseEntity<>( + Map.of("Ошибка в валидации", e.getMessage()), + HttpStatus.BAD_REQUEST + ); + } + @ExceptionHandler public ResponseEntity> handleValidation(final MethodArgumentNotValidException e) { log.error("Not valid argument{}", e.getMessage()); diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/src/main/java/ru/practicum/shareit/item/ItemController.java index 0aa70ceef..07406e653 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -10,6 +10,8 @@ import ru.practicum.shareit.item.service.ItemService; import javax.validation.Valid; +import javax.validation.constraints.Positive; +import javax.validation.constraints.PositiveOrZero; import java.util.List; @RestController @@ -41,8 +43,10 @@ public ItemDTOWithBookings get(@RequestHeader("X-Sharer-User-Id") Long userId, @ @GetMapping public List getAllByOwner(@RequestHeader("X-Sharer-User-Id") Long userId, - @RequestParam(name = "from", required = false) Integer from, - @RequestParam(name = "size", required = false) Integer size) { + @RequestParam(name = "from", defaultValue = "0") + @PositiveOrZero Integer from, + @RequestParam(name = "size", defaultValue = "10") + @Positive Integer size) { log.info("Получение всех вещей пользователя с id {}", userId); return itemService.getAllByOwner(userId, from, size); } @@ -50,8 +54,10 @@ public List getAllByOwner(@RequestHeader("X-Sharer-User-Id" @GetMapping("/search") public List getAllByText(@RequestHeader("X-Sharer-User-Id") Long userId, @RequestParam String text, - @RequestParam(name = "from", required = false) Integer from, - @RequestParam(name = "size", required = false) Integer size) { + @RequestParam(name = "from", defaultValue = "0") + @PositiveOrZero Integer from, + @RequestParam(name = "size", defaultValue = "10") + @Positive Integer size) { log.info("Получение вещей для аренды содержащие в названии или описании текст {}", text); return itemService.getForRent(text, from, size); } diff --git a/src/main/java/ru/practicum/shareit/item/ItemRepository.java b/src/main/java/ru/practicum/shareit/item/ItemRepository.java index 74ad6a7ea..1b13aa370 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemRepository.java +++ b/src/main/java/ru/practicum/shareit/item/ItemRepository.java @@ -5,6 +5,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.request.model.ItemRequest; import ru.practicum.shareit.user.model.User; import java.util.List; @@ -22,8 +23,6 @@ public interface ItemRepository extends JpaRepository { "AND (available)") Page findItemsByNameOrDescription(String substring, Pageable pageable); - List getAllByOwnerId(long id); - @Query(nativeQuery = true, value = "SELECT * FROM items AS i WHERE i.REQUEST_ID = ?1") List findByRequest(Long idRequest); @@ -31,4 +30,6 @@ public interface ItemRepository extends JpaRepository { Page findByOwner(User user, Pageable pageable); + List findAllByRequestIdInAndAvailableTrue(List items); + } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java index 196a2959f..be1c9df64 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java @@ -2,6 +2,7 @@ import lombok.experimental.UtilityClass; import ru.practicum.shareit.booking.BookingMapper; +import ru.practicum.shareit.booking.dto.BookingDTOToReturn; import ru.practicum.shareit.booking.model.Booking; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithBookings; @@ -73,15 +74,10 @@ public static List mapToItemDto(Iterable items) { return dtos; } - /* public static BookingDTOToReturn.Item toItemToBookingDTO(Item item) { - BookingDTOToReturn.Item item1 = new BookingDTOToReturn.Item(); - item1.setId(item.getId()); - item1.setDescription(item.getDescription()); - item1.setName(item.getName()); - return item1; + public static BookingDTOToReturn.Item toItemToBookingDTO(Item item) { + return new BookingDTOToReturn.Item(item.getId(), item.getName()); } - */ public static ItemDTOWithBookings toDtoWithBookings(Item item, List bookings, List comments) { @@ -114,16 +110,13 @@ public static List mapToItem(Iterable items) { return dtos; } - /* public static Item toItem(BookingDTOToReturn.Item itemForBooking) { + public static Item toItem(BookingDTOToReturn.Item itemForBooking) { Item item = new Item(); item.setId(itemForBooking.getId()); item.setName(itemForBooking.getName()); - item.setDescription(itemForBooking.getDescription()); - // item.setAvailable(itemForBooking.getAvailable()); return item; } - */ } diff --git a/src/main/java/ru/practicum/shareit/item/model/Comment.java b/src/main/java/ru/practicum/shareit/item/model/Comment.java index b14bd1f14..d19c7dbd1 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Comment.java +++ b/src/main/java/ru/practicum/shareit/item/model/Comment.java @@ -1,6 +1,9 @@ package ru.practicum.shareit.item.model; -import lombok.*; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.ToString; import org.hibernate.Hibernate; import ru.practicum.shareit.user.model.User; diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemService.java b/src/main/java/ru/practicum/shareit/item/service/ItemService.java index 7b1700031..cb5429829 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemService.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemService.java @@ -1,8 +1,8 @@ package ru.practicum.shareit.item.service; +import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithBookings; -import ru.practicum.shareit.item.dto.CommentDTO; import java.util.List; diff --git a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java index 4efdeb736..816134bbb 100644 --- a/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/service/ItemServiceImpl.java @@ -18,9 +18,9 @@ import ru.practicum.shareit.exception.NotFoundException; import ru.practicum.shareit.item.CommentRepository; import ru.practicum.shareit.item.ItemRepository; +import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithBookings; -import ru.practicum.shareit.item.dto.CommentDTO; import ru.practicum.shareit.item.mapper.CommentMapper; import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Comment; @@ -106,7 +106,6 @@ public List getAllByOwner(Long userId, Integer page, Intege User user = userRepository.findById(userId).orElseThrow(() -> new NotFoundException("User not found")); List items = new ArrayList<>(); if (page != null && size != null) { - sizeAndPage(size, page); Pageable pageable = PageRequest.of(page / size, size); Page itemsPage = itemRepository.findByOwner(user, pageable); for (Item item : itemsPage) { @@ -174,7 +173,6 @@ public CommentDTO addComment(Long authorId, Long itemId, CommentDTO comment) { public List getForRent(String substring, Integer page, Integer size) { if (!Objects.equals(substring, "")) { if (page != null && size != null) { - sizeAndPage(size, page); Pageable pageable = PageRequest.of(page / size, size); return ItemMapper.mapToItemDto(itemRepository.findItemsByNameOrDescription(substring, pageable)); } @@ -182,13 +180,4 @@ public List getForRent(String substring, Integer page, Integer size) { } return new ArrayList<>(); } - - private void sizeAndPage(Integer size, Integer page) { - if (page < 0 || size < 0) { - throw new BadRequestException("From or size is less than 0"); - } - if (size == 0) { - throw new BadRequestException("Size equals 0"); - } - } } diff --git a/src/main/java/ru/practicum/shareit/request/ItemRequestController.java b/src/main/java/ru/practicum/shareit/request/ItemRequestController.java index 5e49b7c3e..142eb0882 100644 --- a/src/main/java/ru/practicum/shareit/request/ItemRequestController.java +++ b/src/main/java/ru/practicum/shareit/request/ItemRequestController.java @@ -3,17 +3,21 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import ru.practicum.shareit.request.dto.RequestDTO; import ru.practicum.shareit.request.dto.RequestDTOWithItems; import ru.practicum.shareit.request.service.RequestService; +import javax.validation.constraints.Positive; +import javax.validation.constraints.PositiveOrZero; import java.util.List; @RestController @RequestMapping(path = "/requests") @RequiredArgsConstructor(onConstructor_ = @Autowired) @Slf4j +@Validated public class ItemRequestController { private final RequestService requestService; @@ -32,15 +36,17 @@ public List getAllOwnRequest(@RequestHeader("X-Sharer-User- @GetMapping("/all") public List getAllRequest(@RequestHeader("X-Sharer-User-Id") Long userId, - @RequestParam(name = "from", required = false) Integer from, - @RequestParam(name = "size", required = false) Integer size) { + @RequestParam(defaultValue = "0") + @PositiveOrZero Integer from, + @RequestParam(name = "size", defaultValue = "1") + @Positive Integer size) { log.info("Просмотр всех запросов на добавление вещи"); - return requestService.findAll(userId,from, size); + return requestService.findAll(userId, from, size); } @GetMapping("/{requestId}") public RequestDTO getRequest(@RequestHeader("X-Sharer-User-Id") Long userId, @PathVariable Long requestId) { log.info("Просмотр запроса с id {}", requestId); - return requestService.findById(userId, requestId); + return requestService.findById(userId, requestId); } } diff --git a/src/main/java/ru/practicum/shareit/request/RequestMapper.java b/src/main/java/ru/practicum/shareit/request/RequestMapper.java index 42e5f22c9..6e4cfdf36 100644 --- a/src/main/java/ru/practicum/shareit/request/RequestMapper.java +++ b/src/main/java/ru/practicum/shareit/request/RequestMapper.java @@ -1,18 +1,22 @@ package ru.practicum.shareit.request; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.request.dto.RequestDTO; import ru.practicum.shareit.request.dto.RequestDTOWithItems; import ru.practicum.shareit.request.model.ItemRequest; +import ru.practicum.shareit.user.UserMapper; import java.util.List; +@NoArgsConstructor(access = AccessLevel.PRIVATE) public class RequestMapper { public static RequestDTO toRequestDto(ItemRequest itemRequest) { RequestDTO requestDto = new RequestDTO(); requestDto.setId(itemRequest.getId()); requestDto.setDescription(itemRequest.getDescription()); - requestDto.setRequester(itemRequest.getRequester()); + requestDto.setRequester(UserMapper.toUserToRequest(itemRequest.getRequester())); requestDto.setCreated(itemRequest.getCreated()); return requestDto; } @@ -21,7 +25,7 @@ public static ItemRequest toItemRequest(RequestDTO requestDto) { ItemRequest request = new ItemRequest(); request.setId(requestDto.getId()); request.setDescription(requestDto.getDescription()); - request.setRequester(requestDto.getRequester()); + request.setRequester(UserMapper.toUser(requestDto.getRequester())); request.setCreated(requestDto.getCreated()); return request; } @@ -30,7 +34,7 @@ public static RequestDTOWithItems toRequestForFindDto(ItemRequest itemRequest, L RequestDTOWithItems requestDto = new RequestDTOWithItems(); requestDto.setId(itemRequest.getId()); requestDto.setDescription(itemRequest.getDescription()); - requestDto.setRequester(itemRequest.getRequester()); + requestDto.setRequester(UserMapper.toUserToRequest(itemRequest.getRequester())); requestDto.setCreated(itemRequest.getCreated()); requestDto.setItems(item); return requestDto; diff --git a/src/main/java/ru/practicum/shareit/request/RequestRepository.java b/src/main/java/ru/practicum/shareit/request/RequestRepository.java index 915759600..28ed34a56 100644 --- a/src/main/java/ru/practicum/shareit/request/RequestRepository.java +++ b/src/main/java/ru/practicum/shareit/request/RequestRepository.java @@ -2,6 +2,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import ru.practicum.shareit.request.model.ItemRequest; @@ -17,4 +18,6 @@ public interface RequestRepository extends JpaRepository { " WHERE REQUESTER_ID != ?1") Page findAllBy(Long userId, Pageable pageable); + List findAllByRequester_IdNot(Long userId, Pageable pageable); + } \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/request/dto/RequestDTO.java b/src/main/java/ru/practicum/shareit/request/dto/RequestDTO.java index 799d53a56..8ec63dfa4 100644 --- a/src/main/java/ru/practicum/shareit/request/dto/RequestDTO.java +++ b/src/main/java/ru/practicum/shareit/request/dto/RequestDTO.java @@ -1,8 +1,8 @@ package ru.practicum.shareit.request.dto; import lombok.Data; -import ru.practicum.shareit.user.model.User; +import javax.validation.constraints.NotBlank; import java.time.LocalDateTime; @Data @@ -10,10 +10,17 @@ public class RequestDTO { private Long id; + @NotBlank() private String description; private User requester; private LocalDateTime created; + + @Data + public static class User { + private final long id; + private final String name; + } } diff --git a/src/main/java/ru/practicum/shareit/request/dto/RequestDTOWithItems.java b/src/main/java/ru/practicum/shareit/request/dto/RequestDTOWithItems.java index a04d4cd69..05d4ea9be 100644 --- a/src/main/java/ru/practicum/shareit/request/dto/RequestDTOWithItems.java +++ b/src/main/java/ru/practicum/shareit/request/dto/RequestDTOWithItems.java @@ -2,21 +2,12 @@ import lombok.Data; import ru.practicum.shareit.item.dto.ItemDTO; -import ru.practicum.shareit.user.model.User; -import java.time.LocalDateTime; import java.util.List; @Data public class RequestDTOWithItems extends RequestDTO { - private Long id; - - private String description; - - private User requester; - - private LocalDateTime created; - private List items; + } diff --git a/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java b/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java index 0c59d0ad1..012e87d40 100644 --- a/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java +++ b/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java @@ -16,7 +16,7 @@ public class ItemRequest { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @NotNull + @NotNull() @Column private String description; diff --git a/src/main/java/ru/practicum/shareit/request/service/RequestService.java b/src/main/java/ru/practicum/shareit/request/service/RequestService.java index 6264fb43d..fed049bec 100644 --- a/src/main/java/ru/practicum/shareit/request/service/RequestService.java +++ b/src/main/java/ru/practicum/shareit/request/service/RequestService.java @@ -12,5 +12,5 @@ public interface RequestService { List findAll(Long userId, Integer page, Integer size); - RequestDTO findById(Long userId, Long requestId); + RequestDTOWithItems findById(Long userId, Long requestId); } diff --git a/src/main/java/ru/practicum/shareit/request/service/RequestServiceImpl.java b/src/main/java/ru/practicum/shareit/request/service/RequestServiceImpl.java index 3aef5ef91..1ece187d2 100644 --- a/src/main/java/ru/practicum/shareit/request/service/RequestServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/request/service/RequestServiceImpl.java @@ -3,15 +3,13 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import ru.practicum.shareit.exception.BadRequestException; import ru.practicum.shareit.exception.NotFoundException; import ru.practicum.shareit.item.ItemRepository; +import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.request.RequestMapper; @@ -19,13 +17,19 @@ import ru.practicum.shareit.request.dto.RequestDTO; import ru.practicum.shareit.request.dto.RequestDTOWithItems; import ru.practicum.shareit.request.model.ItemRequest; +import ru.practicum.shareit.user.UserMapper; import ru.practicum.shareit.user.UserRepository; import ru.practicum.shareit.user.model.User; import java.time.LocalDateTime; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.Objects; +import java.util.Map; +import java.util.stream.Collectors; + +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.toList; @Service @RequiredArgsConstructor(onConstructor_ = @Autowired) @@ -41,12 +45,8 @@ public class RequestServiceImpl implements RequestService { @Transactional public RequestDTO add(Long userId, RequestDTO request) { User user = uRepository.findById(userId).orElseThrow(() -> new NotFoundException("User not found")); - log.info(request.toString()); - if (request.getDescription() == null || Objects.equals(request.getDescription(), "")) { - throw new BadRequestException("Description is empty"); - } request.setCreated(LocalDateTime.now()); - request.setRequester(user); + request.setRequester(UserMapper.toUserToRequest(user)); ItemRequest itemRequest = rRepository.save(RequestMapper.toItemRequest(request)); return RequestMapper.toRequestDto(itemRequest); } @@ -65,34 +65,29 @@ public List findAllByOwner(Long userId) { @Override public List findAll(Long userId, Integer page, Integer size) { - log.info("start"); - List requestForFindDtos = new ArrayList<>(); - Pageable pageable; - Sort sortById = Sort.by(Sort.Direction.DESC, "created"); - if (page != null && size != null) { - if (page < 0 || size < 0) { - throw new BadRequestException("From and size cannot be less than 0"); - } - if (size == 0) { - throw new BadRequestException("Size cannot be 0"); - } - pageable = PageRequest.of(page / size, size, sortById); - - Page requests = rRepository.findAllBy(userId, pageable); - for (ItemRequest request : requests) { - List items = iRepository.findByRequest(request.getId()); - RequestDTOWithItems request1 = RequestMapper.toRequestForFindDto(request, ItemMapper.mapToItemDto(items)); - requestForFindDtos.add(request1); + Pageable pageable = PageRequest.of(page, size); + List getAllRequests = new ArrayList<>(); + List itemRequests = rRepository.findAllByRequester_IdNot(userId, pageable); + Map> items = iRepository.findAllByRequestIdInAndAvailableTrue(itemRequests) + .stream() + .collect(groupingBy(Item::getRequestId, toList())); + for (ItemRequest request : itemRequests) { + RequestDTOWithItems itemRequestDtoResult; + List itemsToReturn; + if (!items.isEmpty()) { + itemsToReturn = items.get(request) + .stream() + .filter(item -> item.getRequestId().getId().equals(request.getId())) + .map(ItemMapper::toItemDto) + .collect(Collectors.toList()); + itemRequestDtoResult = RequestMapper.toRequestForFindDto(request, itemsToReturn); + getAllRequests.add(itemRequestDtoResult); + } else { + itemRequestDtoResult = RequestMapper.toRequestForFindDto(request, Collections.emptyList()); + getAllRequests.add(itemRequestDtoResult); } - return requestForFindDtos; - } - List requests = rRepository.findAll(); - for (ItemRequest request : requests) { - List items = iRepository.findByRequest(request.getId()); - RequestDTOWithItems request1 = RequestMapper.toRequestForFindDto(request, ItemMapper.mapToItemDto(items)); - requestForFindDtos.add(request1); } - return requestForFindDtos; + return getAllRequests; } @Override diff --git a/src/main/java/ru/practicum/shareit/user/UserMapper.java b/src/main/java/ru/practicum/shareit/user/UserMapper.java index 54dea0aa8..a590925b6 100644 --- a/src/main/java/ru/practicum/shareit/user/UserMapper.java +++ b/src/main/java/ru/practicum/shareit/user/UserMapper.java @@ -1,8 +1,10 @@ package ru.practicum.shareit.user; import lombok.experimental.UtilityClass; +import ru.practicum.shareit.booking.dto.BookingDTOToReturn; import ru.practicum.shareit.item.dto.ItemDTO; import ru.practicum.shareit.item.dto.ItemDTOWithBookings; +import ru.practicum.shareit.request.dto.RequestDTO; import ru.practicum.shareit.user.dto.UserDTO; import ru.practicum.shareit.user.model.User; @@ -43,12 +45,6 @@ public static List mapToUserDto(Iterable users) { return dtos; } - /* public static BookingDTOToReturn.User toUserToBookingDTO(User user) { - return new BookingDTOToReturn.User(user.getId(), user.getName(), user.getEmail()); - } - - */ - public static ItemDTOWithBookings.User toUserToItemWithBookingsDto(User user) { return new ItemDTOWithBookings.User(user.getId(), user.getName(), user.getEmail()); } @@ -64,4 +60,26 @@ public static List mapToUser(Iterable users) { } return dtos; } + + public static User toUser(RequestDTO.User userRequest) { + User user = new User(); + user.setId(userRequest.getId()); + user.setName(userRequest.getName()); + return user; + } + + public static RequestDTO.User toUserToRequest(User user) { + return new RequestDTO.User(user.getId(), user.getName()); + } + + public static BookingDTOToReturn.User toUserToBookingDTO(User user) { + return new BookingDTOToReturn.User(user.getId(), user.getName()); + } + + public static User toUser(BookingDTOToReturn.User userFromDto) { + User user = new User(); + user.setId(userFromDto.getId()); + user.setName(userFromDto.getName()); + return user; + } } diff --git a/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java b/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java index d9b79e7ad..e44b1aae4 100644 --- a/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java +++ b/src/main/java/ru/practicum/shareit/user/dto/UserDTO.java @@ -6,7 +6,7 @@ import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; +import javax.validation.constraints.NotEmpty; @Data public class UserDTO { @@ -17,6 +17,6 @@ public class UserDTO { private String name; @Email(groups = {Update.class, Create.class}) - @NotNull(groups = {Create.class}) + @NotEmpty(groups = {Create.class}) private String email; } diff --git a/src/main/java/ru/practicum/shareit/user/model/User.java b/src/main/java/ru/practicum/shareit/user/model/User.java index 527b23780..e17f3894d 100644 --- a/src/main/java/ru/practicum/shareit/user/model/User.java +++ b/src/main/java/ru/practicum/shareit/user/model/User.java @@ -1,6 +1,9 @@ package ru.practicum.shareit.user.model; -import lombok.*; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.ToString; import org.hibernate.Hibernate; import javax.persistence.*; diff --git a/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java index 0725cf345..5c893d478 100644 --- a/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/user/service/UserServiceImpl.java @@ -22,7 +22,6 @@ public class UserServiceImpl implements UserService { @Transactional @Override public UserDTO create(UserDTO userDto) { - User user = repository.save(UserMapper.toUser(userDto)); return UserMapper.toUserDto(user); } diff --git a/src/test/java/ru/practicum/shareit/ShareItTests.java b/src/test/java/ru/practicum/shareit/ShareItTests.java index 4ef4d2e5c..af38b5863 100644 --- a/src/test/java/ru/practicum/shareit/ShareItTests.java +++ b/src/test/java/ru/practicum/shareit/ShareItTests.java @@ -9,7 +9,9 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.TestExecutionListeners; import org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener; +import ru.practicum.shareit.booking.dto.BookingDTO; import ru.practicum.shareit.booking.dto.BookingDTOToReturn; +import ru.practicum.shareit.booking.model.Status; import ru.practicum.shareit.booking.service.BookingService; import ru.practicum.shareit.exception.BadRequestException; import ru.practicum.shareit.exception.NotFoundException; @@ -19,7 +21,11 @@ import ru.practicum.shareit.item.service.ItemService; import ru.practicum.shareit.request.dto.RequestDTOWithItems; import ru.practicum.shareit.request.service.RequestService; +import ru.practicum.shareit.user.dto.UserDTO; +import ru.practicum.shareit.user.service.UserService; +import java.time.LocalDateTime; +import java.time.Month; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -35,10 +41,70 @@ class ShareItTests { private final ItemService itemService; private final RequestService requestService; + private final UserService userService; + @Test void contextLoads() { } + @Test + void createUser() { + UserDTO userDTO = new UserDTO(); + userDTO.setId(1); + userDTO.setName("Aelin"); + userDTO.setEmail("aelin@whitethorn.com"); + + UserDTO user = userService.create(userDTO); + assertThat(user).isNotNull(); + assertThat(user.getId()).isEqualTo(1); + assertThat(user.getName()).isEqualTo("Aelin"); + assertThat(user.getEmail()).isEqualTo("aelin@whitethorn.com"); + } + + @Test + void getItem() { + ItemDTOWithBookings itemDTO = itemService.get(1L, 1L); + assertThat(itemDTO).isNotNull(); + assertThat(itemDTO.getId()).isEqualTo(1L); + assertThat(itemDTO.getName()).isEqualTo("Sword"); + assertThat(itemDTO.getDescription()).isEqualTo("For fights"); + assertThat(itemDTO.getAvailable()).isEqualTo(true); + } + + @Test + void getBookingWithEndBeforeStart() { + BookingDTO bDto = new BookingDTO(); + bDto.setBookerId(1L); + bDto.setId(1); + bDto.setStart(LocalDateTime.of(2023, Month.FEBRUARY, 13, 12, 29, 00)); + bDto.setEnd(LocalDateTime.of(2022, Month.FEBRUARY, 13, 12, 29, 00)); + bDto.setStatus(Status.WAITING); + bDto.setItemId(3L); + + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> bookingService.add(1L, bDto)); + assertThat(exception.getMessage()).isEqualTo("Wrong date"); + } + + @Test + void bookingGet() { + BookingDTOToReturn booking = bookingService.get(2L, 4L); + assertThat(booking).isNotNull(); + assertThat(booking.getId()).isEqualTo(4L); + assertThat(booking.getBooker().getId()).isEqualTo(1); + assertThat(booking.getStatus()).isEqualTo(Status.WAITING); + assertThat(booking.getStart()).isEqualTo(LocalDateTime.parse("2023-11-11T12:32:59")); + } + + @Test + void bookingGetNoRights() { + final NotFoundException exception = Assertions.assertThrows( + NotFoundException.class, + () -> bookingService.get(2L, 1L)); + assertThat(exception.getMessage()).isEqualTo("No rights"); + } + @Test void getAllOwnItemTest() { List items = itemService.getAllByOwner(1L, null, null); @@ -58,21 +124,21 @@ void getAllOwnItemNotFoundUserTest() { @Test void getAllOwnItemFromOrSizeLessThanZeroTest() { - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, + final ArithmeticException exception = Assertions.assertThrows( + ArithmeticException.class, () -> itemService.getAllByOwner(1L, -1, 0)); - Assertions.assertEquals("From or size is less than 0", + Assertions.assertEquals("/ by zero", exception.getMessage()); } @Test void getAllOwnItemSizeEqualToZeroTest() { - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, + final ArithmeticException exception = Assertions.assertThrows( + ArithmeticException.class, () -> itemService.getAllByOwner(1L, 1, 0)); - Assertions.assertEquals("Size equals 0", exception.getMessage()); + Assertions.assertEquals("/ by zero", exception.getMessage()); } @Test @@ -88,21 +154,21 @@ void getItemsForRentTest() { @Test void getItemForRentEqualToZeroTest() { - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, - () -> itemService.getForRent("F", 0, 0)); + final ArithmeticException exception = Assertions.assertThrows( + ArithmeticException.class, + () -> itemService.getForRent("S", 0, 0)); - Assertions.assertEquals("Size equals 0", exception.getMessage()); + Assertions.assertEquals("/ by zero", exception.getMessage()); } @Test void getItemsForRentFromOrSizeLessThanZeroTest() { - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, + final ArithmeticException exception = Assertions.assertThrows( + ArithmeticException.class, () -> itemService.getForRent("F", -1, 0)); - Assertions.assertEquals("From or size is less than 0", + Assertions.assertEquals("/ by zero", exception.getMessage()); } @@ -129,6 +195,13 @@ void getBookingByBookerStateCurrentTest() { assertThat(bookings.get(0).getId()).isEqualTo(2); } + @Test + void getBookingByBookerStatePastTest() { + List bookings = bookingService.getByBooker(3L, + "PAST", null, null); + assertThat(bookings).isEmpty(); + } + @Test void getBookingByBookerStateFutureTest() { List bookings = bookingService.getByBooker(2L, @@ -139,7 +212,7 @@ void getBookingByBookerStateFutureTest() { } @Test - void getBookingByBookerStateWaitingOrRejectedTest() { + void getBookingByBookerStateWaitingTest() { List bookings = bookingService.getByBooker(1L, "WAITING", 0, 1); assertThat(bookings).isNotEmpty(); @@ -151,7 +224,7 @@ void getBookingByBookerStateWaitingOrRejectedTest() { void getBookingsByBookerUnknownStatePageableTest() { final StatusBadRequestException exception = Assertions.assertThrows( StatusBadRequestException.class, - () -> bookingService.getByBooker(3L, "RED", 0, 1)); + () -> bookingService.getByBooker(3L, "WRONG", 0, 1)); Assertions.assertEquals("Unknown state: UNSUPPORTED_STATUS", exception.getMessage()); @@ -169,22 +242,22 @@ void getBookingsByBookerNotFoundUserTest() { @Test void getBookingsByBookerSizeOrPageLessZeroTest() { - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, + final IllegalArgumentException exception = Assertions.assertThrows( + IllegalArgumentException.class, () -> bookingService.getByBooker(3L, null, -1, 1)); - Assertions.assertEquals("Wrong meaning page or size", + Assertions.assertEquals("Page index must not be less than zero", exception.getMessage()); } @Test void getBookingsByBookerSizeEqualZeroTest() { - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, + final ArithmeticException exception = Assertions.assertThrows( + ArithmeticException.class, () -> bookingService.getByBooker(3L, null, 0, 0)); - Assertions.assertEquals("Size equals 0!", exception.getMessage()); + Assertions.assertEquals("/ by zero", exception.getMessage()); } @@ -199,11 +272,11 @@ void getBookingsByOwnerNotFoundUserTest() { @Test void getBookingsByOwnerSizeOrPageLessZeroTest() { - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, + final IllegalArgumentException exception = Assertions.assertThrows( + IllegalArgumentException.class, () -> bookingService.getByOwner(1L, null, -1, 1)); - Assertions.assertEquals("From or size is less than 0", + Assertions.assertEquals("Page index must not be less than zero", exception.getMessage()); } @@ -276,30 +349,29 @@ void findAllOwnRequestsNotFoundUserTest() { @Test void findAllRequestsTest() { - List requests = requestService.findAll(1L, null, null); + List requests = requestService.findAll(1L, 0, 1); assertThat(requests).isNotEmpty(); - assertThat(requests.size()).isEqualTo(4); - assertThat(requests.get(0).getId()).isEqualTo(1); + assertThat(requests.size()).isEqualTo(1); + assertThat(requests.get(0).getId()).isEqualTo(2); } @Test void findAllRequestsSizeOrPageLessZeroTest() { - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, + final IllegalArgumentException exception = Assertions.assertThrows( + IllegalArgumentException.class, () -> requestService.findAll(1L, 1, -1)); - Assertions.assertEquals("From and size cannot be less than 0", + Assertions.assertEquals("Page size must not be less than one", exception.getMessage()); } @Test void findAllRequestsSizeEqualZeroTest() { - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, + final IllegalArgumentException exception = Assertions.assertThrows( + IllegalArgumentException.class, () -> requestService.findAll(1L, 1, 0)); - Assertions.assertEquals("Size cannot be 0", - exception.getMessage()); - } + + } diff --git a/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java b/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java index b3c1712bb..27a791c53 100644 --- a/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java +++ b/src/test/java/ru/practicum/shareit/booking/BookingControllerTest.java @@ -12,7 +12,9 @@ import ru.practicum.shareit.booking.dto.BookingDTOToReturn; import ru.practicum.shareit.booking.model.Status; import ru.practicum.shareit.booking.service.BookingServiceImpl; +import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.user.UserMapper; import ru.practicum.shareit.user.model.User; import java.nio.charset.StandardCharsets; @@ -58,13 +60,11 @@ void addBookingControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.id", is(bookingDto.getId()), Long.class)) .andExpect(jsonPath("$.start", is(bookingDto.getStart().toString()))) - .andExpect(jsonPath("$.booker.id", is(bookingDto.getBooker().getId().intValue()))) + .andExpect(jsonPath("$.booker.id", is((int)bookingDto.getBooker().getId()))) .andExpect(jsonPath("$.booker.name", is(bookingDto.getBooker().getName()))) - .andExpect(jsonPath("$.booker.email", is(bookingDto.getBooker().getEmail()))) .andExpect(jsonPath("$.end", is(bookingDto.getEnd().toString()))) .andExpect(jsonPath("$.item.id", is((int) bookingDto.getItem().getId()))) .andExpect(jsonPath("$.item.name", is(bookingDto.getItem().getName()))) - .andExpect(jsonPath("$.item.description", is(bookingDto.getItem().getDescription()))) .andExpect(jsonPath("$.status", is(bookingDto.getStatus().toString()))); } @@ -87,13 +87,11 @@ void updateStatusBookingControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.id", is(bookingDto.getId()), Long.class)) .andExpect(jsonPath("$.start", is(bookingDto.getStart().toString()))) - .andExpect(jsonPath("$.booker.id", is(bookingDto.getBooker().getId().intValue()))) + .andExpect(jsonPath("$.booker.id", is((int)bookingDto.getBooker().getId()))) .andExpect(jsonPath("$.booker.name", is(bookingDto.getBooker().getName()))) - .andExpect(jsonPath("$.booker.email", is(bookingDto.getBooker().getEmail()))) .andExpect(jsonPath("$.end", is(bookingDto.getEnd().toString()))) .andExpect(jsonPath("$.item.id", is((int) bookingDto.getItem().getId()))) .andExpect(jsonPath("$.item.name", is(bookingDto.getItem().getName()))) - .andExpect(jsonPath("$.item.description", is(bookingDto.getItem().getDescription()))) .andExpect(jsonPath("$.status", is(bookingDto.getStatus().toString()))); } @@ -114,13 +112,11 @@ void getBookingControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.id", is(bookingDto.getId()), Long.class)) .andExpect(jsonPath("$.start", is(bookingDto.getStart().toString()))) - .andExpect(jsonPath("$.booker.id", is(bookingDto.getBooker().getId().intValue()))) + .andExpect(jsonPath("$.booker.id", is((int)bookingDto.getBooker().getId()))) .andExpect(jsonPath("$.booker.name", is(bookingDto.getBooker().getName()))) - .andExpect(jsonPath("$.booker.email", is(bookingDto.getBooker().getEmail()))) .andExpect(jsonPath("$.end", is(bookingDto.getEnd().toString()))) .andExpect(jsonPath("$.item.id", is((int) bookingDto.getItem().getId()))) .andExpect(jsonPath("$.item.name", is(bookingDto.getItem().getName()))) - .andExpect(jsonPath("$.item.description", is(bookingDto.getItem().getDescription()))) .andExpect(jsonPath("$.status", is(bookingDto.getStatus().toString()))); } @@ -144,13 +140,11 @@ void findBookingByBookerControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$[0].id", is(bookingDto.getId()), Long.class)) .andExpect(jsonPath("$[0].start", is(bookingDto.getStart().toString()))) - .andExpect(jsonPath("$[0].booker.id", is(bookingDto.getBooker().getId().intValue()))) + .andExpect(jsonPath("$[0].booker.id", is((int)bookingDto.getBooker().getId()))) .andExpect(jsonPath("$[0].booker.name", is(bookingDto.getBooker().getName()))) - .andExpect(jsonPath("$[0].booker.email", is(bookingDto.getBooker().getEmail()))) .andExpect(jsonPath("$[0].end", is(bookingDto.getEnd().toString()))) .andExpect(jsonPath("$[0].item.id", is((int) bookingDto.getItem().getId()))) .andExpect(jsonPath("$[0].item.name", is(bookingDto.getItem().getName()))) - .andExpect(jsonPath("$[0].item.description", is(bookingDto.getItem().getDescription()))) .andExpect(jsonPath("$[0].status", is(bookingDto.getStatus().toString()))); } @@ -174,13 +168,11 @@ void findBookingByOwnerControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$[0].id", is(bookingDto.getId()), Long.class)) .andExpect(jsonPath("$[0].start", is(bookingDto.getStart().toString()))) - .andExpect(jsonPath("$[0].booker.id", is(bookingDto.getBooker().getId().intValue()))) + .andExpect(jsonPath("$[0].booker.id", is((int)bookingDto.getBooker().getId()))) .andExpect(jsonPath("$[0].booker.name", is(bookingDto.getBooker().getName()))) - .andExpect(jsonPath("$[0].booker.email", is(bookingDto.getBooker().getEmail()))) .andExpect(jsonPath("$[0].end", is(bookingDto.getEnd().toString()))) .andExpect(jsonPath("$[0].item.id", is((int) bookingDto.getItem().getId()))) .andExpect(jsonPath("$[0].item.name", is(bookingDto.getItem().getName()))) - .andExpect(jsonPath("$[0].item.description", is(bookingDto.getItem().getDescription()))) .andExpect(jsonPath("$[0].status", is(bookingDto.getStatus().toString()))); } @@ -205,9 +197,9 @@ private void addBookingDto() { booker.setName("Rowan"); booker.setEmail("rowan@whitethorn.com"); bookingDto.setId(2L); - bookingDto.setItem(item); + bookingDto.setItem(ItemMapper.toItemToBookingDTO(item)); bookingDto.setStatus(Status.WAITING); - bookingDto.setBooker(booker); + bookingDto.setBooker(UserMapper.toUserToBookingDTO(booker)); String date = "2023-11-24T18:08:54"; LocalDateTime localdatetime = LocalDateTime.parse(date); bookingDto.setStart(localdatetime); diff --git a/src/test/java/ru/practicum/shareit/booking/BookingRepositoryTest.java b/src/test/java/ru/practicum/shareit/booking/BookingRepositoryTest.java index cbd63d735..d8b469ef9 100644 --- a/src/test/java/ru/practicum/shareit/booking/BookingRepositoryTest.java +++ b/src/test/java/ru/practicum/shareit/booking/BookingRepositoryTest.java @@ -27,18 +27,16 @@ @Slf4j class BookingRepositoryTest { - @Autowired - private TestEntityManager em; - - @Autowired - private BookingRepository bookingRepository; - private final User user = new User(); private final Item item = new Item(); private final ItemRequest request = new ItemRequest(); private final Booking bookingOne = new Booking(); private final Booking bookingTwo = new Booking(); private final List bookingsList = new ArrayList<>(); + @Autowired + private TestEntityManager em; + @Autowired + private BookingRepository bookingRepository; @Test void findByItemOrderByStartDescTest() { diff --git a/src/test/java/ru/practicum/shareit/booking/dto/BookingDtoForItemTest.java b/src/test/java/ru/practicum/shareit/booking/dto/BookingDtoForItemTest.java new file mode 100644 index 000000000..8553ff04e --- /dev/null +++ b/src/test/java/ru/practicum/shareit/booking/dto/BookingDtoForItemTest.java @@ -0,0 +1,32 @@ +package ru.practicum.shareit.booking.dto; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.json.JsonTest; +import org.springframework.boot.test.json.JacksonTester; +import org.springframework.boot.test.json.JsonContent; + +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; + +@JsonTest +class BookingDtoForItemTest { + @Autowired + private JacksonTester json; + + @Test + void testBookingDto() throws Exception { + BookingDTOForItem bookingDto = new BookingDTOForItem(); + bookingDto.setId(1); + bookingDto.setBookerId(1L); + bookingDto.setDateTime(LocalDateTime.parse("2017-10-19T23:50:50")); + + JsonContent result = json.write(bookingDto); + + assertThat(result).extractingJsonPathNumberValue("$.id").isEqualTo(1); + assertThat(result).extractingJsonPathValue("$.dateTime").isEqualTo("2017-10-19T23:50:50"); + assertThat(result).extractingJsonPathValue("$.bookerId").isEqualTo(1); + } + +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/booking/dto/BookingDtoToReturnTest.java b/src/test/java/ru/practicum/shareit/booking/dto/BookingDtoToReturnTest.java new file mode 100644 index 000000000..20ea18635 --- /dev/null +++ b/src/test/java/ru/practicum/shareit/booking/dto/BookingDtoToReturnTest.java @@ -0,0 +1,48 @@ +package ru.practicum.shareit.booking.dto; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.json.JsonTest; +import org.springframework.boot.test.json.JacksonTester; +import org.springframework.boot.test.json.JsonContent; +import ru.practicum.shareit.booking.model.Status; +import ru.practicum.shareit.user.UserMapper; + +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; + +@JsonTest +class BookingDtoToReturnTest { + @Autowired + private JacksonTester json; + + private final BookingDTOToReturn.User user = new BookingDTOToReturn.User(2L, "Rowan"); + private final BookingDTOToReturn.Item item = new BookingDTOToReturn.Item(1L, "Sword"); + + @Test + void testBookingDto() throws Exception { + String date = "2017-10-19T23:50:50"; + LocalDateTime localdatetime = LocalDateTime.parse(date); + BookingDTOToReturn bookingDto = new BookingDTOToReturn(); + bookingDto.setId(1); + bookingDto.setItem(item); + bookingDto.setStatus(Status.WAITING); + bookingDto.setStart(localdatetime); + localdatetime = LocalDateTime.parse(date); + bookingDto.setEnd(localdatetime); + bookingDto.setBooker(user); + + JsonContent result = json.write(bookingDto); + + assertThat(result).extractingJsonPathNumberValue("$.id").isEqualTo(1); + assertThat(result).extractingJsonPathValue("$.item.id").isEqualTo(1); + assertThat(result).extractingJsonPathValue("$.item.name").isEqualTo("Sword"); + assertThat(result).extractingJsonPathValue("$.status").isEqualTo("WAITING"); + assertThat(result).extractingJsonPathValue("$.start").isEqualTo("2017-10-19T23:50:50"); + assertThat(result).extractingJsonPathValue("$.end").isEqualTo("2017-10-19T23:50:50"); + assertThat(result).extractingJsonPathValue("$.booker.id").isEqualTo(2); + assertThat(result).extractingJsonPathValue("$.booker.name").isEqualTo("Rowan"); + } + +} \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java b/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java index 2d8ba3c72..56903b976 100644 --- a/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java +++ b/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java @@ -1,7 +1,6 @@ package ru.practicum.shareit.booking.service; import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -9,7 +8,6 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.stubbing.Answer; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.test.annotation.DirtiesContext; @@ -22,9 +20,11 @@ import ru.practicum.shareit.exception.NotFoundException; import ru.practicum.shareit.exception.StatusBadRequestException; import ru.practicum.shareit.item.ItemRepository; +import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.item.service.ItemServiceImpl; import ru.practicum.shareit.request.model.ItemRequest; +import ru.practicum.shareit.user.UserMapper; import ru.practicum.shareit.user.UserRepository; import ru.practicum.shareit.user.model.User; import ru.practicum.shareit.user.service.UserServiceImpl; @@ -89,8 +89,10 @@ void addBookingTest() { .isPresent() .hasValueSatisfying(addBookingTest -> { assertThat(addBookingTest).hasFieldOrPropertyWithValue("id", booking.getId()); - assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); - assertThat(addBookingTest).hasFieldOrPropertyWithValue("booker", booking.getBooker()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", + ItemMapper.toItemToBookingDTO(booking.getItem())); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("booker", + UserMapper.toUserToBookingDTO(booking.getBooker())); assertThat(addBookingTest).hasFieldOrPropertyWithValue("status", booking.getStatus()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("start", booking.getStart()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("end", booking.getEnd()); @@ -228,6 +230,30 @@ void addBookingNotValidStartTest() { exception.getMessage()); } + @Test + void addBookingEndIsBeforeStartTest() { + addBooking(); + addUser(); + addItem(); + booking.setStart(LocalDateTime.parse("2017-10-19T23:50:50")); + booking.setEnd(LocalDateTime.parse("2016-10-19T23:50:50")); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(item)); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> bookingService.add(2L, BookingMapper.toBookingDto(booking))); + + Assertions.assertEquals("Wrong date", + exception.getMessage()); + } + @Test void updateStatusBookingApprovedTest() { addUser(); @@ -305,11 +331,6 @@ void updateStatusBookingBadRequestTest() { addBooking(); booking.setStatus(Status.APPROVED); - /* Mockito - .when(bookingRepository.findById(Mockito.anyLong())) - .thenReturn(Optional.of(booking)); - */ - Mockito .when(bookingRepository.getReferenceById(Mockito.anyLong())) .thenReturn(booking); @@ -339,8 +360,10 @@ void getBookingTest() { .isPresent() .hasValueSatisfying(addBookingTest -> { assertThat(addBookingTest).hasFieldOrPropertyWithValue("id", booking.getId()); - assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", booking.getItem()); - assertThat(addBookingTest).hasFieldOrPropertyWithValue("booker", booking.getBooker()); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("item", + ItemMapper.toItemToBookingDTO(booking.getItem())); + assertThat(addBookingTest).hasFieldOrPropertyWithValue("booker", + UserMapper.toUserToBookingDTO(booking.getBooker())); assertThat(addBookingTest).hasFieldOrPropertyWithValue("status", booking.getStatus()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("start", booking.getStart()); assertThat(addBookingTest).hasFieldOrPropertyWithValue("end", booking.getEnd()); @@ -490,7 +513,7 @@ void getBookingByBookerWithPageableTest() { .when(bookingRepository.findByBookerOrderByStartDesc(any(), any())) .thenReturn(page); - List bookings = bookingService.getByBooker(3L, null, 0, 1); + List bookings = bookingService.getByBooker(3L, "ALL", 0, 1); List bookings1 = List.copyOf(bookings); Assertions.assertEquals(bookingList.get(0).getId(), bookings1.get(0).getId()); @@ -852,11 +875,11 @@ void getBookingByBookerSizeOrPageLessZeroTest() { .when(userRepository.findById(Mockito.anyLong())) .thenReturn(Optional.of(user)); - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, + final IllegalArgumentException exception = Assertions.assertThrows( + IllegalArgumentException.class, () -> bookingService.getByBooker(3L, null, -1, 1)); - Assertions.assertEquals("Wrong meaning page or size", + Assertions.assertEquals("Page index must not be less than zero", exception.getMessage()); } @@ -870,11 +893,11 @@ void getBookingByBookerSizeEqualZeroTest() { .when(userRepository.findById(Mockito.anyLong())) .thenReturn(Optional.of(user)); - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, + final ArithmeticException exception = Assertions.assertThrows( + ArithmeticException.class, () -> bookingService.getByBooker(3L, null, 0, 0)); - Assertions.assertEquals("Size equals 0!", exception.getMessage()); + Assertions.assertEquals("/ by zero", exception.getMessage()); } @@ -900,11 +923,11 @@ void getBookingByOwnerSizeOrPageLessZeroTest() { .when(userRepository.findById(Mockito.anyLong())) .thenReturn(Optional.of(user)); - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, + final IllegalArgumentException exception = Assertions.assertThrows( + IllegalArgumentException.class, () -> bookingService.getByOwner(1L, null, -1, 1)); - Assertions.assertEquals("From or size is less than 0", + Assertions.assertEquals("Page index must not be less than zero", exception.getMessage()); } @@ -918,11 +941,11 @@ void getBookingByOwnerSizeEqualZeroTest() { .when(userRepository.findById(Mockito.anyLong())) .thenReturn(Optional.of(user)); - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, + final ArithmeticException exception = Assertions.assertThrows( + ArithmeticException.class, () -> bookingService.getByOwner(1L, null, 0, 0)); - Assertions.assertEquals("Size equals 0", exception.getMessage()); + Assertions.assertEquals("/ by zero", exception.getMessage()); } @@ -1044,7 +1067,7 @@ void getBookingByOwnerWithPageableTest() { } @Test - // @MockitoSettings(strictness = Strictness.LENIENT) + // @MockitoSettings(strictness = Strictness.LENIENT) void getBookingByOwnerCURRENTTest() { addUser(); addItem(); @@ -1065,7 +1088,7 @@ void getBookingByOwnerCURRENTTest() { .when(bookingRepository.findByOwnerAndCurrent(anyLong(), any(LocalDateTime.class))) .thenReturn(bookingList); - List bookings = bookingService.getByOwner(1L,"CURRENT", + List bookings = bookingService.getByOwner(1L, "CURRENT", null, null); log.info(String.valueOf(bookingList.size())); @@ -1182,7 +1205,7 @@ void getBookingByOwnerFUTURETest() { .when(userRepository.findById(Mockito.anyLong())) .thenReturn(Optional.of(user)); - Mockito + Mockito .when(bookingRepository.findByUserAndFuture(anyLong(), any(LocalDateTime.class))) .thenReturn(bookingList); @@ -1193,10 +1216,6 @@ void getBookingByOwnerFUTURETest() { } - private Answer getList() { - return (Answer)bookingRepository.findByUserAndFuture(any(), any()); - } - @Test void getBookingByOwnerFUTUREWithPageableTest() { addUser(); @@ -1414,9 +1433,4 @@ private void addBooking() { booking.setEnd(localdatetime); booking.setBooker(booker); } - - @AfterEach - private void delete() { - itemRepository.deleteAll(); - } } \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/item/CommentRepositoryTest.java b/src/test/java/ru/practicum/shareit/item/CommentRepositoryTest.java index 5abc2961a..9da9754bb 100644 --- a/src/test/java/ru/practicum/shareit/item/CommentRepositoryTest.java +++ b/src/test/java/ru/practicum/shareit/item/CommentRepositoryTest.java @@ -17,17 +17,14 @@ @DataJpaTest @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) class CommentRepositoryTest { + private final Comment comment = new Comment(); + private final User user = new User(); + private final Item item = new Item(); @Autowired private TestEntityManager em; - @Autowired private CommentRepository commentRepository; - private final Comment comment = new Comment(); - private final User user = new User(); - - private final Item item = new Item(); - @Test public void findByItemJpaTest() { addComment(); diff --git a/src/test/java/ru/practicum/shareit/item/ItemRepositoryTest.java b/src/test/java/ru/practicum/shareit/item/ItemRepositoryTest.java index 7a7df1560..47adb168d 100644 --- a/src/test/java/ru/practicum/shareit/item/ItemRepositoryTest.java +++ b/src/test/java/ru/practicum/shareit/item/ItemRepositoryTest.java @@ -20,16 +20,14 @@ @Slf4j class ItemRepositoryTest { + private final Item item = new Item(); + private final User user = new User(); + private final ItemRequest request = new ItemRequest(); @Autowired private TestEntityManager em; - @Autowired private ItemRepository itemRepository; - private final Item item = new Item(); - private final User user = new User(); - private final ItemRequest request = new ItemRequest(); - @Test void findItemByRequestJpaTest() { addItem(); diff --git a/src/test/java/ru/practicum/shareit/item/dto/ItemDtoTest.java b/src/test/java/ru/practicum/shareit/item/dto/ItemDtoTest.java index dd3bc997b..08be4403f 100644 --- a/src/test/java/ru/practicum/shareit/item/dto/ItemDtoTest.java +++ b/src/test/java/ru/practicum/shareit/item/dto/ItemDtoTest.java @@ -12,11 +12,10 @@ @JsonTest class ItemDtoTest { + private final User user = new User(); @Autowired private JacksonTester json; - private final User user = new User(); - @Test void testItemDto() throws Exception { addUser(); diff --git a/src/test/java/ru/practicum/shareit/item/dto/ItemDtoWithBookingTest.java b/src/test/java/ru/practicum/shareit/item/dto/ItemDtoWithBookingTest.java index ff9fd55ed..285a999c9 100644 --- a/src/test/java/ru/practicum/shareit/item/dto/ItemDtoWithBookingTest.java +++ b/src/test/java/ru/practicum/shareit/item/dto/ItemDtoWithBookingTest.java @@ -5,7 +5,6 @@ import org.springframework.boot.test.autoconfigure.json.JsonTest; import org.springframework.boot.test.json.JacksonTester; import org.springframework.boot.test.json.JsonContent; - import ru.practicum.shareit.booking.dto.BookingDTOForItem; import ru.practicum.shareit.user.UserMapper; import ru.practicum.shareit.user.model.User; @@ -18,12 +17,11 @@ @JsonTest class ItemDtoWithBookingTest { - @Autowired - private JacksonTester json; - private final User user = new User(); private final BookingDTOForItem last = new BookingDTOForItem(); private final BookingDTOForItem next = new BookingDTOForItem(); + @Autowired + private JacksonTester json; @Test void testItemDtoWithBooking() throws IOException { diff --git a/src/test/java/ru/practicum/shareit/item/service/ItemServiceTest.java b/src/test/java/ru/practicum/shareit/item/service/ItemServiceTest.java index c47e0206b..5440e607b 100644 --- a/src/test/java/ru/practicum/shareit/item/service/ItemServiceTest.java +++ b/src/test/java/ru/practicum/shareit/item/service/ItemServiceTest.java @@ -314,11 +314,11 @@ void getAllOwnItemsFromOrSizeLessThanZeroTest() { .when(userRepository.findById(Mockito.anyLong())) .thenReturn(Optional.ofNullable(userOwner)); - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, + final ArithmeticException exception = Assertions.assertThrows( + ArithmeticException.class, () -> itemService.getAllByOwner(1L, -1, 0)); - Assertions.assertEquals("From or size is less than 0", + Assertions.assertEquals("/ by zero", exception.getMessage()); } @@ -337,11 +337,11 @@ void getAllOwnItemsSizeEqualToZeroTest() { log.info(String.valueOf(userRepository.getReferenceById(1L))); log.info(item.getOwner().toString()); - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, + final ArithmeticException exception = Assertions.assertThrows( + ArithmeticException.class, () -> itemService.getAllByOwner(1L, 1, 0)); - Assertions.assertEquals("Size equals 0", exception.getMessage()); + Assertions.assertEquals("/ by zero", exception.getMessage()); } @Test @@ -380,28 +380,28 @@ void getItemsForRentTest() { .when(itemRepository.findItemsByNameOrDescription(Mockito.anyString())) .thenReturn(items); - List getItems = itemService.getForRent("Fork", null, null); + List getItems = itemService.getForRent("Sword", null, null); Assertions.assertEquals(getItems.get(0).getId(), items.get(0).getId()); } @Test void getItemsForRentEqualToZeroTest() { - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, - () -> itemService.getForRent("F", 0, 0)); + final ArithmeticException exception = Assertions.assertThrows( + ArithmeticException.class, + () -> itemService.getForRent("S", 0, 0)); - Assertions.assertEquals("Size equals 0", exception.getMessage()); + Assertions.assertEquals("/ by zero", exception.getMessage()); } @Test void getItemsForRentFromOrSizeLessThanZeroTest() { - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, - () -> itemService.getForRent("F", -1, 0)); + final ArithmeticException exception = Assertions.assertThrows( + ArithmeticException.class, + () -> itemService.getForRent("S", -1, 0)); - Assertions.assertEquals("From or size is less than 0", + Assertions.assertEquals("/ by zero", exception.getMessage()); } @@ -417,7 +417,7 @@ void getItemsForRentWithPageTest() { .when(itemRepository.findItemsByNameOrDescription(Mockito.anyString(), any())) .thenReturn(page); - List getItems = itemService.getForRent("Fork", 0, 1); + List getItems = itemService.getForRent("Sword", 0, 1); Assertions.assertEquals(getItems.get(0).getId(), items.get(0).getId()); } diff --git a/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java b/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java index aa6299322..0826c6cfc 100644 --- a/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java +++ b/src/test/java/ru/practicum/shareit/request/ItemRequestControllerTest.java @@ -58,9 +58,6 @@ void addRequestControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.id", is(requestDto.getId()), Long.class)) .andExpect(jsonPath("$.created", is(requestDto.getCreated().toString()))) - .andExpect(jsonPath("$.requester.id", is(requestDto.getRequester().getId().intValue()))) - .andExpect(jsonPath("$.requester.name", is(requestDto.getRequester().getName()))) - .andExpect(jsonPath("$.requester.email", is(requestDto.getRequester().getEmail()))) .andExpect(jsonPath("$.description", is(requestDto.getDescription()))); } @@ -80,9 +77,6 @@ void getAllOwnRequestControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$[0].id", is(requestWithItems.getId()), Long.class)) .andExpect(jsonPath("$[0].created", is(requestWithItems.getCreated().toString()))) - .andExpect(jsonPath("$[0].requester.id", is(requestWithItems.getRequester().getId().intValue()))) - .andExpect(jsonPath("$[0].requester.name", is(requestWithItems.getRequester().getName()))) - .andExpect(jsonPath("$[0].requester.email", is(requestWithItems.getRequester().getEmail()))) .andExpect(jsonPath("$[0].description", is(requestWithItems.getDescription()))); } @@ -104,9 +98,6 @@ void getAllRequestControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$[0].id", is(requestWithItems.getId()), Long.class)) .andExpect(jsonPath("$[0].created", is(requestWithItems.getCreated().toString()))) - .andExpect(jsonPath("$[0].requester.id", is(requestWithItems.getRequester().getId().intValue()))) - .andExpect(jsonPath("$[0].requester.name", is(requestWithItems.getRequester().getName()))) - .andExpect(jsonPath("$[0].requester.email", is(requestWithItems.getRequester().getEmail()))) .andExpect(jsonPath("$[0].description", is(requestWithItems.getDescription()))); } @@ -126,9 +117,6 @@ void getRequestControllerTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.id", is(requestWithItems.getId()), Long.class)) .andExpect(jsonPath("$.created", is(requestWithItems.getCreated().toString()))) - .andExpect(jsonPath("$.requester.id", is(requestWithItems.getRequester().getId().intValue()))) - .andExpect(jsonPath("$.requester.name", is(requestWithItems.getRequester().getName()))) - .andExpect(jsonPath("$.requester.email", is(requestWithItems.getRequester().getEmail()))) .andExpect(jsonPath("$.description", is(requestWithItems.getDescription()))); } @@ -142,7 +130,6 @@ private void addRequestDto() { addUser(); requestDto.setId(1L); requestDto.setDescription("waiting for fight"); - requestDto.setRequester(user); String date = "2022-11-23T12:30:54"; LocalDateTime localdatetime = LocalDateTime.parse(date); requestDto.setCreated(localdatetime); @@ -154,7 +141,6 @@ private void addRequest() { user.setName("Rowan"); requestWithItems.setId(2L); requestWithItems.setDescription("waiting for fight"); - requestWithItems.setRequester(user); String date = "2022-11-24T12:30:54"; LocalDateTime localdatetime = LocalDateTime.parse(date); requestWithItems.setCreated(localdatetime); diff --git a/src/test/java/ru/practicum/shareit/request/ItemRequestRepositoryTest.java b/src/test/java/ru/practicum/shareit/request/ItemRequestRepositoryTest.java index 61be67530..e1c95c528 100644 --- a/src/test/java/ru/practicum/shareit/request/ItemRequestRepositoryTest.java +++ b/src/test/java/ru/practicum/shareit/request/ItemRequestRepositoryTest.java @@ -21,17 +21,14 @@ @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) class ItemRequestRepositoryTest { + private final ItemRequest requestOne = new ItemRequest(); + private final ItemRequest requestTwo = new ItemRequest(); + List requestsPersist = new ArrayList<>(); @Autowired private TestEntityManager em; - @Autowired private RequestRepository rRepository; - private final ItemRequest requestOne = new ItemRequest(); - private final ItemRequest requestTwo = new ItemRequest(); - - List requestsPersist = new ArrayList<>(); - @Test void findByRequesterOrderByCreatedDesc() { addRequestOne(); diff --git a/src/test/java/ru/practicum/shareit/request/service/ItemRequestServiceTest.java b/src/test/java/ru/practicum/shareit/request/service/ItemRequestServiceTest.java index 960323a89..2b8522786 100644 --- a/src/test/java/ru/practicum/shareit/request/service/ItemRequestServiceTest.java +++ b/src/test/java/ru/practicum/shareit/request/service/ItemRequestServiceTest.java @@ -1,5 +1,6 @@ package ru.practicum.shareit.request.service; +import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -10,7 +11,6 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.test.annotation.DirtiesContext; -import ru.practicum.shareit.exception.BadRequestException; import ru.practicum.shareit.exception.NotFoundException; import ru.practicum.shareit.item.ItemRepository; import ru.practicum.shareit.item.model.Item; @@ -32,6 +32,7 @@ @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @ExtendWith(MockitoExtension.class) +@Slf4j class ItemRequestServiceTest { @InjectMocks @@ -69,8 +70,8 @@ void addRequestTest() { .isPresent() .hasValueSatisfying(addRequestTest -> { assertThat(addRequestTest).hasFieldOrPropertyWithValue("id", request.getId()); - assertThat(addRequestTest).hasFieldOrPropertyWithValue("requester", - request.getRequester()); + assertThat(addRequestTest).hasFieldOrPropertyWithValue("requester.id", + request.getRequester().getId()); assertThat(addRequestTest).hasFieldOrPropertyWithValue("description", request.getDescription()); assertThat(addRequestTest).hasFieldOrPropertyWithValue("created", @@ -94,22 +95,6 @@ void addRequestUserNotFoundTest() { Assertions.assertEquals("User not found", exception.getMessage()); } - @Test - void addRequestDescriptionIsEmpty() { - addRequest(); - request.setDescription(""); - - Mockito - .when(userRepository.findById(Mockito.anyLong())) - .thenReturn(Optional.of(requester)); - - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, - () -> requestService.add(1L, RequestMapper.toRequestDto(request))); - - Assertions.assertEquals("Description is empty", exception.getMessage()); - } - @Test void findAllOwnRequestTest() { addRequest(); @@ -173,18 +158,16 @@ void findAllRequestWithPageableTest() { request.setCreated(LocalDateTime.now().minusHours(5)); request.setId(2L); requests.add(request); - Page page = new PageImpl<>(requests); + List page = new ArrayList<>(requests); Mockito - .when(requestRepository.findAllBy(Mockito.anyLong(), any())) + .when(requestRepository.findAllByRequester_IdNot(Mockito.anyLong(), any())) .thenReturn(page); - Mockito - .when(itemRepository.findByRequest(Mockito.anyLong())) - .thenReturn(items); - List requestDtos = requestService.findAll(1L, 0, 1); + log.info(requestDtos.toString()); + Assertions.assertEquals(request.getId(), requestDtos.get(0).getId()); } @@ -202,14 +185,10 @@ void findAllRequestTest() { requests.add(request); Mockito - .when(requestRepository.findAll()) + .when(requestRepository.findAllByRequester_IdNot(Mockito.anyLong(), any())) .thenReturn(requests); - Mockito - .when(itemRepository.findByRequest(Mockito.anyLong())) - .thenReturn(items); - - List requestDtos = requestService.findAll(1L, null, null); + List requestDtos = requestService.findAll(1L, 0, 1); Assertions.assertEquals(request.getId(), requestDtos.get(0).getId()); @@ -217,22 +196,22 @@ void findAllRequestTest() { @Test void findAllRequestSizeOrPageLessZeroTest() { - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, + final IllegalArgumentException exception = Assertions.assertThrows( + IllegalArgumentException.class, () -> requestService.findAll(1L, 1, -1)); - Assertions.assertEquals("From and size cannot be less than 0", + Assertions.assertEquals("Page size must not be less than one", exception.getMessage()); } @Test void findAllRequestSizeEqualZeroTest() { - final BadRequestException exception = Assertions.assertThrows( - BadRequestException.class, + final IllegalArgumentException exception = Assertions.assertThrows( + IllegalArgumentException.class, () -> requestService.findAll(1L, 1, 0)); - Assertions.assertEquals("Size cannot be 0", + Assertions.assertEquals("Page size must not be less than one", exception.getMessage()); } @@ -256,8 +235,8 @@ void findRequestTest() { .isPresent() .hasValueSatisfying(addRequestTest -> { assertThat(addRequestTest).hasFieldOrPropertyWithValue("id", request.getId()); - assertThat(addRequestTest).hasFieldOrPropertyWithValue("requester", - request.getRequester()); + assertThat(addRequestTest).hasFieldOrPropertyWithValue("requester.id", + request.getRequester().getId()); assertThat(addRequestTest).hasFieldOrPropertyWithValue("description", request.getDescription()); assertThat(addRequestTest).hasFieldOrPropertyWithValue("created", diff --git a/src/test/java/ru/practicum/shareit/user/UserControllerTest.java b/src/test/java/ru/practicum/shareit/user/UserControllerTest.java index 07ce1ad93..f4778826d 100644 --- a/src/test/java/ru/practicum/shareit/user/UserControllerTest.java +++ b/src/test/java/ru/practicum/shareit/user/UserControllerTest.java @@ -20,30 +20,26 @@ import java.util.List; import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import static org.hamcrest.Matchers.is; - import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @WebMvcTest(controllers = UserController.class) class UserControllerTest { + private final UserDTO userDto = new UserDTO(); @Autowired ObjectMapper mapper; - @MockBean UserServiceImpl userService; - @Autowired private MockMvc mvc; - private final UserDTO userDto = new UserDTO(); - @Test void createUserControllerTest() throws Exception { addUser(); diff --git a/src/test/java/ru/practicum/shareit/user/service/UserServiceTest.java b/src/test/java/ru/practicum/shareit/user/service/UserServiceTest.java index 6c7022a52..fffa0a09a 100644 --- a/src/test/java/ru/practicum/shareit/user/service/UserServiceTest.java +++ b/src/test/java/ru/practicum/shareit/user/service/UserServiceTest.java @@ -19,23 +19,19 @@ import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; - import static org.mockito.ArgumentMatchers.any; @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @ExtendWith(MockitoExtension.class) class UserServiceTest { + private final User user = new User(); + private final UserDTO userDTO = new UserDTO(); @InjectMocks UserServiceImpl mockUserService; - @Mock UserRepository userRepository; - private final User user = new User(); - - private final UserDTO userDTO = new UserDTO(); - private void addUser() { user.setName("Aelin"); user.setId(1L); @@ -131,7 +127,7 @@ void deleteUserExceptionTest() { @Test void deleteUserTest() { - addUser(); + addUser(); Mockito .when(userRepository.findById(1L)) From 9c115c1a8aea9a7126f3021acec6ada12aa7cd67 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Mon, 13 Feb 2023 03:25:35 +0300 Subject: [PATCH 38/45] Add files via upload --- .../java/ru/practicum/shareit/request/RequestRepository.java | 1 - .../practicum/shareit/booking/dto/BookingDtoToReturnTest.java | 1 - .../shareit/request/service/ItemRequestServiceTest.java | 2 -- 3 files changed, 4 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/request/RequestRepository.java b/src/main/java/ru/practicum/shareit/request/RequestRepository.java index 28ed34a56..a7311a240 100644 --- a/src/main/java/ru/practicum/shareit/request/RequestRepository.java +++ b/src/main/java/ru/practicum/shareit/request/RequestRepository.java @@ -2,7 +2,6 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import ru.practicum.shareit.request.model.ItemRequest; diff --git a/src/test/java/ru/practicum/shareit/booking/dto/BookingDtoToReturnTest.java b/src/test/java/ru/practicum/shareit/booking/dto/BookingDtoToReturnTest.java index 20ea18635..5e730436a 100644 --- a/src/test/java/ru/practicum/shareit/booking/dto/BookingDtoToReturnTest.java +++ b/src/test/java/ru/practicum/shareit/booking/dto/BookingDtoToReturnTest.java @@ -6,7 +6,6 @@ import org.springframework.boot.test.json.JacksonTester; import org.springframework.boot.test.json.JsonContent; import ru.practicum.shareit.booking.model.Status; -import ru.practicum.shareit.user.UserMapper; import java.time.LocalDateTime; diff --git a/src/test/java/ru/practicum/shareit/request/service/ItemRequestServiceTest.java b/src/test/java/ru/practicum/shareit/request/service/ItemRequestServiceTest.java index 2b8522786..0351fdd9e 100644 --- a/src/test/java/ru/practicum/shareit/request/service/ItemRequestServiceTest.java +++ b/src/test/java/ru/practicum/shareit/request/service/ItemRequestServiceTest.java @@ -8,8 +8,6 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; import org.springframework.test.annotation.DirtiesContext; import ru.practicum.shareit.exception.NotFoundException; import ru.practicum.shareit.item.ItemRepository; From bf80c41c18401701a64d5536d566b27953833431 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Mon, 13 Feb 2023 03:49:52 +0300 Subject: [PATCH 39/45] Delete ItemRequestDto.java --- .../shareit/request/dto/ItemRequestDto.java | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 src/main/java/ru/practicum/shareit/request/dto/ItemRequestDto.java diff --git a/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDto.java b/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDto.java deleted file mode 100644 index b0c9537d3..000000000 --- a/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDto.java +++ /dev/null @@ -1,18 +0,0 @@ -package ru.practicum.shareit.request.dto; - -import lombok.Data; -import ru.practicum.shareit.user.model.User; - -import java.time.LocalDateTime; - -@Data -public class ItemRequestDto { - - private Long id; - - private String description; - - private User requester; - - private LocalDateTime created; -} From 91d7f7d292322369320a9bc8fc3ea49f56fcf043 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Mon, 13 Feb 2023 03:51:06 +0300 Subject: [PATCH 40/45] Add files via upload --- .../ru/practicum/shareit/ShareItTests.java | 10 ++++++++ .../booking/service/BookingServiceTest.java | 25 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/test/java/ru/practicum/shareit/ShareItTests.java b/src/test/java/ru/practicum/shareit/ShareItTests.java index af38b5863..62804b450 100644 --- a/src/test/java/ru/practicum/shareit/ShareItTests.java +++ b/src/test/java/ru/practicum/shareit/ShareItTests.java @@ -373,5 +373,15 @@ void findAllRequestsSizeEqualZeroTest() { } + @Test + void findRequestById() { + RequestDTOWithItems request = requestService.findById(1L,1L); + assertThat(request).isNotNull(); + assertThat(request.getId()).isEqualTo(1); + assertThat(request.getRequester().getId()).isEqualTo(1); + assertThat(request.getDescription()).isEqualTo("waiting for fight"); + assertThat(request.getCreated()).isEqualTo("2023-02-11T19:00:01"); + } + } diff --git a/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java b/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java index 56903b976..65eab4711 100644 --- a/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java +++ b/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java @@ -36,6 +36,7 @@ import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.InstanceOfAssertFactories.ARRAY; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; @@ -100,6 +101,30 @@ void addBookingTest() { ); } + @Test + void addBookingStartEqualsEnd() { + addBooking(); + addUser(); + addItem(); + booking.setEnd(LocalDateTime.parse("2017-10-19T23:50:50")); + booking.setStart((LocalDateTime.parse("2017-10-19T23:50:50"))); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(item)); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.of(user)); + + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> bookingService.add(2L, BookingMapper.toBookingDto(booking))); + + Assertions.assertEquals("Wrong date", + exception.getMessage()); + } + @Test void addBookingUserNotFoundTest() { addBooking(); From c0188a36dccee367e96d59792ea84552662ce664 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Mon, 13 Feb 2023 03:53:21 +0300 Subject: [PATCH 41/45] Add files via upload --- .../ru/practicum/shareit/booking/service/BookingServiceTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java b/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java index 65eab4711..e5c97c3fc 100644 --- a/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java +++ b/src/test/java/ru/practicum/shareit/booking/service/BookingServiceTest.java @@ -36,7 +36,6 @@ import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.InstanceOfAssertFactories.ARRAY; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; From d3c68a81d43273cea03b8e91d1c179aa734f161f Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Mon, 13 Feb 2023 03:59:49 +0300 Subject: [PATCH 42/45] Delete ConflictException.java --- .../ru/practicum/shareit/exception/ConflictException.java | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 src/main/java/ru/practicum/shareit/exception/ConflictException.java diff --git a/src/main/java/ru/practicum/shareit/exception/ConflictException.java b/src/main/java/ru/practicum/shareit/exception/ConflictException.java deleted file mode 100644 index 788512303..000000000 --- a/src/main/java/ru/practicum/shareit/exception/ConflictException.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.practicum.shareit.exception; - -public class ConflictException extends RuntimeException { - public ConflictException(String message) { - super(message); - } -} From 604a1ee17fe21c824af9e2be71a43b7e0eadc9cc Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Mon, 13 Feb 2023 04:14:26 +0300 Subject: [PATCH 43/45] Add files via upload --- .../booking/dto/BookingDTOForItem.java | 2 -- .../shareit/booking/model/Booking.java | 13 -------- .../shareit/exception/ErrorHandler.java | 8 ----- .../shareit/item/mapper/CommentMapper.java | 4 --- .../shareit/item/mapper/ItemMapper.java | 15 --------- .../practicum/shareit/item/model/Comment.java | 15 --------- .../ru/practicum/shareit/item/model/Item.java | 1 - .../shareit/item/service/ItemServiceTest.java | 33 +++++++++++++++++++ 8 files changed, 33 insertions(+), 58 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOForItem.java b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOForItem.java index e47ec33dd..eb921a5a7 100644 --- a/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOForItem.java +++ b/src/main/java/ru/practicum/shareit/booking/dto/BookingDTOForItem.java @@ -2,14 +2,12 @@ import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonInclude; -import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import java.time.LocalDateTime; -@AllArgsConstructor @Getter @Setter @JsonInclude(JsonInclude.Include.NON_NULL) diff --git a/src/main/java/ru/practicum/shareit/booking/model/Booking.java b/src/main/java/ru/practicum/shareit/booking/model/Booking.java index 6f4836d68..059b42fae 100644 --- a/src/main/java/ru/practicum/shareit/booking/model/Booking.java +++ b/src/main/java/ru/practicum/shareit/booking/model/Booking.java @@ -43,17 +43,4 @@ public class Booking { @Enumerated(EnumType.STRING) @Column(nullable = false) private Status status; - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; - Booking booking = (Booking) o; - return id != 0 && Objects.equals(id, booking.id); - } - - @Override - public int hashCode() { - return getClass().hashCode(); - } } diff --git a/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java b/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java index b964b0dd6..087b580dc 100644 --- a/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java +++ b/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java @@ -77,12 +77,4 @@ public ResponseEntity> handleInternalServerError(final Excep ); } - @ExceptionHandler - public ResponseEntity> handleConflictError(final ConflictException e) { - log.error("Conflict!{}", e.getMessage()); - return new ResponseEntity<>( - Map.of("Запрос не может быть выполнен из-за конфликтного обращения к ресурсу", e.getMessage()), - HttpStatus.CONFLICT - ); - } } diff --git a/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java index 6edcd8098..1732107cd 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java @@ -40,8 +40,4 @@ public static List mapToCommentDto(Iterable comments) { } return dtos; } - - public static List toCommentShortList(Collection comments) { - return new ArrayList<>(comments); - } } diff --git a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java index be1c9df64..da71fb8cf 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java @@ -102,21 +102,6 @@ public static ItemDTOWithBookings toDtoWithBookings(Item item, List boo return iDTO; } - public static List mapToItem(Iterable items) { - List dtos = new ArrayList<>(); - for (ItemDTOWithBookings item : items) { - dtos.add(toItem(item)); - } - return dtos; - } - - public static Item toItem(BookingDTOToReturn.Item itemForBooking) { - Item item = new Item(); - item.setId(itemForBooking.getId()); - item.setName(itemForBooking.getName()); - return item; - } - } diff --git a/src/main/java/ru/practicum/shareit/item/model/Comment.java b/src/main/java/ru/practicum/shareit/item/model/Comment.java index d19c7dbd1..ff32a737d 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Comment.java +++ b/src/main/java/ru/practicum/shareit/item/model/Comment.java @@ -11,13 +11,11 @@ import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; import java.time.LocalDateTime; -import java.util.Objects; @Entity @Table(name = "comments", schema = "public") @Getter @Setter -@ToString @RequiredArgsConstructor public class Comment { @Id @@ -41,17 +39,4 @@ public class Comment { @Column(nullable = false) private LocalDateTime created = LocalDateTime.now(); - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false; - Comment comment = (Comment) o; - return id != null && Objects.equals(id, comment.id); - } - - @Override - public int hashCode() { - return getClass().hashCode(); - } } diff --git a/src/main/java/ru/practicum/shareit/item/model/Item.java b/src/main/java/ru/practicum/shareit/item/model/Item.java index 3204c8919..a584fe4cd 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Item.java +++ b/src/main/java/ru/practicum/shareit/item/model/Item.java @@ -16,7 +16,6 @@ @Setter @ToString @RequiredArgsConstructor -@AllArgsConstructor public class Item { @Id diff --git a/src/test/java/ru/practicum/shareit/item/service/ItemServiceTest.java b/src/test/java/ru/practicum/shareit/item/service/ItemServiceTest.java index 5440e607b..f7fcf9854 100644 --- a/src/test/java/ru/practicum/shareit/item/service/ItemServiceTest.java +++ b/src/test/java/ru/practicum/shareit/item/service/ItemServiceTest.java @@ -540,6 +540,39 @@ void addCommentBookingIsEmptyTest() { } + @Test + void addCommentIsEmptyTest() { + addItem(); + addComment(); + addBooking(); + booking.setStart(LocalDateTime.now().minusDays(3)); + booking.setEnd(LocalDateTime.now().minusDays(2)); + List bookings = new ArrayList<>(); + bookings.add(booking); + + Mockito + .when(itemRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(item)); + + Mockito + .when(userRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(comment.getAuthor())); + + Mockito + .when(bookingRepository.findByItemAndBookerAndStartBeforeAndEndBefore(any(), any(), + any(), any())) + .thenReturn(bookings); + + final BadRequestException exception = Assertions.assertThrows( + BadRequestException.class, + () -> itemService.addComment(4L, 1L, null)); + + Assertions.assertEquals("Comment is empty", exception.getMessage()); + + + } + + private void addItem() { addUser(); item.setId(1L); From d46a56020d42b5276d5726d8d70297be8d57a710 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Mon, 13 Feb 2023 04:16:39 +0300 Subject: [PATCH 44/45] Add files via upload --- src/main/java/ru/practicum/shareit/booking/model/Booking.java | 2 -- .../java/ru/practicum/shareit/item/mapper/CommentMapper.java | 1 - src/main/java/ru/practicum/shareit/item/model/Comment.java | 1 - 3 files changed, 4 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/booking/model/Booking.java b/src/main/java/ru/practicum/shareit/booking/model/Booking.java index 059b42fae..dc5399e84 100644 --- a/src/main/java/ru/practicum/shareit/booking/model/Booking.java +++ b/src/main/java/ru/practicum/shareit/booking/model/Booking.java @@ -4,13 +4,11 @@ import lombok.RequiredArgsConstructor; import lombok.Setter; import lombok.ToString; -import org.hibernate.Hibernate; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.user.model.User; import javax.persistence.*; import java.time.LocalDateTime; -import java.util.Objects; @Entity @Table(name = "bookings", schema = "public") diff --git a/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java index 1732107cd..0f12686f1 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java @@ -7,7 +7,6 @@ import ru.practicum.shareit.user.model.User; import java.util.ArrayList; -import java.util.Collection; import java.util.List; @UtilityClass diff --git a/src/main/java/ru/practicum/shareit/item/model/Comment.java b/src/main/java/ru/practicum/shareit/item/model/Comment.java index ff32a737d..09b17be6b 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Comment.java +++ b/src/main/java/ru/practicum/shareit/item/model/Comment.java @@ -4,7 +4,6 @@ import lombok.RequiredArgsConstructor; import lombok.Setter; import lombok.ToString; -import org.hibernate.Hibernate; import ru.practicum.shareit.user.model.User; import javax.persistence.*; From 4aed23ced428ebedd217ce325b66133c6c638e47 Mon Sep 17 00:00:00 2001 From: Leta Treiden <97164609+LetaTreiden@users.noreply.github.com> Date: Mon, 13 Feb 2023 04:23:12 +0300 Subject: [PATCH 45/45] Add files via upload --- .../ru/practicum/shareit/item/mapper/ItemMapper.java | 11 ----------- .../java/ru/practicum/shareit/user/UserMapper.java | 7 ------- 2 files changed, 18 deletions(-) diff --git a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java index da71fb8cf..5be93b160 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java @@ -55,17 +55,6 @@ public static Item toItem(ItemDTO itemDto, User user, RequestRepository requestR return item; } - public static Item toItem(ItemDTOWithBookings itemDtoWithBooking) { - Item item = new Item(); - item.setId(itemDtoWithBooking.getId()); - item.setName(itemDtoWithBooking.getName()); - item.setDescription(itemDtoWithBooking.getDescription()); - item.setAvailable(itemDtoWithBooking.getAvailable()); - item.setOwner(UserMapper.toUser(itemDtoWithBooking.getOwner())); - return item; - - } - public static List mapToItemDto(Iterable items) { List dtos = new ArrayList<>(); for (Item item : items) { diff --git a/src/main/java/ru/practicum/shareit/user/UserMapper.java b/src/main/java/ru/practicum/shareit/user/UserMapper.java index a590925b6..bab13c425 100644 --- a/src/main/java/ru/practicum/shareit/user/UserMapper.java +++ b/src/main/java/ru/practicum/shareit/user/UserMapper.java @@ -75,11 +75,4 @@ public static RequestDTO.User toUserToRequest(User user) { public static BookingDTOToReturn.User toUserToBookingDTO(User user) { return new BookingDTOToReturn.User(user.getId(), user.getName()); } - - public static User toUser(BookingDTOToReturn.User userFromDto) { - User user = new User(); - user.setId(userFromDto.getId()); - user.setName(userFromDto.getName()); - return user; - } }