-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: 즐겨찾기 엔티티 추가 * refactor: 즐겨찾기 엔티티 생성자 추가 * feat: 즐겨찾기 기능 구현 * test: 즐겨찾기 추가 기능 테스트 작성 * refactor: 즐겨찾기 최대 개수 수정 * feat: 즐겨찾기 조회 및 삭제 구현 * test: 즐겨찾기 조회 및 삭제 테스트 작성 * refactor: Star 엔티티의 token 필드에 nullable 옵션 추가 * refactor: 리뷰 기반 즐겨찾기 숫자 검증 로직 수정 * refactor: 리뷰 기반 핀 등록 숫자 검증 로직 수정 * refactor: 테스트 리뷰 반영 * refactor: 테이블 명 수정 * test: Star Api 테스트 작성 * refactor: 리뷰 반영 * refactor: 리뷰 반영 및 테스트 수정 * refactor: SubjectService 테스트에 StarRepository 삭제 추가 * refactor: Star 엔티티 테이블 명 수정 * refactor: 정책 수정에 따른 테스트 수정
- Loading branch information
Showing
13 changed files
with
433 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package kr.allcll.seatfinder.star; | ||
|
||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.FetchType; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.JoinColumn; | ||
import jakarta.persistence.ManyToOne; | ||
import jakarta.persistence.Table; | ||
import kr.allcll.seatfinder.subject.Subject; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Table(name = "stars") | ||
@Entity | ||
@Getter | ||
@NoArgsConstructor | ||
public class Star { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
@Column(name = "token", nullable = false) | ||
private String token; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY, optional = false) | ||
@JoinColumn(name = "subject_id", nullable = false) | ||
private Subject subject; | ||
|
||
public Star(String token, Subject subject) { | ||
this.token = token; | ||
this.subject = subject; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package kr.allcll.seatfinder.star; | ||
|
||
import kr.allcll.seatfinder.ThreadLocalHolder; | ||
import kr.allcll.seatfinder.star.dto.StarredSubjectIdsResponse; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.DeleteMapping; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
public class StarApi { | ||
|
||
private final StarService starService; | ||
|
||
@PostMapping("/api/stars") | ||
ResponseEntity<Void> addStarOnSubject(@RequestParam Long subjectId) { | ||
starService.addStarOnSubject(subjectId, ThreadLocalHolder.SHARED_TOKEN.get()); | ||
return ResponseEntity.ok().build(); | ||
} | ||
|
||
@DeleteMapping("/api/stars/{subjectId}") | ||
public ResponseEntity<Void> deleteStarOnSubject(@PathVariable Long subjectId) { | ||
starService.deleteStarOnSubject(subjectId, ThreadLocalHolder.SHARED_TOKEN.get()); | ||
return ResponseEntity.ok().build(); | ||
} | ||
|
||
@GetMapping("/api/stars") | ||
public ResponseEntity<StarredSubjectIdsResponse> retrieveStars() { | ||
StarredSubjectIdsResponse response = starService.retrieveStars(ThreadLocalHolder.SHARED_TOKEN.get()); | ||
return ResponseEntity.ok(response); | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/main/java/kr/allcll/seatfinder/star/StarRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package kr.allcll.seatfinder.star; | ||
|
||
import java.util.List; | ||
import kr.allcll.seatfinder.subject.Subject; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface StarRepository extends JpaRepository<Star, Long> { | ||
|
||
boolean existsBySubjectAndToken(Subject subject, String token); | ||
|
||
List<Star> findAllByToken(String token); | ||
|
||
Long countAllByToken(String token); | ||
|
||
void deleteStarBySubjectIdAndToken(Long subjectId, String token); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package kr.allcll.seatfinder.star; | ||
|
||
import java.util.List; | ||
import kr.allcll.seatfinder.exception.AllcllErrorCode; | ||
import kr.allcll.seatfinder.exception.AllcllException; | ||
import kr.allcll.seatfinder.star.dto.StarredSubjectIdResponse; | ||
import kr.allcll.seatfinder.star.dto.StarredSubjectIdsResponse; | ||
import kr.allcll.seatfinder.subject.Subject; | ||
import kr.allcll.seatfinder.subject.SubjectRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Service | ||
@Transactional(readOnly = true) | ||
@RequiredArgsConstructor | ||
public class StarService { | ||
|
||
private static final int MAX_STAR_NUMBER = 50; | ||
|
||
private final StarRepository starRepository; | ||
private final SubjectRepository subjectRepository; | ||
|
||
@Transactional | ||
public void addStarOnSubject(Long subjectId, String token) { | ||
|
||
Subject subject = subjectRepository.findById(subjectId) | ||
.orElseThrow(() -> new AllcllException(AllcllErrorCode.SUBJECT_NOT_FOUND)); | ||
validateCanAddStar(subject, token); | ||
starRepository.save(new Star(token, subject)); | ||
} | ||
|
||
private void validateCanAddStar(Subject subject, String token) { | ||
Long starCount = starRepository.countAllByToken(token); | ||
if (starCount >= MAX_STAR_NUMBER) { | ||
throw new AllcllException(AllcllErrorCode.STAR_LIMIT_EXCEEDED, MAX_STAR_NUMBER); | ||
} | ||
if (starRepository.existsBySubjectAndToken(subject, token)) { | ||
throw new AllcllException(AllcllErrorCode.DUPLICATE_STAR, subject.getCuriNm()); | ||
} | ||
} | ||
|
||
@Transactional | ||
public void deleteStarOnSubject(Long subjectId, String token) { | ||
starRepository.deleteStarBySubjectIdAndToken(subjectId, token); | ||
} | ||
|
||
public StarredSubjectIdsResponse retrieveStars(String token) { | ||
List<Star> stars = starRepository.findAllByToken(token); | ||
return new StarredSubjectIdsResponse(stars.stream() | ||
.map(star -> new StarredSubjectIdResponse(star.getSubject().getId())) | ||
.toList()); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
src/main/java/kr/allcll/seatfinder/star/dto/StarredSubjectIdResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package kr.allcll.seatfinder.star.dto; | ||
|
||
public record StarredSubjectIdResponse( | ||
Long subjectId | ||
) { | ||
|
||
} |
9 changes: 9 additions & 0 deletions
9
src/main/java/kr/allcll/seatfinder/star/dto/StarredSubjectIdsResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package kr.allcll.seatfinder.star.dto; | ||
|
||
import java.util.List; | ||
|
||
public record StarredSubjectIdsResponse( | ||
List<StarredSubjectIdResponse> subjects | ||
) { | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package kr.allcll.seatfinder.star; | ||
|
||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat; | ||
import static org.mockito.Mockito.when; | ||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; | ||
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.status; | ||
|
||
import jakarta.servlet.http.Cookie; | ||
import java.util.List; | ||
import kr.allcll.seatfinder.star.dto.StarredSubjectIdResponse; | ||
import kr.allcll.seatfinder.star.dto.StarredSubjectIdsResponse; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; | ||
import org.springframework.test.context.bean.override.mockito.MockitoBean; | ||
import org.springframework.test.web.servlet.MockMvc; | ||
import org.springframework.test.web.servlet.MvcResult; | ||
|
||
@WebMvcTest(StarApi.class) | ||
class StarApiTest { | ||
|
||
@Autowired | ||
private MockMvc mockMvc; | ||
|
||
@MockitoBean | ||
private StarService starService; | ||
|
||
@Test | ||
@DisplayName("관담 기능의 즐겨찾기 등록을 할 때에 요청과 응답을 확인한다.") | ||
void addStarOnSubjectWhenStarNotExist() throws Exception { | ||
// when, then | ||
mockMvc.perform(post("/api/stars") | ||
.param("subjectId", "1")) | ||
.andExpect(status().isOk()); | ||
} | ||
|
||
@Test | ||
@DisplayName("관담 기능의 즐겨찾기를 삭제할 때 요청과 응답을 확인한다.") | ||
void deleteStarOnSubject() throws Exception { | ||
// when, then | ||
mockMvc.perform(delete("/api/stars/{subjectId}", 1L)) | ||
.andExpect(status().isOk()); | ||
} | ||
|
||
@Test | ||
@DisplayName("관담기능을 조회할 때 요청과 응답을 확인한다.") | ||
void retrieveStars() throws Exception { | ||
// given | ||
String expected = """ | ||
{ | ||
"subjects":[ | ||
{ | ||
"subjectId":1 | ||
}, | ||
{ | ||
"subjectId":2 | ||
} | ||
] | ||
} | ||
"""; | ||
|
||
List<StarredSubjectIdResponse> subjects = List.of( | ||
new StarredSubjectIdResponse(1L), | ||
new StarredSubjectIdResponse(2L) | ||
); | ||
when(starService.retrieveStars("tokenValue")) | ||
.thenReturn(new StarredSubjectIdsResponse(subjects)); | ||
|
||
// when | ||
MvcResult result = mockMvc.perform(get("/api/stars") | ||
.cookie(new Cookie("token", "tokenValue"))) | ||
.andExpect(status().isOk()) | ||
.andReturn(); | ||
|
||
// then | ||
assertThat(result.getResponse().getContentAsString()).isEqualToIgnoringWhitespace(expected); | ||
} | ||
} |
Oops, something went wrong.