-
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(Problem): Bookmark 생성,삭제 API 구현 (#9)
* Refactor(Problem): 가독성 등을 위해 문제 조회에서 DB관련 로직과 응답 DTO 매핑을 분리 * Feat(Problem): Bookmark Entity 구현 - Entity, Repository와 매핑관계 구현 * Feat(Problem): Bookmark 생성 API 구현 * Test(Problem): Bookmark 생성 API 테스트 구현 * Feat(Problem): Bookmark 삭제 API 구현 * Test(Problem): Bookmark 생성 API 테스트 추가 구현 - 예외 상황 테스트 * Test(Problem): Bookmark 삭제 API 테스트 구현 Jira issue: SWM-36
- Loading branch information
Showing
12 changed files
with
339 additions
and
9 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
33 changes: 31 additions & 2 deletions
33
jabiseo-api/src/main/java/com/jabiseo/problem/usecase/CreateBookmarkUseCase.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 |
---|---|---|
@@ -1,12 +1,41 @@ | ||
package com.jabiseo.problem.usecase; | ||
|
||
import com.jabiseo.member.domain.Member; | ||
import com.jabiseo.member.domain.MemberRepository; | ||
import com.jabiseo.problem.domain.Bookmark; | ||
import com.jabiseo.problem.domain.BookmarkRepository; | ||
import com.jabiseo.problem.domain.Problem; | ||
import com.jabiseo.problem.domain.ProblemRepository; | ||
import com.jabiseo.problem.dto.CreateBookmarkRequest; | ||
import com.jabiseo.problem.exception.ProblemBusinessException; | ||
import com.jabiseo.problem.exception.ProblemErrorCode; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Service | ||
@Transactional | ||
@RequiredArgsConstructor | ||
public class CreateBookmarkUseCase { | ||
|
||
public String execute(CreateBookmarkRequest request) { | ||
return "bookmarkId"; | ||
private final MemberRepository memberRepository; | ||
|
||
private final ProblemRepository problemRepository; | ||
|
||
private final BookmarkRepository bookmarkRepository; | ||
|
||
public String execute(String memberId, CreateBookmarkRequest request) { | ||
if (bookmarkRepository.existsByMemberIdAndProblemId(memberId, request.problemId())) { | ||
throw new ProblemBusinessException(ProblemErrorCode.BOOKMARK_ALREADY_EXISTS); | ||
} | ||
|
||
Member member = memberRepository.getReferenceById(memberId); | ||
Problem problem = problemRepository.findById(request.problemId()) | ||
.orElseThrow(() -> new ProblemBusinessException(ProblemErrorCode.PROBLEM_NOT_FOUND)); | ||
|
||
|
||
Bookmark bookmark = Bookmark.of(member, problem); | ||
|
||
return bookmarkRepository.save(bookmark).getId(); | ||
} | ||
} |
17 changes: 15 additions & 2 deletions
17
jabiseo-api/src/main/java/com/jabiseo/problem/usecase/DeleteBookmarkUseCase.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 |
---|---|---|
@@ -1,12 +1,25 @@ | ||
package com.jabiseo.problem.usecase; | ||
|
||
import com.jabiseo.problem.domain.Bookmark; | ||
import com.jabiseo.problem.domain.BookmarkRepository; | ||
import com.jabiseo.problem.dto.DeleteBookmarkRequest; | ||
import com.jabiseo.problem.exception.ProblemBusinessException; | ||
import com.jabiseo.problem.exception.ProblemErrorCode; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@Service | ||
@Transactional | ||
@RequiredArgsConstructor | ||
public class DeleteBookmarkUseCase { | ||
|
||
public void execute(DeleteBookmarkRequest request) { | ||
return; | ||
private final BookmarkRepository bookmarkRepository; | ||
|
||
public void execute(String memberId, DeleteBookmarkRequest request) { | ||
Bookmark bookmark = bookmarkRepository.findByMemberIdAndProblemId(memberId, request.problemId()) | ||
.orElseThrow(() -> new ProblemBusinessException(ProblemErrorCode.BOOKMARK_NOT_FOUND)); | ||
|
||
bookmarkRepository.delete(bookmark); | ||
} | ||
} |
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
106 changes: 106 additions & 0 deletions
106
jabiseo-api/src/test/java/com/jabiseo/problem/usecase/CreateBookmarkUseCaseTest.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,106 @@ | ||
package com.jabiseo.problem.usecase; | ||
|
||
import com.jabiseo.member.domain.Member; | ||
import com.jabiseo.member.domain.MemberRepository; | ||
import com.jabiseo.problem.domain.Bookmark; | ||
import com.jabiseo.problem.domain.BookmarkRepository; | ||
import com.jabiseo.problem.domain.Problem; | ||
import com.jabiseo.problem.domain.ProblemRepository; | ||
import com.jabiseo.problem.dto.CreateBookmarkRequest; | ||
import com.jabiseo.problem.exception.ProblemBusinessException; | ||
import com.jabiseo.problem.exception.ProblemErrorCode; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
import org.mockito.ArgumentCaptor; | ||
import org.mockito.InjectMocks; | ||
import org.mockito.Mock; | ||
import org.mockito.junit.jupiter.MockitoExtension; | ||
|
||
import java.util.Optional; | ||
|
||
import static com.jabiseo.fixture.MemberFixture.createMember; | ||
import static com.jabiseo.fixture.ProblemFixture.createProblem; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
import static org.mockito.ArgumentMatchers.any; | ||
import static org.mockito.BDDMockito.given; | ||
import static org.mockito.Mockito.verify; | ||
|
||
@DisplayName("북마크 생성 테스트") | ||
@ExtendWith(MockitoExtension.class) | ||
class CreateBookmarkUseCaseTest { | ||
|
||
@InjectMocks | ||
CreateBookmarkUseCase sut; | ||
|
||
@Mock | ||
MemberRepository memberRepository; | ||
|
||
@Mock | ||
ProblemRepository problemRepository; | ||
|
||
@Mock | ||
BookmarkRepository bookmarkRepository; | ||
|
||
@Test | ||
@DisplayName("북마크 생성 테스트 성공 케이스") | ||
void givenMemberIdAndProblemId_whenCreatingBookmark_thenCreateBookmark() { | ||
//given | ||
String memberId = "1"; | ||
String problemId = "2"; | ||
Member member = createMember(memberId); | ||
Problem problem = createProblem(problemId); | ||
given(memberRepository.getReferenceById(memberId)).willReturn(member); | ||
given(problemRepository.findById(problemId)).willReturn(Optional.of(problem)); | ||
given(bookmarkRepository.existsByMemberIdAndProblemId(memberId, problemId)).willReturn(false); | ||
given(bookmarkRepository.save(any())).willReturn(Bookmark.of(member, problem)); | ||
|
||
|
||
//when | ||
sut.execute(memberId, new CreateBookmarkRequest(problemId)); | ||
|
||
//then | ||
ArgumentCaptor<Bookmark> bookmarkCaptor = ArgumentCaptor.forClass(Bookmark.class); | ||
verify(bookmarkRepository).save(bookmarkCaptor.capture()); | ||
Bookmark savedBookmark = bookmarkCaptor.getValue(); | ||
|
||
assertThat(savedBookmark).isNotNull(); | ||
assertThat(savedBookmark.getMember().getId()).isEqualTo(memberId); | ||
assertThat(savedBookmark.getProblem().getId()).isEqualTo(problemId); | ||
} | ||
|
||
@Test | ||
@DisplayName("이미 북마크한 문제를 북마크하는 경우 테스트") | ||
void givenAlreadyExistedMemberIdAndProblemId_whenCreatingBookmark_thenReturnError() { | ||
//given | ||
String memberId = "1"; | ||
String problemId = "2"; | ||
given(bookmarkRepository.existsByMemberIdAndProblemId(memberId, problemId)).willReturn(true); | ||
|
||
|
||
//when & then | ||
assertThatThrownBy(() -> sut.execute(memberId, new CreateBookmarkRequest(problemId))) | ||
.isInstanceOf(ProblemBusinessException.class) | ||
.hasFieldOrPropertyWithValue("errorCode", ProblemErrorCode.BOOKMARK_ALREADY_EXISTS); | ||
|
||
} | ||
|
||
@Test | ||
@DisplayName("존재하지 않는 문제의 북마크 생성 테스트") | ||
void givenMemberIdAndNonExistedProblemId_whenCreatingBookmark_thenReturnError() { | ||
//given | ||
String memberId = "1"; | ||
String problemId = "2"; | ||
given(bookmarkRepository.existsByMemberIdAndProblemId(memberId, problemId)).willReturn(false); | ||
given(problemRepository.findById(problemId)).willReturn(Optional.empty()); | ||
|
||
//when & then | ||
assertThatThrownBy(() -> sut.execute(memberId, new CreateBookmarkRequest(problemId))) | ||
.isInstanceOf(ProblemBusinessException.class) | ||
.hasFieldOrPropertyWithValue("errorCode", ProblemErrorCode.PROBLEM_NOT_FOUND); | ||
|
||
} | ||
|
||
|
||
} |
72 changes: 72 additions & 0 deletions
72
jabiseo-api/src/test/java/com/jabiseo/problem/usecase/DeleteBookmarkUseCaseTest.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,72 @@ | ||
package com.jabiseo.problem.usecase; | ||
|
||
import com.jabiseo.member.domain.Member; | ||
import com.jabiseo.problem.domain.Bookmark; | ||
import com.jabiseo.problem.domain.BookmarkRepository; | ||
import com.jabiseo.problem.domain.Problem; | ||
import com.jabiseo.problem.dto.DeleteBookmarkRequest; | ||
import com.jabiseo.problem.exception.ProblemBusinessException; | ||
import com.jabiseo.problem.exception.ProblemErrorCode; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
import org.mockito.ArgumentCaptor; | ||
import org.mockito.InjectMocks; | ||
import org.mockito.Mock; | ||
import org.mockito.junit.jupiter.MockitoExtension; | ||
|
||
import java.util.Optional; | ||
|
||
import static com.jabiseo.fixture.MemberFixture.createMember; | ||
import static com.jabiseo.fixture.ProblemFixture.createProblem; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
import static org.mockito.BDDMockito.given; | ||
import static org.mockito.Mockito.verify; | ||
|
||
@DisplayName("북마크 삭제 테스트") | ||
@ExtendWith(MockitoExtension.class) | ||
class DeleteBookmarkUseCaseTest { | ||
|
||
@InjectMocks | ||
DeleteBookmarkUseCase sut; | ||
|
||
@Mock | ||
BookmarkRepository bookmarkRepository; | ||
|
||
@Test | ||
@DisplayName("북마크 삭제 테스트 성공 케이스") | ||
void givenMemberIdAndProblemId_whenDeletingBookmark_thenDeleteBookmark() { | ||
//given | ||
String memberId = "1"; | ||
String problemId = "2"; | ||
Member member = createMember(memberId); | ||
Problem problem = createProblem(problemId); | ||
Bookmark bookmark = Bookmark.of(member, problem); | ||
given(bookmarkRepository.findByMemberIdAndProblemId(memberId, problemId)).willReturn(Optional.of(bookmark)); | ||
|
||
//when | ||
sut.execute(memberId, new DeleteBookmarkRequest(problemId)); | ||
|
||
//then | ||
ArgumentCaptor<Bookmark> bookmarkCaptor = ArgumentCaptor.forClass(Bookmark.class); | ||
verify(bookmarkRepository).delete(bookmarkCaptor.capture()); | ||
Bookmark deletedBookmark = bookmarkCaptor.getValue(); | ||
assertThat(deletedBookmark).isEqualTo(bookmark); | ||
} | ||
|
||
@Test | ||
@DisplayName("존재하지 않는 북마크를 삭제하는 경우 테스트") | ||
void givenNonExistBookmarkWithMemberIdAndProblemId_whenDeletingBookmark_thenReturnError() { | ||
//given | ||
String memberId = "1"; | ||
String problemId = "2"; | ||
given(bookmarkRepository.findByMemberIdAndProblemId(memberId, problemId)).willReturn(Optional.empty()); | ||
|
||
//when & then | ||
assertThatThrownBy(() -> sut.execute(memberId, new DeleteBookmarkRequest(problemId))) | ||
.isInstanceOf(ProblemBusinessException.class) | ||
.hasFieldOrPropertyWithValue("errorCode", ProblemErrorCode.BOOKMARK_NOT_FOUND); | ||
} | ||
|
||
} |
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
Oops, something went wrong.