Skip to content

Commit

Permalink
Merge pull request #22 from Findy-org/feat/즐겨찾기-이름-변경
Browse files Browse the repository at this point in the history
[FINDY-33] feat: 즐겨찾기 이름 변경
  • Loading branch information
Hoya324 authored Nov 16, 2024
2 parents f9f1f29 + d19882a commit 1629604
Show file tree
Hide file tree
Showing 10 changed files with 240 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
import org.findy.findy_be.bookmark.application.delete.DeleteBookmark;
import org.findy.findy_be.bookmark.application.find.FindAllPagedBookmarks;
import org.findy.findy_be.bookmark.application.register.RegisterYoutubeBookmark;
import org.findy.findy_be.bookmark.application.update.UpdateBookmark;
import org.findy.findy_be.bookmark.dto.request.CreateCustomBookmarkRequest;
import org.findy.findy_be.bookmark.dto.request.UpdateBookmarkRequest;
import org.findy.findy_be.bookmark.dto.request.YoutubeBookmarkRequest;
import org.findy.findy_be.bookmark.dto.response.BookmarkResponse;
import org.findy.findy_be.common.dto.pagination.request.PagedRequest;
Expand All @@ -17,6 +19,7 @@
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
Expand All @@ -33,6 +36,7 @@ public class BookmarkController implements BookmarkAPIPresentation {
private final CreateCustomBookmark createCustomBookmark;
private final FindAllPagedBookmarks findAllPagedBookmarks;
private final DeleteBookmark deleteBookmark;
private final UpdateBookmark updateBookmark;

@PostMapping("/youtube")
public void registerYoutubeBookmark(@LoginUser User user, @Valid @RequestBody YoutubeBookmarkRequest request) {
Expand All @@ -54,4 +58,10 @@ public SliceResponse<BookmarkResponse> getBookmarkList(@LoginUser User user,
public void deleteBookmark(@LoginUser User user, @PathVariable("id") Long bookmarkId) {
deleteBookmark.invoke(user.getUserId(), bookmarkId);
}

@PutMapping("/{id}")
public void updateBookmark(@LoginUser User user, @PathVariable("id") Long bookmarkId,
@RequestBody UpdateBookmarkRequest request) {
updateBookmark.invoke(user.getUserId(), bookmarkId, request);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.findy.findy_be.bookmark.api.swagger;

import org.findy.findy_be.bookmark.dto.request.CreateCustomBookmarkRequest;
import org.findy.findy_be.bookmark.dto.request.UpdateBookmarkRequest;
import org.findy.findy_be.bookmark.dto.request.YoutubeBookmarkRequest;
import org.findy.findy_be.bookmark.dto.response.BookmarkResponse;
import org.findy.findy_be.common.dto.pagination.request.PagedRequest;
Expand Down Expand Up @@ -63,4 +64,16 @@ public interface BookmarkAPIPresentation {
@CustomApiResponse(error = "InternalServerError", status = 500, message = "내부 서버 오류가 발생했습니다.", description = "서버 내부에서 예기치 않은 오류가 발생한 경우")
})
void deleteBookmark(@LoginUser User user, @PathVariable("id") Long bookmarkId);

@Operation(summary = "북마크 수정", description = "북마크를 수정하는 API(현재는 name만)", responses = {
@ApiResponse(responseCode = "200", description = "북마크 수정 성공")
})
@CustomApiResponses({
@CustomApiResponse(error = "IllegalArgumentException", status = 400, message = "잘못된 요청입니다.", description = "잘못된 쿼리 파라미터가 포함된 경우"),
@CustomApiResponse(error = "ForbiddenAccessException", status = 403, message = "해당 즐겨찾기에 접근할 권한이 없습니다.", description = "권한이 없는 유저가 즐겨찾기에 접근할 경우"),
@CustomApiResponse(error = "EntityNotFoundException", status = 404, message = "해당 id : {id}의 즐겨찾기가 존재하지 않습니다.", description = "존재하지 않는 즐겨찾기에 접근할 경우"),
@CustomApiResponse(error = "InternalServerError", status = 500, message = "내부 서버 오류가 발생했습니다.", description = "서버 내부에서 예기치 않은 오류가 발생한 경우")
})
void updateBookmark(@LoginUser User user, @PathVariable("id") Long bookmarkId,
@RequestBody UpdateBookmarkRequest request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void invoke(final User user, final YoutubeBookmarkRequest request) {
List<RegisterPlaceRequest> placeRequests = request.places();
bookmarkRepository.findByUserAndYoutuberId(user, request.youtuberId()).ifPresentOrElse(
existingBookmark -> {
existingBookmark.updateYoutuberName(request.youtuberName());
existingBookmark.updateName(request.youtuberName());
validateBookmarkOwner(user, existingBookmark.getUser());
batchRegisterPlace.invoke(existingBookmark, placeRequests);
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.findy.findy_be.bookmark.application.update;

import org.findy.findy_be.bookmark.dto.request.UpdateBookmarkRequest;

public interface UpdateBookmark {

void invoke(String userId, Long bookmarkId, UpdateBookmarkRequest request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.findy.findy_be.bookmark.application.update;

import static org.findy.findy_be.common.exception.ErrorCode.*;

import org.findy.findy_be.bookmark.domain.Bookmark;
import org.findy.findy_be.bookmark.dto.request.UpdateBookmarkRequest;
import org.findy.findy_be.bookmark.repository.BookmarkRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.persistence.EntityNotFoundException;
import lombok.RequiredArgsConstructor;

@Service
@Transactional
@RequiredArgsConstructor
public class UpdateBookmarkService implements UpdateBookmark {

private final BookmarkRepository bookmarkRepository;

@Override
public void invoke(final String userId, final Long bookmarkId, final UpdateBookmarkRequest request) {
Bookmark bookmark = bookmarkRepository.findById(bookmarkId)
.orElseThrow(
() -> new EntityNotFoundException(String.format(NOT_FOUND_BOOKMARK_BY_ID.getMessage(), bookmarkId)));
validateBookmarkUser(userId, bookmark);
bookmark.updateName(request.name());
}

private static void validateBookmarkUser(final String userId, final Bookmark bookmark) {
if (!bookmark.getUser().getUserId().equals(userId)) {
throw new IllegalArgumentException(FORBIDDEN_BOOKMARK_ACCESS.getMessage());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ public void incrementMarkersCount(int incrementValue) {
this.markersCount += incrementValue;
}

public void updateYoutuberName(String youtuberName) {
this.name = this.name.equals(youtuberName) ? this.name : youtuberName;
public void updateName(String name) {
this.name = this.name.equals(name) || name == null ? this.name : name;
}

public static Bookmark of(String name, BookmarkType type, String youtuberId, String youtuberProfile,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.findy.findy_be.bookmark.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;

@Schema(description = "즐겨찾기 이름 변경 DTO")
public record UpdateBookmarkRequest(

@NotNull(message = "북마크 이름은 비어있을 수 없습니다.")
@Schema(description = "북마크 이름", example = "서촌")
String name
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.findy.findy_be.bookmark.domain.Bookmark;
import org.findy.findy_be.bookmark.domain.BookmarkType;
import org.findy.findy_be.bookmark.dto.request.CreateCustomBookmarkRequest;
import org.findy.findy_be.bookmark.dto.request.UpdateBookmarkRequest;
import org.findy.findy_be.bookmark.dto.request.YoutubeBookmarkRequest;
import org.findy.findy_be.bookmark.repository.BookmarkRepository;
import org.findy.findy_be.common.IntegrationTest;
Expand Down Expand Up @@ -205,6 +206,21 @@ void setUp() {
Assertions.assertThat(resultBookmark.isEmpty()).isTrue();
}

@DisplayName("[성공] 북마크 수정 요청")
@Test
void 북마크_이름_수정() throws Exception {
// given
Bookmark bookmark = bookmarkRepository.save(Bookmark.of("서촌", BookmarkType.CUSTOM, null, null, null, testUser));
UpdateBookmarkRequest request = new UpdateBookmarkRequest("안국");

// when
PutBookmark(bookmark.getId(), request);

// then
Optional<Bookmark> resultBookmark = bookmarkRepository.findById(bookmark.getId());
Assertions.assertThat(resultBookmark.get().getName()).isEqualTo("안국");
}

private @NotNull ResultActions PostYoutubeBookmark(Object content) throws Exception {
return mvc.perform(post("/api/bookmarks/youtube")
.contentType(MediaType.APPLICATION_JSON)
Expand Down Expand Up @@ -232,6 +248,13 @@ void setUp() {
.andDo(print());
}

private @NotNull ResultActions PutBookmark(Long id, UpdateBookmarkRequest request) throws Exception {
return mvc.perform(put("/api/bookmarks/{id}", id)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andDo(print());
}

private void initBookmark() {
List<Bookmark> bookmarks = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package org.findy.findy_be.bookmark.application.update;

import static org.assertj.core.api.Assertions.*;
import static org.findy.findy_be.common.exception.ErrorCode.*;
import static org.mockito.Mockito.*;

import java.time.LocalDateTime;
import java.util.Optional;

import org.findy.findy_be.auth.oauth.domain.SocialProviderType;
import org.findy.findy_be.bookmark.domain.Bookmark;
import org.findy.findy_be.bookmark.dto.request.UpdateBookmarkRequest;
import org.findy.findy_be.bookmark.repository.BookmarkRepository;
import org.findy.findy_be.common.MockTest;
import org.findy.findy_be.user.domain.RoleType;
import org.findy.findy_be.user.domain.User;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import jakarta.persistence.EntityNotFoundException;

class UpdateBookmarkServiceTest extends MockTest {

@Mock
private BookmarkRepository bookmarkRepository;

@InjectMocks
private UpdateBookmarkService updateBookmarkService;

private User user;
private Bookmark bookmark;

@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
user = User.create("N49sfgdahdKz_fp-223424er1N3D6kd", "나경호", "[email protected]", "Y",
"https://github.com/account", SocialProviderType.NAVER, RoleType.USER,
LocalDateTime.now(), LocalDateTime.now());
bookmark = Bookmark.createCustomType("서촌", user);
}

@DisplayName("[성공] 즐겨찾기 이름 업데이트")
@Test
void 즐겨찾기_이름_업데이트() throws Exception {
// given
Long customBookmarkId = 1L;
UpdateBookmarkRequest request = new UpdateBookmarkRequest("새로운 이름");
when(bookmarkRepository.findById(customBookmarkId)).thenReturn(Optional.of(bookmark));

// when
updateBookmarkService.invoke(user.getUserId(), customBookmarkId, request);

// then
assertThat(bookmark.getName()).isEqualTo("새로운 이름");
verify(bookmarkRepository, times(1)).findById(customBookmarkId);
}

@DisplayName("[실패] 존재하지 않는 즐겨찾기 ID일 경우 EntityNotFoundException 발생")
@Test
void 존재하지_않는_즐겨찾기_ID일_경우() {
// given
Long nonExistentBookmarkId = 999L;
UpdateBookmarkRequest request = new UpdateBookmarkRequest("새로운 이름");
when(bookmarkRepository.findById(nonExistentBookmarkId)).thenReturn(Optional.empty());

// when & then
assertThatThrownBy(() -> updateBookmarkService.invoke(user.getUserId(), nonExistentBookmarkId, request))
.isInstanceOf(EntityNotFoundException.class)
.hasMessageContaining(String.format(NOT_FOUND_BOOKMARK_BY_ID.getMessage(), nonExistentBookmarkId));
}

@DisplayName("[실패] 다른 사용자의 즐겨찾기를 업데이트하려고 할 경우 IllegalArgumentException 발생")
@Test
void 다른_사용자의_즐겨찾기를_업데이트하려고_할_경우() {
// given
Long customBookmarkId = 1L;
UpdateBookmarkRequest request = new UpdateBookmarkRequest("새로운 이름");
when(bookmarkRepository.findById(customBookmarkId)).thenReturn(Optional.of(bookmark));

// when & then
assertThatThrownBy(() -> updateBookmarkService.invoke("다른사용자ID", customBookmarkId, request))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining(FORBIDDEN_BOOKMARK_ACCESS.getMessage());
}

@DisplayName("[성공] 동일한 이름 요청 시 업데이트하지 않음")
@Test
void 동일한_이름_요청_시() throws Exception {
// given
Long customBookmarkId = 1L;
UpdateBookmarkRequest request = new UpdateBookmarkRequest("서촌"); // 기존 이름과 동일
when(bookmarkRepository.findById(customBookmarkId)).thenReturn(Optional.of(bookmark));

// when
updateBookmarkService.invoke(user.getUserId(), customBookmarkId, request);

// then
assertThat(bookmark.getName()).isEqualTo("서촌"); // 이름이 변경되지 않음
verify(bookmarkRepository, times(1)).findById(customBookmarkId);
}
}
30 changes: 30 additions & 0 deletions src/test/java/org/findy/findy_be/bookmark/domain/BookmarkTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,34 @@ void setUp() {
assertThat(bookmark.getName()).isEqualTo(name);
assertThat(bookmark.getYoutuberProfile()).isNull();
}

@DisplayName("[성공] 즐겨찾기 이름 변경")
@Test
public void 즐겨찾기_이름_변경_성공() throws Exception {
// given
String name = "서촌";
Bookmark bookmark = Bookmark.createCustomType(name, user);
String newName = "안국";

// when
bookmark.updateName(newName);

// then
assertThat(bookmark.getName()).isEqualTo(newName);
}

@DisplayName("[성공 case2] 즐겨찾기 이름 변경 null인 경우 유지")
@Test
public void 즐겨찾기_이름_변경_Null인_경우() throws Exception {
// given
String name = "서촌";
Bookmark bookmark = Bookmark.createCustomType(name, user);
String newNullName = null;

// when
bookmark.updateName(newNullName);

// then
assertThat(bookmark.getName()).isEqualTo(name);
}
}

0 comments on commit 1629604

Please sign in to comment.