From 59fbc2de2d6c92d06799bb34589c30a8f43a56ef Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Wed, 2 Jul 2025 15:15:26 +0400 Subject: [PATCH 01/11] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2015=D0=B3=D0=BE=20(=D0=B4=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=B0=D0=BD=D0=BE=20=D1=81=D0=BE=D0=B3=D0=BB=D0=B0=D1=81=D0=BD?= =?UTF-8?q?=D0=BE=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=87=D0=B0=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=D0=BC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shareit/request/dto/ItemRequestDto.java | 7 ------- .../request/dto/ItemRequestInputDto.java | 17 +++++++++++++++++ .../request/dto/ItemRequestOutputDto.java | 17 +++++++++++++++++ 3 files changed, 34 insertions(+), 7 deletions(-) delete mode 100644 src/main/java/ru/practicum/shareit/request/dto/ItemRequestDto.java create mode 100644 src/main/java/ru/practicum/shareit/request/dto/ItemRequestInputDto.java create mode 100644 src/main/java/ru/practicum/shareit/request/dto/ItemRequestOutputDto.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 7b3ed54..0000000 --- a/src/main/java/ru/practicum/shareit/request/dto/ItemRequestDto.java +++ /dev/null @@ -1,7 +0,0 @@ -package ru.practicum.shareit.request.dto; - -/** - * TODO Sprint add-item-requests. - */ -public class ItemRequestDto { -} diff --git a/src/main/java/ru/practicum/shareit/request/dto/ItemRequestInputDto.java b/src/main/java/ru/practicum/shareit/request/dto/ItemRequestInputDto.java new file mode 100644 index 0000000..3599502 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/dto/ItemRequestInputDto.java @@ -0,0 +1,17 @@ +package ru.practicum.shareit.request.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ItemRequestInputDto { + private Long itemRequestId; + private String requestDescription; + private Long requesterId; + private LocalDate requestDate; +} diff --git a/src/main/java/ru/practicum/shareit/request/dto/ItemRequestOutputDto.java b/src/main/java/ru/practicum/shareit/request/dto/ItemRequestOutputDto.java new file mode 100644 index 0000000..39b1d20 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/dto/ItemRequestOutputDto.java @@ -0,0 +1,17 @@ +package ru.practicum.shareit.request.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ItemRequestOutputDto { + private Long itemRequestId; + private String requestDescription; + private Long requesterId; + private LocalDate requestDate; +} From 87593ca7c600f8d5661ad02e7e156a71378930a4 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Wed, 2 Jul 2025 15:27:03 +0400 Subject: [PATCH 02/11] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2015=D0=B3=D0=BE=20(=D0=B4=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=B0=D0=BD=D0=BE=20=D1=81=D0=BE=D0=B3=D0=BB=D0=B0=D1=81=D0=BD?= =?UTF-8?q?=D0=BE=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=87=D0=B0=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=D0=BC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ru/practicum/shareit/item/model/Item.java | 1 - 1 file changed, 1 deletion(-) 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 c1d6d11..8bec23e 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Item.java +++ b/src/main/java/ru/practicum/shareit/item/model/Item.java @@ -15,7 +15,6 @@ @ToString @Table(name = "items") public class Item { - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "item_id") From 0fbe38187f5b3b05140d71bcf1c40189e062cb74 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Sun, 6 Jul 2025 13:16:19 +0400 Subject: [PATCH 03/11] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2016=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20(=D1=8D=D1=82=D0=B0=D0=BF=201)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 4 + .../shareit/booking/BookingController.java | 5 +- .../shareit/item/ItemServiceImpl.java | 6 ++ .../item/interfaces/ItemRepository.java | 2 + .../shareit/item/mapper/ItemMapper.java | 2 +- .../ru/practicum/shareit/item/model/Item.java | 2 +- .../request/ItemRequestController.java | 12 --- .../shareit/request/RequestController.java | 41 ++++++++++ .../shareit/request/RequestServiceImpl.java | 79 +++++++++++++++++++ .../request/dto/ItemRequestInputDto.java | 17 ---- .../request/dto/ItemRequestOutputDto.java | 17 ---- .../shareit/request/dto/RequestInputDto.java | 23 ++++++ .../shareit/request/dto/RequestOutputDto.java | 25 ++++++ .../dto/RequestOutputWithItemsDto.java | 30 +++++++ .../request/interfaces/RequestRepository.java | 11 ++- .../interfaces/RequestServiceInterface.java | 17 ++++ .../shareit/request/mapper/RequestMapper.java | 17 ++++ .../request/{ => model}/ItemRequest.java | 17 ++-- src/main/resources/schema.sql | 7 +- .../shareit/mapperTest/ItemMapperTest.java | 5 +- 20 files changed, 274 insertions(+), 65 deletions(-) delete mode 100644 src/main/java/ru/practicum/shareit/request/ItemRequestController.java create mode 100644 src/main/java/ru/practicum/shareit/request/RequestController.java create mode 100644 src/main/java/ru/practicum/shareit/request/RequestServiceImpl.java delete mode 100644 src/main/java/ru/practicum/shareit/request/dto/ItemRequestInputDto.java delete mode 100644 src/main/java/ru/practicum/shareit/request/dto/ItemRequestOutputDto.java create mode 100644 src/main/java/ru/practicum/shareit/request/dto/RequestInputDto.java create mode 100644 src/main/java/ru/practicum/shareit/request/dto/RequestOutputDto.java create mode 100644 src/main/java/ru/practicum/shareit/request/dto/RequestOutputWithItemsDto.java create mode 100644 src/main/java/ru/practicum/shareit/request/interfaces/RequestServiceInterface.java create mode 100644 src/main/java/ru/practicum/shareit/request/mapper/RequestMapper.java rename src/main/java/ru/practicum/shareit/request/{ => model}/ItemRequest.java (62%) diff --git a/pom.xml b/pom.xml index 091dc51..c3f31c2 100644 --- a/pom.xml +++ b/pom.xml @@ -78,6 +78,10 @@ lombok-mapstruct-binding ${lombok-mapstruct-binding.version} + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + diff --git a/src/main/java/ru/practicum/shareit/booking/BookingController.java b/src/main/java/ru/practicum/shareit/booking/BookingController.java index 5d1a56c..80c11aa 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingController.java +++ b/src/main/java/ru/practicum/shareit/booking/BookingController.java @@ -5,7 +5,7 @@ import org.springframework.web.bind.annotation.*; import ru.practicum.shareit.booking.dto.BookingRequestDto; import ru.practicum.shareit.booking.dto.BookingResponseDto; -import ru.practicum.shareit.booking.intrfaces.BookingServiceInterface; + import java.util.Collection; @@ -13,7 +13,8 @@ @RequestMapping(path = "/bookings") @RequiredArgsConstructor public class BookingController { - private final BookingServiceInterface bookingService; + + private final BookingServiceImpl bookingService; public static final String USER_ID = "X-Sharer-User-Id"; @PostMapping diff --git a/src/main/java/ru/practicum/shareit/item/ItemServiceImpl.java b/src/main/java/ru/practicum/shareit/item/ItemServiceImpl.java index 3b77efe..feae224 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemServiceImpl.java +++ b/src/main/java/ru/practicum/shareit/item/ItemServiceImpl.java @@ -18,6 +18,7 @@ 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.interfaces.RequestRepository; import ru.practicum.shareit.user.interfaces.UserRepository; import ru.practicum.shareit.user.mapper.UserMapper; import ru.practicum.shareit.user.model.User; @@ -38,6 +39,7 @@ public class ItemServiceImpl implements ItemServiceInterface { private final UserRepository userRepository; private final CommentRepository commentRepository; private final BookingRepository bookingRepository; + private final RequestRepository requestRepository; private final ItemMapper itemMapper; private final UserMapper userMapper; private final CommentMapper commentMapper; @@ -53,6 +55,10 @@ public ItemResponseDto createItem(ItemRequestDto item, Long ownerId) { Item itemSaved = itemMapper.toItem(item); itemSaved.setOwner(owner); + if (item.getRequestId() != null) { + itemSaved.setItemRequest(requestRepository.getRequestByItemRequestId(item.getRequestId()) + .orElseThrow(() -> new NotFoundException("Request with id " + item.getRequestId() + " not found"))); + } itemRepository.save(itemSaved); diff --git a/src/main/java/ru/practicum/shareit/item/interfaces/ItemRepository.java b/src/main/java/ru/practicum/shareit/item/interfaces/ItemRepository.java index d27984b..2942a2e 100644 --- a/src/main/java/ru/practicum/shareit/item/interfaces/ItemRepository.java +++ b/src/main/java/ru/practicum/shareit/item/interfaces/ItemRepository.java @@ -17,4 +17,6 @@ public interface ItemRepository extends JpaRepository { @Query(value = "SELECT i FROM Item i WHERE upper(i.itemName) like upper(concat('%', ?1, '%')) " + " OR upper(i.itemDescription) LIKE upper(concat('%', ?1, '%'))") Collection searchByTextContainingIgnoreCase(String text); + + Collection getItemsByItemRequest_ItemRequestId(Long itemRequestId); } 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 38eb932..910271f 100644 --- a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java +++ b/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java @@ -29,7 +29,7 @@ default ItemResponseDto toItemResponseDto(Item item) { itemResponseDto.setOwnerId(item.getOwner().getUserId()); if (item.getItemRequest() != null) { - itemResponseDto.setRequestId(item.getItemRequest().getRequesterId()); + itemResponseDto.setRequestId(item.getItemRequest().getItemRequestId()); } return itemResponseDto; 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 8bec23e..31726c1 100644 --- a/src/main/java/ru/practicum/shareit/item/model/Item.java +++ b/src/main/java/ru/practicum/shareit/item/model/Item.java @@ -5,7 +5,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; -import ru.practicum.shareit.request.ItemRequest; +import ru.practicum.shareit.request.model.ItemRequest; import ru.practicum.shareit.user.model.User; @Data diff --git a/src/main/java/ru/practicum/shareit/request/ItemRequestController.java b/src/main/java/ru/practicum/shareit/request/ItemRequestController.java deleted file mode 100644 index 064e2e9..0000000 --- a/src/main/java/ru/practicum/shareit/request/ItemRequestController.java +++ /dev/null @@ -1,12 +0,0 @@ -package ru.practicum.shareit.request; - -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/RequestController.java b/src/main/java/ru/practicum/shareit/request/RequestController.java new file mode 100644 index 0000000..817b803 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/RequestController.java @@ -0,0 +1,41 @@ +package ru.practicum.shareit.request; + +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; +import ru.practicum.shareit.request.dto.RequestInputDto; +import ru.practicum.shareit.request.dto.RequestOutputDto; +import ru.practicum.shareit.request.dto.RequestOutputWithItemsDto; +import ru.practicum.shareit.request.interfaces.RequestServiceInterface; + +import java.util.List; + + +@RestController +@RequestMapping(path = "/requests") +@RequiredArgsConstructor +public class RequestController { + private final RequestServiceInterface requestService; + public static final String USER_ID = "X-Sharer-User-Id"; + + @PostMapping + public RequestOutputDto addRequest(@RequestBody RequestInputDto requestInputDto, + @RequestHeader(USER_ID) Long userId) { + return requestService.addItemRequest(requestInputDto, userId); + } + + @GetMapping + public List getRequestByUser(@RequestHeader(USER_ID) Long userId) { + return requestService.getRequestByUser(userId); + } + + @GetMapping("/all") + public List getAllRequests() { + return requestService.getAllRequests(); + } + + @GetMapping("/{requestId}") + public RequestOutputWithItemsDto getRequestById(@PathVariable Long requestId) { + return requestService.getRequestById(requestId); + } +} + diff --git a/src/main/java/ru/practicum/shareit/request/RequestServiceImpl.java b/src/main/java/ru/practicum/shareit/request/RequestServiceImpl.java new file mode 100644 index 0000000..8dc8c0e --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/RequestServiceImpl.java @@ -0,0 +1,79 @@ +package ru.practicum.shareit.request; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import ru.practicum.shareit.item.dto.ItemResponseDto; +import ru.practicum.shareit.item.interfaces.ItemRepository; +import ru.practicum.shareit.item.mapper.ItemMapper; +import ru.practicum.shareit.request.dto.RequestInputDto; +import ru.practicum.shareit.request.dto.RequestOutputDto; +import ru.practicum.shareit.request.dto.RequestOutputWithItemsDto; +import ru.practicum.shareit.request.interfaces.RequestServiceInterface; +import ru.practicum.shareit.request.interfaces.RequestRepository; +import ru.practicum.shareit.request.mapper.RequestMapper; +import ru.practicum.shareit.request.model.ItemRequest; +import ru.practicum.shareit.user.interfaces.UserRepository; +import ru.practicum.shareit.user.model.User; + +import java.util.Collection; +import java.util.Comparator; +import java.util.List; + +@Service +@RequiredArgsConstructor +public class RequestServiceImpl implements RequestServiceInterface { + private final UserRepository userRepository; + private final RequestRepository requestRepository; + private final ItemRepository itemRepository; + private final RequestMapper requestMapper; + private final ItemMapper itemMapper; + + @Override + public RequestOutputDto addItemRequest(RequestInputDto requestDto, Long userId) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new RuntimeException("User not found")); + + ItemRequest itemRequest = requestMapper.toRequest(requestDto); + itemRequest.setRequester(user); + return requestMapper.toRequestOutputDto(requestRepository.save(itemRequest)); + } + + @Override + public List getRequestByUser(Long userId) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new RuntimeException("User not found")); + List requests = requestRepository.getRequestByRequester_UserId(userId); + + return requestRepository.getRequestByRequester_UserId(userId).stream() + .map(requestMapper::toRequestOutputDto) + .sorted(Comparator.comparing(RequestOutputDto::getRequestDate)) + .toList() + .reversed(); + } + + @Override + public List getAllRequests() { + return requestRepository.findAll().stream() + .map(requestMapper::toRequestOutputDto) + .sorted(Comparator.comparing(RequestOutputDto::getRequestDate)) + .toList() + .reversed(); + } + + @Override + public RequestOutputWithItemsDto getRequestById(Long requestId) { + ItemRequest itemRequest = requestRepository.getRequestByItemRequestId(requestId) + .orElseThrow(() -> new RuntimeException("Request not found")); + + Collection items = itemRepository.getItemsByItemRequest_ItemRequestId(requestId).stream() + .map(itemMapper::toItemResponseDto) + .toList(); + + RequestOutputWithItemsDto responseDto = requestMapper.toRequestOutputWithItemsDto(itemRequest); + responseDto.setItems(items); + + return responseDto; + } + + +} diff --git a/src/main/java/ru/practicum/shareit/request/dto/ItemRequestInputDto.java b/src/main/java/ru/practicum/shareit/request/dto/ItemRequestInputDto.java deleted file mode 100644 index 3599502..0000000 --- a/src/main/java/ru/practicum/shareit/request/dto/ItemRequestInputDto.java +++ /dev/null @@ -1,17 +0,0 @@ -package ru.practicum.shareit.request.dto; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.time.LocalDate; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class ItemRequestInputDto { - private Long itemRequestId; - private String requestDescription; - private Long requesterId; - private LocalDate requestDate; -} diff --git a/src/main/java/ru/practicum/shareit/request/dto/ItemRequestOutputDto.java b/src/main/java/ru/practicum/shareit/request/dto/ItemRequestOutputDto.java deleted file mode 100644 index 39b1d20..0000000 --- a/src/main/java/ru/practicum/shareit/request/dto/ItemRequestOutputDto.java +++ /dev/null @@ -1,17 +0,0 @@ -package ru.practicum.shareit.request.dto; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.time.LocalDate; - -@Data -@NoArgsConstructor -@AllArgsConstructor -public class ItemRequestOutputDto { - private Long itemRequestId; - private String requestDescription; - private Long requesterId; - private LocalDate requestDate; -} diff --git a/src/main/java/ru/practicum/shareit/request/dto/RequestInputDto.java b/src/main/java/ru/practicum/shareit/request/dto/RequestInputDto.java new file mode 100644 index 0000000..c88b416 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/dto/RequestInputDto.java @@ -0,0 +1,23 @@ +package ru.practicum.shareit.request.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class RequestInputDto { + @JsonProperty("id") + private Long itemRequestId; + + @NotNull + @JsonProperty("description") + private String requestDescription; + + private LocalDateTime requestDate = LocalDateTime.now(); +} diff --git a/src/main/java/ru/practicum/shareit/request/dto/RequestOutputDto.java b/src/main/java/ru/practicum/shareit/request/dto/RequestOutputDto.java new file mode 100644 index 0000000..711abeb --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/dto/RequestOutputDto.java @@ -0,0 +1,25 @@ +package ru.practicum.shareit.request.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import ru.practicum.shareit.user.dto.UserBookingDto; + +import java.time.LocalDateTime; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class RequestOutputDto { + @JsonProperty("id") + private Long itemRequestId; + + @JsonProperty("description") + private String requestDescription; + + private UserBookingDto requester; + + @JsonProperty("created") + private LocalDateTime requestDate; +} diff --git a/src/main/java/ru/practicum/shareit/request/dto/RequestOutputWithItemsDto.java b/src/main/java/ru/practicum/shareit/request/dto/RequestOutputWithItemsDto.java new file mode 100644 index 0000000..98d8d0b --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/dto/RequestOutputWithItemsDto.java @@ -0,0 +1,30 @@ +package ru.practicum.shareit.request.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import ru.practicum.shareit.item.dto.ItemResponseDto; +import ru.practicum.shareit.user.dto.UserBookingDto; + +import java.time.LocalDateTime; +import java.util.Collection; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class RequestOutputWithItemsDto { + @JsonProperty("id") + private Long itemRequestId; + + @JsonProperty("description") + private String requestDescription; + + private UserBookingDto requester; + + @JsonProperty("created") + private LocalDateTime requestDate; + + @JsonProperty("items") + Collection items; +} diff --git a/src/main/java/ru/practicum/shareit/request/interfaces/RequestRepository.java b/src/main/java/ru/practicum/shareit/request/interfaces/RequestRepository.java index cea05b1..d6d8803 100644 --- a/src/main/java/ru/practicum/shareit/request/interfaces/RequestRepository.java +++ b/src/main/java/ru/practicum/shareit/request/interfaces/RequestRepository.java @@ -1,8 +1,17 @@ package ru.practicum.shareit.request.interfaces; import org.springframework.data.jpa.repository.JpaRepository; -import ru.practicum.shareit.request.ItemRequest; +import ru.practicum.shareit.request.model.ItemRequest; + +import java.util.List; +import java.util.Optional; public interface RequestRepository extends JpaRepository { ItemRequest save(ItemRequest item); + + List getRequestByRequester_UserId(Long userId); + + List findAll(); + + Optional getRequestByItemRequestId(Long requestId); } diff --git a/src/main/java/ru/practicum/shareit/request/interfaces/RequestServiceInterface.java b/src/main/java/ru/practicum/shareit/request/interfaces/RequestServiceInterface.java new file mode 100644 index 0000000..2238138 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/interfaces/RequestServiceInterface.java @@ -0,0 +1,17 @@ +package ru.practicum.shareit.request.interfaces; + +import ru.practicum.shareit.request.dto.RequestInputDto; +import ru.practicum.shareit.request.dto.RequestOutputDto; +import ru.practicum.shareit.request.dto.RequestOutputWithItemsDto; + +import java.util.List; + +public interface RequestServiceInterface { + RequestOutputDto addItemRequest(RequestInputDto requestDto, Long userId); + + List getRequestByUser(Long userId); + + List getAllRequests(); + + RequestOutputWithItemsDto getRequestById(Long requestId); +} diff --git a/src/main/java/ru/practicum/shareit/request/mapper/RequestMapper.java b/src/main/java/ru/practicum/shareit/request/mapper/RequestMapper.java new file mode 100644 index 0000000..d623e12 --- /dev/null +++ b/src/main/java/ru/practicum/shareit/request/mapper/RequestMapper.java @@ -0,0 +1,17 @@ +package ru.practicum.shareit.request.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import ru.practicum.shareit.request.dto.RequestInputDto; +import ru.practicum.shareit.request.dto.RequestOutputDto; +import ru.practicum.shareit.request.dto.RequestOutputWithItemsDto; +import ru.practicum.shareit.request.model.ItemRequest; + +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING) +public interface RequestMapper { + ItemRequest toRequest(RequestInputDto itemRequestInputDto); + + RequestOutputDto toRequestOutputDto(ItemRequest itemRequest); + + RequestOutputWithItemsDto toRequestOutputWithItemsDto(ItemRequest itemRequest); +} diff --git a/src/main/java/ru/practicum/shareit/request/ItemRequest.java b/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java similarity index 62% rename from src/main/java/ru/practicum/shareit/request/ItemRequest.java rename to src/main/java/ru/practicum/shareit/request/model/ItemRequest.java index 0da7fda..ee3033a 100644 --- a/src/main/java/ru/practicum/shareit/request/ItemRequest.java +++ b/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java @@ -1,16 +1,14 @@ -package ru.practicum.shareit.request; +package ru.practicum.shareit.request.model; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; +import ru.practicum.shareit.user.model.User; -import java.time.LocalDate; +import java.time.LocalDateTime; -/** - * TODO Sprint add-item-requests. - */ @Data @Entity @Table(name = "requests") @@ -27,9 +25,10 @@ public class ItemRequest { @Column(name = "description") private String requestDescription; - @Column(name = "requestor_id") - private Long requesterId; + @ManyToOne + @JoinColumn(name = "requester_id") + private User requester; - @Transient - private LocalDate requestDate; + @Column(name = "request_date") + private LocalDateTime requestDate; } diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index c07802f..6ce8657 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -36,7 +36,8 @@ CREATE TABLE IF NOT EXISTS bookings ( CREATE TABLE IF NOT EXISTS requests ( request_id BIGSERIAL PRIMARY KEY, - requestor_id BIGINT NOT NULL, - description CHARACTER VARYING (200), - FOREIGN KEY (requestor_id) REFERENCES users (user_id) ON DELETE CASCADE + requester_id BIGINT NOT NULL, + description CHARACTER VARYING (200) NOT NULL, + request_date TIMESTAMP WITHOUT TIME ZONE, + FOREIGN KEY (requester_id) REFERENCES users (user_id) ON DELETE CASCADE ); \ No newline at end of file diff --git a/src/test/java/ru/practicum/shareit/mapperTest/ItemMapperTest.java b/src/test/java/ru/practicum/shareit/mapperTest/ItemMapperTest.java index 5143e32..9468769 100644 --- a/src/test/java/ru/practicum/shareit/mapperTest/ItemMapperTest.java +++ b/src/test/java/ru/practicum/shareit/mapperTest/ItemMapperTest.java @@ -6,10 +6,11 @@ import ru.practicum.shareit.item.dto.*; import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Item; -import ru.practicum.shareit.request.ItemRequest; +import ru.practicum.shareit.request.model.ItemRequest; import ru.practicum.shareit.user.model.User; import java.time.LocalDate; +import java.time.LocalDateTime; import static org.junit.jupiter.api.Assertions.*; @@ -22,7 +23,7 @@ public class ItemMapperTest { User user = new User(1L, "testName1", "test1@test.com"); ItemRequest itemRequest = new ItemRequest(1L, "testDescription1", - 1L, LocalDate.of(2025, 6, 25)); + user, LocalDateTime.of(2025, 6, 25, 15, 25)); @Test public void itemRequestDtoToItemTest() { From 6125b6b1ab2ee2ac8e37e780a3c40ba4e2e37d5b Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Sun, 6 Jul 2025 13:21:39 +0400 Subject: [PATCH 04/11] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2016=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20(=D1=8D=D1=82=D0=B0=D0=BF=201)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ru/practicum/shareit/mapperTest/BookingMapperTest.java | 4 ++-- .../ru/practicum/shareit/mapperTest/CommentMapperTest.java | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/test/java/ru/practicum/shareit/mapperTest/BookingMapperTest.java b/src/test/java/ru/practicum/shareit/mapperTest/BookingMapperTest.java index 5744f96..db894a2 100644 --- a/src/test/java/ru/practicum/shareit/mapperTest/BookingMapperTest.java +++ b/src/test/java/ru/practicum/shareit/mapperTest/BookingMapperTest.java @@ -11,7 +11,7 @@ import ru.practicum.shareit.item.dto.ItemBookerDto; import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Item; -import ru.practicum.shareit.request.ItemRequest; +import ru.practicum.shareit.request.model.ItemRequest; import ru.practicum.shareit.user.dto.UserBookingDto; import ru.practicum.shareit.user.mapper.UserMapper; import ru.practicum.shareit.user.model.User; @@ -36,7 +36,7 @@ public class BookingMapperTest { User user = new User(1L, "testName1", "test1@test.com"); ItemRequest itemRequest = new ItemRequest(1L, "testDescription1", - 1L, LocalDate.of(2025, 6, 25)); + user, LocalDateTime.of(2025, 6, 25, 15, 25)); Item item = new Item(1L, "TestName1", "Test description1", true, user, itemRequest); LocalDateTime startTime = LocalDateTime.of(2025, 6, 25, 12, 30); diff --git a/src/test/java/ru/practicum/shareit/mapperTest/CommentMapperTest.java b/src/test/java/ru/practicum/shareit/mapperTest/CommentMapperTest.java index 6b7179f..89c8199 100644 --- a/src/test/java/ru/practicum/shareit/mapperTest/CommentMapperTest.java +++ b/src/test/java/ru/practicum/shareit/mapperTest/CommentMapperTest.java @@ -9,12 +9,13 @@ import ru.practicum.shareit.item.mapper.CommentMapper; import ru.practicum.shareit.item.model.Comment; import ru.practicum.shareit.item.model.Item; -import ru.practicum.shareit.request.ItemRequest; +import ru.practicum.shareit.request.model.ItemRequest; import ru.practicum.shareit.user.dto.UserAuthorDto; import ru.practicum.shareit.user.mapper.UserMapper; import ru.practicum.shareit.user.model.User; import java.time.LocalDate; +import java.time.LocalDateTime; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -30,7 +31,7 @@ public class CommentMapperTest { User user = new User(1L, "testName1", "test1@test.com"); ItemRequest itemRequest = new ItemRequest(1L, "testDescription1", - 1L, LocalDate.of(2025, 6, 25)); + user, LocalDateTime.of(2025, 6, 25, 15, 25)); Item item = new Item(1L, "TestName1", "Test description1", true, user, itemRequest); From 38699336c4cf6ccc2f1558a4f7a5bcfa5cd72bb6 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Sun, 6 Jul 2025 13:21:39 +0400 Subject: [PATCH 05/11] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2016=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20(=D1=81=20=D1=82=D0=B5=D1=81=D1=82=D0=B0=D0=BC=D0=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .run/ShareitGateway.run.xml | 15 + .run/ShareitServer.run.xml | 15 + docker-compose.yml | 39 +++ gateway/Dockerfile | 5 + gateway/pom.xml | 103 +++++++ .../ru/practicum/shareit/ShareItGateway.java | 12 + .../shareit/booking/BookingClient.java | 57 ++++ .../shareit/booking/BookingController.java | 47 +++ .../booking/dto/BookingRequestDto.java | 4 +- .../booking/dto/BookingResponseDto.java | 30 ++ .../shareit/booking/dto/BookingState.java | 36 +++ .../practicum/shareit/client/BaseClient.java | 125 ++++++++ .../exception/AnotherUserException.java | 0 .../exception/DuplicatedDataException.java | 0 .../shareit/exception/ErrorHandler.java | 14 + .../shareit/exception/ErrorResponse.java | 0 .../shareit/exception/NotFoundException.java | 0 .../exception/ValidationException.java | 0 .../ru/practicum/shareit/item/ItemClient.java | 56 ++++ .../shareit/item/ItemController.java | 60 ++++ .../shareit/item/dto/CommentRequestDto.java | 0 .../item/dto/CommentResponseCreatedDto.java | 0 .../shareit/item/dto/CommentResponseDto.java | 0 .../shareit/item/dto/ItemBookerDto.java | 0 .../shareit/item/dto/ItemRequestDto.java | 0 .../shareit/item/dto/ItemResponseDto.java | 0 .../item/dto/ItemResponseDtoWithComments.java | 2 - .../shareit/request/RequestClient.java | 43 +++ .../shareit/request/RequestController.java | 37 +++ .../shareit/request/dto/RequestInputDto.java | 0 .../shareit/request/dto/RequestOutputDto.java | 0 .../dto/RequestOutputWithItemsDto.java | 0 .../ru/practicum/shareit/user/UserClient.java | 46 +++ .../shareit/user/UserController.java | 42 +++ .../shareit/user/dto/UserAuthorDto.java | 0 .../shareit/user/dto/UserBookingDto.java | 4 + .../shareit/user/dto/UserRequestDto.java | 0 .../shareit/user/dto/UserResponseDto.java | 0 gateway/src/main/resources/application.yml | 7 + pom.xml | 157 ++-------- server/Dockerfile | 5 + server/pom.xml | 147 ++++++++++ .../ru/practicum/shareit/ShareItServer.java | 10 +- .../shareit/booking/BookingController.java | 9 +- .../shareit/booking/BookingServiceImpl.java | 6 +- .../booking/dto/BookingRequestDto.java | 21 ++ .../booking/dto/BookingResponseDto.java | 0 .../interfaces}/BookingRepository.java | 2 +- .../interfaces}/BookingServiceInterface.java | 2 +- .../shareit/booking/mapper/BookingMapper.java | 0 .../shareit/booking/model/Booking.java | 0 .../shareit/booking/model/BookingStatus.java | 0 .../exception/AnotherUserException.java | 8 + .../exception/DuplicatedDataException.java | 8 + .../shareit/exception/ErrorHandler.java | 47 +++ .../shareit/exception/ErrorResponse.java | 16 ++ .../shareit/exception/NotFoundException.java | 10 + .../exception/ValidationException.java | 8 + .../shareit/item/ItemController.java | 4 +- .../shareit/item/ItemServiceImpl.java | 2 +- .../shareit/item/dto/CommentRequestDto.java | 19 ++ .../item/dto/CommentResponseCreatedDto.java | 21 ++ .../shareit/item/dto/CommentResponseDto.java | 21 ++ .../shareit/item/dto/ItemBookerDto.java | 18 ++ .../shareit/item/dto/ItemRequestDto.java | 26 ++ .../shareit/item/dto/ItemResponseDto.java | 29 ++ .../item/dto/ItemResponseDtoWithComments.java | 38 +++ .../item/interfaces/CommentRepository.java | 0 .../item/interfaces/ItemRepository.java | 0 .../item/interfaces/ItemServiceInterface.java | 0 .../item/interfaces/ItemStorageInterface.java | 0 .../shareit/item/mapper/CommentMapper.java | 0 .../shareit/item/mapper/ItemMapper.java | 0 .../practicum/shareit/item/model/Comment.java | 0 .../ru/practicum/shareit/item/model/Item.java | 0 .../shareit/request/RequestController.java | 3 +- .../shareit/request/RequestServiceImpl.java | 7 +- .../shareit/request/dto/RequestInputDto.java | 21 ++ .../shareit/request/dto/RequestOutputDto.java | 25 ++ .../dto/RequestOutputWithItemsDto.java | 30 ++ .../request/interfaces/RequestRepository.java | 0 .../interfaces/RequestServiceInterface.java | 0 .../shareit/request/mapper/RequestMapper.java | 0 .../shareit/request/model/ItemRequest.java | 0 .../shareit/user/UserController.java | 7 +- .../shareit/user/UserServiceImpl.java | 0 .../shareit/user/dto/UserAuthorDto.java | 18 ++ .../shareit/user/dto/UserBookingDto.java | 3 +- .../shareit/user/dto/UserRequestDto.java | 22 ++ .../shareit/user/dto/UserResponseDto.java | 21 ++ .../user/interfaces/UserRepository.java | 0 .../user/interfaces/UserServiceInterface.java | 2 + .../shareit/user/mapper/UserMapper.java | 0 .../ru/practicum/shareit/user/model/User.java | 0 .../src/main/resources/application-test.yml | 15 + server/src/main/resources/application.yml | 25 ++ {src => server/src}/main/resources/schema.sql | 10 +- server/src/main/resources/test-data.sql | 83 ++++++ .../ru/practicum/shareit/ShareItTests.java | 0 .../java/ru/practicum/shareit/TestData.java | 142 +++++++++ .../BookingControllerTest.java | 162 +++++++++++ .../controllersTest/ItemControllerTest.java | 187 ++++++++++++ .../RequestControllerTest.java | 117 ++++++++ .../controllersTest/UserControllerTest.java | 131 +++++++++ .../shareit/mapperTest/BookingMapperTest.java | 6 +- .../shareit/mapperTest/CommentMapperTest.java | 7 +- .../shareit/mapperTest/ItemMapperTest.java | 2 +- .../shareit/mapperTest/UserMapperTest.java | 0 .../serviceTest/BookingServiceTest.java | 244 ++++++++++++++++ .../shareit/serviceTest/ItemServiceTest.java | 272 ++++++++++++++++++ .../serviceTest/RequestServiceTest.java | 90 ++++++ .../shareit/serviceTest/UserServiceTest.java | 117 ++++++++ .../practicum/shareit/PersistenceConfig.java | 66 ----- .../practicum/shareit/item/ItemStorage.java | 67 ----- .../practicum/shareit/user/UserStorage.java | 53 ---- .../user/interfaces/UserStorageInterface.java | 20 -- src/main/resources/application.properties | 13 - src/test/resources/application.properties | 10 - 118 files changed, 3021 insertions(+), 410 deletions(-) create mode 100644 .run/ShareitGateway.run.xml create mode 100644 .run/ShareitServer.run.xml create mode 100644 docker-compose.yml create mode 100644 gateway/Dockerfile create mode 100644 gateway/pom.xml create mode 100644 gateway/src/main/java/ru/practicum/shareit/ShareItGateway.java create mode 100644 gateway/src/main/java/ru/practicum/shareit/booking/BookingClient.java create mode 100644 gateway/src/main/java/ru/practicum/shareit/booking/BookingController.java rename {src => gateway/src}/main/java/ru/practicum/shareit/booking/dto/BookingRequestDto.java (87%) create mode 100644 gateway/src/main/java/ru/practicum/shareit/booking/dto/BookingResponseDto.java create mode 100644 gateway/src/main/java/ru/practicum/shareit/booking/dto/BookingState.java create mode 100644 gateway/src/main/java/ru/practicum/shareit/client/BaseClient.java rename {src => gateway/src}/main/java/ru/practicum/shareit/exception/AnotherUserException.java (100%) rename {src => gateway/src}/main/java/ru/practicum/shareit/exception/DuplicatedDataException.java (100%) rename {src => gateway/src}/main/java/ru/practicum/shareit/exception/ErrorHandler.java (67%) rename {src => gateway/src}/main/java/ru/practicum/shareit/exception/ErrorResponse.java (100%) rename {src => gateway/src}/main/java/ru/practicum/shareit/exception/NotFoundException.java (100%) rename {src => gateway/src}/main/java/ru/practicum/shareit/exception/ValidationException.java (100%) create mode 100644 gateway/src/main/java/ru/practicum/shareit/item/ItemClient.java create mode 100644 gateway/src/main/java/ru/practicum/shareit/item/ItemController.java rename {src => gateway/src}/main/java/ru/practicum/shareit/item/dto/CommentRequestDto.java (100%) rename {src => gateway/src}/main/java/ru/practicum/shareit/item/dto/CommentResponseCreatedDto.java (100%) rename {src => gateway/src}/main/java/ru/practicum/shareit/item/dto/CommentResponseDto.java (100%) rename {src => gateway/src}/main/java/ru/practicum/shareit/item/dto/ItemBookerDto.java (100%) rename {src => gateway/src}/main/java/ru/practicum/shareit/item/dto/ItemRequestDto.java (100%) rename {src => gateway/src}/main/java/ru/practicum/shareit/item/dto/ItemResponseDto.java (100%) rename {src => gateway/src}/main/java/ru/practicum/shareit/item/dto/ItemResponseDtoWithComments.java (93%) create mode 100644 gateway/src/main/java/ru/practicum/shareit/request/RequestClient.java create mode 100644 gateway/src/main/java/ru/practicum/shareit/request/RequestController.java rename {src => gateway/src}/main/java/ru/practicum/shareit/request/dto/RequestInputDto.java (100%) rename {src => gateway/src}/main/java/ru/practicum/shareit/request/dto/RequestOutputDto.java (100%) rename {src => gateway/src}/main/java/ru/practicum/shareit/request/dto/RequestOutputWithItemsDto.java (100%) create mode 100644 gateway/src/main/java/ru/practicum/shareit/user/UserClient.java create mode 100644 gateway/src/main/java/ru/practicum/shareit/user/UserController.java rename {src => gateway/src}/main/java/ru/practicum/shareit/user/dto/UserAuthorDto.java (100%) create mode 100644 gateway/src/main/java/ru/practicum/shareit/user/dto/UserBookingDto.java rename {src => gateway/src}/main/java/ru/practicum/shareit/user/dto/UserRequestDto.java (100%) rename {src => gateway/src}/main/java/ru/practicum/shareit/user/dto/UserResponseDto.java (100%) create mode 100644 gateway/src/main/resources/application.yml create mode 100644 server/Dockerfile create mode 100644 server/pom.xml rename src/main/java/ru/practicum/shareit/ShareItApp.java => server/src/main/java/ru/practicum/shareit/ShareItServer.java (56%) rename {src => server/src}/main/java/ru/practicum/shareit/booking/BookingController.java (86%) rename {src => server/src}/main/java/ru/practicum/shareit/booking/BookingServiceImpl.java (97%) create mode 100644 server/src/main/java/ru/practicum/shareit/booking/dto/BookingRequestDto.java rename {src => server/src}/main/java/ru/practicum/shareit/booking/dto/BookingResponseDto.java (100%) rename {src/main/java/ru/practicum/shareit/booking/intrfaces => server/src/main/java/ru/practicum/shareit/booking/interfaces}/BookingRepository.java (96%) rename {src/main/java/ru/practicum/shareit/booking/intrfaces => server/src/main/java/ru/practicum/shareit/booking/interfaces}/BookingServiceInterface.java (92%) rename {src => server/src}/main/java/ru/practicum/shareit/booking/mapper/BookingMapper.java (100%) rename {src => server/src}/main/java/ru/practicum/shareit/booking/model/Booking.java (100%) rename {src => server/src}/main/java/ru/practicum/shareit/booking/model/BookingStatus.java (100%) create mode 100644 server/src/main/java/ru/practicum/shareit/exception/AnotherUserException.java create mode 100644 server/src/main/java/ru/practicum/shareit/exception/DuplicatedDataException.java create mode 100644 server/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java create mode 100644 server/src/main/java/ru/practicum/shareit/exception/ErrorResponse.java create mode 100644 server/src/main/java/ru/practicum/shareit/exception/NotFoundException.java create mode 100644 server/src/main/java/ru/practicum/shareit/exception/ValidationException.java rename {src => server/src}/main/java/ru/practicum/shareit/item/ItemController.java (94%) rename {src => server/src}/main/java/ru/practicum/shareit/item/ItemServiceImpl.java (99%) create mode 100644 server/src/main/java/ru/practicum/shareit/item/dto/CommentRequestDto.java create mode 100644 server/src/main/java/ru/practicum/shareit/item/dto/CommentResponseCreatedDto.java create mode 100644 server/src/main/java/ru/practicum/shareit/item/dto/CommentResponseDto.java create mode 100644 server/src/main/java/ru/practicum/shareit/item/dto/ItemBookerDto.java create mode 100644 server/src/main/java/ru/practicum/shareit/item/dto/ItemRequestDto.java create mode 100644 server/src/main/java/ru/practicum/shareit/item/dto/ItemResponseDto.java create mode 100644 server/src/main/java/ru/practicum/shareit/item/dto/ItemResponseDtoWithComments.java rename {src => server/src}/main/java/ru/practicum/shareit/item/interfaces/CommentRepository.java (100%) rename {src => server/src}/main/java/ru/practicum/shareit/item/interfaces/ItemRepository.java (100%) rename {src => server/src}/main/java/ru/practicum/shareit/item/interfaces/ItemServiceInterface.java (100%) rename {src => server/src}/main/java/ru/practicum/shareit/item/interfaces/ItemStorageInterface.java (100%) rename {src => server/src}/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java (100%) rename {src => server/src}/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java (100%) rename {src => server/src}/main/java/ru/practicum/shareit/item/model/Comment.java (100%) rename {src => server/src}/main/java/ru/practicum/shareit/item/model/Item.java (100%) rename {src => server/src}/main/java/ru/practicum/shareit/request/RequestController.java (91%) rename {src => server/src}/main/java/ru/practicum/shareit/request/RequestServiceImpl.java (91%) create mode 100644 server/src/main/java/ru/practicum/shareit/request/dto/RequestInputDto.java create mode 100644 server/src/main/java/ru/practicum/shareit/request/dto/RequestOutputDto.java create mode 100644 server/src/main/java/ru/practicum/shareit/request/dto/RequestOutputWithItemsDto.java rename {src => server/src}/main/java/ru/practicum/shareit/request/interfaces/RequestRepository.java (100%) rename {src => server/src}/main/java/ru/practicum/shareit/request/interfaces/RequestServiceInterface.java (100%) rename {src => server/src}/main/java/ru/practicum/shareit/request/mapper/RequestMapper.java (100%) rename {src => server/src}/main/java/ru/practicum/shareit/request/model/ItemRequest.java (100%) rename {src => server/src}/main/java/ru/practicum/shareit/user/UserController.java (83%) rename {src => server/src}/main/java/ru/practicum/shareit/user/UserServiceImpl.java (100%) create mode 100644 server/src/main/java/ru/practicum/shareit/user/dto/UserAuthorDto.java rename {src => server/src}/main/java/ru/practicum/shareit/user/dto/UserBookingDto.java (85%) create mode 100644 server/src/main/java/ru/practicum/shareit/user/dto/UserRequestDto.java create mode 100644 server/src/main/java/ru/practicum/shareit/user/dto/UserResponseDto.java rename {src => server/src}/main/java/ru/practicum/shareit/user/interfaces/UserRepository.java (100%) rename {src => server/src}/main/java/ru/practicum/shareit/user/interfaces/UserServiceInterface.java (99%) rename {src => server/src}/main/java/ru/practicum/shareit/user/mapper/UserMapper.java (100%) rename {src => server/src}/main/java/ru/practicum/shareit/user/model/User.java (100%) create mode 100644 server/src/main/resources/application-test.yml create mode 100644 server/src/main/resources/application.yml rename {src => server/src}/main/resources/schema.sql (81%) create mode 100644 server/src/main/resources/test-data.sql rename {src => server/src}/test/java/ru/practicum/shareit/ShareItTests.java (100%) create mode 100644 server/src/test/java/ru/practicum/shareit/TestData.java create mode 100644 server/src/test/java/ru/practicum/shareit/controllersTest/BookingControllerTest.java create mode 100644 server/src/test/java/ru/practicum/shareit/controllersTest/ItemControllerTest.java create mode 100644 server/src/test/java/ru/practicum/shareit/controllersTest/RequestControllerTest.java create mode 100644 server/src/test/java/ru/practicum/shareit/controllersTest/UserControllerTest.java rename {src => server/src}/test/java/ru/practicum/shareit/mapperTest/BookingMapperTest.java (96%) rename {src => server/src}/test/java/ru/practicum/shareit/mapperTest/CommentMapperTest.java (94%) rename {src => server/src}/test/java/ru/practicum/shareit/mapperTest/ItemMapperTest.java (99%) rename {src => server/src}/test/java/ru/practicum/shareit/mapperTest/UserMapperTest.java (100%) create mode 100644 server/src/test/java/ru/practicum/shareit/serviceTest/BookingServiceTest.java create mode 100644 server/src/test/java/ru/practicum/shareit/serviceTest/ItemServiceTest.java create mode 100644 server/src/test/java/ru/practicum/shareit/serviceTest/RequestServiceTest.java create mode 100644 server/src/test/java/ru/practicum/shareit/serviceTest/UserServiceTest.java delete mode 100644 src/main/java/ru/practicum/shareit/PersistenceConfig.java delete mode 100644 src/main/java/ru/practicum/shareit/item/ItemStorage.java delete mode 100644 src/main/java/ru/practicum/shareit/user/UserStorage.java delete mode 100644 src/main/java/ru/practicum/shareit/user/interfaces/UserStorageInterface.java delete mode 100644 src/main/resources/application.properties delete mode 100644 src/test/resources/application.properties diff --git a/.run/ShareitGateway.run.xml b/.run/ShareitGateway.run.xml new file mode 100644 index 0000000..2b5e51e --- /dev/null +++ b/.run/ShareitGateway.run.xml @@ -0,0 +1,15 @@ + + + + \ No newline at end of file diff --git a/.run/ShareitServer.run.xml b/.run/ShareitServer.run.xml new file mode 100644 index 0000000..80abfa8 --- /dev/null +++ b/.run/ShareitServer.run.xml @@ -0,0 +1,15 @@ + + + + \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..ff9a374 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,39 @@ +services: + gateway: + build: gateway + image: shareit-gateway + container_name: shareit-gateway + ports: + - "8080:8080" + depends_on: + - server + environment: + - SHAREIT_SERVER_URL=http://server:9090 + + server: + build: server + image: shareit-server + container_name: shareit-server + ports: + - "9090:9090" + depends_on: + - db + environment: + - SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/postgres + - SPRING_DATASOURCE_USERNAME=user + - SPRING_DATASOURCE_PASSWORD=12345 + + db: + image: postgres:16.1 + container_name: postgres + ports: + - "6541:5432" + environment: + - POSTGRES_PASSWORD=12345 + - POSTGRES_USER=user + - POSTGRES_DB=postgres + healthcheck: + test: pg_isready -q -d $$POSTGRES_DB -U $$POSTGRES_USER + timeout: 5s + interval: 5s + retries: 10 \ No newline at end of file diff --git a/gateway/Dockerfile b/gateway/Dockerfile new file mode 100644 index 0000000..0ff1817 --- /dev/null +++ b/gateway/Dockerfile @@ -0,0 +1,5 @@ +FROM eclipse-temurin:21-jre-jammy +VOLUME /tmp +ARG JAR_FILE=target/*.jar +COPY ${JAR_FILE} app.jar +ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /app.jar"] \ No newline at end of file diff --git a/gateway/pom.xml b/gateway/pom.xml new file mode 100644 index 0000000..e51a7fe --- /dev/null +++ b/gateway/pom.xml @@ -0,0 +1,103 @@ + + + 4.0.0 + + ru.practicum + shareit + 0.0.1-SNAPSHOT + + + shareit-gateway + 0.0.1-SNAPSHOT + + ShareIt Gateway + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-validation + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.hibernate.validator + hibernate-validator + + + + org.apache.httpcomponents.client5 + httpclient5 + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + org.projectlombok + lombok + true + + + + org.springframework.boot + spring-boot-starter-test + test + + + ru.practicum + shareit-server + 0.0.1-SNAPSHOT + compile + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.projectlombok + lombok + 1.18.38 + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.4.1 + + + + com.baeldung.jar.JarExample + + + + + + + + + \ No newline at end of file diff --git a/gateway/src/main/java/ru/practicum/shareit/ShareItGateway.java b/gateway/src/main/java/ru/practicum/shareit/ShareItGateway.java new file mode 100644 index 0000000..e659d11 --- /dev/null +++ b/gateway/src/main/java/ru/practicum/shareit/ShareItGateway.java @@ -0,0 +1,12 @@ +package ru.practicum.shareit; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ShareItGateway { + public static void main(String[] args) { + SpringApplication.run(ShareItGateway.class, args); + } + +} diff --git a/gateway/src/main/java/ru/practicum/shareit/booking/BookingClient.java b/gateway/src/main/java/ru/practicum/shareit/booking/BookingClient.java new file mode 100644 index 0000000..70e68db --- /dev/null +++ b/gateway/src/main/java/ru/practicum/shareit/booking/BookingClient.java @@ -0,0 +1,57 @@ +package ru.practicum.shareit.booking; + +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.stereotype.Service; +import org.springframework.web.util.DefaultUriBuilderFactory; + +import ru.practicum.shareit.booking.dto.BookingRequestDto; +import ru.practicum.shareit.booking.dto.BookingState; +import ru.practicum.shareit.client.BaseClient; + +@Service +public class BookingClient extends BaseClient { + private static final String API_PREFIX = "/bookings"; + + @Autowired + public BookingClient(@Value("${shareit-server.url}") String serverUrl, RestTemplateBuilder builder) { + super( + builder + .uriTemplateHandler(new DefaultUriBuilderFactory(serverUrl + API_PREFIX)) + .requestFactory(() -> new HttpComponentsClientHttpRequestFactory()) + .build() + ); + } + + public ResponseEntity addBooking(Long userId, BookingRequestDto requestDto) { + return post("", userId, requestDto); + } + + public ResponseEntity getBooking(Long bookingId, Long userId) { + return get("/" + bookingId, userId); + } + + public ResponseEntity bookingApprove(long bookingId, long userId, boolean approved) { + + return patch("/" + bookingId + "?approved=" + approved, userId); + } + + public ResponseEntity getBookingsByUser(Long userId, String state) { + Map parameters = Map.of( + "state", state + ); + return get("", userId, parameters); + } + + public ResponseEntity getBookingsByOwner(Long userId, BookingState state) { + Map parameters = Map.of( + "state", state + ); + return get("/owner", userId, parameters); + } +} diff --git a/gateway/src/main/java/ru/practicum/shareit/booking/BookingController.java b/gateway/src/main/java/ru/practicum/shareit/booking/BookingController.java new file mode 100644 index 0000000..0a16bfb --- /dev/null +++ b/gateway/src/main/java/ru/practicum/shareit/booking/BookingController.java @@ -0,0 +1,47 @@ +package ru.practicum.shareit.booking; + +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import ru.practicum.shareit.booking.dto.BookingRequestDto; +import ru.practicum.shareit.booking.dto.BookingState; + +@RestController +@RequestMapping(path = "/bookings") +@RequiredArgsConstructor +public class BookingController { + private final BookingClient bookingService; + public static final String USER_ID = "X-Sharer-User-Id"; + + @PostMapping + public ResponseEntity addBooking(@RequestBody @Valid BookingRequestDto booking, + @RequestHeader(USER_ID) Long bookerId) { + return bookingService.addBooking(bookerId, booking); + } + + @PatchMapping("/{bookingId}") + public ResponseEntity bookingApprove(@PathVariable Long bookingId, + @RequestHeader (USER_ID) Long ownerId, + @RequestParam Boolean approved) { + return bookingService.bookingApprove(bookingId, ownerId, approved); + } + + @GetMapping("/{bookingId}") + public ResponseEntity getBooking(@PathVariable Long bookingId, + @RequestHeader(USER_ID) Long userId) { + return bookingService.getBooking(bookingId, userId); + } + + @GetMapping + public ResponseEntity getBookingsByUser(@RequestHeader (USER_ID) Long userId, + @RequestParam(name = "state", defaultValue = "all") String state) { + return bookingService.getBookingsByUser(userId, state); + } + + @GetMapping("/owner") + public ResponseEntity getBookingsByOwner(@RequestHeader (USER_ID) Long userId, + @RequestParam(name = "state", defaultValue = "all") BookingState state) { + return bookingService.getBookingsByOwner(userId, state); + } +} diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingRequestDto.java b/gateway/src/main/java/ru/practicum/shareit/booking/dto/BookingRequestDto.java similarity index 87% rename from src/main/java/ru/practicum/shareit/booking/dto/BookingRequestDto.java rename to gateway/src/main/java/ru/practicum/shareit/booking/dto/BookingRequestDto.java index 0e94f98..213047a 100644 --- a/src/main/java/ru/practicum/shareit/booking/dto/BookingRequestDto.java +++ b/gateway/src/main/java/ru/practicum/shareit/booking/dto/BookingRequestDto.java @@ -6,7 +6,6 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import ru.practicum.shareit.booking.model.BookingStatus; import java.time.LocalDateTime; @@ -19,6 +18,7 @@ public class BookingRequestDto { @NotNull @Future + private LocalDateTime start; @NotNull @@ -30,5 +30,5 @@ public class BookingRequestDto { private Long bookerId; - private BookingStatus status; + private BookingState status; } diff --git a/gateway/src/main/java/ru/practicum/shareit/booking/dto/BookingResponseDto.java b/gateway/src/main/java/ru/practicum/shareit/booking/dto/BookingResponseDto.java new file mode 100644 index 0000000..096c6eb --- /dev/null +++ b/gateway/src/main/java/ru/practicum/shareit/booking/dto/BookingResponseDto.java @@ -0,0 +1,30 @@ +package ru.practicum.shareit.booking.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import ru.practicum.shareit.item.dto.ItemBookerDto; +import ru.practicum.shareit.user.dto.UserBookingDto; + +import java.time.LocalDateTime; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class BookingResponseDto { + + @JsonProperty("id") + private Long bookingId; + + private LocalDateTime start; + + private LocalDateTime end; + + private ItemBookerDto item; + + private UserBookingDto booker; + + private BookingState status; + +} diff --git a/gateway/src/main/java/ru/practicum/shareit/booking/dto/BookingState.java b/gateway/src/main/java/ru/practicum/shareit/booking/dto/BookingState.java new file mode 100644 index 0000000..9726a10 --- /dev/null +++ b/gateway/src/main/java/ru/practicum/shareit/booking/dto/BookingState.java @@ -0,0 +1,36 @@ +package ru.practicum.shareit.booking.dto; + +import lombok.Getter; + +import java.util.Optional; + +@Getter +public enum BookingState { + // Все + ALL("ALL"), + // Текущие + CURRENT("CURRENT"), + // Будущие + FUTURE("FUTURE"), + // Завершенные + PAST("PAST"), + // Отклоненные + REJECTED("REJECTED"), + // Ожидающие подтверждения + WAITING("WAITING"),; + + private final String value; + + BookingState(String value) { + this.value = value; + } + + public static Optional from(String stringState) { + for (BookingState state : values()) { + if (state.name().equalsIgnoreCase(stringState)) { + return Optional.of(state); + } + } + return Optional.empty(); + } +} \ No newline at end of file diff --git a/gateway/src/main/java/ru/practicum/shareit/client/BaseClient.java b/gateway/src/main/java/ru/practicum/shareit/client/BaseClient.java new file mode 100644 index 0000000..1413765 --- /dev/null +++ b/gateway/src/main/java/ru/practicum/shareit/client/BaseClient.java @@ -0,0 +1,125 @@ +package ru.practicum.shareit.client; + +import java.util.List; +import java.util.Map; + +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.lang.Nullable; +import org.springframework.web.client.HttpStatusCodeException; +import org.springframework.web.client.RestTemplate; + +public class BaseClient { + protected final RestTemplate rest; + + public BaseClient(RestTemplate rest) { + this.rest = rest; + } + + protected ResponseEntity get(String path) { + return get(path, null, null); + } + + protected ResponseEntity get(String path, long userId) { + return get(path, userId, null); + } + + protected ResponseEntity get(String path, @Nullable Map parameters) { + return get(path,null, parameters); + } + + protected ResponseEntity get(String path, Long userId, @Nullable Map parameters) { + return makeAndSendRequest(HttpMethod.GET, path, userId, parameters, null); + } + + protected ResponseEntity post(String path, T body) { + return post(path, null, null, body); + } + + protected ResponseEntity post(String path, long userId, T body) { + return post(path, userId, null, body); + } + + protected ResponseEntity post(String path, Long userId, @Nullable Map parameters, T body) { + return makeAndSendRequest(HttpMethod.POST, path, userId, parameters, body); + } + + protected ResponseEntity put(String path, long userId, T body) { + return put(path, userId, null, body); + } + + protected ResponseEntity put(String path, long userId, @Nullable Map parameters, T body) { + return makeAndSendRequest(HttpMethod.PUT, path, userId, parameters, body); + } + + protected ResponseEntity patch(String path, T body) { + return patch(path, null, null, body); + } + + protected ResponseEntity patch(String path, long userId) { + return patch(path, userId, null, null); + } + + protected ResponseEntity patch(String path, long userId, T body) { + return patch(path, userId, null, body); + } + + protected ResponseEntity patch(String path, Long userId, @Nullable Map parameters, T body) { + return makeAndSendRequest(HttpMethod.PATCH, path, userId, parameters, body); + } + + protected ResponseEntity delete(String path) { + return delete(path, null, null); + } + + protected ResponseEntity delete(String path, long userId) { + return delete(path, userId, null); + } + + protected ResponseEntity delete(String path, Long userId, @Nullable Map parameters) { + return makeAndSendRequest(HttpMethod.DELETE, path, userId, parameters, null); + } + + private ResponseEntity makeAndSendRequest(HttpMethod method, String path, Long userId, @Nullable Map parameters, @Nullable T body) { + HttpEntity requestEntity = new HttpEntity<>(body, defaultHeaders(userId)); + + ResponseEntity shareitServerResponse; + try { + if (parameters != null) { + shareitServerResponse = rest.exchange(path, method, requestEntity, Object.class, parameters); + } else { + shareitServerResponse = rest.exchange(path, method, requestEntity, Object.class); + } + } catch (HttpStatusCodeException e) { + return ResponseEntity.status(e.getStatusCode()).body(e.getResponseBodyAsByteArray()); + } + return prepareGatewayResponse(shareitServerResponse); + } + + private HttpHeaders defaultHeaders(Long userId) { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.setAccept(List.of(MediaType.APPLICATION_JSON)); + if (userId != null) { + headers.set("X-Sharer-User-Id", String.valueOf(userId)); + } + return headers; + } + + private static ResponseEntity prepareGatewayResponse(ResponseEntity response) { + if (response.getStatusCode().is2xxSuccessful()) { + return response; + } + + ResponseEntity.BodyBuilder responseBuilder = ResponseEntity.status(response.getStatusCode()); + + if (response.hasBody()) { + return responseBuilder.body(response.getBody()); + } + + return responseBuilder.build(); + } +} diff --git a/src/main/java/ru/practicum/shareit/exception/AnotherUserException.java b/gateway/src/main/java/ru/practicum/shareit/exception/AnotherUserException.java similarity index 100% rename from src/main/java/ru/practicum/shareit/exception/AnotherUserException.java rename to gateway/src/main/java/ru/practicum/shareit/exception/AnotherUserException.java diff --git a/src/main/java/ru/practicum/shareit/exception/DuplicatedDataException.java b/gateway/src/main/java/ru/practicum/shareit/exception/DuplicatedDataException.java similarity index 100% rename from src/main/java/ru/practicum/shareit/exception/DuplicatedDataException.java rename to gateway/src/main/java/ru/practicum/shareit/exception/DuplicatedDataException.java diff --git a/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java b/gateway/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java similarity index 67% rename from src/main/java/ru/practicum/shareit/exception/ErrorHandler.java rename to gateway/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java index d118158..61d8fd9 100644 --- a/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java +++ b/gateway/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java @@ -24,6 +24,20 @@ public ErrorResponse handleNotFoundException(final NotFoundException e) { return new ErrorResponse(e.getMessage(), HttpStatus.NOT_FOUND); } + @ExceptionHandler(ValidationException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ErrorResponse handleValidationException(final ValidationException e) { + log.error("Not found: {}", e.getMessage()); + return new ErrorResponse(e.getMessage(), HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler(AnotherUserException.class) + @ResponseStatus(HttpStatus.FORBIDDEN) + public ErrorResponse handleAnotherUserException(final AnotherUserException e) { + log.error("Not found: {}", e.getMessage()); + return new ErrorResponse(e.getMessage(), HttpStatus.FORBIDDEN); + } + @ExceptionHandler @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public ErrorResponse handleException(final RuntimeException e) { diff --git a/src/main/java/ru/practicum/shareit/exception/ErrorResponse.java b/gateway/src/main/java/ru/practicum/shareit/exception/ErrorResponse.java similarity index 100% rename from src/main/java/ru/practicum/shareit/exception/ErrorResponse.java rename to gateway/src/main/java/ru/practicum/shareit/exception/ErrorResponse.java diff --git a/src/main/java/ru/practicum/shareit/exception/NotFoundException.java b/gateway/src/main/java/ru/practicum/shareit/exception/NotFoundException.java similarity index 100% rename from src/main/java/ru/practicum/shareit/exception/NotFoundException.java rename to gateway/src/main/java/ru/practicum/shareit/exception/NotFoundException.java diff --git a/src/main/java/ru/practicum/shareit/exception/ValidationException.java b/gateway/src/main/java/ru/practicum/shareit/exception/ValidationException.java similarity index 100% rename from src/main/java/ru/practicum/shareit/exception/ValidationException.java rename to gateway/src/main/java/ru/practicum/shareit/exception/ValidationException.java diff --git a/gateway/src/main/java/ru/practicum/shareit/item/ItemClient.java b/gateway/src/main/java/ru/practicum/shareit/item/ItemClient.java new file mode 100644 index 0000000..5c0730f --- /dev/null +++ b/gateway/src/main/java/ru/practicum/shareit/item/ItemClient.java @@ -0,0 +1,56 @@ +package ru.practicum.shareit.item; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.stereotype.Service; +import org.springframework.web.util.DefaultUriBuilderFactory; +import ru.practicum.shareit.client.BaseClient; +import ru.practicum.shareit.item.dto.CommentRequestDto; +import ru.practicum.shareit.item.dto.ItemRequestDto; + +import java.util.Map; + +@Service +public class ItemClient extends BaseClient { + private static final String API_PREFIX = "/items"; + + @Autowired + public ItemClient(@Value("${shareit-server.url}") String serverUrl, RestTemplateBuilder builder) { + super( + builder + .uriTemplateHandler(new DefaultUriBuilderFactory(serverUrl + API_PREFIX)) + .requestFactory(() -> new HttpComponentsClientHttpRequestFactory()) + .build() + ); + } + + public ResponseEntity create(Long userId, ItemRequestDto item) { + return post("", userId, item); + } + + public ResponseEntity update(Long itemId, ItemRequestDto item, Long ownerId) { + return patch("/" + itemId, ownerId, item); + } + + public ResponseEntity getItemById(Long itemId, Long ownerId) { + return get("/" + itemId, ownerId); + } + + public ResponseEntity getAllItemsForOwner(Long ownerId) { + return get("", ownerId); + } + + public ResponseEntity searchByText(String text) { + Map parameters = Map.of( + "text", text + ); + return get("/search", parameters); + } + + public ResponseEntity addComment(Long commentatorId, CommentRequestDto comment, Long itemId) { + return post("/" + itemId + "/comment", commentatorId, comment); + } +} diff --git a/gateway/src/main/java/ru/practicum/shareit/item/ItemController.java b/gateway/src/main/java/ru/practicum/shareit/item/ItemController.java new file mode 100644 index 0000000..3faf006 --- /dev/null +++ b/gateway/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -0,0 +1,60 @@ +package ru.practicum.shareit.item; + + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import ru.practicum.shareit.item.dto.*; + + + +@RestController +@RequestMapping("/items") +@RequiredArgsConstructor +@Slf4j +@Validated +public class ItemController { + + public static final String OWNER_ID = "X-Sharer-User-Id"; + private final ItemClient itemService; + + @PostMapping + public ResponseEntity create(@RequestHeader(OWNER_ID) Long ownerId, + @RequestBody ItemRequestDto item) { + return itemService.create(ownerId, item); + } + + @PatchMapping("/{itemId}") + public ResponseEntity update(@RequestBody ItemRequestDto item, + @PathVariable Long itemId, + @RequestHeader(OWNER_ID) Long ownerId) { + return itemService.update(itemId, item, ownerId); + } + + @GetMapping("/{itemId}") + public ResponseEntity getItemById(@PathVariable Long itemId, + @RequestHeader(OWNER_ID) Long ownerId) { + return itemService.getItemById(itemId, ownerId); + } + + @GetMapping + public ResponseEntity getAllItemsForOwner( + @RequestHeader(OWNER_ID) Long ownerId) { + return itemService.getAllItemsForOwner(ownerId); + } + + @GetMapping("/search") + public ResponseEntity searchItems(@RequestParam String text) { + return itemService.searchByText(text); + } + + @PostMapping("/{itemId}/comment") + public ResponseEntity addComment(@RequestBody CommentRequestDto comment, + @PathVariable Long itemId, + @RequestHeader(OWNER_ID) Long commentatorId) { + return itemService.addComment(commentatorId, comment, itemId); + } + +} diff --git a/src/main/java/ru/practicum/shareit/item/dto/CommentRequestDto.java b/gateway/src/main/java/ru/practicum/shareit/item/dto/CommentRequestDto.java similarity index 100% rename from src/main/java/ru/practicum/shareit/item/dto/CommentRequestDto.java rename to gateway/src/main/java/ru/practicum/shareit/item/dto/CommentRequestDto.java diff --git a/src/main/java/ru/practicum/shareit/item/dto/CommentResponseCreatedDto.java b/gateway/src/main/java/ru/practicum/shareit/item/dto/CommentResponseCreatedDto.java similarity index 100% rename from src/main/java/ru/practicum/shareit/item/dto/CommentResponseCreatedDto.java rename to gateway/src/main/java/ru/practicum/shareit/item/dto/CommentResponseCreatedDto.java diff --git a/src/main/java/ru/practicum/shareit/item/dto/CommentResponseDto.java b/gateway/src/main/java/ru/practicum/shareit/item/dto/CommentResponseDto.java similarity index 100% rename from src/main/java/ru/practicum/shareit/item/dto/CommentResponseDto.java rename to gateway/src/main/java/ru/practicum/shareit/item/dto/CommentResponseDto.java diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemBookerDto.java b/gateway/src/main/java/ru/practicum/shareit/item/dto/ItemBookerDto.java similarity index 100% rename from src/main/java/ru/practicum/shareit/item/dto/ItemBookerDto.java rename to gateway/src/main/java/ru/practicum/shareit/item/dto/ItemBookerDto.java diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemRequestDto.java b/gateway/src/main/java/ru/practicum/shareit/item/dto/ItemRequestDto.java similarity index 100% rename from src/main/java/ru/practicum/shareit/item/dto/ItemRequestDto.java rename to gateway/src/main/java/ru/practicum/shareit/item/dto/ItemRequestDto.java diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemResponseDto.java b/gateway/src/main/java/ru/practicum/shareit/item/dto/ItemResponseDto.java similarity index 100% rename from src/main/java/ru/practicum/shareit/item/dto/ItemResponseDto.java rename to gateway/src/main/java/ru/practicum/shareit/item/dto/ItemResponseDto.java diff --git a/src/main/java/ru/practicum/shareit/item/dto/ItemResponseDtoWithComments.java b/gateway/src/main/java/ru/practicum/shareit/item/dto/ItemResponseDtoWithComments.java similarity index 93% rename from src/main/java/ru/practicum/shareit/item/dto/ItemResponseDtoWithComments.java rename to gateway/src/main/java/ru/practicum/shareit/item/dto/ItemResponseDtoWithComments.java index 63d3bd6..5d8009a 100644 --- a/src/main/java/ru/practicum/shareit/item/dto/ItemResponseDtoWithComments.java +++ b/gateway/src/main/java/ru/practicum/shareit/item/dto/ItemResponseDtoWithComments.java @@ -1,7 +1,6 @@ package ru.practicum.shareit.item.dto; import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -14,7 +13,6 @@ @NoArgsConstructor public class ItemResponseDtoWithComments { - @NotNull @JsonProperty("id") private Long itemId; diff --git a/gateway/src/main/java/ru/practicum/shareit/request/RequestClient.java b/gateway/src/main/java/ru/practicum/shareit/request/RequestClient.java new file mode 100644 index 0000000..204efce --- /dev/null +++ b/gateway/src/main/java/ru/practicum/shareit/request/RequestClient.java @@ -0,0 +1,43 @@ +package ru.practicum.shareit.request; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.stereotype.Service; +import org.springframework.web.util.DefaultUriBuilderFactory; +import ru.practicum.shareit.client.BaseClient; +import ru.practicum.shareit.request.dto.RequestInputDto; + + +@Service +public class RequestClient extends BaseClient { + private static final String API_PREFIX = "/requests"; + + @Autowired + public RequestClient(@Value("${shareit-server.url}") String serverUrl, RestTemplateBuilder builder) { + super( + builder + .uriTemplateHandler(new DefaultUriBuilderFactory(serverUrl + API_PREFIX)) + .requestFactory(() -> new HttpComponentsClientHttpRequestFactory()) + .build() + ); + } + + public ResponseEntity addItemRequest(RequestInputDto requestInputDto, Long userId) { + return post("", userId, requestInputDto); + } + + public ResponseEntity getRequestByUser(Long userId) { + return get("", userId); + } + + public ResponseEntity getAllRequests() { + return get("/all"); + } + + public ResponseEntity getRequestById(Long requestId) { + return get("/" + requestId); + } +} diff --git a/gateway/src/main/java/ru/practicum/shareit/request/RequestController.java b/gateway/src/main/java/ru/practicum/shareit/request/RequestController.java new file mode 100644 index 0000000..1570287 --- /dev/null +++ b/gateway/src/main/java/ru/practicum/shareit/request/RequestController.java @@ -0,0 +1,37 @@ +package ru.practicum.shareit.request; + +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import ru.practicum.shareit.request.dto.RequestInputDto; + + +@RestController +@RequestMapping(path = "/requests") +@RequiredArgsConstructor +public class RequestController { + private final RequestClient requestService; + public static final String USER_ID = "X-Sharer-User-Id"; + + @PostMapping + public ResponseEntity addRequest(@RequestBody RequestInputDto requestInputDto, + @RequestHeader(USER_ID) Long userId) { + return requestService.addItemRequest(requestInputDto, userId); + } + + @GetMapping + public ResponseEntity getRequestByUser(@RequestHeader(USER_ID) Long userId) { + return requestService.getRequestByUser(userId); + } + + @GetMapping("/all") + public ResponseEntity getAllRequests() { + return requestService.getAllRequests(); + } + + @GetMapping("/{requestId}") + public ResponseEntity getRequestById(@PathVariable Long requestId) { + return requestService.getRequestById(requestId); + } +} + diff --git a/src/main/java/ru/practicum/shareit/request/dto/RequestInputDto.java b/gateway/src/main/java/ru/practicum/shareit/request/dto/RequestInputDto.java similarity index 100% rename from src/main/java/ru/practicum/shareit/request/dto/RequestInputDto.java rename to gateway/src/main/java/ru/practicum/shareit/request/dto/RequestInputDto.java diff --git a/src/main/java/ru/practicum/shareit/request/dto/RequestOutputDto.java b/gateway/src/main/java/ru/practicum/shareit/request/dto/RequestOutputDto.java similarity index 100% rename from src/main/java/ru/practicum/shareit/request/dto/RequestOutputDto.java rename to gateway/src/main/java/ru/practicum/shareit/request/dto/RequestOutputDto.java diff --git a/src/main/java/ru/practicum/shareit/request/dto/RequestOutputWithItemsDto.java b/gateway/src/main/java/ru/practicum/shareit/request/dto/RequestOutputWithItemsDto.java similarity index 100% rename from src/main/java/ru/practicum/shareit/request/dto/RequestOutputWithItemsDto.java rename to gateway/src/main/java/ru/practicum/shareit/request/dto/RequestOutputWithItemsDto.java diff --git a/gateway/src/main/java/ru/practicum/shareit/user/UserClient.java b/gateway/src/main/java/ru/practicum/shareit/user/UserClient.java new file mode 100644 index 0000000..215102c --- /dev/null +++ b/gateway/src/main/java/ru/practicum/shareit/user/UserClient.java @@ -0,0 +1,46 @@ +package ru.practicum.shareit.user; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.stereotype.Service; +import org.springframework.web.util.DefaultUriBuilderFactory; +import ru.practicum.shareit.client.BaseClient; +import ru.practicum.shareit.user.dto.UserRequestDto; + +@Service +public class UserClient extends BaseClient { + private static final String API_PREFIX = "/users"; + + @Autowired + public UserClient(@Value("${shareit-server.url}") String serverUrl, RestTemplateBuilder builder) { + super( + builder + .uriTemplateHandler(new DefaultUriBuilderFactory(serverUrl + API_PREFIX)) + .requestFactory(() -> new HttpComponentsClientHttpRequestFactory()) + .build() + ); + } + + public ResponseEntity createUser(UserRequestDto user) { + return post("", user); + } + + public ResponseEntity getUserById(Long id) { + return get("/" + id); + } + + public ResponseEntity updateUser(Long id, UserRequestDto user) { + return patch("/" + id, user); + } + + public void deleteUser(Long id) { + delete("/" + id); + } + + public void deleteAllUsers() { + delete(""); + } +} diff --git a/gateway/src/main/java/ru/practicum/shareit/user/UserController.java b/gateway/src/main/java/ru/practicum/shareit/user/UserController.java new file mode 100644 index 0000000..09731bd --- /dev/null +++ b/gateway/src/main/java/ru/practicum/shareit/user/UserController.java @@ -0,0 +1,42 @@ +package ru.practicum.shareit.user; + +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import ru.practicum.shareit.user.dto.UserRequestDto; + +@RestController +@Validated +@RequestMapping(path = "/users") +@RequiredArgsConstructor +public class UserController { + private final UserClient userService; + + @PostMapping + public ResponseEntity createUser(@Valid @RequestBody UserRequestDto user) { + return userService.createUser(user); + } + + @GetMapping("/{id}") + public ResponseEntity getUser(@PathVariable long id) { + return userService.getUserById(id); + } + + @PatchMapping("/{id}") + public ResponseEntity updateUser(@PathVariable long id, @RequestBody UserRequestDto user) { + return userService.updateUser(id, user); + } + + @DeleteMapping("/{id}") + public void deleteUser(@PathVariable long id) { + userService.deleteUser(id); + } + + @DeleteMapping + public void deleteUser() { + userService.deleteAllUsers(); + } + +} diff --git a/src/main/java/ru/practicum/shareit/user/dto/UserAuthorDto.java b/gateway/src/main/java/ru/practicum/shareit/user/dto/UserAuthorDto.java similarity index 100% rename from src/main/java/ru/practicum/shareit/user/dto/UserAuthorDto.java rename to gateway/src/main/java/ru/practicum/shareit/user/dto/UserAuthorDto.java diff --git a/gateway/src/main/java/ru/practicum/shareit/user/dto/UserBookingDto.java b/gateway/src/main/java/ru/practicum/shareit/user/dto/UserBookingDto.java new file mode 100644 index 0000000..f1be4e5 --- /dev/null +++ b/gateway/src/main/java/ru/practicum/shareit/user/dto/UserBookingDto.java @@ -0,0 +1,4 @@ +package ru.practicum.shareit.user.dto; + +public class UserBookingDto { +} diff --git a/src/main/java/ru/practicum/shareit/user/dto/UserRequestDto.java b/gateway/src/main/java/ru/practicum/shareit/user/dto/UserRequestDto.java similarity index 100% rename from src/main/java/ru/practicum/shareit/user/dto/UserRequestDto.java rename to gateway/src/main/java/ru/practicum/shareit/user/dto/UserRequestDto.java diff --git a/src/main/java/ru/practicum/shareit/user/dto/UserResponseDto.java b/gateway/src/main/java/ru/practicum/shareit/user/dto/UserResponseDto.java similarity index 100% rename from src/main/java/ru/practicum/shareit/user/dto/UserResponseDto.java rename to gateway/src/main/java/ru/practicum/shareit/user/dto/UserResponseDto.java diff --git a/gateway/src/main/resources/application.yml b/gateway/src/main/resources/application.yml new file mode 100644 index 0000000..e301265 --- /dev/null +++ b/gateway/src/main/resources/application.yml @@ -0,0 +1,7 @@ +logging.level.org.springframework.web.client.RestTemplate: DEBUG +#logging.level.org.apache.http=DEBUG +#logging.level.httpclient.wire=DEBUG + +server.port: 8080 + +shareit-server.url: http://localhost:9090 \ No newline at end of file diff --git a/pom.xml b/pom.xml index c3f31c2..16ed22f 100644 --- a/pom.xml +++ b/pom.xml @@ -12,102 +12,39 @@ ru.practicum shareit 0.0.1-SNAPSHOT + pom ShareIt + + gateway + server + + 21 1.6.3 0.2.0 - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.boot - spring-boot-configuration-processor - true - - - - org.postgresql - postgresql - runtime - - - - org.projectlombok - lombok - true - - - - com.h2database - h2 - test - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.boot - spring-boot-starter-validation - - - - org.mapstruct - mapstruct - ${org.mapstruct.version} - - - - org.projectlombok - lombok-mapstruct-binding - ${lombok-mapstruct-binding.version} - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - - - - - - - src/main/resources - true - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - org.projectlombok - lombok - - - - - + + org.springframework.boot + spring-boot-maven-plugin + + + true + + + + org.projectlombok + lombok + + + + org.apache.maven.plugins maven-surefire-plugin @@ -143,44 +80,6 @@ - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - 1.8 - 1.8 - - - org.projectlombok - lombok - ${lombok.version} - - - org.mapstruct - mapstruct-processor - ${org.mapstruct.version} - - - org.projectlombok - lombok-mapstruct-binding - ${lombok-mapstruct-binding.version} - - - true - - - -Amapstruct.suppressGeneratorTimestamp=true - - - -Amapstruct.suppressGeneratorVersionInfoComment=true - - - -Amapstruct.verbose=true - - - - com.github.spotbugs spotbugs-maven-plugin @@ -292,17 +191,5 @@ - - coverage - - - - org.jacoco - jacoco-maven-plugin - - - - - - + \ No newline at end of file diff --git a/server/Dockerfile b/server/Dockerfile new file mode 100644 index 0000000..0ff1817 --- /dev/null +++ b/server/Dockerfile @@ -0,0 +1,5 @@ +FROM eclipse-temurin:21-jre-jammy +VOLUME /tmp +ARG JAR_FILE=target/*.jar +COPY ${JAR_FILE} app.jar +ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /app.jar"] \ No newline at end of file diff --git a/server/pom.xml b/server/pom.xml new file mode 100644 index 0000000..5bd587c --- /dev/null +++ b/server/pom.xml @@ -0,0 +1,147 @@ + + + 4.0.0 + + ru.practicum + shareit + 0.0.1-SNAPSHOT + + + shareit-server + 0.0.1-SNAPSHOT + + ShareIt Server + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-actuator + + + + 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.mapstruct + mapstruct + 1.6.3 + + + org.projectlombok + lombok-mapstruct-binding + ${lombok-mapstruct-binding.version} + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + org.projectlombok + lombok + ${lombok.version} + + + org.mapstruct + mapstruct-processor + ${org.mapstruct.version} + + + org.projectlombok + lombok-mapstruct-binding + ${lombok-mapstruct-binding.version} + + + true + + + -Amapstruct.suppressGeneratorTimestamp=true + + + -Amapstruct.suppressGeneratorVersionInfoComment=true + + + -Amapstruct.verbose=true + + + + + + + + + + coverage + + + + org.jacoco + jacoco-maven-plugin + + + + + + + \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/ShareItApp.java b/server/src/main/java/ru/practicum/shareit/ShareItServer.java similarity index 56% rename from src/main/java/ru/practicum/shareit/ShareItApp.java rename to server/src/main/java/ru/practicum/shareit/ShareItServer.java index a00ad56..e793b9c 100644 --- a/src/main/java/ru/practicum/shareit/ShareItApp.java +++ b/server/src/main/java/ru/practicum/shareit/ShareItServer.java @@ -4,10 +4,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class ShareItApp { +public class ShareItServer { - public static void main(String[] args) { - SpringApplication.run(ShareItApp.class, args); - } + public static void main(String[] args) { + SpringApplication.run(ShareItServer.class, args); + } -} +} \ No newline at end of file diff --git a/src/main/java/ru/practicum/shareit/booking/BookingController.java b/server/src/main/java/ru/practicum/shareit/booking/BookingController.java similarity index 86% rename from src/main/java/ru/practicum/shareit/booking/BookingController.java rename to server/src/main/java/ru/practicum/shareit/booking/BookingController.java index 80c11aa..1b0f719 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingController.java +++ b/server/src/main/java/ru/practicum/shareit/booking/BookingController.java @@ -1,24 +1,21 @@ package ru.practicum.shareit.booking; -import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import ru.practicum.shareit.booking.dto.BookingRequestDto; import ru.practicum.shareit.booking.dto.BookingResponseDto; - import java.util.Collection; @RestController @RequestMapping(path = "/bookings") @RequiredArgsConstructor public class BookingController { - private final BookingServiceImpl bookingService; public static final String USER_ID = "X-Sharer-User-Id"; @PostMapping - public BookingResponseDto addBooking(@RequestBody @Valid BookingRequestDto booking, + public BookingResponseDto addBooking(@RequestBody BookingRequestDto booking, @RequestHeader(USER_ID) Long bookerId) { return bookingService.addBooking(booking, bookerId); } @@ -31,8 +28,8 @@ public BookingResponseDto bookingApprove(@PathVariable Long bookingId, } @GetMapping("/{bookingId}") - public BookingResponseDto getBooking(@PathVariable Long bookingId, - @RequestHeader(USER_ID) Long userId) { + public BookingResponseDto getBookingById(@PathVariable Long bookingId, + @RequestHeader(USER_ID) Long userId) { return bookingService.getBookingByBookingId(bookingId, userId); } diff --git a/src/main/java/ru/practicum/shareit/booking/BookingServiceImpl.java b/server/src/main/java/ru/practicum/shareit/booking/BookingServiceImpl.java similarity index 97% rename from src/main/java/ru/practicum/shareit/booking/BookingServiceImpl.java rename to server/src/main/java/ru/practicum/shareit/booking/BookingServiceImpl.java index 4bc3009..7baac4c 100644 --- a/src/main/java/ru/practicum/shareit/booking/BookingServiceImpl.java +++ b/server/src/main/java/ru/practicum/shareit/booking/BookingServiceImpl.java @@ -4,8 +4,8 @@ import org.springframework.stereotype.Service; import ru.practicum.shareit.booking.dto.BookingRequestDto; import ru.practicum.shareit.booking.dto.BookingResponseDto; -import ru.practicum.shareit.booking.intrfaces.BookingRepository; -import ru.practicum.shareit.booking.intrfaces.BookingServiceInterface; +import ru.practicum.shareit.booking.interfaces.BookingRepository; +import ru.practicum.shareit.booking.interfaces.BookingServiceInterface; import ru.practicum.shareit.booking.mapper.BookingMapper; import ru.practicum.shareit.booking.model.Booking; import ru.practicum.shareit.booking.model.BookingStatus; @@ -52,7 +52,7 @@ public BookingResponseDto addBooking(BookingRequestDto booking, Long bookerId) { if (item.getIsAvailable().equals(false)) { saved.setStatus(BookingStatus.REJECTED); storage.save(saved); - throw new RuntimeException("Booking is rejected, item is not available"); + throw new ValidationException("Booking is rejected, item is not available"); } else { saved.setStatus(BookingStatus.WAITING); storage.save(saved); diff --git a/server/src/main/java/ru/practicum/shareit/booking/dto/BookingRequestDto.java b/server/src/main/java/ru/practicum/shareit/booking/dto/BookingRequestDto.java new file mode 100644 index 0000000..cad3ac9 --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/booking/dto/BookingRequestDto.java @@ -0,0 +1,21 @@ +package ru.practicum.shareit.booking.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import ru.practicum.shareit.booking.model.BookingStatus; + +import java.time.LocalDateTime; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class BookingRequestDto { + + private Long bookingId; + private LocalDateTime start; + private LocalDateTime end; + private Long itemId; + private Long bookerId; + private BookingStatus status; +} diff --git a/src/main/java/ru/practicum/shareit/booking/dto/BookingResponseDto.java b/server/src/main/java/ru/practicum/shareit/booking/dto/BookingResponseDto.java similarity index 100% rename from src/main/java/ru/practicum/shareit/booking/dto/BookingResponseDto.java rename to server/src/main/java/ru/practicum/shareit/booking/dto/BookingResponseDto.java diff --git a/src/main/java/ru/practicum/shareit/booking/intrfaces/BookingRepository.java b/server/src/main/java/ru/practicum/shareit/booking/interfaces/BookingRepository.java similarity index 96% rename from src/main/java/ru/practicum/shareit/booking/intrfaces/BookingRepository.java rename to server/src/main/java/ru/practicum/shareit/booking/interfaces/BookingRepository.java index f5c6a0d..fe1b88b 100644 --- a/src/main/java/ru/practicum/shareit/booking/intrfaces/BookingRepository.java +++ b/server/src/main/java/ru/practicum/shareit/booking/interfaces/BookingRepository.java @@ -1,4 +1,4 @@ -package ru.practicum.shareit.booking.intrfaces; +package ru.practicum.shareit.booking.interfaces; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; diff --git a/src/main/java/ru/practicum/shareit/booking/intrfaces/BookingServiceInterface.java b/server/src/main/java/ru/practicum/shareit/booking/interfaces/BookingServiceInterface.java similarity index 92% rename from src/main/java/ru/practicum/shareit/booking/intrfaces/BookingServiceInterface.java rename to server/src/main/java/ru/practicum/shareit/booking/interfaces/BookingServiceInterface.java index 539d1cf..d67f3ec 100644 --- a/src/main/java/ru/practicum/shareit/booking/intrfaces/BookingServiceInterface.java +++ b/server/src/main/java/ru/practicum/shareit/booking/interfaces/BookingServiceInterface.java @@ -1,4 +1,4 @@ -package ru.practicum.shareit.booking.intrfaces; +package ru.practicum.shareit.booking.interfaces; import ru.practicum.shareit.booking.dto.BookingRequestDto; import ru.practicum.shareit.booking.dto.BookingResponseDto; diff --git a/src/main/java/ru/practicum/shareit/booking/mapper/BookingMapper.java b/server/src/main/java/ru/practicum/shareit/booking/mapper/BookingMapper.java similarity index 100% rename from src/main/java/ru/practicum/shareit/booking/mapper/BookingMapper.java rename to server/src/main/java/ru/practicum/shareit/booking/mapper/BookingMapper.java diff --git a/src/main/java/ru/practicum/shareit/booking/model/Booking.java b/server/src/main/java/ru/practicum/shareit/booking/model/Booking.java similarity index 100% rename from src/main/java/ru/practicum/shareit/booking/model/Booking.java rename to server/src/main/java/ru/practicum/shareit/booking/model/Booking.java diff --git a/src/main/java/ru/practicum/shareit/booking/model/BookingStatus.java b/server/src/main/java/ru/practicum/shareit/booking/model/BookingStatus.java similarity index 100% rename from src/main/java/ru/practicum/shareit/booking/model/BookingStatus.java rename to server/src/main/java/ru/practicum/shareit/booking/model/BookingStatus.java diff --git a/server/src/main/java/ru/practicum/shareit/exception/AnotherUserException.java b/server/src/main/java/ru/practicum/shareit/exception/AnotherUserException.java new file mode 100644 index 0000000..6fc8434 --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/exception/AnotherUserException.java @@ -0,0 +1,8 @@ +package ru.practicum.shareit.exception; + +public class AnotherUserException extends RuntimeException { + + public AnotherUserException(String message) { + super(message); + } +} diff --git a/server/src/main/java/ru/practicum/shareit/exception/DuplicatedDataException.java b/server/src/main/java/ru/practicum/shareit/exception/DuplicatedDataException.java new file mode 100644 index 0000000..3aef12f --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/exception/DuplicatedDataException.java @@ -0,0 +1,8 @@ +package ru.practicum.shareit.exception; + +public class DuplicatedDataException extends RuntimeException { + + public DuplicatedDataException(String message) { + super(message); + } +} diff --git a/server/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java b/server/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java new file mode 100644 index 0000000..61d8fd9 --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/exception/ErrorHandler.java @@ -0,0 +1,47 @@ +package ru.practicum.shareit.exception; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +@Slf4j +public class ErrorHandler { + + @ExceptionHandler(DuplicatedDataException.class) + @ResponseStatus(HttpStatus.CONFLICT) + public ErrorResponse handleDuplicatedDataException(final DuplicatedDataException e) { + log.error("Duplicated: {}", e.getMessage()); + return new ErrorResponse(e.getMessage(), HttpStatus.CONFLICT); + } + + @ExceptionHandler(NotFoundException.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public ErrorResponse handleNotFoundException(final NotFoundException e) { + log.error("Not found: {}", e.getMessage()); + return new ErrorResponse(e.getMessage(), HttpStatus.NOT_FOUND); + } + + @ExceptionHandler(ValidationException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ErrorResponse handleValidationException(final ValidationException e) { + log.error("Not found: {}", e.getMessage()); + return new ErrorResponse(e.getMessage(), HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler(AnotherUserException.class) + @ResponseStatus(HttpStatus.FORBIDDEN) + public ErrorResponse handleAnotherUserException(final AnotherUserException e) { + log.error("Not found: {}", e.getMessage()); + return new ErrorResponse(e.getMessage(), HttpStatus.FORBIDDEN); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public ErrorResponse handleException(final RuntimeException e) { + log.error("ServerError: {}", e.getMessage()); + return new ErrorResponse(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } +} diff --git a/server/src/main/java/ru/practicum/shareit/exception/ErrorResponse.java b/server/src/main/java/ru/practicum/shareit/exception/ErrorResponse.java new file mode 100644 index 0000000..40e1fb8 --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/exception/ErrorResponse.java @@ -0,0 +1,16 @@ +package ru.practicum.shareit.exception; + +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +public class ErrorResponse { + String error; + HttpStatus status; + + public ErrorResponse(String error, HttpStatus status) { + this.error = error; + this.status = status; + } + +} diff --git a/server/src/main/java/ru/practicum/shareit/exception/NotFoundException.java b/server/src/main/java/ru/practicum/shareit/exception/NotFoundException.java new file mode 100644 index 0000000..89a2ad0 --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/exception/NotFoundException.java @@ -0,0 +1,10 @@ +package ru.practicum.shareit.exception; + +public class NotFoundException extends RuntimeException { + + public NotFoundException(String message) { + super(message); + } + +} + diff --git a/server/src/main/java/ru/practicum/shareit/exception/ValidationException.java b/server/src/main/java/ru/practicum/shareit/exception/ValidationException.java new file mode 100644 index 0000000..56cb5a8 --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/exception/ValidationException.java @@ -0,0 +1,8 @@ +package ru.practicum.shareit.exception; + +public class ValidationException extends RuntimeException { + + public ValidationException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/practicum/shareit/item/ItemController.java b/server/src/main/java/ru/practicum/shareit/item/ItemController.java similarity index 94% rename from src/main/java/ru/practicum/shareit/item/ItemController.java rename to server/src/main/java/ru/practicum/shareit/item/ItemController.java index 418f8b6..a8b5154 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/server/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -1,7 +1,5 @@ package ru.practicum.shareit.item; - -import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; @@ -22,7 +20,7 @@ public class ItemController { @PostMapping public ItemResponseDto create(@RequestHeader(OWNER_ID) Long ownerId, - @Valid @RequestBody ItemRequestDto item) { + @RequestBody ItemRequestDto item) { return itemService.createItem(item, ownerId); } diff --git a/src/main/java/ru/practicum/shareit/item/ItemServiceImpl.java b/server/src/main/java/ru/practicum/shareit/item/ItemServiceImpl.java similarity index 99% rename from src/main/java/ru/practicum/shareit/item/ItemServiceImpl.java rename to server/src/main/java/ru/practicum/shareit/item/ItemServiceImpl.java index feae224..9e4dd0a 100644 --- a/src/main/java/ru/practicum/shareit/item/ItemServiceImpl.java +++ b/server/src/main/java/ru/practicum/shareit/item/ItemServiceImpl.java @@ -3,7 +3,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import ru.practicum.shareit.booking.dto.BookingResponseDto; -import ru.practicum.shareit.booking.intrfaces.BookingRepository; +import ru.practicum.shareit.booking.interfaces.BookingRepository; import ru.practicum.shareit.booking.mapper.BookingMapper; import ru.practicum.shareit.booking.model.Booking; import ru.practicum.shareit.booking.model.BookingStatus; diff --git a/server/src/main/java/ru/practicum/shareit/item/dto/CommentRequestDto.java b/server/src/main/java/ru/practicum/shareit/item/dto/CommentRequestDto.java new file mode 100644 index 0000000..3462221 --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/item/dto/CommentRequestDto.java @@ -0,0 +1,19 @@ +package ru.practicum.shareit.item.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class CommentRequestDto { + + @JsonProperty("id") + private Long authorId; + + @JsonProperty("text") + private String text; + + private LocalDateTime date = LocalDateTime.now(); + +} diff --git a/server/src/main/java/ru/practicum/shareit/item/dto/CommentResponseCreatedDto.java b/server/src/main/java/ru/practicum/shareit/item/dto/CommentResponseCreatedDto.java new file mode 100644 index 0000000..5e37d63 --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/item/dto/CommentResponseCreatedDto.java @@ -0,0 +1,21 @@ +package ru.practicum.shareit.item.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CommentResponseCreatedDto { + @JsonProperty("id") + private Long commentId; + + @JsonProperty("text") + private String text; + + private String authorName; + + private Boolean created = true; +} diff --git a/server/src/main/java/ru/practicum/shareit/item/dto/CommentResponseDto.java b/server/src/main/java/ru/practicum/shareit/item/dto/CommentResponseDto.java new file mode 100644 index 0000000..af164d7 --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/item/dto/CommentResponseDto.java @@ -0,0 +1,21 @@ +package ru.practicum.shareit.item.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import ru.practicum.shareit.user.dto.UserAuthorDto; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CommentResponseDto { + + @JsonProperty("id") + private Long commentId; + + @JsonProperty("text") + private String text; + + private UserAuthorDto author; +} diff --git a/server/src/main/java/ru/practicum/shareit/item/dto/ItemBookerDto.java b/server/src/main/java/ru/practicum/shareit/item/dto/ItemBookerDto.java new file mode 100644 index 0000000..28d23ca --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/item/dto/ItemBookerDto.java @@ -0,0 +1,18 @@ +package ru.practicum.shareit.item.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ItemBookerDto { + + @JsonProperty("id") + private Long itemId; + + @JsonProperty("name") + private String itemName; +} diff --git a/server/src/main/java/ru/practicum/shareit/item/dto/ItemRequestDto.java b/server/src/main/java/ru/practicum/shareit/item/dto/ItemRequestDto.java new file mode 100644 index 0000000..d2a9880 --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/item/dto/ItemRequestDto.java @@ -0,0 +1,26 @@ +package ru.practicum.shareit.item.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ItemRequestDto { + @JsonProperty("id") + private Long itemId; + + @JsonProperty("name") + private String itemName; + + @JsonProperty("description") + private String itemDescription; + + @JsonProperty("available") + private Boolean isAvailable; + + private Long requestId; + +} diff --git a/server/src/main/java/ru/practicum/shareit/item/dto/ItemResponseDto.java b/server/src/main/java/ru/practicum/shareit/item/dto/ItemResponseDto.java new file mode 100644 index 0000000..dfec0b2 --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/item/dto/ItemResponseDto.java @@ -0,0 +1,29 @@ +package ru.practicum.shareit.item.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ItemResponseDto { + + @JsonProperty("id") + private Long itemId; + + @JsonProperty("name") + private String itemName; + + @JsonProperty("description") + private String itemDescription; + + @JsonProperty("available") + private Boolean isAvailable; + + @JsonProperty("userId") + private Long ownerId; + + private Long requestId; +} diff --git a/server/src/main/java/ru/practicum/shareit/item/dto/ItemResponseDtoWithComments.java b/server/src/main/java/ru/practicum/shareit/item/dto/ItemResponseDtoWithComments.java new file mode 100644 index 0000000..5d8009a --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/item/dto/ItemResponseDtoWithComments.java @@ -0,0 +1,38 @@ +package ru.practicum.shareit.item.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import ru.practicum.shareit.booking.dto.BookingResponseDto; + +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ItemResponseDtoWithComments { + + @JsonProperty("id") + private Long itemId; + + @JsonProperty("name") + private String itemName; + + @JsonProperty("description") + private String itemDescription; + + @JsonProperty("available") + private Boolean isAvailable; + + @JsonProperty("userId") + private Long ownerId; + + private Long requestId; + + private BookingResponseDto lastBooking; + + private BookingResponseDto nextBooking; + + private List comments; +} diff --git a/src/main/java/ru/practicum/shareit/item/interfaces/CommentRepository.java b/server/src/main/java/ru/practicum/shareit/item/interfaces/CommentRepository.java similarity index 100% rename from src/main/java/ru/practicum/shareit/item/interfaces/CommentRepository.java rename to server/src/main/java/ru/practicum/shareit/item/interfaces/CommentRepository.java diff --git a/src/main/java/ru/practicum/shareit/item/interfaces/ItemRepository.java b/server/src/main/java/ru/practicum/shareit/item/interfaces/ItemRepository.java similarity index 100% rename from src/main/java/ru/practicum/shareit/item/interfaces/ItemRepository.java rename to server/src/main/java/ru/practicum/shareit/item/interfaces/ItemRepository.java diff --git a/src/main/java/ru/practicum/shareit/item/interfaces/ItemServiceInterface.java b/server/src/main/java/ru/practicum/shareit/item/interfaces/ItemServiceInterface.java similarity index 100% rename from src/main/java/ru/practicum/shareit/item/interfaces/ItemServiceInterface.java rename to server/src/main/java/ru/practicum/shareit/item/interfaces/ItemServiceInterface.java diff --git a/src/main/java/ru/practicum/shareit/item/interfaces/ItemStorageInterface.java b/server/src/main/java/ru/practicum/shareit/item/interfaces/ItemStorageInterface.java similarity index 100% rename from src/main/java/ru/practicum/shareit/item/interfaces/ItemStorageInterface.java rename to server/src/main/java/ru/practicum/shareit/item/interfaces/ItemStorageInterface.java diff --git a/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java b/server/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java similarity index 100% rename from src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java rename to server/src/main/java/ru/practicum/shareit/item/mapper/CommentMapper.java diff --git a/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java b/server/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java similarity index 100% rename from src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java rename to server/src/main/java/ru/practicum/shareit/item/mapper/ItemMapper.java diff --git a/src/main/java/ru/practicum/shareit/item/model/Comment.java b/server/src/main/java/ru/practicum/shareit/item/model/Comment.java similarity index 100% rename from src/main/java/ru/practicum/shareit/item/model/Comment.java rename to server/src/main/java/ru/practicum/shareit/item/model/Comment.java diff --git a/src/main/java/ru/practicum/shareit/item/model/Item.java b/server/src/main/java/ru/practicum/shareit/item/model/Item.java similarity index 100% rename from src/main/java/ru/practicum/shareit/item/model/Item.java rename to server/src/main/java/ru/practicum/shareit/item/model/Item.java diff --git a/src/main/java/ru/practicum/shareit/request/RequestController.java b/server/src/main/java/ru/practicum/shareit/request/RequestController.java similarity index 91% rename from src/main/java/ru/practicum/shareit/request/RequestController.java rename to server/src/main/java/ru/practicum/shareit/request/RequestController.java index 817b803..eb712aa 100644 --- a/src/main/java/ru/practicum/shareit/request/RequestController.java +++ b/server/src/main/java/ru/practicum/shareit/request/RequestController.java @@ -7,6 +7,7 @@ import ru.practicum.shareit.request.dto.RequestOutputWithItemsDto; import ru.practicum.shareit.request.interfaces.RequestServiceInterface; +import java.util.Collection; import java.util.List; @@ -24,7 +25,7 @@ public RequestOutputDto addRequest(@RequestBody RequestInputDto requestInputDto, } @GetMapping - public List getRequestByUser(@RequestHeader(USER_ID) Long userId) { + public Collection getRequestByUser(@RequestHeader(USER_ID) Long userId) { return requestService.getRequestByUser(userId); } diff --git a/src/main/java/ru/practicum/shareit/request/RequestServiceImpl.java b/server/src/main/java/ru/practicum/shareit/request/RequestServiceImpl.java similarity index 91% rename from src/main/java/ru/practicum/shareit/request/RequestServiceImpl.java rename to server/src/main/java/ru/practicum/shareit/request/RequestServiceImpl.java index 8dc8c0e..c19ce0b 100644 --- a/src/main/java/ru/practicum/shareit/request/RequestServiceImpl.java +++ b/server/src/main/java/ru/practicum/shareit/request/RequestServiceImpl.java @@ -2,6 +2,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import ru.practicum.shareit.exception.NotFoundException; import ru.practicum.shareit.item.dto.ItemResponseDto; import ru.practicum.shareit.item.interfaces.ItemRepository; import ru.practicum.shareit.item.mapper.ItemMapper; @@ -31,7 +32,7 @@ public class RequestServiceImpl implements RequestServiceInterface { @Override public RequestOutputDto addItemRequest(RequestInputDto requestDto, Long userId) { User user = userRepository.findById(userId) - .orElseThrow(() -> new RuntimeException("User not found")); + .orElseThrow(() -> new NotFoundException("User not found")); ItemRequest itemRequest = requestMapper.toRequest(requestDto); itemRequest.setRequester(user); @@ -41,7 +42,7 @@ public RequestOutputDto addItemRequest(RequestInputDto requestDto, Long userId) @Override public List getRequestByUser(Long userId) { User user = userRepository.findById(userId) - .orElseThrow(() -> new RuntimeException("User not found")); + .orElseThrow(() -> new NotFoundException("User not found")); List requests = requestRepository.getRequestByRequester_UserId(userId); return requestRepository.getRequestByRequester_UserId(userId).stream() @@ -63,7 +64,7 @@ public List getAllRequests() { @Override public RequestOutputWithItemsDto getRequestById(Long requestId) { ItemRequest itemRequest = requestRepository.getRequestByItemRequestId(requestId) - .orElseThrow(() -> new RuntimeException("Request not found")); + .orElseThrow(() -> new NotFoundException("Request not found")); Collection items = itemRepository.getItemsByItemRequest_ItemRequestId(requestId).stream() .map(itemMapper::toItemResponseDto) diff --git a/server/src/main/java/ru/practicum/shareit/request/dto/RequestInputDto.java b/server/src/main/java/ru/practicum/shareit/request/dto/RequestInputDto.java new file mode 100644 index 0000000..658010d --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/request/dto/RequestInputDto.java @@ -0,0 +1,21 @@ +package ru.practicum.shareit.request.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class RequestInputDto { + @JsonProperty("id") + private Long itemRequestId; + + @JsonProperty("description") + private String requestDescription; + + private LocalDateTime requestDate = LocalDateTime.now(); +} diff --git a/server/src/main/java/ru/practicum/shareit/request/dto/RequestOutputDto.java b/server/src/main/java/ru/practicum/shareit/request/dto/RequestOutputDto.java new file mode 100644 index 0000000..711abeb --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/request/dto/RequestOutputDto.java @@ -0,0 +1,25 @@ +package ru.practicum.shareit.request.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import ru.practicum.shareit.user.dto.UserBookingDto; + +import java.time.LocalDateTime; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class RequestOutputDto { + @JsonProperty("id") + private Long itemRequestId; + + @JsonProperty("description") + private String requestDescription; + + private UserBookingDto requester; + + @JsonProperty("created") + private LocalDateTime requestDate; +} diff --git a/server/src/main/java/ru/practicum/shareit/request/dto/RequestOutputWithItemsDto.java b/server/src/main/java/ru/practicum/shareit/request/dto/RequestOutputWithItemsDto.java new file mode 100644 index 0000000..98d8d0b --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/request/dto/RequestOutputWithItemsDto.java @@ -0,0 +1,30 @@ +package ru.practicum.shareit.request.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import ru.practicum.shareit.item.dto.ItemResponseDto; +import ru.practicum.shareit.user.dto.UserBookingDto; + +import java.time.LocalDateTime; +import java.util.Collection; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class RequestOutputWithItemsDto { + @JsonProperty("id") + private Long itemRequestId; + + @JsonProperty("description") + private String requestDescription; + + private UserBookingDto requester; + + @JsonProperty("created") + private LocalDateTime requestDate; + + @JsonProperty("items") + Collection items; +} diff --git a/src/main/java/ru/practicum/shareit/request/interfaces/RequestRepository.java b/server/src/main/java/ru/practicum/shareit/request/interfaces/RequestRepository.java similarity index 100% rename from src/main/java/ru/practicum/shareit/request/interfaces/RequestRepository.java rename to server/src/main/java/ru/practicum/shareit/request/interfaces/RequestRepository.java diff --git a/src/main/java/ru/practicum/shareit/request/interfaces/RequestServiceInterface.java b/server/src/main/java/ru/practicum/shareit/request/interfaces/RequestServiceInterface.java similarity index 100% rename from src/main/java/ru/practicum/shareit/request/interfaces/RequestServiceInterface.java rename to server/src/main/java/ru/practicum/shareit/request/interfaces/RequestServiceInterface.java diff --git a/src/main/java/ru/practicum/shareit/request/mapper/RequestMapper.java b/server/src/main/java/ru/practicum/shareit/request/mapper/RequestMapper.java similarity index 100% rename from src/main/java/ru/practicum/shareit/request/mapper/RequestMapper.java rename to server/src/main/java/ru/practicum/shareit/request/mapper/RequestMapper.java diff --git a/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java b/server/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java similarity index 100% rename from src/main/java/ru/practicum/shareit/request/model/ItemRequest.java rename to server/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java diff --git a/src/main/java/ru/practicum/shareit/user/UserController.java b/server/src/main/java/ru/practicum/shareit/user/UserController.java similarity index 83% rename from src/main/java/ru/practicum/shareit/user/UserController.java rename to server/src/main/java/ru/practicum/shareit/user/UserController.java index 0289b90..4b95fe5 100644 --- a/src/main/java/ru/practicum/shareit/user/UserController.java +++ b/server/src/main/java/ru/practicum/shareit/user/UserController.java @@ -1,6 +1,5 @@ package ru.practicum.shareit.user; -import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -15,7 +14,7 @@ public class UserController { private final UserServiceImpl userService; @PostMapping - public UserResponseDto createUser(@Valid @RequestBody UserRequestDto user) { + public UserResponseDto createUser(@RequestBody UserRequestDto user) { return userService.createUser(user); } @@ -30,12 +29,12 @@ public UserResponseDto updateUser(@PathVariable long id, @RequestBody UserReques } @DeleteMapping("/{id}") - public void deleteUser(@PathVariable long id) { + public void deleteAllUsers(@PathVariable long id) { userService.deleteUser(id); } @DeleteMapping - public void deleteUser() { + public void deleteAllUsers() { userService.deleteAllUsers(); } diff --git a/src/main/java/ru/practicum/shareit/user/UserServiceImpl.java b/server/src/main/java/ru/practicum/shareit/user/UserServiceImpl.java similarity index 100% rename from src/main/java/ru/practicum/shareit/user/UserServiceImpl.java rename to server/src/main/java/ru/practicum/shareit/user/UserServiceImpl.java diff --git a/server/src/main/java/ru/practicum/shareit/user/dto/UserAuthorDto.java b/server/src/main/java/ru/practicum/shareit/user/dto/UserAuthorDto.java new file mode 100644 index 0000000..3ad9b9a --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/user/dto/UserAuthorDto.java @@ -0,0 +1,18 @@ +package ru.practicum.shareit.user.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UserAuthorDto { + + @JsonProperty("id") + private Long userId; + + @JsonProperty("authorName") + private String userName; +} diff --git a/src/main/java/ru/practicum/shareit/user/dto/UserBookingDto.java b/server/src/main/java/ru/practicum/shareit/user/dto/UserBookingDto.java similarity index 85% rename from src/main/java/ru/practicum/shareit/user/dto/UserBookingDto.java rename to server/src/main/java/ru/practicum/shareit/user/dto/UserBookingDto.java index ef634fa..bffdc8f 100644 --- a/src/main/java/ru/practicum/shareit/user/dto/UserBookingDto.java +++ b/server/src/main/java/ru/practicum/shareit/user/dto/UserBookingDto.java @@ -1,7 +1,6 @@ package ru.practicum.shareit.user.dto; import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -10,7 +9,7 @@ @AllArgsConstructor @NoArgsConstructor public class UserBookingDto { - @NotNull + @JsonProperty("id") private Long userId; diff --git a/server/src/main/java/ru/practicum/shareit/user/dto/UserRequestDto.java b/server/src/main/java/ru/practicum/shareit/user/dto/UserRequestDto.java new file mode 100644 index 0000000..1cdead7 --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/user/dto/UserRequestDto.java @@ -0,0 +1,22 @@ +package ru.practicum.shareit.user.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class UserRequestDto { + + @JsonProperty("id") + private Long userId; + + + @JsonProperty("name") + private String userName; + + @JsonProperty("email") + private String userEmail; +} diff --git a/server/src/main/java/ru/practicum/shareit/user/dto/UserResponseDto.java b/server/src/main/java/ru/practicum/shareit/user/dto/UserResponseDto.java new file mode 100644 index 0000000..c03b139 --- /dev/null +++ b/server/src/main/java/ru/practicum/shareit/user/dto/UserResponseDto.java @@ -0,0 +1,21 @@ +package ru.practicum.shareit.user.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class UserResponseDto { + + @JsonProperty("id") + private Long userId; + + @JsonProperty("name") + private String userName; + + @JsonProperty("email") + private String userEmail; +} diff --git a/src/main/java/ru/practicum/shareit/user/interfaces/UserRepository.java b/server/src/main/java/ru/practicum/shareit/user/interfaces/UserRepository.java similarity index 100% rename from src/main/java/ru/practicum/shareit/user/interfaces/UserRepository.java rename to server/src/main/java/ru/practicum/shareit/user/interfaces/UserRepository.java diff --git a/src/main/java/ru/practicum/shareit/user/interfaces/UserServiceInterface.java b/server/src/main/java/ru/practicum/shareit/user/interfaces/UserServiceInterface.java similarity index 99% rename from src/main/java/ru/practicum/shareit/user/interfaces/UserServiceInterface.java rename to server/src/main/java/ru/practicum/shareit/user/interfaces/UserServiceInterface.java index 1ca30dc..4dca5a4 100644 --- a/src/main/java/ru/practicum/shareit/user/interfaces/UserServiceInterface.java +++ b/server/src/main/java/ru/practicum/shareit/user/interfaces/UserServiceInterface.java @@ -3,6 +3,7 @@ import ru.practicum.shareit.user.dto.UserRequestDto; import ru.practicum.shareit.user.dto.UserResponseDto; + public interface UserServiceInterface { UserResponseDto createUser(UserRequestDto user); @@ -13,4 +14,5 @@ public interface UserServiceInterface { void deleteUser(Long userId); void deleteAllUsers(); + } diff --git a/src/main/java/ru/practicum/shareit/user/mapper/UserMapper.java b/server/src/main/java/ru/practicum/shareit/user/mapper/UserMapper.java similarity index 100% rename from src/main/java/ru/practicum/shareit/user/mapper/UserMapper.java rename to server/src/main/java/ru/practicum/shareit/user/mapper/UserMapper.java diff --git a/src/main/java/ru/practicum/shareit/user/model/User.java b/server/src/main/java/ru/practicum/shareit/user/model/User.java similarity index 100% rename from src/main/java/ru/practicum/shareit/user/model/User.java rename to server/src/main/java/ru/practicum/shareit/user/model/User.java diff --git a/server/src/main/resources/application-test.yml b/server/src/main/resources/application-test.yml new file mode 100644 index 0000000..c02e1e5 --- /dev/null +++ b/server/src/main/resources/application-test.yml @@ -0,0 +1,15 @@ +spring: + config: + activate: + on-profile: test + jpa: + generate-ddl: false + hibernate.ddl-auto: none + datasource: + url: jdbc:h2:mem:testdb;MODE=PostgreSQL + driverClassName: org.h2.Driver + username: user + password: 12345 + sql: + init: + mode: always diff --git a/server/src/main/resources/application.yml b/server/src/main/resources/application.yml new file mode 100644 index 0000000..70ed292 --- /dev/null +++ b/server/src/main/resources/application.yml @@ -0,0 +1,25 @@ +server.port: 9090 + +spring: + jpa: + hibernate.ddl-auto: none + properties.hibernate.format_sql: true + + sql: + init: + mode: always + datasource: + driverClassName: org.postgresql.Driver + url: jdbc:postgresql://localhost:5432/postgres + username: user + password: 12345 +logging: + level: + org: + springframework: + orm.jpa: INFO + transaction: INFO + interceptor: TRACE + JpaTransactionManager: DEBUG + + diff --git a/src/main/resources/schema.sql b/server/src/main/resources/schema.sql similarity index 81% rename from src/main/resources/schema.sql rename to server/src/main/resources/schema.sql index 6ce8657..a7a4013 100644 --- a/src/main/resources/schema.sql +++ b/server/src/main/resources/schema.sql @@ -1,11 +1,11 @@ CREATE TABLE IF NOT EXISTS users ( - user_id BIGSERIAL PRIMARY KEY, + user_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, user_name CHARACTER VARYING(255) NOT NULL, user_email CHARACTER VARYING(500) NOT NULL UNIQUE ); CREATE TABLE IF NOT EXISTS items ( - item_id BIGSERIAL PRIMARY KEY, + item_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, item_name CHARACTER VARYING(255) NOT NULL, item_description CHARACTER VARYING(150) NOT NULL, is_available BOOLEAN NOT NULL, @@ -15,7 +15,7 @@ CREATE TABLE IF NOT EXISTS items ( ); CREATE TABLE IF NOT EXISTS comments ( - comment_id BIGSERIAL PRIMARY KEY, + comment_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, text CHARACTER VARYING(2000) NOT NULL, item_id BIGINT NOT NULL, author_id BIGINT NOT NULL, @@ -24,7 +24,7 @@ CREATE TABLE IF NOT EXISTS comments ( ); CREATE TABLE IF NOT EXISTS bookings ( - booking_id BIGSERIAL PRIMARY KEY, + booking_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, start_date TIMESTAMP WITHOUT TIME ZONE NOT NULL, end_date TIMESTAMP WITHOUT TIME ZONE NOT NULL, item_id BIGINT NOT NULL, @@ -35,7 +35,7 @@ CREATE TABLE IF NOT EXISTS bookings ( ); CREATE TABLE IF NOT EXISTS requests ( - request_id BIGSERIAL PRIMARY KEY, + request_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, requester_id BIGINT NOT NULL, description CHARACTER VARYING (200) NOT NULL, request_date TIMESTAMP WITHOUT TIME ZONE, diff --git a/server/src/main/resources/test-data.sql b/server/src/main/resources/test-data.sql new file mode 100644 index 0000000..4739d1a --- /dev/null +++ b/server/src/main/resources/test-data.sql @@ -0,0 +1,83 @@ +CREATE TABLE IF NOT EXISTS users ( + user_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + user_name VARCHAR(255) NOT NULL, + user_email VARCHAR(500) + +); + +CREATE TABLE IF NOT EXISTS items ( + item_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + item_name VARCHAR(255) NOT NULL, + item_description VARCHAR(150) NOT NULL, + is_available BOOLEAN NOT NULL, + owner_id BIGINT NOT NULL, + request_id BIGINT, + CONSTRAINT fk_items_to_users FOREIGN KEY(owner_id) REFERENCES users(user_id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS comments ( + comment_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + text VARCHAR(2000) NOT NULL, + item_id BIGINT NOT NULL, + author_id BIGINT NOT NULL, + CONSTRAINT fk_comments_to_users FOREIGN KEY (author_id) REFERENCES users (user_id) ON DELETE CASCADE, + CONSTRAINT fk_comments_to_items FOREIGN KEY (item_id) REFERENCES items(item_id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS bookings ( + booking_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + 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 (50), + FOREIGN KEY (item_id) REFERENCES items (item_id) ON DELETE CASCADE, + FOREIGN KEY (booker_id) REFERENCES users (user_id) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS requests ( + request_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + requester_id BIGINT NOT NULL, + description VARCHAR (200) NOT NULL, + request_date TIMESTAMP WITHOUT TIME ZONE, + FOREIGN KEY (requester_id) REFERENCES users (user_id) ON DELETE CASCADE +); + +INSERT INTO users (user_name, user_email) +VALUES ('TestUser1', 'user1@mail.ru'); + +INSERT INTO users (user_name, user_email) +VALUES ('TestUser2', 'user2@mail.ru'); + +INSERT INTO requests (requester_id, description, request_date) +VALUES ( 1, 'Test request description1', '2025-07-07T10:15:25'); + +INSERT INTO requests (requester_id, description, request_date) +VALUES (2, 'Test request description2', '2025-08-08T15:10:20'); + +INSERT INTO items (item_name, item_description, is_available, owner_id, request_id) +VALUES ('testItem1', 'test description1', 'false', 1, 2); + +INSERT INTO items (item_name, item_description, is_available, owner_id, request_id) +VALUES ('testItem2', 'test description2', 'true', 2, 2); + +INSERT INTO bookings (start_date, end_date, item_id, booker_id, status) +VALUES ('2025-07-07T14:40:35', '2025-07-25T18:12:43', 1, 1, 'WAITING'); + +INSERT INTO bookings (start_date, end_date, item_id, booker_id, status) +VALUES ('2025-08-08T15:45:30', '2025-08-18T12:10:40', 2, 2, 'APPROVED'); + +INSERT INTO bookings (start_date, end_date, item_id, booker_id, status) +VALUES ('2025-03-07T14:40:35', '2025-05-25T18:12:43', 1, 1, 'WAITING'); + +INSERT INTO bookings (start_date, end_date, item_id, booker_id, status) +VALUES ('2025-09-07T14:40:35', '2025-10-25T18:12:43', 1, 1, 'WAITING'); + +INSERT INTO bookings (start_date, end_date, item_id, booker_id, status) +VALUES ('2025-05-07T14:40:35', '2025-10-25T18:12:43', 1, 1, 'REJECTED'); + +INSERT INTO bookings (start_date, end_date, item_id, booker_id, status) +VALUES ('2025-02-07T14:40:35', '2025-02-25T18:12:43', 2, 1, 'APPROVED'); + +INSERT INTO comments (text, item_id, author_id) +VALUES ('Test comment text1', 1, 1); diff --git a/src/test/java/ru/practicum/shareit/ShareItTests.java b/server/src/test/java/ru/practicum/shareit/ShareItTests.java similarity index 100% rename from src/test/java/ru/practicum/shareit/ShareItTests.java rename to server/src/test/java/ru/practicum/shareit/ShareItTests.java diff --git a/server/src/test/java/ru/practicum/shareit/TestData.java b/server/src/test/java/ru/practicum/shareit/TestData.java new file mode 100644 index 0000000..b8578f6 --- /dev/null +++ b/server/src/test/java/ru/practicum/shareit/TestData.java @@ -0,0 +1,142 @@ +package ru.practicum.shareit; + +import ru.practicum.shareit.booking.dto.BookingRequestDto; +import ru.practicum.shareit.booking.dto.BookingResponseDto; +import ru.practicum.shareit.booking.model.Booking; +import ru.practicum.shareit.booking.model.BookingStatus; +import ru.practicum.shareit.item.dto.*; +import ru.practicum.shareit.item.model.Comment; +import ru.practicum.shareit.item.model.Item; +import ru.practicum.shareit.request.dto.RequestInputDto; +import ru.practicum.shareit.request.dto.RequestOutputDto; +import ru.practicum.shareit.request.dto.RequestOutputWithItemsDto; +import ru.practicum.shareit.request.model.ItemRequest; +import ru.practicum.shareit.user.dto.UserAuthorDto; +import ru.practicum.shareit.user.dto.UserBookingDto; +import ru.practicum.shareit.user.dto.UserRequestDto; +import ru.practicum.shareit.user.dto.UserResponseDto; +import ru.practicum.shareit.user.model.User; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + + +public class TestData { + public static User user1 = new User(1L, "TestUser1", "user1@mail.ru"); + public static UserBookingDto userBookingDto1 = new UserBookingDto(1L, "TestUser1"); + public static UserAuthorDto userAuthorDto1 = new UserAuthorDto(1L, "TestUser1"); + public static UserRequestDto userRequestDto1 = new UserRequestDto(1L, "TestUser1", "user1@mail.ru"); + public static UserResponseDto userResponseDto1 = new UserResponseDto(1L, "TestUser1", "user1@mail.ru"); + + + public static User user2 = new User(2L, "TestUser2", "user2@mail.ru"); + public static UserBookingDto userBookingDto2 = new UserBookingDto(2L, "TestUser2"); + public static UserAuthorDto userAuthorDto2 = new UserAuthorDto(2L, "TestUser2"); + public static UserRequestDto userRequestDto2 = new UserRequestDto(2L, "TestUser2", "user2@mail.ru"); + public static UserResponseDto userResponseDto2 = new UserResponseDto(2L, "TestUser2", "user2@mail.ru"); + + + public static User user3 = new User(3L, "TestUser3", "user3@mail.ru"); + + + public static ItemRequest request1 = new ItemRequest(1L, "Test request description1", user1, + LocalDateTime.of(2025, 7, 7, 10, 15, 25)); + public static RequestInputDto requestInputDto1 = new RequestInputDto(1L, "Test request description1", + LocalDateTime.of(2025, 7, 7, 10, 15, 25)); + public static RequestOutputDto requestOutputDto1 = new RequestOutputDto(1L, "Test request description1", userBookingDto1, + LocalDateTime.of(2025, 7, 7, 10, 15, 25)); + public static RequestOutputWithItemsDto requestWithItemsDto1 = new RequestOutputWithItemsDto(1L, + "Test request description1", userBookingDto1, + LocalDateTime.of(2025, 7, 7, 10, 15, 25), new ArrayList<>()); + + + public static ItemRequest request2 = new ItemRequest(2L, "Test request description2", user2, + LocalDateTime.of(2025, 8, 8, 15, 10, 20)); + public static RequestInputDto requestInputDto2 = new RequestInputDto(2L, "Test request description2", + LocalDateTime.of(2025, 8, 8, 15, 10, 20)); + public static RequestOutputDto requestOutputDto2 = new RequestOutputDto(2L, "Test request description2", + userBookingDto2, LocalDateTime.of(2025, 8, 8, 15, 10, 20)); + public static RequestOutputWithItemsDto requestWithItemsDto2 = new RequestOutputWithItemsDto(2L, + "Test request description2", userBookingDto2, + LocalDateTime.of(2025, 8, 8, 15, 10, 20), new ArrayList<>()); + + public static List requests = List.of(requestOutputDto1); + + public static List allRequests = List.of(requestOutputDto1, requestOutputDto2); + + public static Item item1 = new Item(1L, "testItem1", + "test description1", false, user1, request1); + public static ItemRequestDto itemRequestDto1 = new ItemRequestDto(1L, "testItem1", + "test description1", false, request1.getItemRequestId()); + public static ItemBookerDto itemBookerDto1 = new ItemBookerDto(1L, "testItem1"); + public static ItemResponseDto itemResponseDto1 = new ItemResponseDto(1L, "testItem1", + "test description1", false, user1.getUserId(), request1.getItemRequestId()); + public static ItemResponseDtoWithComments itemWithComments1 = new ItemResponseDtoWithComments(1L, "testItem1", + "test description1", false, user1.getUserId(), request1.getItemRequestId(), + new BookingResponseDto(), new BookingResponseDto(), new ArrayList<>()); + + + public static Item item2 = new Item(2L, "testItem2", + "test description2", true, user2, request2); + public static ItemBookerDto itemBookerDto2 = new ItemBookerDto(2L, "testItem2"); + public static ItemResponseDto itemResponseDto2 = new ItemResponseDto(2L, "testItem2", + "test description2", true, user2.getUserId(), request2.getItemRequestId()); + public static ItemResponseDtoWithComments itemWithComments2 = new ItemResponseDtoWithComments(2L, + "testItem2", "test description2", true, user2.getUserId(), request2.getItemRequestId(), + new BookingResponseDto(), new BookingResponseDto(), new ArrayList<>()); + + public Collection itemsForOwner = List.of(itemResponseDto1); + + public Collection itemsFound = List.of(itemResponseDto2); + + + public static Booking booking1 = new Booking(1L, LocalDateTime.of(2025, 7, 7, 14, 40, 35), + LocalDateTime.of(2025, 7, 25, 18, 12, 43), item1, user1, BookingStatus.WAITING); + public static BookingResponseDto responseBooking1 = new BookingResponseDto(1L, LocalDateTime.of(2025, 7, 7, 14, 40, 35), + LocalDateTime.of(2025, 7, 15, 18, 12, 43), itemBookerDto1, userBookingDto1, BookingStatus.WAITING); + public static BookingRequestDto bookingRequestDto1 = new BookingRequestDto(1L, LocalDateTime.of(2025, 7, 7, 14, 40, 35), + LocalDateTime.of(2025, 7, 15, 18, 12, 43), itemBookerDto1.getItemId(), userBookingDto1.getUserId(), BookingStatus.WAITING); + + + public static Booking booking2 = new Booking(2L, LocalDateTime.of(2025, 8, 8, 15, 45, 30), + LocalDateTime.of(2025, 8, 18, 12, 10, 40), item2, user2, BookingStatus.APPROVED); + public static BookingResponseDto responseBooking2 = new BookingResponseDto(2L, LocalDateTime.of(2025, 8, 8, 15, 45, 30), + LocalDateTime.of(2025, 8, 18, 12, 10, 40), itemBookerDto2, userBookingDto2, BookingStatus.APPROVED); + public static BookingRequestDto bookingRequestDto2 = new BookingRequestDto(2L, LocalDateTime.of(2025, 8, 8, 15, 45, 30), + LocalDateTime.of(2025, 8, 18, 12, 10, 40), itemBookerDto2.getItemId(), userBookingDto2.getUserId(), BookingStatus.APPROVED); + + + public static Booking bookingPast = new Booking(3L, LocalDateTime.of(2025, 3, 7, 14, 40, 35), + LocalDateTime.of(2025, 5, 25, 18, 12, 43), item1, user1, BookingStatus.WAITING); + public static BookingResponseDto responseBooking3 = new BookingResponseDto(3L, LocalDateTime.of(2025, 3, 7, 14, 40, 35), + LocalDateTime.of(2025, 5, 25, 18, 12, 43), itemBookerDto1, userBookingDto1, BookingStatus.WAITING); + + public static Booking bookingFuture = new Booking(4L, LocalDateTime.of(2025, 9, 7, 14, 40, 35), + LocalDateTime.of(2025, 10, 25, 18, 12, 43), item1, user1, BookingStatus.WAITING); + public static BookingResponseDto responseBooking4 = new BookingResponseDto(4L, LocalDateTime.of(2025, 9, 7, 14, 40, 35), + LocalDateTime.of(2025, 10, 25, 18, 12, 43), itemBookerDto1, userBookingDto1, BookingStatus.WAITING); + + public static Booking bookingRejected = new Booking(5L, LocalDateTime.of(2025, 5, 7, 14, 40, 35), + LocalDateTime.of(2025, 10, 25, 18, 12, 43), item1, user1, BookingStatus.REJECTED); + public static BookingResponseDto responseBooking5 = new BookingResponseDto(5L, LocalDateTime.of(2025, 5, 7, 14, 40, 35), + LocalDateTime.of(2025, 10, 25, 18, 12, 43), itemBookerDto1, userBookingDto1, BookingStatus.REJECTED); + + public static BookingRequestDto bookingRequestDto5 = new BookingRequestDto(3L, LocalDateTime.of(2025, 2, 7, 14, 40, 35), + LocalDateTime.of(2025, 2, 25, 18, 12, 43), itemBookerDto2.getItemId(), userBookingDto1.getUserId(), BookingStatus.APPROVED); + + public Collection bookings = Arrays.asList(responseBooking1, responseBooking2, responseBooking3, responseBooking4, responseBooking5); + + public Collection bookingsForOwner = Arrays.asList(responseBooking1, responseBooking3, responseBooking4, responseBooking5); + + public static Comment comment1 = new Comment(1L, "Test comment text1", user1, item1); + public static CommentResponseDto commentResponseDto1 = new CommentResponseDto(1L, "Test comment text1", userAuthorDto1); + public static CommentResponseCreatedDto createdDto = new CommentResponseCreatedDto(1L, "Test comment text1", userAuthorDto1.getUserName(), true); + + +} + + + diff --git a/server/src/test/java/ru/practicum/shareit/controllersTest/BookingControllerTest.java b/server/src/test/java/ru/practicum/shareit/controllersTest/BookingControllerTest.java new file mode 100644 index 0000000..c0c0bf2 --- /dev/null +++ b/server/src/test/java/ru/practicum/shareit/controllersTest/BookingControllerTest.java @@ -0,0 +1,162 @@ +package ru.practicum.shareit.controllersTest; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.junit.jupiter.api.BeforeEach; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import ru.practicum.shareit.TestData; +import ru.practicum.shareit.booking.BookingController; + +import ru.practicum.shareit.booking.BookingServiceImpl; +import ru.practicum.shareit.booking.dto.BookingResponseDto; +import ru.practicum.shareit.booking.model.BookingStatus; + +import java.nio.charset.StandardCharsets; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +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; + + +@ExtendWith(MockitoExtension.class) +public class BookingControllerTest extends TestData { + @Mock + private BookingServiceImpl bookingService; + + @InjectMocks + private BookingController bookingController; + + private MockMvc mvc; + private final ObjectMapper mapper = JsonMapper.builder() + .addModule(new JavaTimeModule()) + .build(); + + @BeforeEach + void setUp() { + mvc = MockMvcBuilders + .standaloneSetup(bookingController) + .build(); + } + + @Test + void createUserTest() throws Exception { + when(bookingService.addBooking(any(), anyLong())) + .thenReturn(responseBooking1); + + MvcResult result = mvc.perform(post("/bookings") + .header("X-Sharer-User-Id", "1") + .content(mapper.writeValueAsString(bookingRequestDto1)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); + + String body = result.getResponse().getContentAsString(); + BookingResponseDto bookingResponseDto = mapper.readValue(body, BookingResponseDto.class); + + assertAll(() -> { + assertNotNull(bookingResponseDto); + assertEquals(bookingRequestDto1.getStart(), bookingResponseDto.getStart()); + assertEquals(bookingRequestDto1.getEnd(), bookingResponseDto.getEnd()); + assertEquals(bookingRequestDto1.getBookerId(), bookingResponseDto.getBooker().getUserId()); + assertEquals(bookingRequestDto1.getItemId(), bookingResponseDto.getItem().getItemId()); + assertEquals(bookingRequestDto1.getStatus(), bookingResponseDto.getStatus()); + }); + + } + + @Test + void bookingApprovedTest() throws Exception { + when(bookingService.bookingApprove(anyLong(), anyLong(), anyBoolean())) + .thenReturn(responseBooking2); + + MvcResult result = mvc.perform(patch("/bookings/2?approved=true") + .header("X-Sharer-User-Id", "2") + .content(mapper.writeValueAsString(bookingRequestDto1)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); + + String body = result.getResponse().getContentAsString(); + BookingResponseDto bookingResponseDto = mapper.readValue(body, BookingResponseDto.class); + + assertAll(() -> { + assertNotNull(bookingResponseDto); + assertEquals(BookingStatus.APPROVED, bookingResponseDto.getStatus()); + }); + } + + @Test + void getBookingByIdTest() throws Exception { + when(bookingService.getBookingByBookingId(anyLong(), anyLong())) + .thenReturn(responseBooking1); + + MvcResult result = mvc.perform(get("/bookings/1") + .header("X-Sharer-User-Id", "1") + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); + + String body = result.getResponse().getContentAsString(); + BookingResponseDto bookingResponseDto = mapper.readValue(body, BookingResponseDto.class); + + assertAll(() -> { + assertNotNull(bookingResponseDto); + assertEquals(bookingRequestDto1.getBookingId(), bookingResponseDto.getBookingId()); + assertEquals(bookingRequestDto1.getStart(), bookingResponseDto.getStart()); + assertEquals(bookingRequestDto1.getEnd(), bookingResponseDto.getEnd()); + assertEquals(bookingRequestDto1.getBookerId(), bookingResponseDto.getBooker().getUserId()); + assertEquals(bookingRequestDto1.getItemId(), bookingResponseDto.getItem().getItemId()); + assertEquals(bookingRequestDto1.getStatus(), bookingResponseDto.getStatus()); + }); + } + + @Test + void getBookingByUserTest() throws Exception { + + when(bookingService.getBookingsByUser(anyLong(), anyString())) + .thenReturn(bookings); + + mvc.perform(get("/bookings?state=all") + .header("X-Sharer-User-Id", "1") + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.length()").value(5)); + } + + @Test + void getBookingByOwnerTest() throws Exception { + when(bookingService.getBookingsByOwner(anyLong(), anyString())) + .thenReturn(bookingsForOwner); + + mvc.perform(get("/bookings/owner?state=all") + .header("X-Sharer-User-Id", "1") + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.length()").value(4)); + } +} diff --git a/server/src/test/java/ru/practicum/shareit/controllersTest/ItemControllerTest.java b/server/src/test/java/ru/practicum/shareit/controllersTest/ItemControllerTest.java new file mode 100644 index 0000000..73e6ab7 --- /dev/null +++ b/server/src/test/java/ru/practicum/shareit/controllersTest/ItemControllerTest.java @@ -0,0 +1,187 @@ +package ru.practicum.shareit.controllersTest; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import ru.practicum.shareit.TestData; +import ru.practicum.shareit.item.ItemController; +import ru.practicum.shareit.item.ItemServiceImpl; +import ru.practicum.shareit.item.dto.CommentRequestDto; +import ru.practicum.shareit.item.dto.CommentResponseCreatedDto; +import ru.practicum.shareit.item.dto.ItemResponseDto; +import ru.practicum.shareit.item.dto.ItemResponseDtoWithComments; + +import java.nio.charset.StandardCharsets; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.*; +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; + +@ExtendWith(MockitoExtension.class) +public class ItemControllerTest extends TestData { + @Mock + private ItemServiceImpl itemService; + + @InjectMocks + private ItemController itemController; + + private MockMvc mvc; + private final ObjectMapper mapper = JsonMapper.builder() + .addModule(new JavaTimeModule()) + .build(); + + @BeforeEach + void setUp() { + mvc = MockMvcBuilders + .standaloneSetup(itemController) + .build(); + } + + @Test + void createItem() throws Exception { + when(itemService.createItem(any(), anyLong())) + .thenReturn(itemResponseDto1); + + MvcResult result = mvc.perform(post("/items") + .header("X-Sharer-User-Id", "1") + .content(mapper.writeValueAsString(itemRequestDto1)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); + + String body = result.getResponse().getContentAsString(); + ItemResponseDto responseDto = mapper.readValue(body, ItemResponseDto.class); + + assertAll(() -> { + assertNotNull(responseDto); + assertEquals(itemRequestDto1.getItemDescription(), responseDto.getItemDescription()); + assertEquals(itemRequestDto1.getItemName(), responseDto.getItemName()); + assertEquals(itemRequestDto1.getIsAvailable(), responseDto.getIsAvailable()); + assertEquals(itemRequestDto1.getItemId(), responseDto.getItemId()); + assertEquals(itemRequestDto1.getRequestId(), responseDto.getRequestId()); + }); + } + + @Test + void updateItemTest() throws Exception { + ItemResponseDto forUpdate = new ItemResponseDto(); + forUpdate.setItemId(1L); + forUpdate.setRequestId(1L); + forUpdate.setItemName("Test"); + forUpdate.setItemDescription("Test item description"); + forUpdate.setIsAvailable(true); + + when(itemService.updateItem(anyLong(), any(), anyLong())) + .thenReturn(forUpdate); + + MvcResult result = mvc.perform(patch("/items/1") + .header("X-Sharer-User-Id", "1") + .content(mapper.writeValueAsString(itemRequestDto1)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); + + String body = result.getResponse().getContentAsString(); + ItemResponseDto responseDto = mapper.readValue(body, ItemResponseDto.class); + + assertAll(() -> { + assertNotNull(responseDto); + assertEquals(forUpdate.getItemId(), responseDto.getItemId()); + assertEquals(forUpdate.getRequestId(), responseDto.getRequestId()); + assertEquals(forUpdate.getItemName(), responseDto.getItemName()); + assertEquals(forUpdate.getItemDescription(), responseDto.getItemDescription()); + assertEquals(forUpdate.getIsAvailable(), responseDto.getIsAvailable()); + assertEquals(forUpdate.getRequestId(), responseDto.getRequestId()); + }); + } + + @Test + void getItemTest() throws Exception { + when(itemService.getItemById(anyLong(), anyLong())) + .thenReturn(itemWithComments1); + + MvcResult result = mvc.perform(get("/items/1") + .header("X-Sharer-User-Id", "1") + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); + + String body = result.getResponse().getContentAsString(); + ItemResponseDtoWithComments withComments = mapper.readValue(body, ItemResponseDtoWithComments.class); + + assertAll(() -> { + assertNotNull(withComments); + assertThat(withComments).usingRecursiveComparison().isEqualTo(itemWithComments1); + }); + } + + @Test + void getAllItemsForOwnerTest() throws Exception { + when(itemService.getAllItemsForOwner(anyLong())) + .thenReturn(itemsForOwner); + + mvc.perform(get("/items") + .header("X-Sharer-User-Id", "1")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.length()").value(1)); + } + + @Test + void searchItemsTest() throws Exception { + when(itemService.searchByText(anyString())) + .thenReturn(itemsFound); + + mvc.perform(get("/items/search?text=") + .param("text", "testItem2")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.length()").value(1)); + } + + @Test + void addCommentTest() throws Exception { + CommentRequestDto commentRequestDto = new CommentRequestDto(); + commentRequestDto.setText("Test comment text1"); + + when(itemService.addComment(anyLong(), any(), anyLong())) + .thenReturn(createdDto); + + MvcResult result = mvc.perform(post("/items/1/comment") + .header("X-Sharer-User-Id", "1") + .content(mapper.writeValueAsString(commentRequestDto)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); + + String body = result.getResponse().getContentAsString(); + CommentResponseCreatedDto responseDto = mapper.readValue(body, CommentResponseCreatedDto.class); + + assertAll(() -> { + assertNotNull(responseDto); + assertThat(responseDto).usingRecursiveComparison().isEqualTo(createdDto); + }); + + } +} diff --git a/server/src/test/java/ru/practicum/shareit/controllersTest/RequestControllerTest.java b/server/src/test/java/ru/practicum/shareit/controllersTest/RequestControllerTest.java new file mode 100644 index 0000000..5611a33 --- /dev/null +++ b/server/src/test/java/ru/practicum/shareit/controllersTest/RequestControllerTest.java @@ -0,0 +1,117 @@ +package ru.practicum.shareit.controllersTest; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import ru.practicum.shareit.TestData; +import ru.practicum.shareit.request.RequestController; +import ru.practicum.shareit.request.RequestServiceImpl; +import ru.practicum.shareit.request.dto.RequestOutputDto; +import ru.practicum.shareit.request.dto.RequestOutputWithItemsDto; + +import java.nio.charset.StandardCharsets; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +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; + +@ExtendWith(MockitoExtension.class) +public class RequestControllerTest extends TestData { + @Mock + private RequestServiceImpl requestService; + + @InjectMocks + private RequestController controller; + + private MockMvc mvc; + private final ObjectMapper mapper = JsonMapper.builder() + .addModule(new JavaTimeModule()) + .build(); + + @BeforeEach + void setUp() { + mvc = MockMvcBuilders + .standaloneSetup(controller) + .build(); + } + + @Test + void addRequestTest() throws Exception { + when(controller.addRequest(any(), anyLong())) + .thenReturn(requestOutputDto1); + + MvcResult result = mvc.perform(post("/requests") + .header("X-Sharer-User-Id", "1") + .content(mapper.writeValueAsString(requestInputDto1)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); + + String body = result.getResponse().getContentAsString(); + RequestOutputDto responseDto = mapper.readValue(body, RequestOutputDto.class); + + assertAll(() -> { + assertNotNull(responseDto); + assertThat(responseDto).usingRecursiveComparison().isEqualTo(requestOutputDto1); + }); + } + + @Test + void getRequestByUserTest() throws Exception { + when(controller.getRequestByUser(anyLong())) + .thenReturn(requests); + + mvc.perform(get("/requests") + .header("X-Sharer-User-Id", "1")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.length()").value(1)); + } + + @Test + void getAllRequestsTest() throws Exception { + when(controller.getAllRequests()) + .thenReturn(allRequests); + + mvc.perform(get("/requests/all")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.length()").value(2)); + } + + @Test + void getRequestByIdTest() throws Exception { + when(controller.getRequestById(anyLong())) + .thenReturn(requestWithItemsDto1); + + MvcResult result = mvc.perform(get("/requests/1") + .header("X-Sharer-User-Id", "1")) + .andExpect(status().isOk()) + .andReturn(); + + String body = result.getResponse().getContentAsString(); + RequestOutputWithItemsDto responseDto = mapper.readValue(body, RequestOutputWithItemsDto.class); + + assertAll(() -> { + assertNotNull(responseDto); + assertThat(responseDto).usingRecursiveComparison().isEqualTo(requestWithItemsDto1); + }); + } +} diff --git a/server/src/test/java/ru/practicum/shareit/controllersTest/UserControllerTest.java b/server/src/test/java/ru/practicum/shareit/controllersTest/UserControllerTest.java new file mode 100644 index 0000000..fc50c60 --- /dev/null +++ b/server/src/test/java/ru/practicum/shareit/controllersTest/UserControllerTest.java @@ -0,0 +1,131 @@ +package ru.practicum.shareit.controllersTest; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import ru.practicum.shareit.TestData; +import ru.practicum.shareit.user.UserController; +import ru.practicum.shareit.user.UserServiceImpl; + +import org.springframework.http.MediaType; +import ru.practicum.shareit.user.dto.UserResponseDto; + +import java.nio.charset.StandardCharsets; + +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +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; + + +@ExtendWith(MockitoExtension.class) +class UserControllerTest extends TestData { + @Mock + private UserServiceImpl userService; + + @InjectMocks + private UserController controller; + + private final ObjectMapper mapper = new ObjectMapper(); + + private MockMvc mvc; + + + @BeforeEach + void setUp() { + mvc = MockMvcBuilders + .standaloneSetup(controller) + .build(); + } + + @Test + void createUserTest() throws Exception { + when(userService.createUser(any())) + .thenReturn(userResponseDto2); + + mvc.perform(post("/users") + .content(mapper.writeValueAsString(userRequestDto2)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(userResponseDto2.getUserId()), Long.class)) + .andExpect(jsonPath("$.name", is(userResponseDto2.getUserName()), String.class)) + .andExpect(jsonPath("$.email", is(userResponseDto2.getUserEmail()), String.class)); + } + + @Test + void getUserTest() throws Exception { + when(userService.getUserById(any())) + .thenReturn(userResponseDto1); + + mvc.perform(get("/users/1") + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(userResponseDto1.getUserId()), Long.class)) + .andExpect(jsonPath("$.name", is(userResponseDto1.getUserName()), String.class)) + .andExpect(jsonPath("$.email", is(userResponseDto1.getUserEmail()), String.class)); + + } + + @Test + void updateUserTest() throws Exception { + UserResponseDto forUpdate = new UserResponseDto(); + forUpdate.setUserId(1L); + forUpdate.setUserName("UpdatedName"); + forUpdate.setUserEmail("UpdatedEmail@mail.ru"); + + when(userService.updateUser(anyLong(), any())) + .thenReturn(forUpdate); + + MvcResult result = mvc.perform(patch("/users/1") + .content(mapper.writeValueAsString(forUpdate)) + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); + + String responseBody = result.getResponse().getContentAsString(); + UserResponseDto responseDto = mapper.readValue(responseBody, UserResponseDto.class); + assertAll(() -> { + assertNotNull(responseDto); + assertEquals("UpdatedName", responseDto.getUserName()); + assertEquals("UpdatedEmail@mail.ru", responseDto.getUserEmail()); + }); + } + + @Test + void deleteUserTest() throws Exception { + mvc.perform(delete("/users/1") + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + @Test + void getAllUsersTest() throws Exception { + mvc.perform(delete("/users") + .characterEncoding(StandardCharsets.UTF_8) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()); + } +} + + + diff --git a/src/test/java/ru/practicum/shareit/mapperTest/BookingMapperTest.java b/server/src/test/java/ru/practicum/shareit/mapperTest/BookingMapperTest.java similarity index 96% rename from src/test/java/ru/practicum/shareit/mapperTest/BookingMapperTest.java rename to server/src/test/java/ru/practicum/shareit/mapperTest/BookingMapperTest.java index 5744f96..83ee4ed 100644 --- a/src/test/java/ru/practicum/shareit/mapperTest/BookingMapperTest.java +++ b/server/src/test/java/ru/practicum/shareit/mapperTest/BookingMapperTest.java @@ -11,12 +11,12 @@ import ru.practicum.shareit.item.dto.ItemBookerDto; import ru.practicum.shareit.item.mapper.ItemMapper; import ru.practicum.shareit.item.model.Item; -import ru.practicum.shareit.request.ItemRequest; +import ru.practicum.shareit.request.model.ItemRequest; import ru.practicum.shareit.user.dto.UserBookingDto; import ru.practicum.shareit.user.mapper.UserMapper; import ru.practicum.shareit.user.model.User; -import java.time.LocalDate; + import java.time.LocalDateTime; import static org.junit.jupiter.api.Assertions.assertAll; @@ -36,7 +36,7 @@ public class BookingMapperTest { User user = new User(1L, "testName1", "test1@test.com"); ItemRequest itemRequest = new ItemRequest(1L, "testDescription1", - 1L, LocalDate.of(2025, 6, 25)); + user, LocalDateTime.of(2025, 6, 25, 15, 25)); Item item = new Item(1L, "TestName1", "Test description1", true, user, itemRequest); LocalDateTime startTime = LocalDateTime.of(2025, 6, 25, 12, 30); diff --git a/src/test/java/ru/practicum/shareit/mapperTest/CommentMapperTest.java b/server/src/test/java/ru/practicum/shareit/mapperTest/CommentMapperTest.java similarity index 94% rename from src/test/java/ru/practicum/shareit/mapperTest/CommentMapperTest.java rename to server/src/test/java/ru/practicum/shareit/mapperTest/CommentMapperTest.java index 6b7179f..c63d4fe 100644 --- a/src/test/java/ru/practicum/shareit/mapperTest/CommentMapperTest.java +++ b/server/src/test/java/ru/practicum/shareit/mapperTest/CommentMapperTest.java @@ -9,12 +9,13 @@ import ru.practicum.shareit.item.mapper.CommentMapper; import ru.practicum.shareit.item.model.Comment; import ru.practicum.shareit.item.model.Item; -import ru.practicum.shareit.request.ItemRequest; +import ru.practicum.shareit.request.model.ItemRequest; import ru.practicum.shareit.user.dto.UserAuthorDto; import ru.practicum.shareit.user.mapper.UserMapper; import ru.practicum.shareit.user.model.User; -import java.time.LocalDate; + +import java.time.LocalDateTime; import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -30,7 +31,7 @@ public class CommentMapperTest { User user = new User(1L, "testName1", "test1@test.com"); ItemRequest itemRequest = new ItemRequest(1L, "testDescription1", - 1L, LocalDate.of(2025, 6, 25)); + user, LocalDateTime.of(2025, 6, 25, 15, 25)); Item item = new Item(1L, "TestName1", "Test description1", true, user, itemRequest); diff --git a/src/test/java/ru/practicum/shareit/mapperTest/ItemMapperTest.java b/server/src/test/java/ru/practicum/shareit/mapperTest/ItemMapperTest.java similarity index 99% rename from src/test/java/ru/practicum/shareit/mapperTest/ItemMapperTest.java rename to server/src/test/java/ru/practicum/shareit/mapperTest/ItemMapperTest.java index 9468769..1c2aec8 100644 --- a/src/test/java/ru/practicum/shareit/mapperTest/ItemMapperTest.java +++ b/server/src/test/java/ru/practicum/shareit/mapperTest/ItemMapperTest.java @@ -9,7 +9,7 @@ import ru.practicum.shareit.request.model.ItemRequest; import ru.practicum.shareit.user.model.User; -import java.time.LocalDate; + import java.time.LocalDateTime; import static org.junit.jupiter.api.Assertions.*; diff --git a/src/test/java/ru/practicum/shareit/mapperTest/UserMapperTest.java b/server/src/test/java/ru/practicum/shareit/mapperTest/UserMapperTest.java similarity index 100% rename from src/test/java/ru/practicum/shareit/mapperTest/UserMapperTest.java rename to server/src/test/java/ru/practicum/shareit/mapperTest/UserMapperTest.java diff --git a/server/src/test/java/ru/practicum/shareit/serviceTest/BookingServiceTest.java b/server/src/test/java/ru/practicum/shareit/serviceTest/BookingServiceTest.java new file mode 100644 index 0000000..2e85c18 --- /dev/null +++ b/server/src/test/java/ru/practicum/shareit/serviceTest/BookingServiceTest.java @@ -0,0 +1,244 @@ +package ru.practicum.shareit.serviceTest; + +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.jdbc.Sql; +import ru.practicum.shareit.TestData; +import ru.practicum.shareit.booking.BookingServiceImpl; +import ru.practicum.shareit.booking.dto.BookingRequestDto; +import ru.practicum.shareit.booking.dto.BookingResponseDto; +import ru.practicum.shareit.booking.model.BookingStatus; +import ru.practicum.shareit.exception.AnotherUserException; +import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.exception.ValidationException; + + +import java.time.LocalDateTime; +import java.util.Collection; + +import static org.junit.jupiter.api.Assertions.*; + +@Transactional +@SpringBootTest +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) +@Sql(value = "/test-data.sql") +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) +public class BookingServiceTest extends TestData { + final BookingServiceImpl bookingService; + + @Test + public void addBookingTest() { + BookingRequestDto bookingRequestDto = new BookingRequestDto(); + bookingRequestDto.setStart(LocalDateTime.of(2025, 7, 7, 14, 40, 35)); + bookingRequestDto.setEnd(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + bookingRequestDto.setItemId(itemBookerDto2.getItemId()); + + BookingResponseDto bookingSaved = bookingService.addBooking(bookingRequestDto, user1.getUserId()); + + assertAll(() -> { + assertNotNull(bookingSaved); + assertEquals(7, bookingSaved.getBookingId()); + assertEquals(bookingRequestDto.getStart(), bookingSaved.getStart()); + assertEquals(bookingRequestDto.getEnd(), bookingSaved.getEnd()); + assertEquals(BookingStatus.WAITING, bookingSaved.getStatus()); + assertEquals(userBookingDto1, bookingSaved.getBooker()); + assertEquals(itemBookerDto2, bookingSaved.getItem()); + }); + } + + @Test + public void bookingApproveTest() { + BookingResponseDto bookingResponseDto = bookingService.bookingApprove(booking2.getBookingId(), user2.getUserId(), false); + assertAll(() -> { + assertNotNull(bookingResponseDto); + assertEquals(responseBooking2.getBookingId(), bookingResponseDto.getBookingId()); + assertEquals(responseBooking2.getStart(), bookingResponseDto.getStart()); + assertEquals(responseBooking2.getEnd(), bookingResponseDto.getEnd()); + assertEquals(responseBooking2.getStatus(), bookingResponseDto.getStatus()); + assertEquals(responseBooking2.getBooker().getUserId(), bookingResponseDto.getBooker().getUserId()); + assertEquals(responseBooking2.getItem().getItemId(), bookingResponseDto.getItem().getItemId()); + }); + } + + @Test + public void bookingApproveWithWrongOwnerTest() { + + assertThrows(AnotherUserException.class, () -> { + BookingResponseDto bookingResponseDto = + bookingService.bookingApprove(booking2.getBookingId(), user1.getUserId(), false); + }); + } + + @Test + public void bookingApproveWithUnavailableItemTest() { + + assertThrows(ValidationException.class, () -> + bookingService.bookingApprove(booking1.getBookingId(), user1.getUserId(), true)); + } + + @Test + public void getBookingByBookingIdTest() { + BookingResponseDto found = bookingService.getBookingByBookingId(booking1.getBookingId(), user1.getUserId()); + assertAll(() -> { + assertNotNull(found); + assertEquals(found.getBookingId(), booking1.getBookingId()); + assertEquals(found.getStart(), booking1.getStart()); + assertEquals(found.getEnd(), booking1.getEnd()); + assertEquals(found.getStatus(), booking1.getStatus()); + assertEquals(found.getBooker().getUserId(), booking1.getBooker().getUserId()); + assertEquals(found.getItem().getItemId(), booking1.getItem().getItemId()); + }); + } + + @Test + public void getBookingByUserIdWithWrongUserTest() { + assertThrows(AnotherUserException.class, () -> + bookingService.getBookingByBookingId(booking1.getBookingId(), 5L)); + } + + @Test + public void getBookingsByUserWithWrongUserTest() { + assertThrows(NotFoundException.class, () -> + bookingService.getBookingsByUser(5L, "ALL")); + } + + @Test + public void getBookingsByUserWithWrongItemTest() { + assertThrows(NotFoundException.class, () -> + bookingService.getBookingsByUser(user3.getUserId(), "ALL")); + } + + @Test + public void getBookingsByUserALLTest() { + Collection bookings = bookingService.getBookingsByUser(user1.getUserId(), "ALL"); + + assertAll(() -> { + assertNotNull(bookings); + assertEquals(5, bookings.size()); + }); + } + + @Test + public void getBookingsByUserCURRENTTest() { + Collection bookings = bookingService.getBookingsByUser(user1.getUserId(), "CURRENT"); + + assertAll(() -> { + assertNotNull(bookings); + assertEquals(2, bookings.size()); + }); + } + + @Test + public void getBookingsByUserPastTest() { + + Collection bookings = bookingService.getBookingsByUser(user1.getUserId(), "PAST"); + + assertAll(() -> { + assertNotNull(bookings); + assertEquals(2, bookings.size()); + }); + } + + @Test + public void getBookingsByUserFutureTest() { + + Collection bookings = bookingService.getBookingsByUser(user1.getUserId(), "FUTURE"); + + assertAll(() -> { + assertNotNull(bookings); + assertEquals(1, bookings.size()); + assertEquals(4L, bookings.iterator().next().getBookingId()); + }); + } + + @Test + public void getBookingsByUserWaitingTest() { + + Collection bookings = bookingService.getBookingsByUser(user1.getUserId(), "WAITING"); + + assertAll(() -> { + assertNotNull(bookings); + assertEquals(3, bookings.size()); + }); + } + + @Test + public void getBookingsByUserRejectedTest() { + + Collection bookings = bookingService.getBookingsByUser(user1.getUserId(), "REJECTED"); + + assertAll(() -> { + assertNotNull(bookings); + assertEquals(1, bookings.size()); + }); + } + + @Test + public void addBookingWithUnavailableItemTest() { + BookingRequestDto bookingRequestDto = new BookingRequestDto(); + bookingRequestDto.setStart(LocalDateTime.of(2025, 7, 7, 14, 40, 35)); + bookingRequestDto.setEnd(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + bookingRequestDto.setItemId(itemBookerDto1.getItemId()); + + assertThrows(ValidationException.class, () -> bookingService.addBooking(bookingRequestDto, user1.getUserId())); + + } + + @Test + public void getBookingByOwnerTest() { + Collection bookings = bookingService.getBookingsByOwner(itemResponseDto2.getOwnerId(), "ALL"); + assertAll(() -> { + assertNotNull(bookings); + assertEquals(2, bookings.size()); + }); + } + + @Test + public void getBookingByOwnerCurrentTest() { + Collection bookings = bookingService.getBookingsByOwner(itemResponseDto1.getOwnerId(), "CURRENT"); + assertAll(() -> { + assertNotNull(bookings); + assertEquals(2, bookings.size()); + }); + } + + @Test + public void getBookingByOwnerPastTest() { + Collection bookings = bookingService.getBookingsByOwner(itemResponseDto1.getOwnerId(), "PAST"); + assertAll(() -> { + assertNotNull(bookings); + assertEquals(1, bookings.size()); + }); + } + + @Test + public void getBookingByOwnerFutureTest() { + Collection bookings = bookingService.getBookingsByOwner(itemResponseDto1.getOwnerId(), "FUTURE"); + assertAll(() -> { + assertNotNull(bookings); + assertEquals(1, bookings.size()); + }); + } + + @Test + public void getBookingByOwnerWaitingTest() { + Collection bookings = bookingService.getBookingsByOwner(itemResponseDto1.getOwnerId(), "WAITING"); + assertAll(() -> { + assertNotNull(bookings); + assertEquals(3, bookings.size()); + }); + } + + @Test + public void getBookingByOwnerRejectedTest() { + Collection bookings = bookingService.getBookingsByOwner(itemResponseDto1.getOwnerId(), "REJECTED"); + assertAll(() -> { + assertNotNull(bookings); + assertEquals(1, bookings.size()); + }); + } +} diff --git a/server/src/test/java/ru/practicum/shareit/serviceTest/ItemServiceTest.java b/server/src/test/java/ru/practicum/shareit/serviceTest/ItemServiceTest.java new file mode 100644 index 0000000..6932f03 --- /dev/null +++ b/server/src/test/java/ru/practicum/shareit/serviceTest/ItemServiceTest.java @@ -0,0 +1,272 @@ +package ru.practicum.shareit.serviceTest; + +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.jdbc.Sql; +import ru.practicum.shareit.TestData; +import ru.practicum.shareit.exception.AnotherUserException; +import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.exception.ValidationException; +import ru.practicum.shareit.item.ItemServiceImpl; +import ru.practicum.shareit.item.dto.*; + +import java.util.Collection; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +@Transactional +@SpringBootTest +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) +@Sql(value = "/test-data.sql") +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) +public class ItemServiceTest extends TestData { + private final ItemServiceImpl itemService; + + @Test + public void addItemTest() { + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + + ItemResponseDto saved = itemService.createItem(forCreation, user1.getUserId()); + + assertAll(() -> { + assertNotNull(saved); + assertThat(forCreation).usingRecursiveComparison() + .ignoringFields("itemId").isEqualTo(saved); + }); + } + + @Test + void addItem_WithNullOwnerIdTest() { + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + + assertThrows(ValidationException.class, + () -> itemService.createItem(forCreation, null)); + } + + @Test + void addItem_WithUserNotFoundTest() { + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + + assertThrows(NotFoundException.class, + () -> itemService.createItem(forCreation, 5L)); + } + + @Test + void addItem_WithRequestIdTest() { + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + forCreation.setRequestId(1L); + + ItemResponseDto saved = itemService.createItem(forCreation, user1.getUserId()); + assertAll(() -> { + assertNotNull(saved); + assertEquals(1L, saved.getRequestId()); + }); + } + + @Test + void addItem_WithWrongRequestIdTest() { + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + forCreation.setRequestId(5L); + + assertThrows(NotFoundException.class, + () -> itemService.createItem(forCreation, user1.getUserId())); + + } + + @Test + void getItemByIdTest() { + ItemResponseDtoWithComments found = itemService.getItemById(1L, 1L); + + assertAll(() -> { + assertNotNull(found); + assertThat(found.getItemId()).isEqualTo(1L); + }); + } + + @Test + void getItemById_WithWrongItemIdTest() { + assertThrows(NotFoundException.class, + () -> itemService.getItemById(5L, 2L)); + } + + @Test + void getItemById_WithOwnerIdTest() { + ItemResponseDtoWithComments found = itemService.getItemById(1L, 1L); + assertAll(() -> { + assertNotNull(found); + assertNotNull(found.getComments()); + }); + } + + @Test + void getItemById_WithNotOwnerIdTest() { + ItemResponseDtoWithComments found = itemService.getItemById(2L, 1L); + assertAll(() -> { + assertNotNull(found); + assertEquals(0, found.getComments().size()); + }); + } + + @Test + void getItemById_WithOwnerId_AndLastBookingTest() { + ItemResponseDtoWithComments found = itemService.getItemById(1L, 1L); + assertAll(() -> { + assertNotNull(found); + assertNotNull(found.getLastBooking()); + }); + } + + @Test + void getItemById_WithOwnerId_AndNextBookingTest() { + ItemResponseDtoWithComments found = itemService.getItemById(1L, 1L); + assertAll(() -> { + assertNotNull(found); + assertNotNull(found.getNextBooking()); + }); + } + + @Test + void updateItemTest() { + ItemRequestDto forUpdate = new ItemRequestDto(); + forUpdate.setItemName("Test"); + forUpdate.setItemDescription("Test item description"); + forUpdate.setIsAvailable(true); + + ItemResponseDto updated = itemService.updateItem(1L, forUpdate, user1.getUserId()); + assertAll(() -> { + assertNotNull(updated); + assertThat(forUpdate).usingRecursiveComparison() + .ignoringFields("itemId", "requestId").isEqualTo(updated); + }); + } + + @Test + void updateItem_WithWrongOwnerTest() { + ItemRequestDto forUpdate = new ItemRequestDto(); + forUpdate.setItemName("Test"); + forUpdate.setItemDescription("Test item description"); + forUpdate.setIsAvailable(true); + + assertThrows(AnotherUserException.class, + () -> itemService.updateItem(1L, forUpdate, user2.getUserId())); + + } + + @Test + void updateItem_WithoutItemNameTest() { + ItemRequestDto forUpdate = new ItemRequestDto(); + forUpdate.setItemDescription("Test item description"); + forUpdate.setIsAvailable(true); + + ItemResponseDto updated = itemService.updateItem(1L, forUpdate, user1.getUserId()); + assertAll(() -> { + assertNotNull(updated); + assertThat(forUpdate).usingRecursiveComparison() + .ignoringFields("itemId", "requestId", "itemName").isEqualTo(updated); + }); + } + + @Test + void updateItem_WithoutItemDescriptionTest() { + ItemRequestDto forUpdate = new ItemRequestDto(); + forUpdate.setItemName("Test"); + forUpdate.setIsAvailable(true); + + ItemResponseDto updated = itemService.updateItem(1L, forUpdate, user1.getUserId()); + assertAll(() -> { + assertNotNull(updated); + assertThat(forUpdate).usingRecursiveComparison() + .ignoringFields("itemId", "requestId", "itemDescription").isEqualTo(updated); + }); + } + + @Test + void updateItem_WithoutIsAvailableTest() { + ItemRequestDto forUpdate = new ItemRequestDto(); + forUpdate.setItemName("Test"); + forUpdate.setItemDescription("Test item description"); + + ItemResponseDto updated = itemService.updateItem(1L, forUpdate, user1.getUserId()); + assertAll(() -> { + assertNotNull(updated); + assertThat(forUpdate).usingRecursiveComparison() + .ignoringFields("itemId", "requestId", "isAvailable").isEqualTo(updated); + }); + } + + @Test + void getAllItemsForOwnerTest() { + Collection items = itemService.getAllItemsForOwner(user1.getUserId()); + assertAll(() -> { + assertNotNull(items); + assertEquals(1, items.size()); + }); + } + + @Test + void getAllItemsForOwner_WithWrongUserTest() { + assertThrows(NotFoundException.class, + () -> itemService.getAllItemsForOwner(5L)); + } + + @Test + void addCommentTest() { + CommentRequestDto comment = new CommentRequestDto(); + comment.setText("Test comment"); + + CommentResponseCreatedDto created = itemService.addComment(1L, comment, 2L); + + assertAll(() -> { + assertNotNull(created); + assertEquals("Test comment", created.getText()); + }); + } + + @Test + void addComment_WithWrongCommentatorTest() { + CommentRequestDto comment = new CommentRequestDto(); + comment.setText("Test comment"); + + assertThrows(NotFoundException.class, + () -> itemService.addComment(5L, comment, 2L)); + } + + @Test + void addComment_WithWrongDateTest() { + CommentRequestDto comment = new CommentRequestDto(); + comment.setText("Test comment"); + + assertThrows(ValidationException.class, + () -> itemService.addComment(1L, comment, 1L)); + } + + @Test + void searchByTextTest() { + Collection items = itemService.searchByText("testItem2"); + + assertAll(() -> { + assertNotNull(items); + assertEquals(1, items.size()); + }); + } +} diff --git a/server/src/test/java/ru/practicum/shareit/serviceTest/RequestServiceTest.java b/server/src/test/java/ru/practicum/shareit/serviceTest/RequestServiceTest.java new file mode 100644 index 0000000..ddbc306 --- /dev/null +++ b/server/src/test/java/ru/practicum/shareit/serviceTest/RequestServiceTest.java @@ -0,0 +1,90 @@ +package ru.practicum.shareit.serviceTest; + +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.jdbc.Sql; +import ru.practicum.shareit.TestData; +import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.request.RequestServiceImpl; +import ru.practicum.shareit.request.dto.RequestInputDto; +import ru.practicum.shareit.request.dto.RequestOutputDto; +import ru.practicum.shareit.request.dto.RequestOutputWithItemsDto; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + + +@Transactional +@SpringBootTest +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) +@Sql(value = "/test-data.sql") +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) +public class RequestServiceTest extends TestData { + private final RequestServiceImpl requestService; + + @Test + void addRequestTest() { + RequestInputDto requestInputDto = new RequestInputDto(); + requestInputDto.setRequestDescription("RequestDescription"); + + RequestOutputDto requestOutputDto = requestService.addItemRequest(requestInputDto, user1.getUserId()); + + assertThat(requestOutputDto).usingRecursiveComparison() + .ignoringFields("itemRequestId", "requester").isEqualTo(requestInputDto); + } + + @Test + void addRequest_WithWrongUserTest() { + RequestInputDto requestInputDto = new RequestInputDto(); + requestInputDto.setRequestDescription("RequestDescription"); + + assertThrows(NotFoundException.class, + () -> requestService.addItemRequest(requestInputDto, 5L)); + } + + @Test + void getRequestByUserTest() { + List requests = requestService.getRequestByUser(user1.getUserId()); + + assertAll(() -> { + assertNotNull(requests); + assertThat(requests.size()).isEqualTo(1); + }); + } + + @Test + void getRequestByWrongUserTest() { + assertThrows(NotFoundException.class, + () -> requestService.getRequestByUser(5L)); + } + + @Test + void getAllRequestsTest() { + List requests = requestService.getAllRequests(); + assertAll(() -> { + assertNotNull(requests); + assertThat(requests.size()).isEqualTo(2); + }); + } + + @Test + void getRequestByIdTest() { + RequestOutputWithItemsDto found = requestService.getRequestById(1L); + assertAll(() -> { + assertNotNull(found); + assertEquals(1L, found.getItemRequestId()); + }); + } + + @Test + void getRequestByWrongIdTest() { + assertThrows(NotFoundException.class, + () -> requestService.getRequestById(7L)); + } +} diff --git a/server/src/test/java/ru/practicum/shareit/serviceTest/UserServiceTest.java b/server/src/test/java/ru/practicum/shareit/serviceTest/UserServiceTest.java new file mode 100644 index 0000000..93abdae --- /dev/null +++ b/server/src/test/java/ru/practicum/shareit/serviceTest/UserServiceTest.java @@ -0,0 +1,117 @@ +package ru.practicum.shareit.serviceTest; + +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.jdbc.Sql; +import ru.practicum.shareit.TestData; +import ru.practicum.shareit.exception.DuplicatedDataException; +import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.user.UserServiceImpl; +import ru.practicum.shareit.user.dto.UserRequestDto; +import ru.practicum.shareit.user.dto.UserResponseDto; +import ru.practicum.shareit.user.interfaces.UserRepository; +import ru.practicum.shareit.user.model.User; + +import java.util.Collection; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +@Transactional +@SpringBootTest +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) +@Sql(value = "/test-data.sql") +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) +public class UserServiceTest extends TestData { + private final UserServiceImpl userService; + private final UserRepository userRepository; + + @Test + void addUserTest() { + UserRequestDto forCreation = new UserRequestDto(); + forCreation.setUserName("User3"); + forCreation.setUserEmail("User3@mail.ru"); + UserResponseDto userResponseDto = userService.createUser(forCreation); + + assertAll(() -> + assertNotNull(userResponseDto)); + assertThat(forCreation).usingRecursiveComparison().ignoringFields("userId") + .isEqualTo(userResponseDto); + } + + @Test + void createUser_WithWrongEmailTest() { + assertThrows(DuplicatedDataException.class, + () -> userService.createUser(userRequestDto1)); + } + + @Test + void getUserByIdTest() { + UserResponseDto found = userService.getUserById(1L); + + assertAll(() -> { + assertNotNull(found); + assertThat(found).usingRecursiveComparison().isEqualTo(userResponseDto1); + }); + } + + @Test + void getUserById_NotFoundExceptionTest() { + assertThrows(NotFoundException.class, + () -> userService.getUserById(5L)); + } + + @Test + void updateUserTest() { + UserRequestDto forUpdate = new UserRequestDto(); + forUpdate.setUserName("UpdatedName"); + forUpdate.setUserEmail("UpdatedEmail@mail.ru"); + + UserResponseDto updated = new UserResponseDto(1L, "UpdatedName", "UpdatedEmail@mail.ru"); + + UserResponseDto userResponseDto = userService.updateUser(1L, forUpdate); + assertAll(() -> { + assertEquals(userBookingDto1.getUserId(), userResponseDto.getUserId()); + assertThat(updated).usingRecursiveComparison().ignoringFields("userId").isEqualTo(userResponseDto); + }); + } + + @Test + void updateUserTest_NotFoundExceptionTest() { + UserRequestDto forUpdate = new UserRequestDto(); + forUpdate.setUserName("UpdatedName"); + forUpdate.setUserEmail("UpdatedEmail@mail.ru"); + + assertThrows(NotFoundException.class, () -> userService.updateUser(5L, forUpdate)); + } + + @Test + void deleteUserByIdTest() { + assertEquals(userResponseDto1, userService.getUserById(1L)); + + userService.deleteUser(1L); + + assertThrows(NotFoundException.class, () -> userService.getUserById(1L)); + + } + + @Test + void deleteUserById_NotFoundExceptionTest() { + assertThrows(NotFoundException.class, () -> userService.deleteUser(5L)); + } + + @Test + void deleteAllUserTest() { + Collection users = userRepository.findAll(); + assertNotNull(users); + + userService.deleteAllUsers(); + + assertEquals(0, userRepository.findAll().size()); + } + +} diff --git a/src/main/java/ru/practicum/shareit/PersistenceConfig.java b/src/main/java/ru/practicum/shareit/PersistenceConfig.java deleted file mode 100644 index 04d14b2..0000000 --- a/src/main/java/ru/practicum/shareit/PersistenceConfig.java +++ /dev/null @@ -1,66 +0,0 @@ -package ru.practicum.shareit; - -import jakarta.persistence.EntityManagerFactory; -import lombok.RequiredArgsConstructor; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.jdbc.datasource.DriverManagerDataSource; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -import javax.sql.DataSource; -import java.util.Properties; - -@Configuration -@RequiredArgsConstructor -@EnableTransactionManagement -@EnableJpaRepositories(basePackages = "ru.practicum") -public class PersistenceConfig { - private final Environment environment; - - @Bean - public DataSource dataSource() { - DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setDriverClassName(environment.getRequiredProperty("spring.datasource.driverClassName")); - dataSource.setUrl(environment.getRequiredProperty("spring.datasource.url")); - dataSource.setUsername(environment.getRequiredProperty("spring.datasource.username")); - dataSource.setPassword(environment.getRequiredProperty("spring.datasource.password")); - return dataSource; - } - - private Properties hibernateProperties() { - Properties properties = new Properties(); - properties.put("spring.jpa.properties.hibernate.jdbc.time_zone", - environment.getRequiredProperty("spring.jpa.properties.hibernate.jdbc.time_zone")); - properties.put("spring.jpa.properties.hibernate.format_sql", - environment.getProperty("spring.jpa.properties.hibernate.format_sql", "false")); - return properties; - } - - @Bean - public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) { - final HibernateJpaVendorAdapter vendorAdapter = - new HibernateJpaVendorAdapter(); - - final LocalContainerEntityManagerFactoryBean emf = - new LocalContainerEntityManagerFactoryBean(); - - emf.setDataSource(dataSource); - emf.setJpaVendorAdapter(vendorAdapter); - emf.setPackagesToScan("ru.practicum"); - emf.setJpaProperties(hibernateProperties()); - - return emf; - } - - @Bean - public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { - JpaTransactionManager transactionManager = new JpaTransactionManager(); - transactionManager.setEntityManagerFactory(entityManagerFactory); - return transactionManager; - } -} diff --git a/src/main/java/ru/practicum/shareit/item/ItemStorage.java b/src/main/java/ru/practicum/shareit/item/ItemStorage.java deleted file mode 100644 index e9ba003..0000000 --- a/src/main/java/ru/practicum/shareit/item/ItemStorage.java +++ /dev/null @@ -1,67 +0,0 @@ -package ru.practicum.shareit.item; - -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Repository; -import ru.practicum.shareit.item.interfaces.ItemStorageInterface; -import ru.practicum.shareit.item.model.Item; - -import java.util.*; -import java.util.stream.Collectors; - -@Repository -@RequiredArgsConstructor -public class ItemStorage implements ItemStorageInterface { - - private Long nextItemId = 1L; - private final Map items = new HashMap<>(); - - public Item createItem(Item item) { - item.setItemId(nextItemId++); - items.put(item.getItemId(), item); - return item; - } - - public Optional getItemById(Long id) { - return Optional.ofNullable(items.get(id)); - } - - public Item updateItem(Item item) { - Item oldItem = items.get(item.getItemId()); - - if (oldItem != null) { - - if (item.getItemName() != null) { - oldItem.setItemName(item.getItemName()); - } - - if (item.getItemDescription() != null) { - oldItem.setItemDescription(item.getItemDescription()); - } - - if (item.getIsAvailable() != null) { - oldItem.setIsAvailable(item.getIsAvailable()); - } - - } - return oldItem; - } - - public Collection getAllItemsForOwner(Long ownerId) { - return items.values() - .stream() - .filter(item -> Objects.equals(item.getOwner().getUserId(), ownerId)) - .collect(Collectors.toList()); - } - - public Collection searchByText(String text) { - Collection itemCollection = new ArrayList<>(); - for (Item item : items.values()) { - if (item.getItemName().toLowerCase().contains(text.toLowerCase())) { - itemCollection.add(item); - } else if (item.getItemDescription().toLowerCase().contains(text.toLowerCase())) { - itemCollection.add(item); - } - } - return itemCollection; - } -} diff --git a/src/main/java/ru/practicum/shareit/user/UserStorage.java b/src/main/java/ru/practicum/shareit/user/UserStorage.java deleted file mode 100644 index 040839d..0000000 --- a/src/main/java/ru/practicum/shareit/user/UserStorage.java +++ /dev/null @@ -1,53 +0,0 @@ -package ru.practicum.shareit.user; - -import org.springframework.stereotype.Repository; -import ru.practicum.shareit.user.interfaces.UserStorageInterface; -import ru.practicum.shareit.user.model.User; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -@Repository -public class UserStorage implements UserStorageInterface { - - private final Map users = new HashMap<>(); - private Long nextUserId = 1L; - - public User createUser(User user) { - user.setUserId(nextUserId++); - users.put(user.getUserId(), user); - return user; - } - - public Optional getUserById(Long userId) { - return Optional.ofNullable(users.get(userId)); - } - - public User updateUser(Long userId, User user) { - User oldUser = users.get(userId); - - if (user.getUserName() != null) { - oldUser.setUserName(user.getUserName()); - } - - if (user.getUserEmail() != null) { - oldUser.setUserEmail(user.getUserEmail()); - } - - return oldUser; - } - - public Collection getAllUsers() { - return users.values(); - } - - public void deleteUser(Long userId) { - users.remove(userId); - } - - public void deleteAllUsers() { - users.clear(); - } -} diff --git a/src/main/java/ru/practicum/shareit/user/interfaces/UserStorageInterface.java b/src/main/java/ru/practicum/shareit/user/interfaces/UserStorageInterface.java deleted file mode 100644 index dafdbf4..0000000 --- a/src/main/java/ru/practicum/shareit/user/interfaces/UserStorageInterface.java +++ /dev/null @@ -1,20 +0,0 @@ -package ru.practicum.shareit.user.interfaces; - -import ru.practicum.shareit.user.model.User; - -import java.util.Collection; -import java.util.Optional; - -public interface UserStorageInterface { - User createUser(User user); - - Optional getUserById(Long userId); - - User updateUser(Long userId, User user); - - Collection getAllUsers(); - - void deleteUser(Long userId); - - void deleteAllUsers(); -} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index e1fc5d9..0000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1,13 +0,0 @@ -spring.jpa.hibernate.ddl-auto=none -spring.jpa.properties.hibernate.format_sql=true -spring.jpa.properties.hibernate.jdbc.time_zone=UTC -spring.sql.init.mode=always -spring.datasource.url=jdbc:postgresql://localhost:5432/postgres -spring.datasource.driverClassName=org.postgresql.Driver -spring.datasource.username=user -spring.datasource.password=12345 - -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 \ No newline at end of file diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties deleted file mode 100644 index 0024b61..0000000 --- a/src/test/resources/application.properties +++ /dev/null @@ -1,10 +0,0 @@ -spring.sql.init.mode=always -spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE -spring.datasource.driverClassName=org.h2.Driver -spring.datasource.username=user -spring.datasource.password=12345 - -spring.jpa.properties.hibernate.format_sql=true -spring.jpa.properties.hibernate.jdbc.time_zone=UTC -spring.jpa.hibernate.ddl-auto=create-drop -spring.jpa.database-platform=org.hibernate.dialect.H2Dialect \ No newline at end of file From 516a69a2c52a5d4b0bcf86e93973358673de21e7 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Sun, 13 Jul 2025 16:32:26 +0400 Subject: [PATCH 06/11] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2016=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20(=D1=81=20=D1=82=D0=B5=D1=81=D1=82=D0=B0=D0=BC=D0=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ru/practicum/shareit/mapperTest/CommentMapperTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/test/java/ru/practicum/shareit/mapperTest/CommentMapperTest.java b/server/src/test/java/ru/practicum/shareit/mapperTest/CommentMapperTest.java index 89c8199..2ad1ac0 100644 --- a/server/src/test/java/ru/practicum/shareit/mapperTest/CommentMapperTest.java +++ b/server/src/test/java/ru/practicum/shareit/mapperTest/CommentMapperTest.java @@ -14,7 +14,6 @@ import ru.practicum.shareit.user.mapper.UserMapper; import ru.practicum.shareit.user.model.User; -import java.time.LocalDate; import java.time.LocalDateTime; import static org.junit.jupiter.api.Assertions.assertAll; From 85ce5305e471ade783bb061e025ef45aabaac7b0 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Sun, 13 Jul 2025 16:50:39 +0400 Subject: [PATCH 07/11] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2016=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20(=D1=81=20=D1=82=D0=B5=D1=81=D1=82=D0=B0=D0=BC=D0=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ru/practicum/shareit/serviceTest/BookingServiceTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/test/java/ru/practicum/shareit/serviceTest/BookingServiceTest.java b/server/src/test/java/ru/practicum/shareit/serviceTest/BookingServiceTest.java index 2e85c18..a21974a 100644 --- a/server/src/test/java/ru/practicum/shareit/serviceTest/BookingServiceTest.java +++ b/server/src/test/java/ru/practicum/shareit/serviceTest/BookingServiceTest.java @@ -241,4 +241,5 @@ public void getBookingByOwnerRejectedTest() { assertEquals(1, bookings.size()); }); } + } From 8f7b3ba51b362386231d0a06a40928812f9a4018 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Mon, 14 Jul 2025 08:00:48 +0400 Subject: [PATCH 08/11] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2016=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20(=D1=81=20=D1=82=D0=B5=D1=81=D1=82=D0=B0=D0=BC=D0=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/src/main/resources/test-data.sql | 83 ---- .../java/ru/practicum/shareit/TestData.java | 98 +++- .../serviceTest/BookingServiceTest.java | 427 +++++++++++++++--- .../shareit/serviceTest/ItemServiceTest.java | 291 ++++++++++-- .../serviceTest/RequestServiceTest.java | 88 +++- .../shareit/serviceTest/UserServiceTest.java | 29 +- 6 files changed, 798 insertions(+), 218 deletions(-) delete mode 100644 server/src/main/resources/test-data.sql diff --git a/server/src/main/resources/test-data.sql b/server/src/main/resources/test-data.sql deleted file mode 100644 index 4739d1a..0000000 --- a/server/src/main/resources/test-data.sql +++ /dev/null @@ -1,83 +0,0 @@ -CREATE TABLE IF NOT EXISTS users ( - user_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - user_name VARCHAR(255) NOT NULL, - user_email VARCHAR(500) - -); - -CREATE TABLE IF NOT EXISTS items ( - item_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - item_name VARCHAR(255) NOT NULL, - item_description VARCHAR(150) NOT NULL, - is_available BOOLEAN NOT NULL, - owner_id BIGINT NOT NULL, - request_id BIGINT, - CONSTRAINT fk_items_to_users FOREIGN KEY(owner_id) REFERENCES users(user_id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS comments ( - comment_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - text VARCHAR(2000) NOT NULL, - item_id BIGINT NOT NULL, - author_id BIGINT NOT NULL, - CONSTRAINT fk_comments_to_users FOREIGN KEY (author_id) REFERENCES users (user_id) ON DELETE CASCADE, - CONSTRAINT fk_comments_to_items FOREIGN KEY (item_id) REFERENCES items(item_id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS bookings ( - booking_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - 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 (50), - FOREIGN KEY (item_id) REFERENCES items (item_id) ON DELETE CASCADE, - FOREIGN KEY (booker_id) REFERENCES users (user_id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS requests ( - request_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - requester_id BIGINT NOT NULL, - description VARCHAR (200) NOT NULL, - request_date TIMESTAMP WITHOUT TIME ZONE, - FOREIGN KEY (requester_id) REFERENCES users (user_id) ON DELETE CASCADE -); - -INSERT INTO users (user_name, user_email) -VALUES ('TestUser1', 'user1@mail.ru'); - -INSERT INTO users (user_name, user_email) -VALUES ('TestUser2', 'user2@mail.ru'); - -INSERT INTO requests (requester_id, description, request_date) -VALUES ( 1, 'Test request description1', '2025-07-07T10:15:25'); - -INSERT INTO requests (requester_id, description, request_date) -VALUES (2, 'Test request description2', '2025-08-08T15:10:20'); - -INSERT INTO items (item_name, item_description, is_available, owner_id, request_id) -VALUES ('testItem1', 'test description1', 'false', 1, 2); - -INSERT INTO items (item_name, item_description, is_available, owner_id, request_id) -VALUES ('testItem2', 'test description2', 'true', 2, 2); - -INSERT INTO bookings (start_date, end_date, item_id, booker_id, status) -VALUES ('2025-07-07T14:40:35', '2025-07-25T18:12:43', 1, 1, 'WAITING'); - -INSERT INTO bookings (start_date, end_date, item_id, booker_id, status) -VALUES ('2025-08-08T15:45:30', '2025-08-18T12:10:40', 2, 2, 'APPROVED'); - -INSERT INTO bookings (start_date, end_date, item_id, booker_id, status) -VALUES ('2025-03-07T14:40:35', '2025-05-25T18:12:43', 1, 1, 'WAITING'); - -INSERT INTO bookings (start_date, end_date, item_id, booker_id, status) -VALUES ('2025-09-07T14:40:35', '2025-10-25T18:12:43', 1, 1, 'WAITING'); - -INSERT INTO bookings (start_date, end_date, item_id, booker_id, status) -VALUES ('2025-05-07T14:40:35', '2025-10-25T18:12:43', 1, 1, 'REJECTED'); - -INSERT INTO bookings (start_date, end_date, item_id, booker_id, status) -VALUES ('2025-02-07T14:40:35', '2025-02-25T18:12:43', 2, 1, 'APPROVED'); - -INSERT INTO comments (text, item_id, author_id) -VALUES ('Test comment text1', 1, 1); diff --git a/server/src/test/java/ru/practicum/shareit/TestData.java b/server/src/test/java/ru/practicum/shareit/TestData.java index b8578f6..5f035c8 100644 --- a/server/src/test/java/ru/practicum/shareit/TestData.java +++ b/server/src/test/java/ru/practicum/shareit/TestData.java @@ -29,6 +29,21 @@ public class TestData { public static UserBookingDto userBookingDto1 = new UserBookingDto(1L, "TestUser1"); public static UserAuthorDto userAuthorDto1 = new UserAuthorDto(1L, "TestUser1"); public static UserRequestDto userRequestDto1 = new UserRequestDto(1L, "TestUser1", "user1@mail.ru"); + + public static UserRequestDto userForCreate() { + UserRequestDto user = new UserRequestDto(); + user.setUserName("TestUser1"); + user.setUserEmail("user1@mail.ru"); + return user; + } + + public static UserRequestDto user2ForCreate() { + UserRequestDto user = new UserRequestDto(); + user.setUserName("TestUser2"); + user.setUserEmail("user2@mail.ru"); + return user; + } + public static UserResponseDto userResponseDto1 = new UserResponseDto(1L, "TestUser1", "user1@mail.ru"); @@ -52,6 +67,29 @@ public class TestData { "Test request description1", userBookingDto1, LocalDateTime.of(2025, 7, 7, 10, 15, 25), new ArrayList<>()); + public static ItemRequestDto itemForCreate() { + ItemRequestDto request = new ItemRequestDto(); + request.setItemName("testItem1"); + request.setItemDescription("test description1"); + request.setIsAvailable(true); + return request; + } + + public static ItemRequestDto item2ForCreate() { + ItemRequestDto request = new ItemRequestDto(); + request.setItemName("testItem2"); + request.setItemDescription("test description2"); + request.setIsAvailable(false); + return request; + } + + public static ItemRequestDto itemForUpdate() { + ItemRequestDto request = new ItemRequestDto(); + request.setItemName("testItem1"); + request.setItemDescription("test description1"); + request.setIsAvailable(false); + return request; + } public static ItemRequest request2 = new ItemRequest(2L, "Test request description2", user2, LocalDateTime.of(2025, 8, 8, 15, 10, 20)); @@ -63,6 +101,7 @@ public class TestData { "Test request description2", userBookingDto2, LocalDateTime.of(2025, 8, 8, 15, 10, 20), new ArrayList<>()); + public static List requests = List.of(requestOutputDto1); public static List allRequests = List.of(requestOutputDto1, requestOutputDto2); @@ -92,41 +131,75 @@ public class TestData { public Collection itemsFound = List.of(itemResponseDto2); - - public static Booking booking1 = new Booking(1L, LocalDateTime.of(2025, 7, 7, 14, 40, 35), - LocalDateTime.of(2025, 7, 25, 18, 12, 43), item1, user1, BookingStatus.WAITING); public static BookingResponseDto responseBooking1 = new BookingResponseDto(1L, LocalDateTime.of(2025, 7, 7, 14, 40, 35), LocalDateTime.of(2025, 7, 15, 18, 12, 43), itemBookerDto1, userBookingDto1, BookingStatus.WAITING); public static BookingRequestDto bookingRequestDto1 = new BookingRequestDto(1L, LocalDateTime.of(2025, 7, 7, 14, 40, 35), LocalDateTime.of(2025, 7, 15, 18, 12, 43), itemBookerDto1.getItemId(), userBookingDto1.getUserId(), BookingStatus.WAITING); + public static BookingRequestDto booking1ForCreate() { + BookingRequestDto bookingRequestDto = new BookingRequestDto(); + bookingRequestDto.setStart(LocalDateTime.of(2025, 7, 7, 14, 40, 35)); + bookingRequestDto.setEnd(LocalDateTime.of(2025, 7, 25, 18, 12, 43)); + bookingRequestDto.setItemId(1L); + bookingRequestDto.setBookerId(1L); + bookingRequestDto.setStatus(BookingStatus.WAITING); + return bookingRequestDto; + } - public static Booking booking2 = new Booking(2L, LocalDateTime.of(2025, 8, 8, 15, 45, 30), - LocalDateTime.of(2025, 8, 18, 12, 10, 40), item2, user2, BookingStatus.APPROVED); public static BookingResponseDto responseBooking2 = new BookingResponseDto(2L, LocalDateTime.of(2025, 8, 8, 15, 45, 30), LocalDateTime.of(2025, 8, 18, 12, 10, 40), itemBookerDto2, userBookingDto2, BookingStatus.APPROVED); - public static BookingRequestDto bookingRequestDto2 = new BookingRequestDto(2L, LocalDateTime.of(2025, 8, 8, 15, 45, 30), - LocalDateTime.of(2025, 8, 18, 12, 10, 40), itemBookerDto2.getItemId(), userBookingDto2.getUserId(), BookingStatus.APPROVED); - - public static Booking bookingPast = new Booking(3L, LocalDateTime.of(2025, 3, 7, 14, 40, 35), - LocalDateTime.of(2025, 5, 25, 18, 12, 43), item1, user1, BookingStatus.WAITING); public static BookingResponseDto responseBooking3 = new BookingResponseDto(3L, LocalDateTime.of(2025, 3, 7, 14, 40, 35), LocalDateTime.of(2025, 5, 25, 18, 12, 43), itemBookerDto1, userBookingDto1, BookingStatus.WAITING); + public static Booking bookingFuture = new Booking(4L, LocalDateTime.of(2025, 9, 7, 14, 40, 35), LocalDateTime.of(2025, 10, 25, 18, 12, 43), item1, user1, BookingStatus.WAITING); public static BookingResponseDto responseBooking4 = new BookingResponseDto(4L, LocalDateTime.of(2025, 9, 7, 14, 40, 35), LocalDateTime.of(2025, 10, 25, 18, 12, 43), itemBookerDto1, userBookingDto1, BookingStatus.WAITING); + + public static BookingRequestDto booking4ForCreate() { + BookingRequestDto bookingRequestDto = new BookingRequestDto(); + bookingRequestDto.setStart(LocalDateTime.of(2025, 9, 7, 14, 40, 35)); + bookingRequestDto.setEnd(LocalDateTime.of(2025, 10, 25, 18, 12, 43)); + bookingRequestDto.setItemId(1L); + bookingRequestDto.setStatus(BookingStatus.WAITING); + return bookingRequestDto; + } + public static Booking bookingRejected = new Booking(5L, LocalDateTime.of(2025, 5, 7, 14, 40, 35), LocalDateTime.of(2025, 10, 25, 18, 12, 43), item1, user1, BookingStatus.REJECTED); public static BookingResponseDto responseBooking5 = new BookingResponseDto(5L, LocalDateTime.of(2025, 5, 7, 14, 40, 35), LocalDateTime.of(2025, 10, 25, 18, 12, 43), itemBookerDto1, userBookingDto1, BookingStatus.REJECTED); + public static BookingRequestDto booking5ForCreate() { + BookingRequestDto bookingRequestDto = new BookingRequestDto(); + bookingRequestDto.setStart(LocalDateTime.of(2025, 5, 7, 14, 40, 35)); + bookingRequestDto.setEnd(LocalDateTime.of(2025, 10, 25, 18, 12, 43)); + bookingRequestDto.setItemId(1L); + bookingRequestDto.setStatus(BookingStatus.REJECTED); + return bookingRequestDto; + } + + public static BookingRequestDto bookingForUpdate() { + BookingRequestDto bookingRequestDto = new BookingRequestDto(); + bookingRequestDto.setStatus(BookingStatus.REJECTED); + return bookingRequestDto; + } + public static BookingRequestDto bookingRequestDto5 = new BookingRequestDto(3L, LocalDateTime.of(2025, 2, 7, 14, 40, 35), LocalDateTime.of(2025, 2, 25, 18, 12, 43), itemBookerDto2.getItemId(), userBookingDto1.getUserId(), BookingStatus.APPROVED); + public static BookingRequestDto booking6ForCreate() { + BookingRequestDto bookingRequestDto = new BookingRequestDto(); + bookingRequestDto.setStart(LocalDateTime.of(2025, 2, 7, 14, 40, 35)); + bookingRequestDto.setEnd(LocalDateTime.of(2025, 2, 25, 18, 12, 43)); + bookingRequestDto.setItemId(1L); + bookingRequestDto.setStatus(BookingStatus.APPROVED); + return bookingRequestDto; + } + public Collection bookings = Arrays.asList(responseBooking1, responseBooking2, responseBooking3, responseBooking4, responseBooking5); public Collection bookingsForOwner = Arrays.asList(responseBooking1, responseBooking3, responseBooking4, responseBooking5); @@ -135,6 +208,11 @@ public class TestData { public static CommentResponseDto commentResponseDto1 = new CommentResponseDto(1L, "Test comment text1", userAuthorDto1); public static CommentResponseCreatedDto createdDto = new CommentResponseCreatedDto(1L, "Test comment text1", userAuthorDto1.getUserName(), true); + public static CommentRequestDto commentForCreation() { + CommentRequestDto commentRequestDto = new CommentRequestDto(); + commentRequestDto.setText("Test comment text1"); + return commentRequestDto; + } } diff --git a/server/src/test/java/ru/practicum/shareit/serviceTest/BookingServiceTest.java b/server/src/test/java/ru/practicum/shareit/serviceTest/BookingServiceTest.java index a21974a..f3115e2 100644 --- a/server/src/test/java/ru/practicum/shareit/serviceTest/BookingServiceTest.java +++ b/server/src/test/java/ru/practicum/shareit/serviceTest/BookingServiceTest.java @@ -5,8 +5,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.jdbc.Sql; import ru.practicum.shareit.TestData; import ru.practicum.shareit.booking.BookingServiceImpl; import ru.practicum.shareit.booking.dto.BookingRequestDto; @@ -15,6 +13,11 @@ import ru.practicum.shareit.exception.AnotherUserException; import ru.practicum.shareit.exception.NotFoundException; import ru.practicum.shareit.exception.ValidationException; +import ru.practicum.shareit.item.ItemServiceImpl; +import ru.practicum.shareit.item.dto.ItemRequestDto; +import ru.practicum.shareit.item.dto.ItemResponseDto; +import ru.practicum.shareit.user.UserServiceImpl; +import ru.practicum.shareit.user.dto.UserResponseDto; import java.time.LocalDateTime; @@ -23,142 +26,278 @@ import static org.junit.jupiter.api.Assertions.*; @Transactional -@SpringBootTest +@SpringBootTest(properties = "jdbc.url=jdbc:h2:mem:testdb;MODE=PostgreSQL", + webEnvironment = SpringBootTest.WebEnvironment.NONE) @RequiredArgsConstructor(onConstructor = @__(@Autowired)) -@Sql(value = "/test-data.sql") -@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) public class BookingServiceTest extends TestData { - final BookingServiceImpl bookingService; + private final BookingServiceImpl bookingService; + private final UserServiceImpl userService; + private final ItemServiceImpl itemService; - @Test + @Test public void addBookingTest() { - BookingRequestDto bookingRequestDto = new BookingRequestDto(); - bookingRequestDto.setStart(LocalDateTime.of(2025, 7, 7, 14, 40, 35)); - bookingRequestDto.setEnd(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); - bookingRequestDto.setItemId(itemBookerDto2.getItemId()); + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); - BookingResponseDto bookingSaved = bookingService.addBooking(bookingRequestDto, user1.getUserId()); + BookingRequestDto bookingRequestDto = new BookingRequestDto(); + bookingRequestDto.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + bookingRequestDto.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + bookingRequestDto.setItemId(item.getItemId()); + BookingResponseDto bookingSaved = bookingService.addBooking(bookingRequestDto, user.getUserId()); assertAll(() -> { assertNotNull(bookingSaved); - assertEquals(7, bookingSaved.getBookingId()); assertEquals(bookingRequestDto.getStart(), bookingSaved.getStart()); assertEquals(bookingRequestDto.getEnd(), bookingSaved.getEnd()); assertEquals(BookingStatus.WAITING, bookingSaved.getStatus()); - assertEquals(userBookingDto1, bookingSaved.getBooker()); - assertEquals(itemBookerDto2, bookingSaved.getItem()); + assertEquals(user.getUserId(), bookingSaved.getBooker().getUserId()); + assertEquals(item.getItemId(), bookingSaved.getItem().getItemId()); }); } @Test public void bookingApproveTest() { - BookingResponseDto bookingResponseDto = bookingService.bookingApprove(booking2.getBookingId(), user2.getUserId(), false); + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + + BookingRequestDto bookingRequestDto = new BookingRequestDto(); + bookingRequestDto.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + bookingRequestDto.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + bookingRequestDto.setItemId(item.getItemId()); + BookingResponseDto bookingSaved = bookingService.addBooking(bookingRequestDto, user.getUserId()); + + BookingResponseDto bookingResponseDto = bookingService.bookingApprove(bookingSaved.getBookingId(), user.getUserId(), false); + assertAll(() -> { assertNotNull(bookingResponseDto); - assertEquals(responseBooking2.getBookingId(), bookingResponseDto.getBookingId()); - assertEquals(responseBooking2.getStart(), bookingResponseDto.getStart()); - assertEquals(responseBooking2.getEnd(), bookingResponseDto.getEnd()); - assertEquals(responseBooking2.getStatus(), bookingResponseDto.getStatus()); - assertEquals(responseBooking2.getBooker().getUserId(), bookingResponseDto.getBooker().getUserId()); - assertEquals(responseBooking2.getItem().getItemId(), bookingResponseDto.getItem().getItemId()); + assertEquals(BookingStatus.APPROVED, bookingResponseDto.getStatus()); }); } @Test public void bookingApproveWithWrongOwnerTest() { + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + + BookingRequestDto bookingRequestDto = new BookingRequestDto(); + bookingRequestDto.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + bookingRequestDto.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + bookingRequestDto.setItemId(item.getItemId()); + BookingResponseDto bookingSaved = bookingService.addBooking(bookingRequestDto, user.getUserId()); assertThrows(AnotherUserException.class, () -> { BookingResponseDto bookingResponseDto = - bookingService.bookingApprove(booking2.getBookingId(), user1.getUserId(), false); + bookingService.bookingApprove(bookingSaved.getBookingId(), 25L, false); }); } @Test public void bookingApproveWithUnavailableItemTest() { + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + + BookingRequestDto bookingRequestDto = new BookingRequestDto(); + bookingRequestDto.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + bookingRequestDto.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + bookingRequestDto.setItemId(item.getItemId()); + BookingResponseDto bookingSaved = bookingService.addBooking(bookingRequestDto, user.getUserId()); + + ItemRequestDto itemForUpdate = new ItemRequestDto(); + itemForUpdate.setIsAvailable(false); + itemService.updateItem(item.getItemId(), itemForUpdate, user.getUserId()); assertThrows(ValidationException.class, () -> - bookingService.bookingApprove(booking1.getBookingId(), user1.getUserId(), true)); + bookingService.bookingApprove(bookingSaved.getBookingId(), user.getUserId(), false)); } @Test public void getBookingByBookingIdTest() { - BookingResponseDto found = bookingService.getBookingByBookingId(booking1.getBookingId(), user1.getUserId()); + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + + BookingRequestDto bookingRequestDto = new BookingRequestDto(); + bookingRequestDto.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + bookingRequestDto.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + bookingRequestDto.setItemId(item.getItemId()); + BookingResponseDto bookingSaved = bookingService.addBooking(bookingRequestDto, user.getUserId()); + assertAll(() -> { - assertNotNull(found); - assertEquals(found.getBookingId(), booking1.getBookingId()); - assertEquals(found.getStart(), booking1.getStart()); - assertEquals(found.getEnd(), booking1.getEnd()); - assertEquals(found.getStatus(), booking1.getStatus()); - assertEquals(found.getBooker().getUserId(), booking1.getBooker().getUserId()); - assertEquals(found.getItem().getItemId(), booking1.getItem().getItemId()); + assertNotNull(bookingSaved); + assertEquals(LocalDateTime.of(2025, 8, 8, 15, 45, 30), bookingSaved.getStart()); + assertEquals(LocalDateTime.of(2025, 8, 18, 12, 10, 40), bookingSaved.getEnd()); + assertEquals(BookingStatus.WAITING, bookingSaved.getStatus()); + assertEquals(user.getUserId(), bookingSaved.getBooker().getUserId()); + assertEquals(item.getItemId(), bookingSaved.getItem().getItemId()); }); } @Test public void getBookingByUserIdWithWrongUserTest() { + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + UserResponseDto user1 = userService.createUser(user2ForCreate()); + + BookingRequestDto bookingRequestDto = new BookingRequestDto(); + bookingRequestDto.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + bookingRequestDto.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + bookingRequestDto.setItemId(item.getItemId()); + BookingResponseDto bookingResponseDto = bookingService.addBooking(bookingRequestDto, user.getUserId()); + assertThrows(AnotherUserException.class, () -> - bookingService.getBookingByBookingId(booking1.getBookingId(), 5L)); + bookingService.getBookingByBookingId(bookingResponseDto.getBookingId(), user1.getUserId())); } @Test public void getBookingsByUserWithWrongUserTest() { - assertThrows(NotFoundException.class, () -> - bookingService.getBookingsByUser(5L, "ALL")); - } + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + + BookingRequestDto bookingRequestDto = new BookingRequestDto(); + bookingRequestDto.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + bookingRequestDto.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + bookingRequestDto.setItemId(item.getItemId()); + bookingService.addBooking(bookingRequestDto, user.getUserId()); - @Test - public void getBookingsByUserWithWrongItemTest() { assertThrows(NotFoundException.class, () -> - bookingService.getBookingsByUser(user3.getUserId(), "ALL")); + bookingService.getBookingsByUser(125L, "ALL")); } @Test public void getBookingsByUserALLTest() { - Collection bookings = bookingService.getBookingsByUser(user1.getUserId(), "ALL"); + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + + BookingRequestDto booking1 = booking1ForCreate(); + booking1.setStart(LocalDateTime.of(2025, 7, 7, 14, 40, 35)); + booking1.setEnd(LocalDateTime.of(2025, 7, 25, 18, 12, 43)); + booking1.setItemId(item.getItemId()); + booking1.setBookerId(user.getUserId()); + bookingService.addBooking(booking1, user.getUserId()); + + BookingRequestDto booking2 = booking1ForCreate(); + booking2.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + booking2.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + booking2.setItemId(item.getItemId()); + booking2.setBookerId(user.getUserId()); + bookingService.addBooking(booking2, user.getUserId()); + + BookingRequestDto booking3 = booking1ForCreate(); + booking3.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + booking3.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + booking3.setItemId(item.getItemId()); + booking3.setBookerId(user.getUserId()); + bookingService.addBooking(booking3, user.getUserId()); + + Collection bookings = bookingService.getBookingsByUser(user.getUserId(), "ALL"); assertAll(() -> { assertNotNull(bookings); - assertEquals(5, bookings.size()); + assertEquals(3, bookings.size()); }); } @Test public void getBookingsByUserCURRENTTest() { - Collection bookings = bookingService.getBookingsByUser(user1.getUserId(), "CURRENT"); + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + + BookingRequestDto booking1 = booking1ForCreate(); + booking1.setStart(LocalDateTime.of(2025, 7, 7, 14, 40, 35)); + booking1.setEnd(LocalDateTime.of(2025, 7, 25, 18, 12, 43)); + booking1.setItemId(item.getItemId()); + booking1.setBookerId(user.getUserId()); + bookingService.addBooking(booking1, user.getUserId()); + + Collection bookings = bookingService.getBookingsByUser(user.getUserId(), "CURRENT"); assertAll(() -> { assertNotNull(bookings); - assertEquals(2, bookings.size()); + assertEquals(1, bookings.size()); }); } @Test public void getBookingsByUserPastTest() { + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); - Collection bookings = bookingService.getBookingsByUser(user1.getUserId(), "PAST"); + BookingRequestDto booking1 = booking1ForCreate(); + booking1.setStart(LocalDateTime.of(2025, 7, 7, 14, 40, 35)); + booking1.setEnd(LocalDateTime.of(2025, 7, 25, 18, 12, 43)); + booking1.setItemId(item.getItemId()); + booking1.setBookerId(user.getUserId()); + bookingService.addBooking(booking1, user.getUserId()); + + BookingRequestDto booking2 = booking1ForCreate(); + booking2.setStart(LocalDateTime.of(2025, 3, 7, 14, 40, 35)); + booking2.setEnd(LocalDateTime.of(2025, 5, 25, 18, 12, 43)); + booking2.setItemId(item.getItemId()); + booking2.setBookerId(user.getUserId()); + bookingService.addBooking(booking2, user.getUserId()); + + Collection bookings = bookingService.getBookingsByUser(user.getUserId(), "PAST"); assertAll(() -> { assertNotNull(bookings); - assertEquals(2, bookings.size()); + assertEquals(1, bookings.size()); }); } @Test public void getBookingsByUserFutureTest() { + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + + BookingRequestDto booking1 = booking1ForCreate(); + booking1.setStart(LocalDateTime.of(2025, 7, 7, 14, 40, 35)); + booking1.setEnd(LocalDateTime.of(2025, 7, 25, 18, 12, 43)); + booking1.setItemId(item.getItemId()); + booking1.setBookerId(user.getUserId()); + bookingService.addBooking(booking1, user.getUserId()); + + BookingRequestDto booking2 = booking1ForCreate(); + booking2.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + booking2.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + booking2.setItemId(item.getItemId()); + booking2.setBookerId(user.getUserId()); + bookingService.addBooking(booking2, user.getUserId()); - Collection bookings = bookingService.getBookingsByUser(user1.getUserId(), "FUTURE"); + + Collection bookings = bookingService.getBookingsByUser(user.getUserId(), "FUTURE"); assertAll(() -> { assertNotNull(bookings); assertEquals(1, bookings.size()); - assertEquals(4L, bookings.iterator().next().getBookingId()); }); } @Test public void getBookingsByUserWaitingTest() { - - Collection bookings = bookingService.getBookingsByUser(user1.getUserId(), "WAITING"); + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + + BookingRequestDto booking1 = booking1ForCreate(); + booking1.setStart(LocalDateTime.of(2025, 7, 7, 14, 40, 35)); + booking1.setEnd(LocalDateTime.of(2025, 7, 25, 18, 12, 43)); + booking1.setItemId(item.getItemId()); + booking1.setBookerId(user.getUserId()); + bookingService.addBooking(booking1, user.getUserId()); + + BookingRequestDto booking2 = booking1ForCreate(); + booking2.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + booking2.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + booking2.setItemId(item.getItemId()); + booking2.setBookerId(user.getUserId()); + bookingService.addBooking(booking2, user.getUserId()); + + BookingRequestDto booking3 = booking1ForCreate(); + booking3.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + booking3.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + booking3.setItemId(item.getItemId()); + booking3.setBookerId(user.getUserId()); + bookingService.addBooking(booking3, user.getUserId()); + + Collection bookings = bookingService.getBookingsByUser(user.getUserId(), "WAITING"); assertAll(() -> { assertNotNull(bookings); @@ -168,8 +307,33 @@ public void getBookingsByUserWaitingTest() { @Test public void getBookingsByUserRejectedTest() { - - Collection bookings = bookingService.getBookingsByUser(user1.getUserId(), "REJECTED"); + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + ItemResponseDto item2 = itemService.createItem(item2ForCreate(), user.getUserId()); + + BookingRequestDto booking1 = booking1ForCreate(); + booking1.setStart(LocalDateTime.of(2025, 7, 7, 14, 40, 35)); + booking1.setEnd(LocalDateTime.of(2025, 7, 25, 18, 12, 43)); + booking1.setItemId(item.getItemId()); + booking1.setBookerId(user.getUserId()); + bookingService.addBooking(booking1, user.getUserId()); + + BookingRequestDto booking2 = booking1ForCreate(); + booking2.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + booking2.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + booking2.setItemId(item.getItemId()); + booking2.setBookerId(user.getUserId()); + bookingService.addBooking(booking2, user.getUserId()); + + BookingRequestDto booking3 = booking1ForCreate(); + booking3.setStart(LocalDateTime.of(2025, 5, 7, 14, 40, 35)); + booking3.setEnd(LocalDateTime.of(2025, 10, 25, 18, 12, 43)); + booking3.setItemId(item2.getItemId()); + booking3.setBookerId(user.getUserId()); + assertThrows(ValidationException.class, + () -> bookingService.addBooking(booking3, user.getUserId())); + + Collection bookings = bookingService.getBookingsByUser(user.getUserId(), "REJECTED"); assertAll(() -> { assertNotNull(bookings); @@ -179,36 +343,104 @@ public void getBookingsByUserRejectedTest() { @Test public void addBookingWithUnavailableItemTest() { + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + BookingRequestDto bookingRequestDto = new BookingRequestDto(); bookingRequestDto.setStart(LocalDateTime.of(2025, 7, 7, 14, 40, 35)); bookingRequestDto.setEnd(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); - bookingRequestDto.setItemId(itemBookerDto1.getItemId()); + bookingRequestDto.setItemId(item.getItemId()); + ItemResponseDto itemUpdated = itemService.updateItem(item.getItemId(), itemForUpdate(), user.getUserId()); - assertThrows(ValidationException.class, () -> bookingService.addBooking(bookingRequestDto, user1.getUserId())); + assertThrows(ValidationException.class, () -> bookingService.addBooking(bookingRequestDto, user.getUserId())); } @Test public void getBookingByOwnerTest() { - Collection bookings = bookingService.getBookingsByOwner(itemResponseDto2.getOwnerId(), "ALL"); + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + UserResponseDto user1 = userService.createUser(user2ForCreate()); + + BookingRequestDto booking1 = booking1ForCreate(); + booking1.setStart(LocalDateTime.of(2025, 7, 7, 14, 40, 35)); + booking1.setEnd(LocalDateTime.of(2025, 7, 25, 18, 12, 43)); + booking1.setItemId(item.getItemId()); + booking1.setBookerId(user1.getUserId()); + bookingService.addBooking(booking1, user.getUserId()); + + BookingRequestDto booking2 = booking1ForCreate(); + booking2.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + booking2.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + booking2.setItemId(item.getItemId()); + booking2.setBookerId(user.getUserId()); + bookingService.addBooking(booking2, user.getUserId()); + + BookingRequestDto booking3 = booking1ForCreate(); + booking3.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + booking3.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + booking3.setItemId(item.getItemId()); + booking3.setBookerId(user.getUserId()); + bookingService.addBooking(booking3, user.getUserId()); + + Collection bookings = bookingService.getBookingsByOwner(item.getOwnerId(), "ALL"); + assertAll(() -> { assertNotNull(bookings); - assertEquals(2, bookings.size()); + assertEquals(3, bookings.size()); }); } @Test public void getBookingByOwnerCurrentTest() { - Collection bookings = bookingService.getBookingsByOwner(itemResponseDto1.getOwnerId(), "CURRENT"); + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + UserResponseDto user1 = userService.createUser(user2ForCreate()); + + BookingRequestDto booking1 = booking1ForCreate(); + booking1.setStart(LocalDateTime.of(2025, 7, 7, 14, 40, 35)); + booking1.setEnd(LocalDateTime.of(2025, 7, 25, 18, 12, 43)); + booking1.setItemId(item.getItemId()); + booking1.setBookerId(user1.getUserId()); + bookingService.addBooking(booking1, user.getUserId()); + + BookingRequestDto booking2 = booking1ForCreate(); + booking2.setStart(LocalDateTime.of(2025, 3, 7, 14, 40, 35)); + booking2.setEnd(LocalDateTime.of(2025, 5, 25, 18, 12, 43)); + booking2.setItemId(item.getItemId()); + booking2.setBookerId(user1.getUserId()); + bookingService.addBooking(booking2, user.getUserId()); + + Collection bookings = bookingService.getBookingsByOwner(item.getOwnerId(), "CURRENT"); + assertAll(() -> { assertNotNull(bookings); - assertEquals(2, bookings.size()); + assertEquals(1, bookings.size()); }); } @Test public void getBookingByOwnerPastTest() { - Collection bookings = bookingService.getBookingsByOwner(itemResponseDto1.getOwnerId(), "PAST"); + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + UserResponseDto user1 = userService.createUser(user2ForCreate()); + + BookingRequestDto booking1 = booking1ForCreate(); + booking1.setStart(LocalDateTime.of(2025, 7, 7, 14, 40, 35)); + booking1.setEnd(LocalDateTime.of(2025, 7, 25, 18, 12, 43)); + booking1.setItemId(item.getItemId()); + booking1.setBookerId(user1.getUserId()); + bookingService.addBooking(booking1, user.getUserId()); + + BookingRequestDto booking2 = booking1ForCreate(); + booking2.setStart(LocalDateTime.of(2025, 3, 7, 14, 40, 35)); + booking2.setEnd(LocalDateTime.of(2025, 5, 25, 18, 12, 43)); + booking2.setItemId(item.getItemId()); + booking2.setBookerId(user1.getUserId()); + bookingService.addBooking(booking2, user.getUserId()); + + Collection bookings = bookingService.getBookingsByOwner(item.getOwnerId(), "PAST"); + assertAll(() -> { assertNotNull(bookings); assertEquals(1, bookings.size()); @@ -217,7 +449,26 @@ public void getBookingByOwnerPastTest() { @Test public void getBookingByOwnerFutureTest() { - Collection bookings = bookingService.getBookingsByOwner(itemResponseDto1.getOwnerId(), "FUTURE"); + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + UserResponseDto user1 = userService.createUser(user2ForCreate()); + + BookingRequestDto booking1 = booking1ForCreate(); + booking1.setStart(LocalDateTime.of(2025, 7, 7, 14, 40, 35)); + booking1.setEnd(LocalDateTime.of(2025, 7, 25, 18, 12, 43)); + booking1.setItemId(item.getItemId()); + booking1.setBookerId(user1.getUserId()); + bookingService.addBooking(booking1, user.getUserId()); + + BookingRequestDto booking2 = booking1ForCreate(); + booking2.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + booking2.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + booking2.setItemId(item.getItemId()); + booking2.setBookerId(user.getUserId()); + bookingService.addBooking(booking2, user.getUserId()); + + Collection bookings = bookingService.getBookingsByOwner(item.getOwnerId(), "FUTURE"); + assertAll(() -> { assertNotNull(bookings); assertEquals(1, bookings.size()); @@ -226,7 +477,32 @@ public void getBookingByOwnerFutureTest() { @Test public void getBookingByOwnerWaitingTest() { - Collection bookings = bookingService.getBookingsByOwner(itemResponseDto1.getOwnerId(), "WAITING"); + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + UserResponseDto user1 = userService.createUser(user2ForCreate()); + + BookingRequestDto booking1 = booking1ForCreate(); + booking1.setStart(LocalDateTime.of(2025, 7, 7, 14, 40, 35)); + booking1.setEnd(LocalDateTime.of(2025, 7, 25, 18, 12, 43)); + booking1.setItemId(item.getItemId()); + booking1.setBookerId(user1.getUserId()); + bookingService.addBooking(booking1, user.getUserId()); + + BookingRequestDto booking2 = booking1ForCreate(); + booking2.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + booking2.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + booking2.setItemId(item.getItemId()); + booking2.setBookerId(user.getUserId()); + bookingService.addBooking(booking2, user.getUserId()); + + BookingRequestDto booking3 = booking1ForCreate(); + booking3.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + booking3.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + booking3.setItemId(item.getItemId()); + booking3.setBookerId(user.getUserId()); + bookingService.addBooking(booking3, user.getUserId()); + + Collection bookings = bookingService.getBookingsByOwner(item.getOwnerId(), "WAITING"); assertAll(() -> { assertNotNull(bookings); assertEquals(3, bookings.size()); @@ -235,7 +511,36 @@ public void getBookingByOwnerWaitingTest() { @Test public void getBookingByOwnerRejectedTest() { - Collection bookings = bookingService.getBookingsByOwner(itemResponseDto1.getOwnerId(), "REJECTED"); + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + UserResponseDto user1 = userService.createUser(user2ForCreate()); + ItemResponseDto item2 = itemService.createItem(item2ForCreate(), user.getUserId()); + + BookingRequestDto booking1 = booking1ForCreate(); + booking1.setStart(LocalDateTime.of(2025, 7, 7, 14, 40, 35)); + booking1.setEnd(LocalDateTime.of(2025, 7, 25, 18, 12, 43)); + booking1.setItemId(item.getItemId()); + booking1.setBookerId(user1.getUserId()); + bookingService.addBooking(booking1, user.getUserId()); + + BookingRequestDto booking2 = booking1ForCreate(); + booking2.setStart(LocalDateTime.of(2025, 8, 8, 15, 45, 30)); + booking2.setEnd(LocalDateTime.of(2025, 8, 18, 12, 10, 40)); + booking2.setItemId(item.getItemId()); + booking2.setBookerId(user1.getUserId()); + bookingService.addBooking(booking2, user.getUserId()); + + BookingRequestDto booking3 = booking1ForCreate(); + booking3.setStart(LocalDateTime.of(2025, 5, 7, 14, 40, 35)); + booking3.setEnd(LocalDateTime.of(2025, 10, 25, 18, 12, 43)); + booking3.setItemId(item2.getItemId()); + booking3.setBookerId(user1.getUserId()); + assertThrows(ValidationException.class, + () -> bookingService.addBooking(booking3, user.getUserId())); + + + Collection bookings = bookingService.getBookingsByOwner(item.getOwnerId(), "REJECTED"); + assertAll(() -> { assertNotNull(bookings); assertEquals(1, bookings.size()); diff --git a/server/src/test/java/ru/practicum/shareit/serviceTest/ItemServiceTest.java b/server/src/test/java/ru/practicum/shareit/serviceTest/ItemServiceTest.java index 6932f03..abb2b5d 100644 --- a/server/src/test/java/ru/practicum/shareit/serviceTest/ItemServiceTest.java +++ b/server/src/test/java/ru/practicum/shareit/serviceTest/ItemServiceTest.java @@ -5,36 +5,47 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.jdbc.Sql; import ru.practicum.shareit.TestData; +import ru.practicum.shareit.booking.BookingServiceImpl; +import ru.practicum.shareit.booking.dto.BookingRequestDto; +import ru.practicum.shareit.booking.dto.BookingResponseDto; import ru.practicum.shareit.exception.AnotherUserException; import ru.practicum.shareit.exception.NotFoundException; import ru.practicum.shareit.exception.ValidationException; import ru.practicum.shareit.item.ItemServiceImpl; import ru.practicum.shareit.item.dto.*; +import ru.practicum.shareit.request.RequestServiceImpl; +import ru.practicum.shareit.request.dto.RequestInputDto; +import ru.practicum.shareit.request.dto.RequestOutputDto; +import ru.practicum.shareit.user.UserServiceImpl; +import ru.practicum.shareit.user.dto.UserResponseDto; +import java.time.LocalDateTime; import java.util.Collection; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.junit.jupiter.api.Assertions.*; @Transactional -@SpringBootTest +@SpringBootTest(properties = "jdbc.url=jdbc:h2:mem:testdb;MODE=PostgreSQL", + webEnvironment = SpringBootTest.WebEnvironment.NONE) @RequiredArgsConstructor(onConstructor = @__(@Autowired)) -@Sql(value = "/test-data.sql") -@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) public class ItemServiceTest extends TestData { private final ItemServiceImpl itemService; + private final UserServiceImpl userService; + private final RequestServiceImpl requestService; + private final BookingServiceImpl bookingService; @Test public void addItemTest() { + UserResponseDto user = userService.createUser(userForCreate()); + ItemRequestDto forCreation = new ItemRequestDto(); forCreation.setItemName("Test"); forCreation.setItemDescription("Test item description"); forCreation.setIsAvailable(true); - ItemResponseDto saved = itemService.createItem(forCreation, user1.getUserId()); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); assertAll(() -> { assertNotNull(saved); @@ -45,6 +56,8 @@ public void addItemTest() { @Test void addItem_WithNullOwnerIdTest() { + UserResponseDto user = userService.createUser(userForCreate()); + ItemRequestDto forCreation = new ItemRequestDto(); forCreation.setItemName("Test"); forCreation.setItemDescription("Test item description"); @@ -56,62 +69,99 @@ void addItem_WithNullOwnerIdTest() { @Test void addItem_WithUserNotFoundTest() { + UserResponseDto user = userService.createUser(userForCreate()); + ItemRequestDto forCreation = new ItemRequestDto(); forCreation.setItemName("Test"); forCreation.setItemDescription("Test item description"); forCreation.setIsAvailable(true); assertThrows(NotFoundException.class, - () -> itemService.createItem(forCreation, 5L)); + () -> itemService.createItem(forCreation, 573L)); } @Test void addItem_WithRequestIdTest() { + UserResponseDto user = userService.createUser(userForCreate()); + + RequestInputDto request = new RequestInputDto(); + request.setRequestDescription("Test request description"); + RequestOutputDto reqSaved = requestService.addItemRequest(request, user.getUserId()); + ItemRequestDto forCreation = new ItemRequestDto(); forCreation.setItemName("Test"); forCreation.setItemDescription("Test item description"); forCreation.setIsAvailable(true); - forCreation.setRequestId(1L); + forCreation.setRequestId(reqSaved.getItemRequestId()); - ItemResponseDto saved = itemService.createItem(forCreation, user1.getUserId()); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); assertAll(() -> { assertNotNull(saved); - assertEquals(1L, saved.getRequestId()); + assertEquals(reqSaved.getItemRequestId(), saved.getRequestId()); }); } @Test void addItem_WithWrongRequestIdTest() { + UserResponseDto user = userService.createUser(userForCreate()); + ItemRequestDto forCreation = new ItemRequestDto(); forCreation.setItemName("Test"); forCreation.setItemDescription("Test item description"); forCreation.setIsAvailable(true); - forCreation.setRequestId(5L); + forCreation.setRequestId(525L); assertThrows(NotFoundException.class, - () -> itemService.createItem(forCreation, user1.getUserId())); + () -> itemService.createItem(forCreation, user.getUserId())); } @Test void getItemByIdTest() { - ItemResponseDtoWithComments found = itemService.getItemById(1L, 1L); + UserResponseDto user = userService.createUser(userForCreate()); + + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); + + ItemResponseDtoWithComments found = itemService.getItemById(saved.getItemId(), user.getUserId()); assertAll(() -> { assertNotNull(found); - assertThat(found.getItemId()).isEqualTo(1L); + assertThat(found.getItemId()).isEqualTo(saved.getItemId()); }); } @Test void getItemById_WithWrongItemIdTest() { + UserResponseDto user = userService.createUser(userForCreate()); + + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); + + ItemResponseDtoWithComments found = itemService.getItemById(saved.getItemId(), user.getUserId()); + assertThrows(NotFoundException.class, - () -> itemService.getItemById(5L, 2L)); + () -> itemService.getItemById(535L, user.getUserId())); } @Test void getItemById_WithOwnerIdTest() { - ItemResponseDtoWithComments found = itemService.getItemById(1L, 1L); + UserResponseDto user = userService.createUser(userForCreate()); + + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); + + ItemResponseDtoWithComments found = itemService.getItemById(saved.getItemId(), user.getUserId()); + assertAll(() -> { assertNotNull(found); assertNotNull(found.getComments()); @@ -119,8 +169,16 @@ void getItemById_WithOwnerIdTest() { } @Test - void getItemById_WithNotOwnerIdTest() { - ItemResponseDtoWithComments found = itemService.getItemById(2L, 1L); + void getItemById_WithWrongOwnerIdTest() { + UserResponseDto user = userService.createUser(userForCreate()); + + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); + + ItemResponseDtoWithComments found = itemService.getItemById(saved.getItemId(), 237L); assertAll(() -> { assertNotNull(found); assertEquals(0, found.getComments().size()); @@ -129,7 +187,23 @@ void getItemById_WithNotOwnerIdTest() { @Test void getItemById_WithOwnerId_AndLastBookingTest() { - ItemResponseDtoWithComments found = itemService.getItemById(1L, 1L); + UserResponseDto user = userService.createUser(userForCreate()); + UserResponseDto user2 = userService.createUser(user2ForCreate()); + + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); + + BookingRequestDto booking2 = booking1ForCreate(); + booking2.setStart(LocalDateTime.of(2025, 3, 7, 14, 40, 35)); + booking2.setEnd(LocalDateTime.of(2025, 5, 25, 18, 12, 43)); + booking2.setItemId(saved.getItemId()); + booking2.setBookerId(user2.getUserId()); + bookingService.addBooking(booking2, user2.getUserId()); + + ItemResponseDtoWithComments found = itemService.getItemById(saved.getItemId(), user.getUserId()); assertAll(() -> { assertNotNull(found); assertNotNull(found.getLastBooking()); @@ -138,7 +212,23 @@ void getItemById_WithOwnerId_AndLastBookingTest() { @Test void getItemById_WithOwnerId_AndNextBookingTest() { - ItemResponseDtoWithComments found = itemService.getItemById(1L, 1L); + UserResponseDto user = userService.createUser(userForCreate()); + UserResponseDto user2 = userService.createUser(user2ForCreate()); + + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); + + BookingRequestDto booking2 = booking1ForCreate(); + booking2.setStart(LocalDateTime.of(2025, 9, 7, 14, 40, 35)); + booking2.setEnd(LocalDateTime.of(2025, 10, 25, 18, 12, 43)); + booking2.setItemId(saved.getItemId()); + booking2.setBookerId(user2.getUserId()); + bookingService.addBooking(booking2, user2.getUserId()); + + ItemResponseDtoWithComments found = itemService.getItemById(saved.getItemId(), user.getUserId()); assertAll(() -> { assertNotNull(found); assertNotNull(found.getNextBooking()); @@ -147,12 +237,21 @@ void getItemById_WithOwnerId_AndNextBookingTest() { @Test void updateItemTest() { + UserResponseDto user = userService.createUser(userForCreate()); + + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); + ItemRequestDto forUpdate = new ItemRequestDto(); - forUpdate.setItemName("Test"); - forUpdate.setItemDescription("Test item description"); + forUpdate.setItemName("TestName"); + forUpdate.setItemDescription("Test description"); forUpdate.setIsAvailable(true); - ItemResponseDto updated = itemService.updateItem(1L, forUpdate, user1.getUserId()); + ItemResponseDto updated = itemService.updateItem(saved.getItemId(), forUpdate, user.getUserId()); + assertAll(() -> { assertNotNull(updated); assertThat(forUpdate).usingRecursiveComparison() @@ -162,23 +261,40 @@ void updateItemTest() { @Test void updateItem_WithWrongOwnerTest() { + UserResponseDto user = userService.createUser(userForCreate()); + UserResponseDto user2 = userService.createUser(user2ForCreate()); + + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); + ItemRequestDto forUpdate = new ItemRequestDto(); - forUpdate.setItemName("Test"); - forUpdate.setItemDescription("Test item description"); + forUpdate.setItemName("TestName"); + forUpdate.setItemDescription("Test description"); forUpdate.setIsAvailable(true); assertThrows(AnotherUserException.class, - () -> itemService.updateItem(1L, forUpdate, user2.getUserId())); + () -> itemService.updateItem(saved.getItemId(), forUpdate, user2.getUserId())); } @Test void updateItem_WithoutItemNameTest() { + UserResponseDto user = userService.createUser(userForCreate()); + + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); + ItemRequestDto forUpdate = new ItemRequestDto(); forUpdate.setItemDescription("Test item description"); forUpdate.setIsAvailable(true); - ItemResponseDto updated = itemService.updateItem(1L, forUpdate, user1.getUserId()); + ItemResponseDto updated = itemService.updateItem(saved.getItemId(), forUpdate, user.getUserId()); assertAll(() -> { assertNotNull(updated); assertThat(forUpdate).usingRecursiveComparison() @@ -188,11 +304,19 @@ void updateItem_WithoutItemNameTest() { @Test void updateItem_WithoutItemDescriptionTest() { + UserResponseDto user = userService.createUser(userForCreate()); + + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); + ItemRequestDto forUpdate = new ItemRequestDto(); forUpdate.setItemName("Test"); forUpdate.setIsAvailable(true); - ItemResponseDto updated = itemService.updateItem(1L, forUpdate, user1.getUserId()); + ItemResponseDto updated = itemService.updateItem(saved.getItemId(), forUpdate, user.getUserId()); assertAll(() -> { assertNotNull(updated); assertThat(forUpdate).usingRecursiveComparison() @@ -202,11 +326,19 @@ void updateItem_WithoutItemDescriptionTest() { @Test void updateItem_WithoutIsAvailableTest() { + UserResponseDto user = userService.createUser(userForCreate()); + + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); + ItemRequestDto forUpdate = new ItemRequestDto(); forUpdate.setItemName("Test"); forUpdate.setItemDescription("Test item description"); - ItemResponseDto updated = itemService.updateItem(1L, forUpdate, user1.getUserId()); + ItemResponseDto updated = itemService.updateItem(saved.getItemId(), forUpdate, user.getUserId()); assertAll(() -> { assertNotNull(updated); assertThat(forUpdate).usingRecursiveComparison() @@ -216,25 +348,70 @@ void updateItem_WithoutIsAvailableTest() { @Test void getAllItemsForOwnerTest() { - Collection items = itemService.getAllItemsForOwner(user1.getUserId()); + UserResponseDto user = userService.createUser(userForCreate()); + + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); + + ItemRequestDto forCreation2 = new ItemRequestDto(); + forCreation2.setItemName("Test2"); + forCreation2.setItemDescription("Test item description2"); + forCreation2.setIsAvailable(true); + ItemResponseDto saved2 = itemService.createItem(forCreation2, user.getUserId()); + + Collection items = itemService.getAllItemsForOwner(user.getUserId()); assertAll(() -> { assertNotNull(items); - assertEquals(1, items.size()); + assertEquals(2, items.size()); }); } @Test void getAllItemsForOwner_WithWrongUserTest() { + UserResponseDto user = userService.createUser(userForCreate()); + + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); + + ItemRequestDto forCreation2 = new ItemRequestDto(); + forCreation2.setItemName("Test2"); + forCreation2.setItemDescription("Test item description2"); + forCreation2.setIsAvailable(true); + ItemResponseDto saved2 = itemService.createItem(forCreation2, user.getUserId()); + assertThrows(NotFoundException.class, - () -> itemService.getAllItemsForOwner(5L)); + () -> itemService.getAllItemsForOwner(458L)); } @Test void addCommentTest() { + UserResponseDto user = userService.createUser(userForCreate()); + UserResponseDto user2 = userService.createUser(user2ForCreate()); + + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); + + BookingRequestDto booking2 = booking1ForCreate(); + booking2.setStart(LocalDateTime.of(2025, 3, 7, 14, 40, 35)); + booking2.setEnd(LocalDateTime.of(2025, 5, 25, 18, 12, 43)); + booking2.setItemId(saved.getItemId()); + booking2.setBookerId(user2.getUserId()); + BookingResponseDto bookingSaved = bookingService.addBooking(booking2, user.getUserId()); + bookingService.bookingApprove(bookingSaved.getBookingId(), user.getUserId(), false); + CommentRequestDto comment = new CommentRequestDto(); comment.setText("Test comment"); - CommentResponseCreatedDto created = itemService.addComment(1L, comment, 2L); + CommentResponseCreatedDto created = itemService.addComment(user.getUserId(), comment, saved.getItemId()); assertAll(() -> { assertNotNull(created); @@ -244,25 +421,67 @@ void addCommentTest() { @Test void addComment_WithWrongCommentatorTest() { + UserResponseDto user = userService.createUser(userForCreate()); + UserResponseDto user2 = userService.createUser(user2ForCreate()); + + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); + + BookingRequestDto booking2 = booking1ForCreate(); + booking2.setStart(LocalDateTime.of(2025, 3, 7, 14, 40, 35)); + booking2.setEnd(LocalDateTime.of(2025, 5, 25, 18, 12, 43)); + booking2.setItemId(saved.getItemId()); + booking2.setBookerId(user2.getUserId()); + BookingResponseDto bookingSaved = bookingService.addBooking(booking2, user.getUserId()); + bookingService.bookingApprove(bookingSaved.getBookingId(), user.getUserId(), false); + CommentRequestDto comment = new CommentRequestDto(); comment.setText("Test comment"); assertThrows(NotFoundException.class, - () -> itemService.addComment(5L, comment, 2L)); + () -> itemService.addComment(256L, comment, saved.getItemId())); } @Test void addComment_WithWrongDateTest() { + UserResponseDto user = userService.createUser(userForCreate()); + UserResponseDto user2 = userService.createUser(user2ForCreate()); + + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); + + BookingRequestDto booking2 = booking1ForCreate(); + booking2.setStart(LocalDateTime.of(2025, 6, 8, 14, 40, 35)); + booking2.setEnd(LocalDateTime.of(2025, 9, 25, 18, 12, 43)); + booking2.setItemId(saved.getItemId()); + booking2.setBookerId(user2.getUserId()); + BookingResponseDto bookingSaved = bookingService.addBooking(booking2, user.getUserId()); + bookingService.bookingApprove(bookingSaved.getBookingId(), user.getUserId(), false); + CommentRequestDto comment = new CommentRequestDto(); comment.setText("Test comment"); assertThrows(ValidationException.class, - () -> itemService.addComment(1L, comment, 1L)); + () -> itemService.addComment(user.getUserId(), comment, saved.getItemId())); } @Test void searchByTextTest() { - Collection items = itemService.searchByText("testItem2"); + UserResponseDto user = userService.createUser(userForCreate()); + + ItemRequestDto forCreation = new ItemRequestDto(); + forCreation.setItemName("Test"); + forCreation.setItemDescription("Test item description"); + forCreation.setIsAvailable(true); + ItemResponseDto saved = itemService.createItem(forCreation, user.getUserId()); + + Collection items = itemService.searchByText("Test"); assertAll(() -> { assertNotNull(items); diff --git a/server/src/test/java/ru/practicum/shareit/serviceTest/RequestServiceTest.java b/server/src/test/java/ru/practicum/shareit/serviceTest/RequestServiceTest.java index ddbc306..f03f612 100644 --- a/server/src/test/java/ru/practicum/shareit/serviceTest/RequestServiceTest.java +++ b/server/src/test/java/ru/practicum/shareit/serviceTest/RequestServiceTest.java @@ -5,14 +5,16 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.jdbc.Sql; import ru.practicum.shareit.TestData; import ru.practicum.shareit.exception.NotFoundException; +import ru.practicum.shareit.item.ItemServiceImpl; +import ru.practicum.shareit.item.dto.ItemResponseDto; import ru.practicum.shareit.request.RequestServiceImpl; import ru.practicum.shareit.request.dto.RequestInputDto; import ru.practicum.shareit.request.dto.RequestOutputDto; import ru.practicum.shareit.request.dto.RequestOutputWithItemsDto; +import ru.practicum.shareit.user.UserServiceImpl; +import ru.practicum.shareit.user.dto.UserResponseDto; import java.util.List; @@ -21,36 +23,50 @@ @Transactional -@SpringBootTest +@SpringBootTest(properties = "jdbc.url=jdbc:h2:mem:testdb;MODE=PostgreSQL", + webEnvironment = SpringBootTest.WebEnvironment.NONE) @RequiredArgsConstructor(onConstructor = @__(@Autowired)) -@Sql(value = "/test-data.sql") -@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) public class RequestServiceTest extends TestData { private final RequestServiceImpl requestService; + private final UserServiceImpl userService; + private final ItemServiceImpl itemService; @Test void addRequestTest() { - RequestInputDto requestInputDto = new RequestInputDto(); - requestInputDto.setRequestDescription("RequestDescription"); + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + + RequestInputDto request = new RequestInputDto(); + request.setRequestDescription("Test request description1"); - RequestOutputDto requestOutputDto = requestService.addItemRequest(requestInputDto, user1.getUserId()); + RequestOutputDto requestOutputDto = requestService.addItemRequest(request, user.getUserId()); assertThat(requestOutputDto).usingRecursiveComparison() - .ignoringFields("itemRequestId", "requester").isEqualTo(requestInputDto); + .ignoringFields("itemRequestId", "requester").isEqualTo(request); } @Test void addRequest_WithWrongUserTest() { + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + RequestInputDto requestInputDto = new RequestInputDto(); requestInputDto.setRequestDescription("RequestDescription"); assertThrows(NotFoundException.class, - () -> requestService.addItemRequest(requestInputDto, 5L)); + () -> requestService.addItemRequest(requestInputDto, 125L)); } @Test void getRequestByUserTest() { - List requests = requestService.getRequestByUser(user1.getUserId()); + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + + RequestInputDto request = new RequestInputDto(); + request.setRequestDescription("RequestDescription"); + requestService.addItemRequest(request, user.getUserId()); + + List requests = requestService.getRequestByUser(user.getUserId()); assertAll(() -> { assertNotNull(requests); @@ -60,13 +76,32 @@ void getRequestByUserTest() { @Test void getRequestByWrongUserTest() { + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + + RequestInputDto request = new RequestInputDto(); + request.setRequestDescription("RequestDescription"); + requestService.addItemRequest(request, user.getUserId()); + assertThrows(NotFoundException.class, - () -> requestService.getRequestByUser(5L)); + () -> requestService.getRequestByUser(526L)); } @Test void getAllRequestsTest() { + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + + RequestInputDto request = new RequestInputDto(); + request.setRequestDescription("RequestDescription"); + requestService.addItemRequest(request, user.getUserId()); + + RequestInputDto request1 = new RequestInputDto(); + request1.setRequestDescription("RequestDescription1"); + requestService.addItemRequest(request1, user.getUserId()); + List requests = requestService.getAllRequests(); + assertAll(() -> { assertNotNull(requests); assertThat(requests.size()).isEqualTo(2); @@ -75,16 +110,39 @@ void getAllRequestsTest() { @Test void getRequestByIdTest() { - RequestOutputWithItemsDto found = requestService.getRequestById(1L); + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + + RequestInputDto request = new RequestInputDto(); + request.setRequestDescription("RequestDescription"); + requestService.addItemRequest(request, user.getUserId()); + + RequestInputDto request1 = new RequestInputDto(); + request1.setRequestDescription("RequestDescription1"); + RequestOutputDto saved = requestService.addItemRequest(request1, user.getUserId()); + + RequestOutputWithItemsDto found = requestService.getRequestById(saved.getItemRequestId()); + assertAll(() -> { assertNotNull(found); - assertEquals(1L, found.getItemRequestId()); + assertEquals(saved.getItemRequestId(), found.getItemRequestId()); }); } @Test void getRequestByWrongIdTest() { + UserResponseDto user = userService.createUser(userForCreate()); + ItemResponseDto item = itemService.createItem(itemForCreate(), user.getUserId()); + + RequestInputDto request = new RequestInputDto(); + request.setRequestDescription("RequestDescription"); + requestService.addItemRequest(request, user.getUserId()); + + RequestInputDto request1 = new RequestInputDto(); + request1.setRequestDescription("RequestDescription1"); + RequestOutputDto saved = requestService.addItemRequest(request1, user.getUserId()); + assertThrows(NotFoundException.class, - () -> requestService.getRequestById(7L)); + () -> requestService.getRequestById(73L)); } } diff --git a/server/src/test/java/ru/practicum/shareit/serviceTest/UserServiceTest.java b/server/src/test/java/ru/practicum/shareit/serviceTest/UserServiceTest.java index 93abdae..a2ab1b3 100644 --- a/server/src/test/java/ru/practicum/shareit/serviceTest/UserServiceTest.java +++ b/server/src/test/java/ru/practicum/shareit/serviceTest/UserServiceTest.java @@ -5,8 +5,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.jdbc.Sql; import ru.practicum.shareit.TestData; import ru.practicum.shareit.exception.DuplicatedDataException; import ru.practicum.shareit.exception.NotFoundException; @@ -22,10 +20,9 @@ import static org.junit.jupiter.api.Assertions.*; @Transactional -@SpringBootTest +@SpringBootTest(properties = "jdbc.url=jdbc:h2:mem:testdb;MODE=PostgreSQL", + webEnvironment = SpringBootTest.WebEnvironment.NONE) @RequiredArgsConstructor(onConstructor = @__(@Autowired)) -@Sql(value = "/test-data.sql") -@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) public class UserServiceTest extends TestData { private final UserServiceImpl userService; private final UserRepository userRepository; @@ -45,17 +42,20 @@ void addUserTest() { @Test void createUser_WithWrongEmailTest() { + userService.createUser(userForCreate()); assertThrows(DuplicatedDataException.class, () -> userService.createUser(userRequestDto1)); } @Test void getUserByIdTest() { - UserResponseDto found = userService.getUserById(1L); + UserResponseDto user = userService.createUser(userForCreate()); + + UserResponseDto found = userService.getUserById(user.getUserId()); assertAll(() -> { assertNotNull(found); - assertThat(found).usingRecursiveComparison().isEqualTo(userResponseDto1); + assertThat(found).usingRecursiveComparison().isEqualTo(user); }); } @@ -67,15 +67,18 @@ void getUserById_NotFoundExceptionTest() { @Test void updateUserTest() { + + UserResponseDto user = userService.createUser(userForCreate()); + UserRequestDto forUpdate = new UserRequestDto(); forUpdate.setUserName("UpdatedName"); forUpdate.setUserEmail("UpdatedEmail@mail.ru"); - UserResponseDto updated = new UserResponseDto(1L, "UpdatedName", "UpdatedEmail@mail.ru"); + UserResponseDto updated = new UserResponseDto(user.getUserId(), "UpdatedName", "UpdatedEmail@mail.ru"); - UserResponseDto userResponseDto = userService.updateUser(1L, forUpdate); + UserResponseDto userResponseDto = userService.updateUser(user.getUserId(), forUpdate); assertAll(() -> { - assertEquals(userBookingDto1.getUserId(), userResponseDto.getUserId()); + assertEquals(user.getUserId(), userResponseDto.getUserId()); assertThat(updated).usingRecursiveComparison().ignoringFields("userId").isEqualTo(userResponseDto); }); } @@ -91,11 +94,11 @@ void updateUserTest_NotFoundExceptionTest() { @Test void deleteUserByIdTest() { - assertEquals(userResponseDto1, userService.getUserById(1L)); + UserResponseDto user = userService.createUser(userForCreate()); - userService.deleteUser(1L); + userService.deleteUser(user.getUserId()); - assertThrows(NotFoundException.class, () -> userService.getUserById(1L)); + assertThrows(NotFoundException.class, () -> userService.getUserById(user.getUserId())); } From 2560fa698d069f2b58c395e18c4f25e4123d159d Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Mon, 14 Jul 2025 14:06:05 +0400 Subject: [PATCH 09/11] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2016=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20(=D1=81=20=D1=82=D0=B5=D1=81=D1=82=D0=B0=D0=BC=D0=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index ff9a374..6b5e23c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -31,7 +31,7 @@ services: environment: - POSTGRES_PASSWORD=12345 - POSTGRES_USER=user - - POSTGRES_DB=postgres + - POSTGRES_DB=shareit healthcheck: test: pg_isready -q -d $$POSTGRES_DB -U $$POSTGRES_USER timeout: 5s From 6c8c8efa829d058c36d586fa0ed9f76a9cace9b6 Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Mon, 14 Jul 2025 17:10:08 +0400 Subject: [PATCH 10/11] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2016=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20(=D1=81=20=D1=82=D0=B5=D1=81=D1=82=D0=B0=D0=BC=D0=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gateway/pom.xml | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/gateway/pom.xml b/gateway/pom.xml index e51a7fe..833b0ed 100644 --- a/gateway/pom.xml +++ b/gateway/pom.xml @@ -84,18 +84,7 @@ - - org.apache.maven.plugins - maven-jar-plugin - 3.4.1 - - - - com.baeldung.jar.JarExample - - - - + From aa13df101cf0bc226445248030bd9710176b9c7f Mon Sep 17 00:00:00 2001 From: NadezhdaTA Date: Tue, 15 Jul 2025 15:37:17 +0400 Subject: [PATCH 11/11] =?UTF-8?q?=D0=A4=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=2016=D0=B3=D0=BE=20=D1=81=D0=BF=D1=80=D0=B8=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20=D1=81=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shareit/item/ItemController.java | 3 +- .../shareit/request/RequestController.java | 3 +- .../shareit/request/RequestServiceImpl.java | 17 +- .../shareit/request/dto/RequestInputDto.java | 2 +- .../shareit/request/dto/RequestOutputDto.java | 2 +- .../dto/RequestOutputWithItemsDto.java | 2 +- .../request/interfaces/RequestRepository.java | 5 +- .../shareit/request/model/ItemRequest.java | 2 +- .../java/ru/practicum/shareit/TestData.java | 145 +++++++----------- 9 files changed, 69 insertions(+), 112 deletions(-) diff --git a/gateway/src/main/java/ru/practicum/shareit/item/ItemController.java b/gateway/src/main/java/ru/practicum/shareit/item/ItemController.java index 3faf006..05240a8 100644 --- a/gateway/src/main/java/ru/practicum/shareit/item/ItemController.java +++ b/gateway/src/main/java/ru/practicum/shareit/item/ItemController.java @@ -1,6 +1,7 @@ package ru.practicum.shareit.item; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; @@ -22,7 +23,7 @@ public class ItemController { @PostMapping public ResponseEntity create(@RequestHeader(OWNER_ID) Long ownerId, - @RequestBody ItemRequestDto item) { + @RequestBody @Valid ItemRequestDto item) { return itemService.create(ownerId, item); } diff --git a/gateway/src/main/java/ru/practicum/shareit/request/RequestController.java b/gateway/src/main/java/ru/practicum/shareit/request/RequestController.java index 1570287..3cd1da4 100644 --- a/gateway/src/main/java/ru/practicum/shareit/request/RequestController.java +++ b/gateway/src/main/java/ru/practicum/shareit/request/RequestController.java @@ -1,5 +1,6 @@ package ru.practicum.shareit.request; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -14,7 +15,7 @@ public class RequestController { public static final String USER_ID = "X-Sharer-User-Id"; @PostMapping - public ResponseEntity addRequest(@RequestBody RequestInputDto requestInputDto, + public ResponseEntity addRequest(@RequestBody @Valid RequestInputDto requestInputDto, @RequestHeader(USER_ID) Long userId) { return requestService.addItemRequest(requestInputDto, userId); } diff --git a/server/src/main/java/ru/practicum/shareit/request/RequestServiceImpl.java b/server/src/main/java/ru/practicum/shareit/request/RequestServiceImpl.java index c19ce0b..9ad3095 100644 --- a/server/src/main/java/ru/practicum/shareit/request/RequestServiceImpl.java +++ b/server/src/main/java/ru/practicum/shareit/request/RequestServiceImpl.java @@ -17,7 +17,6 @@ import ru.practicum.shareit.user.model.User; import java.util.Collection; -import java.util.Comparator; import java.util.List; @Service @@ -43,22 +42,17 @@ public RequestOutputDto addItemRequest(RequestInputDto requestDto, Long userId) public List getRequestByUser(Long userId) { User user = userRepository.findById(userId) .orElseThrow(() -> new NotFoundException("User not found")); - List requests = requestRepository.getRequestByRequester_UserId(userId); - return requestRepository.getRequestByRequester_UserId(userId).stream() + return requestRepository.findItemRequestByRequester_UserIdOrderByCreatedAtDesc(userId).stream() .map(requestMapper::toRequestOutputDto) - .sorted(Comparator.comparing(RequestOutputDto::getRequestDate)) - .toList() - .reversed(); + .toList(); } @Override public List getAllRequests() { - return requestRepository.findAll().stream() + return requestRepository.findAllByOrderByCreatedAtDesc().stream() .map(requestMapper::toRequestOutputDto) - .sorted(Comparator.comparing(RequestOutputDto::getRequestDate)) - .toList() - .reversed(); + .toList(); } @Override @@ -66,7 +60,8 @@ public RequestOutputWithItemsDto getRequestById(Long requestId) { ItemRequest itemRequest = requestRepository.getRequestByItemRequestId(requestId) .orElseThrow(() -> new NotFoundException("Request not found")); - Collection items = itemRepository.getItemsByItemRequest_ItemRequestId(requestId).stream() + Collection items = + itemRepository.getItemsByItemRequest_ItemRequestId(requestId).stream() .map(itemMapper::toItemResponseDto) .toList(); diff --git a/server/src/main/java/ru/practicum/shareit/request/dto/RequestInputDto.java b/server/src/main/java/ru/practicum/shareit/request/dto/RequestInputDto.java index 658010d..ace1634 100644 --- a/server/src/main/java/ru/practicum/shareit/request/dto/RequestInputDto.java +++ b/server/src/main/java/ru/practicum/shareit/request/dto/RequestInputDto.java @@ -17,5 +17,5 @@ public class RequestInputDto { @JsonProperty("description") private String requestDescription; - private LocalDateTime requestDate = LocalDateTime.now(); + private LocalDateTime createdAt = LocalDateTime.now(); } diff --git a/server/src/main/java/ru/practicum/shareit/request/dto/RequestOutputDto.java b/server/src/main/java/ru/practicum/shareit/request/dto/RequestOutputDto.java index 711abeb..0fafba4 100644 --- a/server/src/main/java/ru/practicum/shareit/request/dto/RequestOutputDto.java +++ b/server/src/main/java/ru/practicum/shareit/request/dto/RequestOutputDto.java @@ -21,5 +21,5 @@ public class RequestOutputDto { private UserBookingDto requester; @JsonProperty("created") - private LocalDateTime requestDate; + private LocalDateTime createdAt; } diff --git a/server/src/main/java/ru/practicum/shareit/request/dto/RequestOutputWithItemsDto.java b/server/src/main/java/ru/practicum/shareit/request/dto/RequestOutputWithItemsDto.java index 98d8d0b..75eeac8 100644 --- a/server/src/main/java/ru/practicum/shareit/request/dto/RequestOutputWithItemsDto.java +++ b/server/src/main/java/ru/practicum/shareit/request/dto/RequestOutputWithItemsDto.java @@ -23,7 +23,7 @@ public class RequestOutputWithItemsDto { private UserBookingDto requester; @JsonProperty("created") - private LocalDateTime requestDate; + private LocalDateTime createdAt; @JsonProperty("items") Collection items; diff --git a/server/src/main/java/ru/practicum/shareit/request/interfaces/RequestRepository.java b/server/src/main/java/ru/practicum/shareit/request/interfaces/RequestRepository.java index d6d8803..43b6b2b 100644 --- a/server/src/main/java/ru/practicum/shareit/request/interfaces/RequestRepository.java +++ b/server/src/main/java/ru/practicum/shareit/request/interfaces/RequestRepository.java @@ -9,9 +9,10 @@ public interface RequestRepository extends JpaRepository { ItemRequest save(ItemRequest item); - List getRequestByRequester_UserId(Long userId); + List findItemRequestByRequester_UserIdOrderByCreatedAtDesc(Long userId); - List findAll(); + List findAllByOrderByCreatedAtDesc(); Optional getRequestByItemRequestId(Long requestId); + } diff --git a/server/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java b/server/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java index ee3033a..a8e64d2 100644 --- a/server/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java +++ b/server/src/main/java/ru/practicum/shareit/request/model/ItemRequest.java @@ -30,5 +30,5 @@ public class ItemRequest { private User requester; @Column(name = "request_date") - private LocalDateTime requestDate; + private LocalDateTime createdAt; } diff --git a/server/src/test/java/ru/practicum/shareit/TestData.java b/server/src/test/java/ru/practicum/shareit/TestData.java index 5f035c8..e2c1e83 100644 --- a/server/src/test/java/ru/practicum/shareit/TestData.java +++ b/server/src/test/java/ru/practicum/shareit/TestData.java @@ -2,10 +2,8 @@ import ru.practicum.shareit.booking.dto.BookingRequestDto; import ru.practicum.shareit.booking.dto.BookingResponseDto; -import ru.practicum.shareit.booking.model.Booking; import ru.practicum.shareit.booking.model.BookingStatus; import ru.practicum.shareit.item.dto.*; -import ru.practicum.shareit.item.model.Comment; import ru.practicum.shareit.item.model.Item; import ru.practicum.shareit.request.dto.RequestInputDto; import ru.practicum.shareit.request.dto.RequestOutputDto; @@ -28,7 +26,8 @@ public class TestData { public static User user1 = new User(1L, "TestUser1", "user1@mail.ru"); public static UserBookingDto userBookingDto1 = new UserBookingDto(1L, "TestUser1"); public static UserAuthorDto userAuthorDto1 = new UserAuthorDto(1L, "TestUser1"); - public static UserRequestDto userRequestDto1 = new UserRequestDto(1L, "TestUser1", "user1@mail.ru"); + public static UserRequestDto userRequestDto1 = + new UserRequestDto(1L, "TestUser1", "user1@mail.ru"); public static UserRequestDto userForCreate() { UserRequestDto user = new UserRequestDto(); @@ -44,29 +43,31 @@ public static UserRequestDto user2ForCreate() { return user; } - public static UserResponseDto userResponseDto1 = new UserResponseDto(1L, "TestUser1", "user1@mail.ru"); + public static UserResponseDto userResponseDto1 = + new UserResponseDto(1L, "TestUser1", "user1@mail.ru"); public static User user2 = new User(2L, "TestUser2", "user2@mail.ru"); - public static UserBookingDto userBookingDto2 = new UserBookingDto(2L, "TestUser2"); - public static UserAuthorDto userAuthorDto2 = new UserAuthorDto(2L, "TestUser2"); - public static UserRequestDto userRequestDto2 = new UserRequestDto(2L, "TestUser2", "user2@mail.ru"); - public static UserResponseDto userResponseDto2 = new UserResponseDto(2L, "TestUser2", "user2@mail.ru"); - - - public static User user3 = new User(3L, "TestUser3", "user3@mail.ru"); + public static UserBookingDto userBookingDto2 = + new UserBookingDto(2L, "TestUser2"); + public static UserRequestDto userRequestDto2 = + new UserRequestDto(2L, "TestUser2", "user2@mail.ru"); + public static UserResponseDto userResponseDto2 = + new UserResponseDto(2L, "TestUser2", "user2@mail.ru"); public static ItemRequest request1 = new ItemRequest(1L, "Test request description1", user1, LocalDateTime.of(2025, 7, 7, 10, 15, 25)); public static RequestInputDto requestInputDto1 = new RequestInputDto(1L, "Test request description1", LocalDateTime.of(2025, 7, 7, 10, 15, 25)); - public static RequestOutputDto requestOutputDto1 = new RequestOutputDto(1L, "Test request description1", userBookingDto1, + public static RequestOutputDto requestOutputDto1 = new RequestOutputDto( + 1L, "Test request description1", userBookingDto1, LocalDateTime.of(2025, 7, 7, 10, 15, 25)); public static RequestOutputWithItemsDto requestWithItemsDto1 = new RequestOutputWithItemsDto(1L, "Test request description1", userBookingDto1, LocalDateTime.of(2025, 7, 7, 10, 15, 25), new ArrayList<>()); + public static ItemRequestDto itemForCreate() { ItemRequestDto request = new ItemRequestDto(); request.setItemName("testItem1"); @@ -93,19 +94,15 @@ public static ItemRequestDto itemForUpdate() { public static ItemRequest request2 = new ItemRequest(2L, "Test request description2", user2, LocalDateTime.of(2025, 8, 8, 15, 10, 20)); - public static RequestInputDto requestInputDto2 = new RequestInputDto(2L, "Test request description2", - LocalDateTime.of(2025, 8, 8, 15, 10, 20)); - public static RequestOutputDto requestOutputDto2 = new RequestOutputDto(2L, "Test request description2", + public static RequestOutputDto requestOutputDto2 = new RequestOutputDto( + 2L, "Test request description2", userBookingDto2, LocalDateTime.of(2025, 8, 8, 15, 10, 20)); - public static RequestOutputWithItemsDto requestWithItemsDto2 = new RequestOutputWithItemsDto(2L, - "Test request description2", userBookingDto2, - LocalDateTime.of(2025, 8, 8, 15, 10, 20), new ArrayList<>()); public static List requests = List.of(requestOutputDto1); - public static List allRequests = List.of(requestOutputDto1, requestOutputDto2); + public static Item item1 = new Item(1L, "testItem1", "test description1", false, user1, request1); public static ItemRequestDto itemRequestDto1 = new ItemRequestDto(1L, "testItem1", @@ -113,28 +110,29 @@ public static ItemRequestDto itemForUpdate() { public static ItemBookerDto itemBookerDto1 = new ItemBookerDto(1L, "testItem1"); public static ItemResponseDto itemResponseDto1 = new ItemResponseDto(1L, "testItem1", "test description1", false, user1.getUserId(), request1.getItemRequestId()); - public static ItemResponseDtoWithComments itemWithComments1 = new ItemResponseDtoWithComments(1L, "testItem1", - "test description1", false, user1.getUserId(), request1.getItemRequestId(), - new BookingResponseDto(), new BookingResponseDto(), new ArrayList<>()); + public static ItemResponseDtoWithComments itemWithComments1 = new ItemResponseDtoWithComments( + 1L, "testItem1", "test description1", false, + user1.getUserId(), request1.getItemRequestId(), new BookingResponseDto(), new BookingResponseDto(), new ArrayList<>()); - public static Item item2 = new Item(2L, "testItem2", - "test description2", true, user2, request2); public static ItemBookerDto itemBookerDto2 = new ItemBookerDto(2L, "testItem2"); public static ItemResponseDto itemResponseDto2 = new ItemResponseDto(2L, "testItem2", "test description2", true, user2.getUserId(), request2.getItemRequestId()); - public static ItemResponseDtoWithComments itemWithComments2 = new ItemResponseDtoWithComments(2L, - "testItem2", "test description2", true, user2.getUserId(), request2.getItemRequestId(), - new BookingResponseDto(), new BookingResponseDto(), new ArrayList<>()); public Collection itemsForOwner = List.of(itemResponseDto1); - public Collection itemsFound = List.of(itemResponseDto2); - public static BookingResponseDto responseBooking1 = new BookingResponseDto(1L, LocalDateTime.of(2025, 7, 7, 14, 40, 35), - LocalDateTime.of(2025, 7, 15, 18, 12, 43), itemBookerDto1, userBookingDto1, BookingStatus.WAITING); - public static BookingRequestDto bookingRequestDto1 = new BookingRequestDto(1L, LocalDateTime.of(2025, 7, 7, 14, 40, 35), - LocalDateTime.of(2025, 7, 15, 18, 12, 43), itemBookerDto1.getItemId(), userBookingDto1.getUserId(), BookingStatus.WAITING); + + public static BookingResponseDto responseBooking1 = new BookingResponseDto(1L, + LocalDateTime.of(2025, 7, 7, 14, 40, 35), + LocalDateTime.of(2025, 7, 15, 18, 12, 43), + itemBookerDto1, userBookingDto1, BookingStatus.WAITING); + + public static BookingRequestDto bookingRequestDto1 = new BookingRequestDto(1L, + LocalDateTime.of(2025, 7, 7, 14, 40, 35), + LocalDateTime.of(2025, 7, 15, 18, 12, 43), + itemBookerDto1.getItemId(), userBookingDto1.getUserId(), BookingStatus.WAITING); + public static BookingRequestDto booking1ForCreate() { BookingRequestDto bookingRequestDto = new BookingRequestDto(); @@ -146,73 +144,34 @@ public static BookingRequestDto booking1ForCreate() { return bookingRequestDto; } - public static BookingResponseDto responseBooking2 = new BookingResponseDto(2L, LocalDateTime.of(2025, 8, 8, 15, 45, 30), - LocalDateTime.of(2025, 8, 18, 12, 10, 40), itemBookerDto2, userBookingDto2, BookingStatus.APPROVED); + public static BookingResponseDto responseBooking2 = new BookingResponseDto( + 2L, LocalDateTime.of(2025, 8, 8, 15, 45, 30), + LocalDateTime.of(2025, 8, 18, 12, 10, 40), + itemBookerDto2, userBookingDto2, BookingStatus.APPROVED); - public static BookingResponseDto responseBooking3 = new BookingResponseDto(3L, LocalDateTime.of(2025, 3, 7, 14, 40, 35), - LocalDateTime.of(2025, 5, 25, 18, 12, 43), itemBookerDto1, userBookingDto1, BookingStatus.WAITING); + public static BookingResponseDto responseBooking3 = new BookingResponseDto( + 3L, LocalDateTime.of(2025, 3, 7, 14, 40, 35), + LocalDateTime.of(2025, 5, 25, 18, 12, 43), + itemBookerDto1, userBookingDto1, BookingStatus.WAITING); + public static BookingResponseDto responseBooking4 = new BookingResponseDto( + 4L, LocalDateTime.of(2025, 9, 7, 14, 40, 35), + LocalDateTime.of(2025, 10, 25, 18, 12, 43), + itemBookerDto1, userBookingDto1, BookingStatus.WAITING); - public static Booking bookingFuture = new Booking(4L, LocalDateTime.of(2025, 9, 7, 14, 40, 35), - LocalDateTime.of(2025, 10, 25, 18, 12, 43), item1, user1, BookingStatus.WAITING); - public static BookingResponseDto responseBooking4 = new BookingResponseDto(4L, LocalDateTime.of(2025, 9, 7, 14, 40, 35), - LocalDateTime.of(2025, 10, 25, 18, 12, 43), itemBookerDto1, userBookingDto1, BookingStatus.WAITING); + public static BookingResponseDto responseBooking5 = new BookingResponseDto( + 5L, LocalDateTime.of(2025, 5, 7, 14, 40, 35), + LocalDateTime.of(2025, 10, 25, 18, 12, 43), + itemBookerDto1, userBookingDto1, BookingStatus.REJECTED); + public Collection bookings = + Arrays.asList(responseBooking1, responseBooking2, responseBooking3, responseBooking4, responseBooking5); - public static BookingRequestDto booking4ForCreate() { - BookingRequestDto bookingRequestDto = new BookingRequestDto(); - bookingRequestDto.setStart(LocalDateTime.of(2025, 9, 7, 14, 40, 35)); - bookingRequestDto.setEnd(LocalDateTime.of(2025, 10, 25, 18, 12, 43)); - bookingRequestDto.setItemId(1L); - bookingRequestDto.setStatus(BookingStatus.WAITING); - return bookingRequestDto; - } - - public static Booking bookingRejected = new Booking(5L, LocalDateTime.of(2025, 5, 7, 14, 40, 35), - LocalDateTime.of(2025, 10, 25, 18, 12, 43), item1, user1, BookingStatus.REJECTED); - public static BookingResponseDto responseBooking5 = new BookingResponseDto(5L, LocalDateTime.of(2025, 5, 7, 14, 40, 35), - LocalDateTime.of(2025, 10, 25, 18, 12, 43), itemBookerDto1, userBookingDto1, BookingStatus.REJECTED); + public Collection bookingsForOwner = + Arrays.asList(responseBooking1, responseBooking3, responseBooking4, responseBooking5); - public static BookingRequestDto booking5ForCreate() { - BookingRequestDto bookingRequestDto = new BookingRequestDto(); - bookingRequestDto.setStart(LocalDateTime.of(2025, 5, 7, 14, 40, 35)); - bookingRequestDto.setEnd(LocalDateTime.of(2025, 10, 25, 18, 12, 43)); - bookingRequestDto.setItemId(1L); - bookingRequestDto.setStatus(BookingStatus.REJECTED); - return bookingRequestDto; - } - - public static BookingRequestDto bookingForUpdate() { - BookingRequestDto bookingRequestDto = new BookingRequestDto(); - bookingRequestDto.setStatus(BookingStatus.REJECTED); - return bookingRequestDto; - } - - public static BookingRequestDto bookingRequestDto5 = new BookingRequestDto(3L, LocalDateTime.of(2025, 2, 7, 14, 40, 35), - LocalDateTime.of(2025, 2, 25, 18, 12, 43), itemBookerDto2.getItemId(), userBookingDto1.getUserId(), BookingStatus.APPROVED); - - public static BookingRequestDto booking6ForCreate() { - BookingRequestDto bookingRequestDto = new BookingRequestDto(); - bookingRequestDto.setStart(LocalDateTime.of(2025, 2, 7, 14, 40, 35)); - bookingRequestDto.setEnd(LocalDateTime.of(2025, 2, 25, 18, 12, 43)); - bookingRequestDto.setItemId(1L); - bookingRequestDto.setStatus(BookingStatus.APPROVED); - return bookingRequestDto; - } - - public Collection bookings = Arrays.asList(responseBooking1, responseBooking2, responseBooking3, responseBooking4, responseBooking5); - - public Collection bookingsForOwner = Arrays.asList(responseBooking1, responseBooking3, responseBooking4, responseBooking5); - - public static Comment comment1 = new Comment(1L, "Test comment text1", user1, item1); - public static CommentResponseDto commentResponseDto1 = new CommentResponseDto(1L, "Test comment text1", userAuthorDto1); - public static CommentResponseCreatedDto createdDto = new CommentResponseCreatedDto(1L, "Test comment text1", userAuthorDto1.getUserName(), true); - - public static CommentRequestDto commentForCreation() { - CommentRequestDto commentRequestDto = new CommentRequestDto(); - commentRequestDto.setText("Test comment text1"); - return commentRequestDto; - } + public static CommentResponseCreatedDto createdDto = + new CommentResponseCreatedDto(1L, "Test comment text1", userAuthorDto1.getUserName(), true); }