diff --git a/build.gradle b/build.gradle index 163e43c..4510766 100644 --- a/build.gradle +++ b/build.gradle @@ -56,13 +56,13 @@ tasks.named('test') { useJUnitPlatform() } -processResources.dependsOn('copySecret') - -tasks.register('copySecret', Copy) { - from './matal-submodule' - include "application*.yml" - into './src/main/resources' -} +//processResources.dependsOn('copySecret') +// +//tasks.register('copySecret', Copy) { +// from './matal-submodule' +// include "application*.yml" +// into './src/main/resources' +//} tasks.named("jar") { enabled = false; diff --git a/src/main/java/matal/bookmark/controller/BookmarkController.java b/src/main/java/matal/bookmark/controller/BookmarkController.java index 0b2c56e..352c41e 100644 --- a/src/main/java/matal/bookmark/controller/BookmarkController.java +++ b/src/main/java/matal/bookmark/controller/BookmarkController.java @@ -7,8 +7,10 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.List; import lombok.RequiredArgsConstructor; import matal.bookmark.dto.response.BookmarkResponseDto; +import matal.bookmark.dto.response.BookmarkStoreIdsResponseDto; import matal.bookmark.service.BookmarkService; import matal.global.auth.LoginMember; import matal.global.exception.ErrorResponse; @@ -51,7 +53,7 @@ public ResponseEntity createBookmark( } @GetMapping - @Operation(summary = "북마크 조회 기능", description = "사용자가 북마크한 가게들을 조회할 때 사용하는 API") + @Operation(summary = "북마크 페이징 조회 기능", description = "사용자가 북마크한 가게들을 10개씩 조회할 때 사용하는 API") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "북마크 조회 성공", content = {@Content(schema = @Schema(implementation = Void.class))}), @@ -67,6 +69,22 @@ public ResponseEntity> getBookmarks( return ResponseEntity.ok(bookmarkResponse); } + @GetMapping("/ids") + @Operation(summary = "북마크 IDs 조회 기능", description = "사용자가 북마크한 가게들을 모두 조회할 때 사용하는 API") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "북마크 조회 성공", + content = {@Content(schema = @Schema(implementation = Void.class))}), + @ApiResponse(responseCode = "401", description = "회원 세션 정보 없음", + content = {@Content(schema = @Schema(implementation = ErrorResponse.class))}), + @ApiResponse(responseCode = "404", description = "회원 조회 실패", + content = {@Content(schema = @Schema(implementation = ErrorResponse.class))})}) + public ResponseEntity> getBookmarkStoreIds( + @LoginMember @Parameter(hidden = true) AuthMember authMember) + { + List bookmarkResponse = bookmarkService.getBookmarkStoreIds(authMember); + return ResponseEntity.ok(bookmarkResponse); + } + @DeleteMapping("/{id}") @Operation(summary = "북마크 삭제 기능", description = "사용자가 가게를 북마크로 저장할 때 사용하는 API") @ApiResponses(value = { diff --git a/src/main/java/matal/bookmark/domain/Bookmark.java b/src/main/java/matal/bookmark/domain/Bookmark.java index 7197480..a2f492e 100644 --- a/src/main/java/matal/bookmark/domain/Bookmark.java +++ b/src/main/java/matal/bookmark/domain/Bookmark.java @@ -2,6 +2,7 @@ import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; @@ -29,11 +30,11 @@ public class Bookmark extends BaseTimeEntity { @Column(name = "bookmark_id") private Long bookmarkId; - @OneToOne + @OneToOne(fetch = FetchType.LAZY, optional = false) @JoinColumn(name = "member_id") private Member member; - @OneToOne + @OneToOne(fetch = FetchType.LAZY, optional = false) @JoinColumn(name = "store_id") private Store store; diff --git a/src/main/java/matal/bookmark/domain/repository/BookmarkRepository.java b/src/main/java/matal/bookmark/domain/repository/BookmarkRepository.java index 4110f58..69d2d07 100644 --- a/src/main/java/matal/bookmark/domain/repository/BookmarkRepository.java +++ b/src/main/java/matal/bookmark/domain/repository/BookmarkRepository.java @@ -1,15 +1,28 @@ package matal.bookmark.domain.repository; +import java.util.List; import matal.bookmark.domain.Bookmark; +import matal.bookmark.dto.response.BookmarkStoreIdsResponseDto; import matal.member.domain.Member; import matal.store.domain.Store; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.EntityGraph; +import org.springframework.data.jpa.repository.EntityGraph.EntityGraphType; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; public interface BookmarkRepository extends JpaRepository { - Page findBookmarksByMemberId(Long id, Pageable pageable); + @EntityGraph(attributePaths = {"store"}, type = EntityGraphType.FETCH) + @Query("SELECT DISTINCT b FROM Bookmark b LEFT JOIN b.store WHERE b.member.id = :memberId") + Page findBookmarksByMemberId(@Param("memberId") Long id, Pageable pageable); + + @Query("SELECT new matal.bookmark.dto.response.BookmarkStoreIdsResponseDto(b.bookmarkId, b.store.storeId) " + + "FROM Bookmark b WHERE b.member.id = :memberId") + List findBookmarkStoreIdsByMemberId(@Param("memberId") Long memberId); + Boolean existsBookmarkByStoreAndMember(Store store, Member member); } diff --git a/src/main/java/matal/bookmark/dto/response/BookmarkStoreIdsResponseDto.java b/src/main/java/matal/bookmark/dto/response/BookmarkStoreIdsResponseDto.java new file mode 100644 index 0000000..8d799ab --- /dev/null +++ b/src/main/java/matal/bookmark/dto/response/BookmarkStoreIdsResponseDto.java @@ -0,0 +1,5 @@ +package matal.bookmark.dto.response; + +public record BookmarkStoreIdsResponseDto(Long bookmarkId, + Long storeId) { +} diff --git a/src/main/java/matal/bookmark/service/BookmarkService.java b/src/main/java/matal/bookmark/service/BookmarkService.java index c7cd760..3094958 100644 --- a/src/main/java/matal/bookmark/service/BookmarkService.java +++ b/src/main/java/matal/bookmark/service/BookmarkService.java @@ -1,8 +1,10 @@ package matal.bookmark.service; +import java.util.List; import lombok.RequiredArgsConstructor; import matal.bookmark.domain.Bookmark; import matal.bookmark.domain.repository.BookmarkRepository; +import matal.bookmark.dto.response.BookmarkStoreIdsResponseDto; import matal.bookmark.dto.response.BookmarkResponseDto; import matal.global.exception.AlreadyExistException; import matal.global.exception.AuthException; @@ -50,6 +52,12 @@ public Page getBookmarks(AuthMember authMember, int page) { return bookmarkRepository.findBookmarksByMemberId(authMember.memberId(), pageable).map(BookmarkResponseDto::from); } + @Transactional(readOnly = true) + public List getBookmarkStoreIds(AuthMember authMember) { + validateMember(authMember.memberId()); + return bookmarkRepository.findBookmarkStoreIdsByMemberId(authMember.memberId()); + } + @Transactional public void deleteBookmark(AuthMember authMember, Long bookmarkId) { validateMember(authMember.memberId()); diff --git a/src/test/java/matal/bookmark/controller/BookmarkControllerTest.java b/src/test/java/matal/bookmark/controller/BookmarkControllerTest.java index c6a765c..7fed7c9 100644 --- a/src/test/java/matal/bookmark/controller/BookmarkControllerTest.java +++ b/src/test/java/matal/bookmark/controller/BookmarkControllerTest.java @@ -15,6 +15,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.util.List; import matal.bookmark.dto.response.BookmarkResponseDto; +import matal.bookmark.dto.response.BookmarkStoreIdsResponseDto; import matal.bookmark.service.BookmarkService; import matal.global.exception.AuthException; import matal.global.exception.NotFoundException; @@ -101,8 +102,6 @@ void beforeEach() { ) ) ); - - Pageable pageable = PageRequest.of(0, 10); } @Test @@ -160,7 +159,7 @@ void testCreateBookmarkFailure2() throws Exception { } @Test - @DisplayName("북마크 리스트 조회 성공 테스트") + @DisplayName("북마크 페이지 조회 성공 테스트") void testGetBookmarksSuccess() throws Exception { // given Pageable pageable = PageRequest.of(0, 10); @@ -182,7 +181,7 @@ void testGetBookmarksSuccess() throws Exception { } @Test - @DisplayName("북마크 리스트 조회 시 세션 정보 없음으로 인한 실패 테스트") + @DisplayName("북마크 페이지 조회 시 세션 정보 없음으로 인한 실패 테스트") void testGetBookmarksFailure() throws Exception { // given @@ -198,7 +197,7 @@ void testGetBookmarksFailure() throws Exception { } @Test - @DisplayName("북마크 리스트 조회 시 회원 정보를 찾지 못해 발생하는 실패 테스트") + @DisplayName("북마크 페이지 조회 시 회원 정보를 찾지 못해 발생하는 실패 테스트") void testGetBookmarksFailure2() throws Exception { // given @@ -214,6 +213,68 @@ void testGetBookmarksFailure2() throws Exception { .andDo(print()); } + @Test + @DisplayName("북마크, 가게 아이디 조회 성공 테스트") + void testGetBookmarkStoreIdsSuccess() throws Exception { + // given + List bookmarks = List.of( + new BookmarkStoreIdsResponseDto( + 1L, 1L + ), + new BookmarkStoreIdsResponseDto( + 1L, 2L + ) + ); + + + // when + when(bookmarkService.getBookmarkStoreIds(mockMember)).thenReturn(bookmarks); + + // then + mockMvc.perform(get("/api/bookmarks/ids") + .contentType("application/json") + .session(mockSession)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].bookmarkId").value(1L)) + .andExpect(jsonPath("$[0].storeId").value(1L)) + .andExpect(jsonPath("$[1].bookmarkId").value(1L)) + .andExpect(jsonPath("$[1].storeId").value(2L)) + .andDo(print()); + } + + @Test + @DisplayName("북마크 가게 아이디 조회 시 세션 정보 없음으로 인한 실패 테스트") + void testGetBookmarkStoreIdsFailure() throws Exception { + // given + + // when + when(bookmarkService.getBookmarkStoreIds(mockMember)) + .thenThrow(new AuthException(ResponseCode.SESSION_VALUE_EXCEPTION)); + + // then + mockMvc.perform(get("/api/bookmarks/ids") + .contentType("application/json")) + .andExpect(status().isUnauthorized()) + .andDo(print()); + } + + @Test + @DisplayName("북마크 가게 아이디 조회 시 회원 정보를 찾지 못해 발생하는 실패 테스트") + void testGetBookmarkStoreIdsFailure2() throws Exception { + // given + + // when + doThrow(new NotFoundException(ResponseCode.STORE_NOT_FOUND_ID)) + .when(bookmarkService).getBookmarkStoreIds(mockMember); + + // then + mockMvc.perform(get("/api/bookmarks/ids") + .contentType("application/json") + .session(mockSession)) + .andExpect(status().isNotFound()) + .andDo(print()); + } + @Test @DisplayName("북마크 삭제 성공 테스트") void testDelteBookmarkSuccess() throws Exception { diff --git a/src/test/java/matal/bookmark/service/BookmarkServiceTest.java b/src/test/java/matal/bookmark/service/BookmarkServiceTest.java index be9209e..78c047a 100644 --- a/src/test/java/matal/bookmark/service/BookmarkServiceTest.java +++ b/src/test/java/matal/bookmark/service/BookmarkServiceTest.java @@ -13,6 +13,7 @@ import matal.bookmark.domain.Bookmark; import matal.bookmark.domain.repository.BookmarkRepository; import matal.bookmark.dto.response.BookmarkResponseDto; +import matal.bookmark.dto.response.BookmarkStoreIdsResponseDto; import matal.global.exception.NotFoundException; import matal.global.exception.ResponseCode; import matal.member.domain.Member; @@ -154,7 +155,7 @@ void testSaveBookmarkFailure3() { } @Test - @DisplayName("북마크 리스트 조회 성공 테스트") + @DisplayName("북마크 페이지 조회 성공 테스트") void testGetBookmarksSuccess() { // given List bookmarks = List.of( @@ -184,7 +185,7 @@ void testGetBookmarksSuccess() { } @Test - @DisplayName("북마크 리스트 조회 시 회원 정보 없음으로 인한 실패 테스트") + @DisplayName("북마크 페이지 조회 시 회원 정보 없음으로 인한 실패 테스트") void testGetBookmarksFailure() { // given @@ -196,6 +197,48 @@ void testGetBookmarksFailure() { assertThrows(NotFoundException.class, () -> bookmarkService.getBookmarks(mockMember, 0)); } + @Test + @DisplayName("북마크 가게 아이디 조회 성공 테스트") + void testGetBookmarkStoresIdsSuccess() { + // given + List bookmarks = List.of( + new BookmarkStoreIdsResponseDto( + 1L, + 1L + ), + new BookmarkStoreIdsResponseDto( + 1L, + 2L + ) + ); + + + // when + when(memberRepository.findById(any())).thenReturn(Optional.of(member)); + when(bookmarkRepository.findBookmarkStoreIdsByMemberId(any())).thenReturn(bookmarks); + + // then + List response = bookmarkService.getBookmarkStoreIds(mockMember); + assertThat(response.get(0).bookmarkId()).isEqualTo(bookmarks.get(0).bookmarkId()); + assertThat(response.get(1).bookmarkId()).isEqualTo(bookmarks.get(1).bookmarkId()); + assertThat(response.get(0).storeId()).isEqualTo(bookmarks.get(0).storeId()); + assertThat(response.get(1).storeId()).isEqualTo(bookmarks.get(1).storeId()); + + } + + @Test + @DisplayName("북마크 가게 아이디 조회 시 회원 정보 없음으로 인한 실패 테스트") + void testGetBookmarkStoresIdsFailure() { + // given + + // when + when(memberRepository.findById(any())) + .thenThrow(new NotFoundException(ResponseCode.MEMBER_NOT_FOUND_ID)); + + // then + assertThrows(NotFoundException.class, () -> bookmarkService.getBookmarkStoreIds(mockMember)); + } + @Test @DisplayName("북마크 삭제 성공 테스트") void testDeleteBookmarkSuccess() {