diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..7f9d6a5 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/src/main/java/notai/auth/TokenPair.java b/src/main/java/notai/auth/TokenPair.java index 4e51456..0051082 100644 --- a/src/main/java/notai/auth/TokenPair.java +++ b/src/main/java/notai/auth/TokenPair.java @@ -1,4 +1,7 @@ package notai.auth; -public record TokenPair(String accessToken, String refreshToken) { +public record TokenPair( + String accessToken, + String refreshToken +) { } diff --git a/src/main/java/notai/auth/TokenService.java b/src/main/java/notai/auth/TokenService.java index b4b8510..9204e5a 100644 --- a/src/main/java/notai/auth/TokenService.java +++ b/src/main/java/notai/auth/TokenService.java @@ -29,20 +29,17 @@ public TokenService(TokenProperty tokenProperty, MemberRepository memberReposito } public String createAccessToken(Long memberId) { - return Jwts.builder() - .claim(MEMBER_ID_CLAIM, memberId) - .issuedAt(new Date()) - .expiration(new Date(System.currentTimeMillis() + accessTokenExpirationMillis)) - .signWith(secretKey, Jwts.SIG.HS512) - .compact(); + return Jwts.builder().claim(MEMBER_ID_CLAIM, + memberId + ).issuedAt(new Date()).expiration(new Date(System.currentTimeMillis() + accessTokenExpirationMillis)).signWith(secretKey, + Jwts.SIG.HS512 + ).compact(); } private String createRefreshToken() { - return Jwts.builder() - .issuedAt(new Date()) - .expiration(new Date(System.currentTimeMillis() + refreshTokenExpirationMillis)) - .signWith(secretKey, Jwts.SIG.HS512) - .compact(); + return Jwts.builder().issuedAt(new Date()).expiration(new Date(System.currentTimeMillis() + refreshTokenExpirationMillis)).signWith(secretKey, + Jwts.SIG.HS512 + ).compact(); } public TokenPair createTokenPair(Long memberId) { @@ -71,12 +68,9 @@ public TokenPair refreshTokenPair(String refreshToken) { public Long extractMemberId(String token) { try { - return Jwts.parser() - .verifyWith(secretKey) - .build() - .parseSignedClaims(token) - .getPayload() - .get(MEMBER_ID_CLAIM, Long.class); + return Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token).getPayload().get(MEMBER_ID_CLAIM, + Long.class + ); } catch (Exception e) { throw new UnAuthorizedException("유효하지 않은 토큰입니다."); } diff --git a/src/main/java/notai/client/oauth/kakao/KakaoClient.java b/src/main/java/notai/client/oauth/kakao/KakaoClient.java index a465b0d..8d0b08d 100644 --- a/src/main/java/notai/client/oauth/kakao/KakaoClient.java +++ b/src/main/java/notai/client/oauth/kakao/KakaoClient.java @@ -1,10 +1,9 @@ package notai.client.oauth.kakao; +import static org.springframework.http.HttpHeaders.AUTHORIZATION; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.service.annotation.GetExchange; -import static org.springframework.http.HttpHeaders.AUTHORIZATION; - public interface KakaoClient { @GetExchange(url = "https://kapi.kakao.com/v2/user/me") diff --git a/src/main/java/notai/client/oauth/kakao/KakaoClientConfig.java b/src/main/java/notai/client/oauth/kakao/KakaoClientConfig.java index 3b79924..af7f7ed 100644 --- a/src/main/java/notai/client/oauth/kakao/KakaoClientConfig.java +++ b/src/main/java/notai/client/oauth/kakao/KakaoClientConfig.java @@ -1,14 +1,13 @@ package notai.client.oauth.kakao; import lombok.extern.slf4j.Slf4j; +import static notai.client.HttpInterfaceUtil.createHttpInterface; import notai.common.exception.type.ExternalApiException; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatusCode; import org.springframework.web.client.RestClient; -import static notai.client.HttpInterfaceUtil.createHttpInterface; - @Slf4j @Configuration public class KakaoClientConfig { diff --git a/src/main/java/notai/client/oauth/kakao/KakaoMemberResponse.java b/src/main/java/notai/client/oauth/kakao/KakaoMemberResponse.java index a6a473e..6e81ed8 100644 --- a/src/main/java/notai/client/oauth/kakao/KakaoMemberResponse.java +++ b/src/main/java/notai/client/oauth/kakao/KakaoMemberResponse.java @@ -10,29 +10,33 @@ @JsonNaming(value = SnakeCaseStrategy.class) public record KakaoMemberResponse( - Long id, - boolean hasSignedUp, - LocalDateTime connectedAt, - KakaoAccount kakaoAccount) { + Long id, + boolean hasSignedUp, + LocalDateTime connectedAt, + KakaoAccount kakaoAccount +) { - public Member toDomain() { - return new Member( - new OauthId(String.valueOf(id), OauthProvider.KAKAO), - kakaoAccount.email, - kakaoAccount.profile.nickname); - } + public Member toDomain() { + return new Member( + new OauthId(String.valueOf(id), OauthProvider.KAKAO), + kakaoAccount.email, + kakaoAccount.profile.nickname + ); + } - @JsonNaming(value = SnakeCaseStrategy.class) - public record KakaoAccount( - Profile profile, - boolean emailNeedsAgreement, - boolean isEmailValid, - boolean isEmailVerified, - String email) { - } + @JsonNaming(value = SnakeCaseStrategy.class) + public record KakaoAccount( + Profile profile, + boolean emailNeedsAgreement, + boolean isEmailValid, + boolean isEmailVerified, + String email + ) { + } - @JsonNaming(value = SnakeCaseStrategy.class) - public record Profile( - String nickname) { - } + @JsonNaming(value = SnakeCaseStrategy.class) + public record Profile( + String nickname + ) { + } } diff --git a/src/main/java/notai/client/oauth/kakao/KakaoOauthClient.java b/src/main/java/notai/client/oauth/kakao/KakaoOauthClient.java index 4688f41..781a134 100644 --- a/src/main/java/notai/client/oauth/kakao/KakaoOauthClient.java +++ b/src/main/java/notai/client/oauth/kakao/KakaoOauthClient.java @@ -4,9 +4,8 @@ import notai.client.oauth.OauthClient; import notai.member.domain.Member; import notai.member.domain.OauthProvider; -import org.springframework.stereotype.Component; - import static notai.member.domain.OauthProvider.KAKAO; +import org.springframework.stereotype.Component; @Component @RequiredArgsConstructor diff --git a/src/main/java/notai/folder/application/FolderQueryService.java b/src/main/java/notai/folder/application/FolderQueryService.java index b51c863..1a3a830 100644 --- a/src/main/java/notai/folder/application/FolderQueryService.java +++ b/src/main/java/notai/folder/application/FolderQueryService.java @@ -1,9 +1,34 @@ package notai.folder.application; import lombok.RequiredArgsConstructor; +import notai.folder.application.result.FolderFindResult; +import notai.folder.domain.Folder; +import notai.folder.domain.FolderRepository; import org.springframework.stereotype.Service; +import java.util.List; + @Service @RequiredArgsConstructor public class FolderQueryService { + + private final FolderRepository folderRepository; + + public List getFolders(Long memberId, Long parentFolderId) { + List folders = getFoldersWithMemberAndParent(memberId, parentFolderId); + // document read + return folders.stream().map(this::getFolderResult).toList(); + } + + private List getFoldersWithMemberAndParent(Long memberId, Long parentFolderId) { + if (parentFolderId == null) { + return folderRepository.findAllByMemberIdAndParentFolderIsNull(memberId); + } + return folderRepository.findAllByMemberIdAndParentFolderId(memberId, parentFolderId); + } + + private FolderFindResult getFolderResult(Folder folder) { + Long parentFolderId = folder.getParentFolder() != null ? folder.getParentFolder().getId() : null; + return FolderFindResult.of(folder.getId(), parentFolderId, folder.getName()); + } } diff --git a/src/main/java/notai/folder/application/FolderService.java b/src/main/java/notai/folder/application/FolderService.java index 74ca5c6..4e5e5ec 100644 --- a/src/main/java/notai/folder/application/FolderService.java +++ b/src/main/java/notai/folder/application/FolderService.java @@ -1,9 +1,69 @@ package notai.folder.application; import lombok.RequiredArgsConstructor; +import notai.common.exception.type.BadRequestException; +import notai.folder.application.result.FolderMoveResult; +import notai.folder.application.result.FolderSaveResult; +import notai.folder.domain.Folder; +import notai.folder.domain.FolderRepository; +import notai.folder.presentation.request.FolderMoveRequest; +import notai.folder.presentation.request.FolderSaveRequest; +import notai.member.domain.Member; +import notai.member.domain.MemberRepository; import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor public class FolderService { + + private final FolderRepository folderRepository; + private final MemberRepository memberRepository; + + public FolderSaveResult saveRootFolder(Long memberId, FolderSaveRequest folderSaveRequest) { + Member member = memberRepository.getById(memberId); + Folder folder = new Folder(member, folderSaveRequest.name()); + Folder savedFolder = folderRepository.save(folder); + return getFolderSaveResult(savedFolder); + } + + public FolderSaveResult saveSubFolder(Long memberId, FolderSaveRequest folderSaveRequest) { + Member member = memberRepository.getById(memberId); + Folder parentFolder = folderRepository.getById(folderSaveRequest.parentFolderId()); + Folder folder = new Folder(member, folderSaveRequest.name(), parentFolder); + Folder savedFolder = folderRepository.save(folder); + return getFolderSaveResult(savedFolder); + } + + public FolderMoveResult moveRootFolder(Long memberId, Long id) { + Folder folder = folderRepository.getById(id); + folder.validateOwner(memberId); + folder.moveRootFolder(); + folderRepository.save(folder); + return getFolderMoveResult(folder); + } + + public FolderMoveResult moveNewParentFolder(Long memberId, Long id, FolderMoveRequest folderMoveRequest) { + Folder folder = folderRepository.getById(id); + Folder parentFolder = folderRepository.getById(folderMoveRequest.targetFolderId()); + folder.validateOwner(memberId); + folder.moveNewParentFolder(parentFolder); + folderRepository.save(folder); + return getFolderMoveResult(folder); + } + + public void deleteFolder(Long memberId, Long id) { + if (!folderRepository.existsByMemberIdAndId(memberId, id)) { + throw new BadRequestException("올바르지 않은 요청입니다."); + } + folderRepository.deleteById(id); + } + + private FolderSaveResult getFolderSaveResult(Folder folder) { + Long parentFolderId = folder.getParentFolder() != null ? folder.getParentFolder().getId() : null; + return FolderSaveResult.of(folder.getId(), parentFolderId, folder.getName()); + } + + private FolderMoveResult getFolderMoveResult(Folder folder) { + return FolderMoveResult.of(folder.getId(), folder.getName()); + } } diff --git a/src/main/java/notai/folder/application/result/FolderFindResult.java b/src/main/java/notai/folder/application/result/FolderFindResult.java new file mode 100644 index 0000000..3014ac0 --- /dev/null +++ b/src/main/java/notai/folder/application/result/FolderFindResult.java @@ -0,0 +1,11 @@ +package notai.folder.application.result; + +public record FolderFindResult( + Long id, + Long parentId, + String name +) { + public static FolderFindResult of(Long id, Long parentId, String name) { + return new FolderFindResult(id, parentId, name); + } +} diff --git a/src/main/java/notai/folder/application/result/FolderMoveResult.java b/src/main/java/notai/folder/application/result/FolderMoveResult.java new file mode 100644 index 0000000..4004836 --- /dev/null +++ b/src/main/java/notai/folder/application/result/FolderMoveResult.java @@ -0,0 +1,10 @@ +package notai.folder.application.result; + +public record FolderMoveResult( + Long id, + String name +) { + public static FolderMoveResult of(Long id, String name) { + return new FolderMoveResult(id, name); + } +} diff --git a/src/main/java/notai/folder/application/result/FolderSaveResult.java b/src/main/java/notai/folder/application/result/FolderSaveResult.java new file mode 100644 index 0000000..bb01f50 --- /dev/null +++ b/src/main/java/notai/folder/application/result/FolderSaveResult.java @@ -0,0 +1,11 @@ +package notai.folder.application.result; + +public record FolderSaveResult( + Long id, + Long parentId, + String name +) { + public static FolderSaveResult of(Long id, Long parentId, String name) { + return new FolderSaveResult(id, parentId, name); + } +} diff --git a/src/main/java/notai/folder/domain/Folder.java b/src/main/java/notai/folder/domain/Folder.java index f6367e8..1cbc797 100644 --- a/src/main/java/notai/folder/domain/Folder.java +++ b/src/main/java/notai/folder/domain/Folder.java @@ -7,7 +7,10 @@ import lombok.Getter; import lombok.NoArgsConstructor; import notai.common.domain.RootEntity; +import notai.common.exception.type.NotFoundException; import notai.member.domain.Member; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; @Entity @Table(name = "folder") @@ -20,7 +23,7 @@ public class Folder extends RootEntity { private Long id; @NotNull - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id", nullable = false) private Member member; @@ -30,6 +33,7 @@ public class Folder extends RootEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "parent_folder_id", referencedColumnName = "id") + @OnDelete(action = OnDeleteAction.CASCADE) private Folder parentFolder; public Folder(Member member, String name) { @@ -50,4 +54,10 @@ public void moveRootFolder() { public void moveNewParentFolder(Folder parentFolder) { this.parentFolder = parentFolder; } + + public void validateOwner(Long memberId) { + if (!this.member.getId().equals(memberId)) { + throw new NotFoundException("해당 이용자가 보유한 폴더 중 이 폴더가 존재하지 않습니다."); + } + } } diff --git a/src/main/java/notai/folder/domain/FolderRepository.java b/src/main/java/notai/folder/domain/FolderRepository.java index 40a2231..d95fc33 100644 --- a/src/main/java/notai/folder/domain/FolderRepository.java +++ b/src/main/java/notai/folder/domain/FolderRepository.java @@ -1,7 +1,18 @@ package notai.folder.domain; -import notai.folder.query.FolderQueryRepository; +import notai.common.exception.type.NotFoundException; import org.springframework.data.jpa.repository.JpaRepository; -public interface FolderRepository extends JpaRepository, FolderQueryRepository { +import java.util.List; + +public interface FolderRepository extends JpaRepository { + default Folder getById(Long id) { + return findById(id).orElseThrow(() -> new NotFoundException("폴더 정보를 찾을 수 없습니다.")); + } + + List findAllByMemberIdAndParentFolderIsNull(Long memberId); + + List findAllByMemberIdAndParentFolderId(Long memberId, Long parentFolderId); + + boolean existsByMemberIdAndId(Long memberId, Long id); } diff --git a/src/main/java/notai/folder/presentation/FolderController.java b/src/main/java/notai/folder/presentation/FolderController.java index 0c0383c..2f503dc 100644 --- a/src/main/java/notai/folder/presentation/FolderController.java +++ b/src/main/java/notai/folder/presentation/FolderController.java @@ -1,10 +1,24 @@ package notai.folder.presentation; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import notai.auth.Auth; import notai.folder.application.FolderQueryService; import notai.folder.application.FolderService; +import notai.folder.application.result.FolderFindResult; +import notai.folder.application.result.FolderMoveResult; +import notai.folder.application.result.FolderSaveResult; +import notai.folder.presentation.request.FolderMoveRequest; +import notai.folder.presentation.request.FolderSaveRequest; +import notai.folder.presentation.response.FolderFindResponse; +import notai.folder.presentation.response.FolderMoveResponse; +import notai.folder.presentation.response.FolderSaveResponse; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.*; + +import java.net.URI; +import java.util.List; @Controller @RequestMapping("/api/folders") @@ -13,4 +27,53 @@ public class FolderController { private final FolderService folderService; private final FolderQueryService folderQueryService; + + @PostMapping + public ResponseEntity saveFolder( + @Auth Long memberId, @Valid @RequestBody FolderSaveRequest folderSaveRequest + ) { + FolderSaveResult folderResult = saveFolderResult(memberId, folderSaveRequest); + FolderSaveResponse response = FolderSaveResponse.from(folderResult); + return ResponseEntity.created(URI.create("/api/folders/" + response.id())).body(response); + } + + @PostMapping("/{id}/move") + public ResponseEntity moveFolder( + @Auth Long memberId, @PathVariable Long id, @Valid @RequestBody FolderMoveRequest folderMoveRequest + ) { + FolderMoveResult folderResult = moveFolderWithRequest(memberId, id, folderMoveRequest); + FolderMoveResponse response = FolderMoveResponse.from(folderResult); + return ResponseEntity.ok(response); + } + + @GetMapping + public ResponseEntity> getFolders( + @Auth Long memberId, @RequestParam(required = false) Long parentFolderId + ) { + List folderResults = folderQueryService.getFolders(memberId, parentFolderId); + List response = folderResults.stream().map(FolderFindResponse::from).toList(); + return ResponseEntity.ok(response); + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteFolder( + @Auth Long memberId, @PathVariable Long id + ) { + folderService.deleteFolder(memberId, id); + return ResponseEntity.noContent().build(); + } + + private FolderSaveResult saveFolderResult(Long memberId, FolderSaveRequest folderSaveRequest) { + if (folderSaveRequest.parentFolderId() != null) { + return folderService.saveSubFolder(memberId, folderSaveRequest); + } + return folderService.saveRootFolder(memberId, folderSaveRequest); + } + + private FolderMoveResult moveFolderWithRequest(Long memberId, Long id, FolderMoveRequest folderMoveRequest) { + if (folderMoveRequest.targetFolderId() != null) { + return folderService.moveNewParentFolder(memberId, id, folderMoveRequest); + } + return folderService.moveRootFolder(memberId, id); + } } diff --git a/src/main/java/notai/folder/presentation/request/FolderMoveRequest.java b/src/main/java/notai/folder/presentation/request/FolderMoveRequest.java new file mode 100644 index 0000000..a1f6ff3 --- /dev/null +++ b/src/main/java/notai/folder/presentation/request/FolderMoveRequest.java @@ -0,0 +1,6 @@ +package notai.folder.presentation.request; + +public record FolderMoveRequest( + Long targetFolderId +) { +} diff --git a/src/main/java/notai/folder/presentation/request/FolderSaveRequest.java b/src/main/java/notai/folder/presentation/request/FolderSaveRequest.java new file mode 100644 index 0000000..b16f7f9 --- /dev/null +++ b/src/main/java/notai/folder/presentation/request/FolderSaveRequest.java @@ -0,0 +1,7 @@ +package notai.folder.presentation.request; + +public record FolderSaveRequest( + Long parentFolderId, + String name +) { +} diff --git a/src/main/java/notai/folder/presentation/response/FolderFindResponse.java b/src/main/java/notai/folder/presentation/response/FolderFindResponse.java new file mode 100644 index 0000000..8d0a687 --- /dev/null +++ b/src/main/java/notai/folder/presentation/response/FolderFindResponse.java @@ -0,0 +1,13 @@ +package notai.folder.presentation.response; + +import notai.folder.application.result.FolderFindResult; + +public record FolderFindResponse( + Long id, + Long parentId, + String name +) { + public static FolderFindResponse from(FolderFindResult folderFindResult) { + return new FolderFindResponse(folderFindResult.id(), folderFindResult.parentId(), folderFindResult.name()); + } +} diff --git a/src/main/java/notai/folder/presentation/response/FolderMoveResponse.java b/src/main/java/notai/folder/presentation/response/FolderMoveResponse.java new file mode 100644 index 0000000..0801a69 --- /dev/null +++ b/src/main/java/notai/folder/presentation/response/FolderMoveResponse.java @@ -0,0 +1,12 @@ +package notai.folder.presentation.response; + +import notai.folder.application.result.FolderMoveResult; + +public record FolderMoveResponse( + Long id, + String name +) { + public static FolderMoveResponse from(FolderMoveResult folderMoveResult) { + return new FolderMoveResponse(folderMoveResult.id(), folderMoveResult.name()); + } +} diff --git a/src/main/java/notai/folder/presentation/response/FolderSaveResponse.java b/src/main/java/notai/folder/presentation/response/FolderSaveResponse.java new file mode 100644 index 0000000..cfc552f --- /dev/null +++ b/src/main/java/notai/folder/presentation/response/FolderSaveResponse.java @@ -0,0 +1,13 @@ +package notai.folder.presentation.response; + +import notai.folder.application.result.FolderSaveResult; + +public record FolderSaveResponse( + Long id, + Long parentId, + String name +) { + public static FolderSaveResponse from(FolderSaveResult folderSaveResult) { + return new FolderSaveResponse(folderSaveResult.id(), folderSaveResult.parentId(), folderSaveResult.name()); + } +} diff --git a/src/main/java/notai/folder/query/FolderQueryRepository.java b/src/main/java/notai/folder/query/FolderQueryRepository.java deleted file mode 100644 index 93bdaee..0000000 --- a/src/main/java/notai/folder/query/FolderQueryRepository.java +++ /dev/null @@ -1,4 +0,0 @@ -package notai.folder.query; - -public interface FolderQueryRepository { -} diff --git a/src/main/java/notai/folder/query/FolderQueryRepositoryImpl.java b/src/main/java/notai/folder/query/FolderQueryRepositoryImpl.java deleted file mode 100644 index c7b7681..0000000 --- a/src/main/java/notai/folder/query/FolderQueryRepositoryImpl.java +++ /dev/null @@ -1,10 +0,0 @@ -package notai.folder.query; - -import com.querydsl.jpa.impl.JPAQueryFactory; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public class FolderQueryRepositoryImpl implements FolderQueryRepository { - - private final JPAQueryFactory jpaQueryFactory; -} diff --git a/src/main/java/notai/llm/domain/TaskStatus.java b/src/main/java/notai/llm/domain/TaskStatus.java index be44ed8..aa0b6dd 100644 --- a/src/main/java/notai/llm/domain/TaskStatus.java +++ b/src/main/java/notai/llm/domain/TaskStatus.java @@ -1,7 +1,5 @@ package notai.llm.domain; public enum TaskStatus { - PENDING, - IN_PROGRESS, - COMPLETED + PENDING, IN_PROGRESS, COMPLETED } diff --git a/src/test/java/notai/BackendApplicationTests.java b/src/test/java/notai/BackendApplicationTests.java index b50683a..e34c1e0 100644 --- a/src/test/java/notai/BackendApplicationTests.java +++ b/src/test/java/notai/BackendApplicationTests.java @@ -6,8 +6,8 @@ @SpringBootTest class BackendApplicationTests { - @Test - void contextLoads() { - } + @Test + void contextLoads() { + } } diff --git a/src/test/java/notai/client/oauth/kakao/KakaoOauthClientTest.java b/src/test/java/notai/client/oauth/kakao/KakaoOauthClientTest.java index 2dd7dcb..880eb1b 100644 --- a/src/test/java/notai/client/oauth/kakao/KakaoOauthClientTest.java +++ b/src/test/java/notai/client/oauth/kakao/KakaoOauthClientTest.java @@ -2,17 +2,16 @@ import notai.member.domain.Member; import notai.member.domain.OauthProvider; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; +import static org.mockito.Mockito.when; import org.mockito.MockitoAnnotations; import java.time.LocalDateTime; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.when; - public class KakaoOauthClientTest { @Mock @@ -39,12 +38,12 @@ public void testFetchMember() { String nickname = "nickname"; KakaoMemberResponse.Profile profile = new KakaoMemberResponse.Profile(nickname); - KakaoMemberResponse.KakaoAccount kakaoAccount = new KakaoMemberResponse.KakaoAccount( - profile, + KakaoMemberResponse.KakaoAccount kakaoAccount = new KakaoMemberResponse.KakaoAccount(profile, emailNeedsAgreement, isEmailValid, isEmailVerified, - email); + email + ); KakaoMemberResponse kakaoMemberResponse = new KakaoMemberResponse(id, hasSignedUp, connectedAt, kakaoAccount); diff --git a/src/test/java/notai/folder/application/FolderQueryServiceTest.java b/src/test/java/notai/folder/application/FolderQueryServiceTest.java new file mode 100644 index 0000000..a567e1d --- /dev/null +++ b/src/test/java/notai/folder/application/FolderQueryServiceTest.java @@ -0,0 +1,64 @@ +package notai.folder.application; + +import notai.folder.application.result.FolderFindResult; +import notai.folder.domain.Folder; +import notai.folder.domain.FolderRepository; +import notai.member.domain.Member; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import static org.mockito.ArgumentMatchers.any; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import static org.mockito.Mockito.*; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; + +@ExtendWith(MockitoExtension.class) +class FolderQueryServiceTest { + + @Mock + private FolderRepository folderRepository; + @InjectMocks + private FolderQueryService folderQueryService; + + @Test + @DisplayName("루트 폴더 조회") + void getFolders_success_parentFolderIdIsNull() { + //given + Folder folder = getFolder(1L, null, "루트폴더"); + List expectedResults = List.of(folder); + + when(folderRepository.findAllByMemberIdAndParentFolderIsNull(any(Long.class))).thenReturn(expectedResults); + //when + List folders = folderQueryService.getFolders(1L, null); + + Assertions.assertThat(folders.size()).isEqualTo(1); + } + + @Test + @DisplayName("계층적 구조의 폴더 조회") + void getFolders_success_parentFolderId() { + //given + Folder folder1 = getFolder(1L, null, "루트폴더"); + Folder folder2 = getFolder(2L, folder1, "서브폴더"); + Folder folder3 = getFolder(3L, folder1, "서브폴더"); + List expectedResults = List.of(folder2, folder3); + + when(folderRepository.findAllByMemberIdAndParentFolderId(any(Long.class), any(Long.class))).thenReturn( + expectedResults); + //when + List folders = folderQueryService.getFolders(1L, 1L); + + Assertions.assertThat(folders.size()).isEqualTo(2); + } + + private Folder getFolder(Long id, Folder parentFolder, String name) { + Member member = mock(Member.class); + Folder folder = spy(new Folder(member, name, parentFolder)); + lenient().when(folder.getId()).thenReturn(id); + return folder; + } +}