Skip to content

Commit

Permalink
Feat/#53 내 리뷰 리스트 불러오기 (#55)
Browse files Browse the repository at this point in the history
* rebase

* rebase

* rebase

* rebase

* #53 test(ReviewControllerTest): 테스트 코드 추가

* #53 refactor(ReviewService): 서비스 리팩토링

* #53 refactor(ReviewCommand): dto 리팩토링

* service fix

* rebase

* build fix
  • Loading branch information
yuna83 authored Jan 16, 2025
1 parent f2ecc28 commit 3cc6bfa
Show file tree
Hide file tree
Showing 10 changed files with 242 additions and 33 deletions.
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
id 'java'
id 'org.springframework.boot' version '3.3.5'
id 'io.spring.dependency-management' version '1.1.6'
id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10'
}

group = 'com.example'
Expand Down Expand Up @@ -62,7 +63,7 @@ dependencies {

// Query DSL
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"

Expand Down
3 changes: 1 addition & 2 deletions src/main/java/com/example/api/domain/Review.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
@Entity
@Getter
@Table(name = "REVIEW")
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class Review extends BaseEntity {
@Id
@Column(name ="REVIEW_ID")
Expand Down Expand Up @@ -37,7 +37,6 @@ public class Review extends BaseEntity {

@Column(name = "REVIEW_CONTENT")
private String reviewContent;

public Review(int reviewStarPoint, String reviewContent, Contract contract) {
this.reviewStarPoint = reviewStarPoint;
this.reviewContent = reviewContent;
Expand Down
22 changes: 19 additions & 3 deletions src/main/java/com/example/api/review/ReviewRepository.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
package com.example.api.review;

import com.example.api.domain.Review;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface ReviewRepository extends JpaRepository<Review, Long> {

@Query("SELECT r FROM Review r JOIN FETCH r.contract WHERE r.contract.offerEmployment.business.employer.accountId = :employerId")
@Query("SELECT r FROM Review r " +
"JOIN FETCH r.contract c " +
"WHERE c.offerEmployment.business.businessId = :employerId")
List<Review> loadReviewsByEmployerId(@Param("employerId") Long employerId);

@Query("SELECT r FROM Review r WHERE (:reviewId IS NULL OR r.reviewId = :reviewId)")
@Query("SELECT r FROM Review r " +
"WHERE (:reviewId IS NULL OR r.reviewId = :reviewId)")
List<Review> findReviewsByDynamicQuery(@Param("reviewId") Long reviewId);

@Query("SELECT r FROM Review r " +
"JOIN FETCH r.writer b " +
"JOIN FETCH r.employee a " +
"JOIN FETCH r.contract c " +
"WHERE a.accountId = :accountId")
List<Review> findReviewsByAccountIdWithDetails(@Param("accountId") Long accountId);

List<Review> findReviewsByEmployee_AccountId(Long accountId);
}



47 changes: 43 additions & 4 deletions src/main/java/com/example/api/review/ReviewService.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@

import java.util.List;

import com.example.api.domain.Review;
import com.example.api.review.dto.ReviewCommand;

import java.time.LocalDateTime;

@Service
@RequiredArgsConstructor
public class ReviewService {
Expand All @@ -21,15 +26,49 @@ public List<ReviewResponse> getAllReviews() {
.toList();
}


@Transactional
public List<ReviewResponse> getReviewsByEmployee(
@Validated final Long reviewId
) {
public List<ReviewResponse> getReviewsByEmployee(@Validated final Long reviewId) {
return reviewRepository.findReviewsByDynamicQuery(reviewId)
.stream()
.map(ReviewResponse::from)
.toList();
}

@Transactional
public List<ReviewResponse> getReviews(@Validated final ReviewCommand reviewCommand) {
final List<Review> reviews = reviewRepository.findReviewsByEmployee_AccountId(reviewCommand.accountId());
return mapToReviewResponses(reviews);
}

@Transactional
public List<ReviewResponse> getReviewsByEmployeeWithDetails(@Validated final ReviewCommand reviewCommand) {
final List<Review> reviews = reviewRepository.findReviewsByAccountIdWithDetails(reviewCommand.accountId());
return mapToReviewResponses(reviews);
}

private List<ReviewResponse> mapToReviewResponses(final List<Review> reviews) {
return reviews.stream()
.map(this::mapToReviewResponse)
.toList();
}

private ReviewResponse mapToReviewResponse(final Review review) {
final String businessName = review.getContract().getOfferEmployment().getBusiness().getBusinessName();
final Long businessId = review.getContract().getOfferEmployment().getBusiness().getBusinessId();
final LocalDateTime contractStartTime = review.getContract().getContractStartTime();
final LocalDateTime contractEndTime = review.getContract().getContractEndTime();
final int reviewStarPoint = review.getReviewStarPoint();
final String reviewContent = review.getReviewContent();

return new ReviewResponse(
review.getReviewId(),
businessName,
businessId,
contractStartTime,
contractEndTime,
reviewStarPoint,
reviewContent
);
}
}

Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<<<<<<< HEAD
<<<<<<< HEAD
package com.example.api.review.controller;

import com.example.api.review.ReviewService;
Expand Down Expand Up @@ -27,4 +29,39 @@ public ResponseEntity<List<ReviewResponse>> getReviewsByEmployee(
final List<ReviewResponse> reviews = reviewService.getReviewsByEmployee(reivewId);
return ResponseEntity.ok(reviews);
}
}
}
=======
package com.example.api.review.controller;public class ReviewController {
=======
package com.example.api.review.controller;

import com.example.api.review.ReviewService;
import com.example.api.review.dto.ReviewCommand;
import com.example.api.review.dto.ReviewResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/v1/info")
@RequiredArgsConstructor
public class ReviewController {
<<<<<<< HEAD
>>>>>>> 0ff3ba1 (#53 feat(ReviewService): 서비스 코드 구현)
}
>>>>>>> 2f6b5cc (#53 feat(ReviewCommand): DTO 작성)
=======
private final ReviewService reviewService;

@GetMapping("/my/reviews")
public ResponseEntity<List<ReviewResponse>> getMyReviews(
@RequestParam final Long accountId
) {
final ReviewCommand reviewCommand = new ReviewCommand(accountId);
final List<ReviewResponse> reviews = reviewService.getReviews(reviewCommand);
return ResponseEntity.ok(reviews);
}
}
>>>>>>> 27670a3 (#53 feat(ReviewController): 컨트롤러 코드 구현)
7 changes: 7 additions & 0 deletions src/main/java/com/example/api/review/dto/ReviewCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.api.review.dto;

public record ReviewCommand(
Long accountId
){}


21 changes: 12 additions & 9 deletions src/main/java/com/example/api/review/dto/ReviewResponse.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
package com.example.api.review.dto;

import com.example.api.domain.Account;
import com.example.api.domain.Business;
import com.example.api.domain.Review;
import java.time.LocalDateTime;

public record ReviewResponse(
Long reviewId,
Business writer,
Account employee,
Long reviewId, //Id
String businessName,
Long businessId,
LocalDateTime contractStartTime,
LocalDateTime contractEndTime,
int reviewStarPoint,
String reviewContent

) {
public static ReviewResponse from(Review review) {
public static ReviewResponse from(final Review review) {
return new ReviewResponse(
review.getReviewId(),
review.getWriter(),
review.getEmployee(),
review.getContract().getOfferEmployment().getBusiness().getBusinessName(),
review.getContract().getOfferEmployment().getBusiness().getBusinessId(),
review.getContract().getContractStartTime(),
review.getContract().getContractEndTime(),
review.getReviewStarPoint(),
review.getReviewContent()
);
}
}


27 changes: 14 additions & 13 deletions src/test/java/com/example/api/inquiry/InquiryServiceTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.example.api.inquiry;

import com.example.api.account.entity.Nationality;
import com.example.api.account.entity.UserRole;
import com.example.api.account.repository.AccountRepository;
import com.example.api.domain.Account;
import com.example.api.domain.Inquiry;
Expand Down Expand Up @@ -35,18 +37,17 @@ void setUp() {
accountRepository.deleteAll();
inquiryRepository.deleteAll();

Account account = new Account();
account.setAccountId(1L);
account.setName("Alice");
account.setEmail("[email protected]");
account.setAge(25);
account.setSex("F");
account.setPhoneNumber("010-1234-5678");
account.setProfileImage("user-uploads/1/profile.png");
account.setStarPoint(4.5f);
account.setWorkCount(10);
account.setOpenStatus(true);
account.setDeleted(false);
Account account = new Account(
"user01",
"password123",
"Alice",
"nickname01",
"010-1234-5678",
"[email protected]",
Nationality.KOREAN,
List.of(UserRole.EMPLOYEE),
false
);
accountRepository.save(account);
}

Expand Down Expand Up @@ -111,4 +112,4 @@ void mapToInquiry_shouldMapCommandToInquiry() {
assertThat(inquiry).isNotNull();
assertThat(inquiry.getTitle()).isEqualTo("Test Title");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.example.api.review.controller;

import com.example.api.review.ReviewService;
import com.example.api.review.dto.ReviewCommand;
import com.example.api.review.dto.ReviewResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;

import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@WebMvcTest(ReviewController.class)
public class ReviewControllerTest {
@Autowired
private MockMvc mockMvc;

@Mock
private ReviewService reviewService;

@InjectMocks
private ReviewController reviewController;

private ReviewResponse reviewResponse1;
private ReviewResponse reviewResponse2;

@BeforeEach
void setUp() {
reviewResponse1 = new ReviewResponse(
"Business A", 101L, LocalDateTime.now(), LocalDateTime.now(), 5, "Great service!");
reviewResponse2 = new ReviewResponse(
"Business B", 102L, LocalDateTime.now(), LocalDateTime.now(), 4, "Good experience.");
}

@Test
void testGetMyReviews() throws Exception {
when(reviewService.getReviews(any(ReviewCommand.class)))
.thenReturn(List.of(reviewResponse1, reviewResponse2));
mockMvc.perform(get("/api/v1/info/my/reviews")
.param("accountId", "123"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.reviews").isArray())
.andExpect(jsonPath("$.reviews[0].businessName").value("Business A"))
.andExpect(jsonPath("$.reviews[1].reviewContent").value("Good experience."));
}

@Test
void testGetMyReviewsNoData() throws Exception {
when(reviewService.getReviews(any(ReviewCommand.class)))
.thenReturn(Collections.emptyList());
mockMvc.perform(get("/api/v1/info/my/reviews")
.param("accountId", "123"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.reviews").isEmpty());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.example.api.review.service;

import static org.assertj.core.api.Assertions.assertThat;

import com.example.api.global.BaseIntegrationTest;
import com.example.api.review.ReviewService;
import com.example.api.review.dto.ReviewCommand;
import com.example.api.review.dto.ReviewResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
public class ReviewServiceTest extends BaseIntegrationTest {
@Autowired
private ReviewService reviewService;

@BeforeEach
void setUp() {
}

@Test
void testGetReviews() {
ReviewCommand reviewCommand = new ReviewCommand(1L);
List<ReviewResponse> reviews = reviewService.getReviews(reviewCommand);
assertThat(reviews).isNotEmpty();
assertThat(reviews.get(0).businessName()).isEqualTo("Tech Solutions Inc.");
assertThat(reviews.get(0).reviewContent()).isEqualTo("Good work");
}

@Test
void testGetReviewsWhenNoReviews() {
ReviewCommand reviewCommand = new ReviewCommand(999L);
List<ReviewResponse> reviews = reviewService.getReviews(reviewCommand);
assertThat(reviews).isEmpty();
}
}

0 comments on commit 3cc6bfa

Please sign in to comment.