Skip to content

Commit

Permalink
Merge pull request #51 from saessagMarket/#48-product-bumping
Browse files Browse the repository at this point in the history
끌어올리기
  • Loading branch information
JinTaekLim authored Jan 30, 2025
2 parents 8c8d680 + ab1dd42 commit a30a292
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@

import com.market.saessag.domain.product.dto.ProductRequest;
import com.market.saessag.domain.product.dto.ProductResponse;
import com.market.saessag.domain.product.entity.Product;
import com.market.saessag.domain.product.service.ProductService;
import com.market.saessag.domain.user.dto.SignInResponse;
import com.market.saessag.global.response.ApiResponse;
import jakarta.servlet.http.HttpSession;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
Expand All @@ -25,13 +24,14 @@ public ApiResponse<Page<ProductResponse>> searchProducts(
@RequestParam(defaultValue = "10") int size,
@RequestParam(required = false) String title,
@RequestParam(required = false) String nickname,
@RequestParam(required = false) String sort, //정렬 기준 (price, addedDate 등)
@RequestParam(defaultValue = "desc") String direction) {
Page<ProductResponse> product = productService.searchProducts(page, size, title, nickname, sort, direction);
return ApiResponse.<Page<ProductResponse>>builder()
.status("200")
.data(product)
.build();
@RequestParam(required = false) String sort
) {
Page<ProductResponse> product = productService.searchProducts(page, size, title, nickname, sort);

return ApiResponse.<Page<ProductResponse>>builder()
.status("200")
.data(product)
.build();
}

//상세 조회
Expand Down Expand Up @@ -98,4 +98,15 @@ public ApiResponse<Void> likeProduct(@PathVariable Long productId, @SessionAttri
.data(null)
.build();
}

@PostMapping("/bump")
public ApiResponse<?> bumpProduct(@RequestParam Long productId, HttpServletRequest session) {
SignInResponse signInResponse = (SignInResponse) session.getAttribute("user");
Product product = productService.bumpProduct(productId, signInResponse.getId());
return ApiResponse.builder()
.status("200")
.data(product.getId())
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ public class Product {
@Enumerated(EnumType.STRING)
private ProductStatus status;

private LocalDateTime bumpAt;


public enum ProductStatus {
FOR_SALE, HIDDEN, SOLD_OUT
}
Expand Down Expand Up @@ -77,6 +80,10 @@ public void updateProduct(String title, Long price, String description, List<Str
this.status = status;
}

public void updateBumpAt(LocalDateTime bumpAt) {
this.bumpAt = bumpAt;
}

public void incrementViews() {
this.views++;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.market.saessag.domain.product.entity.Product;
import com.market.saessag.domain.user.entity.User;
import java.util.Optional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
Expand All @@ -15,4 +16,6 @@ public interface ProductRepository extends JpaRepository<Product, Long> {
Page<Product> findByTitleContaining(String title, Pageable pageable);

Page<Product> findByUser(User user, Pageable pageable);

Optional<Product> findByIdAndUserId(Long id, Long userId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.market.saessag.domain.user.dto.UserResponse;
import com.market.saessag.util.TimeUtils;
import jakarta.transaction.Transactional;
import java.time.LocalDateTime;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
Expand Down Expand Up @@ -78,8 +79,14 @@ public boolean deleteProduct(Long productId) {
return false;
}

public Page<ProductResponse> searchProducts(int page, int size, String title, String nickname, String sort, String direction) {
Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.fromString(direction), sort != null ? sort : "addedDate"));
public Page<ProductResponse> searchProducts(int page, int size, String title, String nickname, String sort) {
Sort sorting = (sort == null || sort.isEmpty()) ?
Sort.by(
Sort.Order.desc("dump_at").nullsLast(),
Sort.Order.desc("added_date")
) : Sort.by(Sort.Order.by(sort));

Pageable pageable = PageRequest.of(page, size, sorting);

if (title != null) {
return productRepository.findByTitleContaining(title, pageable).map(this::convertToDTO);
Expand Down Expand Up @@ -120,6 +127,15 @@ public ProductResponse getProductDetail(Long productId) {
return convertToDTO(id);
}

public Product bumpProduct(Long productId, Long userId) {
Product product = productRepository.findByIdAndUserId(productId, userId)
.orElseThrow(IllegalAccessError::new);

product.updateBumpAt(LocalDateTime.now());
productRepository.save(product);
return product;
}

// 조회수 증가
public void incrementView(Long productId, Long userId) {
Product product = productRepository.findById(productId)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.market.saessag.domain.product.service;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.market.saessag.domain.product.entity.Product;
import com.market.saessag.domain.product.repository.ProductRepository;
import com.market.saessag.domain.user.entity.User;
import java.util.Optional;
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;

@ExtendWith(MockitoExtension.class)
class ProductServiceTest {

@InjectMocks
private ProductService productService;
@Mock
private ProductRepository productRepository;

@Test
void bumpProduct() {
// given
User user = User.builder()
.id(1L)
.email("email")
.password("pw")
.nickname("nickname")
.role("role")
.build();

Product product = Product.builder()
.id(1L)
.build();

when(productRepository.findByIdAndUserId(anyLong(), anyLong()))
.thenReturn(Optional.of(product));

// when
Product newProduct = productService.bumpProduct(product.getId(), user.getId());

// then
assertNotNull(newProduct);
assertEquals(product.getId(), newProduct.getId());
assertNotNull(newProduct.getBumpAt());
verify(productRepository).save(newProduct);
}
}

0 comments on commit a30a292

Please sign in to comment.