diff --git a/src/main/java/ussum/homepage/application/post/service/PostManageService.java b/src/main/java/ussum/homepage/application/post/service/PostManageService.java index 9fdd914..4509629 100644 --- a/src/main/java/ussum/homepage/application/post/service/PostManageService.java +++ b/src/main/java/ussum/homepage/application/post/service/PostManageService.java @@ -34,6 +34,9 @@ import ussum.homepage.domain.post.service.*; import ussum.homepage.domain.post.service.factory.BoardFactory; import ussum.homepage.domain.post.service.factory.BoardImpl; +import ussum.homepage.domain.post.service.factory.postList.DataPostResponseFactory; +import ussum.homepage.domain.post.service.factory.postList.PostListResponseFactory; +import ussum.homepage.domain.post.service.factory.postList.PostResponseFactoryProvider; import ussum.homepage.domain.post.service.formatter.PostDetailFunction; import ussum.homepage.domain.postlike.PostReaction; import ussum.homepage.domain.postlike.service.PostReactionManager; @@ -79,14 +82,6 @@ public class PostManageService { private final PostOfficialCommentFormatter postOfficialCommentFormatter; private final S3utils s3utils; - private final Map, Integer, User, ? extends PostListResDto>> postResponseMap = Map.of( - "공지사항게시판", (post, ignored1, ignored2, user) -> NoticePostResponse.of(post, user), - "분실물게시판", (post, ignored1, ignored2, ignored3) -> LostPostResponse.of(post), - "제휴게시판", (post, ignored1, ignored2, ignored3) -> PartnerPostResponse.of(post), - "감사기구게시판", (post, ignored1, ignored2, ignored3) -> AuditPostResponseDto.of(post), - "청원게시판", (post, ignored1, likeCount, ignored2) -> PetitionPostResponse.of(post, likeCount), - "자료집게시판", (post, postFiles, ignored1, ignored2) -> DataPostResponse.of(post, postFiles) - ); private final Map> postDetailResponseMap = Map.of( "공지사항게시판", (post, isAuthor, ignored, user, another_ignored1, categoryName, imageList, fileList, another_ignored2) -> NoticePostDetailResponse.of(post, isAuthor, user, categoryName, imageList, fileList), @@ -98,14 +93,6 @@ public class PostManageService { public PostListRes getPostList(int page, int take, String boardCode, String groupCode, String memberCode, String category) { Board board = boardReader.getBoardWithBoardCode(boardCode); -// Pageable pageable = PageInfo.of(page, take); -// Page postList = null; -// if(boardCode.equals("공지사항게시판")){ -// postList = postReader.getPostListByBoardIdAndGroupCodeAndMemberCode(board.getId(), groupCode, memberCode, pageable); -// }else { -// postList = postReader.getPostListByBoardId(board.getId(), pageable); -// } - //factory 사용 로직 BoardImpl boardImpl = BoardFactory.createBoard(boardCode, board.getId()); @@ -119,43 +106,34 @@ public PostListRes getPostList(int page, int take, String boardCode, String g PageInfo pageInfo = PageInfo.of(postList); - QuadFunction, Integer, User, ? extends PostListResDto> responseFunction = postResponseMap.get(board.getName()); - - if (responseFunction == null) { - throw new IllegalArgumentException("Unknown board type: " + board.getName()); - } - List responseList = postList.getContent().stream() .map(post -> { - User user = null; - Integer likeCount = null; - switch (board.getName()) { - case "공지사항게시판": - user = userReader.getUserWithId(post.getUserId()); - return responseFunction.apply(post, null, null,user); - case "분실물게시판": - case "제휴게시판": - case "감사기구게시판": - case "자료집": - return responseFunction.apply(post, null, null, null); - case "청원게시판": - likeCount = postReactionReader.countPostReactionsByType(post.getId(), "like"); - return responseFunction.apply(post, null, likeCount,null); - default: - throw new EntityNotFoundException(String.valueOf(POST_NOT_FOUND)); - } + PostListResponseFactory factory = PostResponseFactoryProvider.getFactory(board.getName()); + return factory.createResponse(post, postReader, postReactionReader, userReader); }) .toList(); return PostListRes.of(responseList, pageInfo); + } - public PostListRes getDataList(int page, int take, String majorCategory, String middleCategory, String subCategory){ + public PostListRes getDataList(int page, int take, String majorCategory, String middleCategory, String subCategory) { Pageable pageable = PageInfo.of(page, take); - Page postList = postReader.getPostListByFileCategories(FileCategory.getFileCategoriesByCategories(majorCategory, middleCategory, subCategory), pageable); + Page postList = postReader.getPostListByFileCategories( + FileCategory.getFileCategoriesByCategories(majorCategory, middleCategory, subCategory), + pageable + ); PageInfo pageInfo = PageInfo.of(postList); - QuadFunction , Integer, User, ? extends PostListResDto> responseFunction = postResponseMap.get("자료집게시판"); - List responseList = postList.getContent().stream().map(post -> responseFunction.apply(post, postFileReader.getPostFileListByPostId(post.getId()), null, null)).toList(); + + PostListResponseFactory factory = PostResponseFactoryProvider.getFactory("자료집게시판"); + + List responseList = postList.getContent().stream() + .map(post -> { + List postFiles = postFileReader.getPostFileListByPostId(post.getId()); + return ((DataPostResponseFactory) factory).createDataResponse(post, postFiles); + }) + .toList(); + return PostListRes.of(responseList, pageInfo); } @@ -286,6 +264,8 @@ public void deletePost(String boardCode, Long postId) { public PostListRes searchPost(int page, int take, String q, String boardCode, String groupCode, String memberCode, String category) { Board board = boardReader.getBoardWithBoardCode(boardCode); + + //factory 사용 로직 BoardImpl boardImpl = BoardFactory.createBoard(boardCode, board.getId()); Pageable pageable = PageInfo.of(page, take); @@ -297,35 +277,15 @@ public PostListRes searchPost(int page, int take, String q, String boardCode, PageInfo pageInfo = PageInfo.of(postList); - QuadFunction, Integer, User, ? extends PostListResDto> responseFunction = postResponseMap.get(board.getName()); - - if (responseFunction == null) { - throw new IllegalArgumentException("Unknown board type: " + board.getName()); - } - List responseList = postList.getContent().stream() .map(post -> { - User user = null; - Integer likeCount = null; - switch (board.getName()) { - case "공지사항게시판": - user = userReader.getUserWithId(post.getUserId()); - return responseFunction.apply(post, null, null,user); - case "분실물게시판": - case "제휴게시판": - case "감사기구게시판": - case "자료집": - return responseFunction.apply(post, null, null, null); - case "청원게시판": - likeCount = postReactionReader.countPostReactionsByType(post.getId(), "like"); - return responseFunction.apply(post, null, likeCount,null); - default: - throw new EntityNotFoundException(String.valueOf(POST_NOT_FOUND)); - } + PostListResponseFactory factory = PostResponseFactoryProvider.getFactory(board.getName()); + return factory.createResponse(post, postReader, postReactionReader, userReader); }) .toList(); return PostListRes.of(responseList, pageInfo); + } public TopLikedPostListResponse getTopLikedPostList(int page, int take, String boardCode) { @@ -335,83 +295,4 @@ public TopLikedPostListResponse getTopLikedPostList(int page, int take, String b return TopLikedPostListResponse.of(simplePostDtoList.getContent(), pageInfo); } -} -//스위치 사용 로직 -/* -package ussum.homepage.application.post.service; - -import jakarta.persistence.EntityNotFoundException; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.stereotype.Service; -import ussum.homepage.application.post.service.dto.response.postList.*; -import ussum.homepage.domain.post.Board; -import ussum.homepage.domain.post.Post; -import ussum.homepage.domain.post.service.BoardReader; -import ussum.homepage.domain.post.service.PostReader; -import ussum.homepage.global.common.PageInfo; - -import java.util.List; - -import static ussum.homepage.global.error.status.ErrorStatus.POST_NOT_FOUND; - -@Service -@RequiredArgsConstructor -public class PostManageService { - - private final BoardReader boardReader; - private final PostReader postReader; - - public PostListRes getPostList(int page, int take, String boardCode) { - Board board = boardReader.getBoardWithBoardCode(boardCode); - Pageable pageable = PageInfo.of(page, take); - Page postList = postReader.getPostListByBoardId(board.getId(), pageable); - PageInfo pageInfo = PageInfo.of(postList); - - switch (board.getName()) { - case "공지사항": - return getNoticePostList(postList, pageInfo); - case "분실물": - return getLostPostList(postList, pageInfo); - case "제휴": - return getPartnerPostList(postList, pageInfo); - case "감사기구": - return getAuditPostList(postList, pageInfo); - case "청원": - // return getPetitionPostList(postList, pageInfo); - default: - throw new EntityNotFoundException(String.valueOf(POST_NOT_FOUND)); - } - } - - private PostListRes getNoticePostList(Page postList, PageInfo pageInfo) { - List responseList = postList.getContent().stream() - .map(NoticePostResponse::of) - .toList(); - return PostListRes.of(responseList, pageInfo); - } - - private PostListRes getLostPostList(Page postList, PageInfo pageInfo) { - List responseList = postList.getContent().stream() - .map(LostPostResponse::of) - .toList(); - return PostListRes.of(responseList, pageInfo); - } - - private PostListRes getPartnerPostList(Page postList, PageInfo pageInfo) { - List responseList = postList.getContent().stream() - .map(PartnerPostResponse::of) - .toList(); - return PostListRes.of(responseList, pageInfo); - } - - private PostListRes getAuditPostList(Page postList, PageInfo pageInfo) { - List responseList = postList.getContent().stream() - .map(AuditPostResponseDto::of) - .toList(); - return PostListRes.of(responseList, pageInfo); - } -} - - */ \ No newline at end of file +} \ No newline at end of file diff --git a/src/main/java/ussum/homepage/domain/post/service/factory/postList/AuditPostResponseFactory.java b/src/main/java/ussum/homepage/domain/post/service/factory/postList/AuditPostResponseFactory.java new file mode 100644 index 0000000..0736aa2 --- /dev/null +++ b/src/main/java/ussum/homepage/domain/post/service/factory/postList/AuditPostResponseFactory.java @@ -0,0 +1,15 @@ +package ussum.homepage.domain.post.service.factory.postList; + +import ussum.homepage.application.post.service.dto.response.postList.AuditPostResponseDto; +import ussum.homepage.application.post.service.dto.response.postList.PostListResDto; +import ussum.homepage.domain.post.Post; +import ussum.homepage.domain.post.service.PostReader; +import ussum.homepage.domain.postlike.service.PostReactionReader; +import ussum.homepage.domain.user.service.UserReader; + +public class AuditPostResponseFactory implements PostListResponseFactory { + @Override + public PostListResDto createResponse(Post post, PostReader postReader, PostReactionReader postReactionReader, UserReader userReader) { + return AuditPostResponseDto.of(post); + } +} diff --git a/src/main/java/ussum/homepage/domain/post/service/factory/postList/DataPostResponseFactory.java b/src/main/java/ussum/homepage/domain/post/service/factory/postList/DataPostResponseFactory.java new file mode 100644 index 0000000..53c1884 --- /dev/null +++ b/src/main/java/ussum/homepage/domain/post/service/factory/postList/DataPostResponseFactory.java @@ -0,0 +1,24 @@ +package ussum.homepage.domain.post.service.factory.postList; + +import ussum.homepage.application.post.service.dto.response.DataPostResponse; +import ussum.homepage.application.post.service.dto.response.postList.PostListResDto; +import ussum.homepage.domain.post.Post; +import ussum.homepage.domain.post.PostFile; +import ussum.homepage.domain.post.service.PostReader; +import ussum.homepage.domain.postlike.service.PostReactionReader; +import ussum.homepage.domain.user.service.UserReader; + +import java.util.List; + +public class DataPostResponseFactory implements PostListResponseFactory { + @Override + public PostListResDto createResponse(Post post, PostReader postReader, PostReactionReader postReactionReader, UserReader userReader) { + // 이 메서드는 일반적인 경우에 사용되지 않을 것이므로, 예외를 던지거나 null을 반환할 수 있습니다. + throw new UnsupportedOperationException("Use createDataResponse for DataPostResponse"); + } + + @Override + public PostListResDto createDataResponse(Post post, List postFiles) { + return DataPostResponse.of(post, postFiles); + } +} diff --git a/src/main/java/ussum/homepage/domain/post/service/factory/postList/LostPostResponseFactory.java b/src/main/java/ussum/homepage/domain/post/service/factory/postList/LostPostResponseFactory.java new file mode 100644 index 0000000..30a489c --- /dev/null +++ b/src/main/java/ussum/homepage/domain/post/service/factory/postList/LostPostResponseFactory.java @@ -0,0 +1,13 @@ +package ussum.homepage.domain.post.service.factory.postList; +import ussum.homepage.application.post.service.dto.response.postList.LostPostResponse; +import ussum.homepage.application.post.service.dto.response.postList.PostListResDto; +import ussum.homepage.domain.post.Post; +import ussum.homepage.domain.post.service.PostReader; +import ussum.homepage.domain.postlike.service.PostReactionReader; +import ussum.homepage.domain.user.service.UserReader; +public class LostPostResponseFactory implements PostListResponseFactory { + @Override + public PostListResDto createResponse(Post post, PostReader postReader, PostReactionReader postReactionReader, UserReader userReader) { + return LostPostResponse.of(post); + } +} diff --git a/src/main/java/ussum/homepage/domain/post/service/factory/postList/NoticePostResponseFactory.java b/src/main/java/ussum/homepage/domain/post/service/factory/postList/NoticePostResponseFactory.java new file mode 100644 index 0000000..ad7bd31 --- /dev/null +++ b/src/main/java/ussum/homepage/domain/post/service/factory/postList/NoticePostResponseFactory.java @@ -0,0 +1,16 @@ +package ussum.homepage.domain.post.service.factory.postList; + +import ussum.homepage.application.post.service.dto.response.postList.NoticePostResponse; +import ussum.homepage.application.post.service.dto.response.postList.PostListResDto; +import ussum.homepage.domain.post.Post; +import ussum.homepage.domain.post.service.PostReader; +import ussum.homepage.domain.postlike.service.PostReactionReader; +import ussum.homepage.domain.user.User; +import ussum.homepage.domain.user.service.UserReader; +public class NoticePostResponseFactory implements PostListResponseFactory { + @Override + public PostListResDto createResponse(Post post, PostReader postReader, PostReactionReader postReactionReader, UserReader userReader) { + User user = userReader.getUserWithId(post.getUserId()); + return NoticePostResponse.of(post, user); + } +} diff --git a/src/main/java/ussum/homepage/domain/post/service/factory/postList/PartnerPostResponseFactory.java b/src/main/java/ussum/homepage/domain/post/service/factory/postList/PartnerPostResponseFactory.java new file mode 100644 index 0000000..74c128b --- /dev/null +++ b/src/main/java/ussum/homepage/domain/post/service/factory/postList/PartnerPostResponseFactory.java @@ -0,0 +1,14 @@ +package ussum.homepage.domain.post.service.factory.postList; + +import ussum.homepage.application.post.service.dto.response.postList.PartnerPostResponse; +import ussum.homepage.application.post.service.dto.response.postList.PostListResDto; +import ussum.homepage.domain.post.Post; +import ussum.homepage.domain.post.service.PostReader; +import ussum.homepage.domain.postlike.service.PostReactionReader; +import ussum.homepage.domain.user.service.UserReader; +public class PartnerPostResponseFactory implements PostListResponseFactory { + @Override + public PostListResDto createResponse(Post post, PostReader postReader, PostReactionReader postReactionReader, UserReader userReader) { + return PartnerPostResponse.of(post); + } +} diff --git a/src/main/java/ussum/homepage/domain/post/service/factory/postList/PetitionPostResponseFactory.java b/src/main/java/ussum/homepage/domain/post/service/factory/postList/PetitionPostResponseFactory.java new file mode 100644 index 0000000..5e8dfd2 --- /dev/null +++ b/src/main/java/ussum/homepage/domain/post/service/factory/postList/PetitionPostResponseFactory.java @@ -0,0 +1,16 @@ +package ussum.homepage.domain.post.service.factory.postList; + +import ussum.homepage.application.post.service.dto.response.postList.PetitionPostResponse; +import ussum.homepage.application.post.service.dto.response.postList.PostListResDto; +import ussum.homepage.domain.post.Post; +import ussum.homepage.domain.post.service.PostReader; +import ussum.homepage.domain.postlike.service.PostReactionReader; +import ussum.homepage.domain.user.service.UserReader; + +public class PetitionPostResponseFactory implements PostListResponseFactory { + @Override + public PostListResDto createResponse(Post post, PostReader postReader, PostReactionReader postReactionReader, UserReader userReader) { + Integer likeCount = postReactionReader.countPostReactionsByType(post.getId(), "like"); + return PetitionPostResponse.of(post, likeCount); + } +} diff --git a/src/main/java/ussum/homepage/domain/post/service/factory/postList/PostListResponseFactory.java b/src/main/java/ussum/homepage/domain/post/service/factory/postList/PostListResponseFactory.java new file mode 100644 index 0000000..5b634fb --- /dev/null +++ b/src/main/java/ussum/homepage/domain/post/service/factory/postList/PostListResponseFactory.java @@ -0,0 +1,19 @@ +package ussum.homepage.domain.post.service.factory.postList; + +import ussum.homepage.application.post.service.dto.response.postList.PostListResDto; +import ussum.homepage.domain.post.Post; +import ussum.homepage.domain.post.PostFile; +import ussum.homepage.domain.post.service.PostReader; +import ussum.homepage.domain.postlike.service.PostReactionReader; +import ussum.homepage.domain.user.service.UserReader; + +import java.util.List; + +public interface PostListResponseFactory { + PostListResDto createResponse(Post post, PostReader postReader, PostReactionReader postReactionReader, UserReader userReader); + + // 자료집 게시판을 위한 새로운 메서드 + default PostListResDto createDataResponse(Post post, List postFiles) { + throw new UnsupportedOperationException("This operation is not supported for this board type."); + } +} diff --git a/src/main/java/ussum/homepage/domain/post/service/factory/postList/PostResponseFactoryProvider.java b/src/main/java/ussum/homepage/domain/post/service/factory/postList/PostResponseFactoryProvider.java new file mode 100644 index 0000000..fd3807a --- /dev/null +++ b/src/main/java/ussum/homepage/domain/post/service/factory/postList/PostResponseFactoryProvider.java @@ -0,0 +1,25 @@ +package ussum.homepage.domain.post.service.factory.postList; + +import java.util.HashMap; +import java.util.Map; + +public class PostResponseFactoryProvider { + private static final Map factoryMap = new HashMap<>(); + + static { + factoryMap.put("공지사항게시판", new NoticePostResponseFactory()); + factoryMap.put("분실물게시판", new LostPostResponseFactory()); + factoryMap.put("제휴게시판", new PartnerPostResponseFactory()); + factoryMap.put("감사기구게시판", new AuditPostResponseFactory()); + factoryMap.put("청원게시판", new PetitionPostResponseFactory()); + factoryMap.put("자료집게시판", new DataPostResponseFactory()); + } + + public static PostListResponseFactory getFactory(String boardName) { + PostListResponseFactory factory = factoryMap.get(boardName); + if (factory == null) { + throw new IllegalArgumentException("Unknown board type: " + boardName); + } + return factory; + } +} diff --git a/src/test/java/ussum/homepage/application/post/service/PostManageServiceTest.java b/src/test/java/ussum/homepage/application/post/service/PostManageServiceTest.java new file mode 100644 index 0000000..09d324c --- /dev/null +++ b/src/test/java/ussum/homepage/application/post/service/PostManageServiceTest.java @@ -0,0 +1,261 @@ +package ussum.homepage.application.post.service; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import ussum.homepage.domain.post.Board; +import ussum.homepage.domain.post.Post; +import ussum.homepage.domain.post.service.BoardReader; +import ussum.homepage.domain.post.service.PostReader; +import ussum.homepage.domain.post.service.factory.BoardFactory; +import ussum.homepage.domain.post.service.factory.NoticeBoardImpl; +import ussum.homepage.domain.post.service.factory.postList.NoticePostResponseFactory; +import ussum.homepage.domain.post.service.factory.postList.PostResponseFactoryProvider; +import ussum.homepage.domain.postlike.service.PostReactionReader; +import ussum.homepage.domain.user.User; +import ussum.homepage.domain.user.service.UserReader; +import ussum.homepage.application.post.service.dto.response.postList.NoticePostResponse; +import ussum.homepage.application.post.service.dto.response.postList.PostListRes; +import ussum.homepage.infra.jpa.post.entity.Category; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; +@ExtendWith(MockitoExtension.class) +class PostManageServiceTest { + + @InjectMocks + private PostManageService postManageService; + + @Mock private BoardReader boardReader; + @Mock private PostReader postReader; + @Mock private PostReactionReader postReactionReader; + @Mock private UserReader userReader; + + private NoticePostResponseFactory noticePostResponseFactory; + private NoticeBoardImpl noticeBoardImpl; + + @BeforeEach + void setUp() { + try (MockedStatic mockedBoardFactory = mockStatic(BoardFactory.class)) { + mockedBoardFactory.when(() -> BoardFactory.createBoard(eq("공지사항게시판"), anyLong())) + .thenReturn(noticeBoardImpl); + } + + try (MockedStatic mockedFactoryProvider = mockStatic(PostResponseFactoryProvider.class)) { + mockedFactoryProvider.when(() -> PostResponseFactoryProvider.getFactory("공지사항게시판")) + .thenReturn(noticePostResponseFactory); + } + } + + + private static Stream providePostData() { + return Stream.of( + // 공지사항 카테고리 + Arguments.of(Category.EMERGENCY.getStringCategoryCode(), "새로운", true), + Arguments.of(Category.STUDENT_COUNCIL.getStringCategoryCode(), "진행중", false), + + // 분실물 카테고리 + Arguments.of(Category.LOST_STATUS.getStringCategoryCode(), "완료", false), + Arguments.of(Category.LOST_REPORT.getStringCategoryCode(), "접수", false), + + // 제휴안내 카테고리 + Arguments.of(Category.MEDICAL.getStringCategoryCode(), "새로운", false), + Arguments.of(Category.CULTURE.getStringCategoryCode(), "진행중", false), + + // 청원 카테고리 + Arguments.of(Category.IN_PROGRESS.getStringCategoryCode(), "진행중", false), + Arguments.of(Category.COMPLETED.getStringCategoryCode(), "완료", false), + + // 감사기구 카테고리 + Arguments.of(Category.AUDIT_PLAN.getStringCategoryCode(), "새로운", false), + Arguments.of(Category.AUDIT_RESULT.getStringCategoryCode(), "완료", false), + + // 단과대 카테고리 + Arguments.of(Category.IT_SCHOOL.getStringCategoryCode(), "새로운", false), + Arguments.of(Category.BUSINESS_SCHOOL.getStringCategoryCode(), "완료", false) + ); + } + + @ParameterizedTest + @MethodSource("providePostData") + void getPostList_ShouldReturnCorrectResponse(String category, String status, boolean expectedIsEmergency) { + // Given + int page = 0; + int take = 10; + String boardCode = "공지사항게시판"; + + Board board = TestDataFactory.createBoard(boardCode, 1L); + Post post = TestDataFactory.createPost(1L, "Test Title", "Test Content", category, status); + User user = TestDataFactory.createUser(1L, "Test User"); + + Page postPage = new PageImpl<>(List.of(post)); + + when(boardReader.getBoardWithBoardCode(boardCode)).thenReturn(board); + when(postReader.getPostListByBoardIdAndGroupCodeAndMemberCode(eq(1L), isNull(), isNull(), any(Pageable.class))) + .thenReturn(postPage); + when(userReader.getUserWithId(1L)).thenReturn(user); + + // When + PostListRes result = postManageService.getPostList(page, take, boardCode, null, null, null); + + // Then + assertThat(result).isNotNull(); + assertThat(result.postListResDto()) + .isNotNull() + .hasSize(1); + + NoticePostResponse noticeResponse = (NoticePostResponse) result.postListResDto().get(0); + assertThat(noticeResponse) + .satisfies(response -> { + assertThat(response.getPostId()).isEqualTo(1L); + assertThat(response.getTitle()).isEqualTo("Test Title"); + assertThat(response.getContent()).isEqualTo("Test Content"); + assertThat(response.getCategory()).isEqualTo(category); + assertThat(response.getStatus()).isEqualTo(status); + assertThat(response.getAuthor()).isEqualTo("Test User"); + assertThat(response.getIsEmergency()).isEqualTo(expectedIsEmergency); + }); + + assertThat(result.pageInfo()) + .isNotNull() + .satisfies(pageInfo -> { + assertThat(pageInfo.pageNum()).isEqualTo(0); + assertThat(pageInfo.pageSize()).isEqualTo(1); + assertThat(pageInfo.totalElements()).isEqualTo(1); + }); + } + + @Test + void getPostList_WithEmptyResult_ShouldReturnEmptyList() { + // Given + String boardCode = "공지사항게시판"; + Board board = TestDataFactory.createBoard(boardCode, 1L); + Page emptyPage = new PageImpl<>(List.of()); + + when(boardReader.getBoardWithBoardCode(boardCode)).thenReturn(board); + when(postReader.getPostListByBoardIdAndGroupCodeAndMemberCode(eq(1L), isNull(), isNull(), any(Pageable.class))) + .thenReturn(emptyPage); + + // When + PostListRes result = postManageService.getPostList(0, 10, boardCode, null, null, null); + + // Then + assertThat(result.postListResDto()).isEmpty(); + assertThat(result.pageInfo().totalElements()).isZero(); + } + + @Test + void getPostList_WithInvalidBoardCode_ShouldThrowException() { + // Given + String invalidBoardCode = "InvalidBoard"; + when(boardReader.getBoardWithBoardCode(invalidBoardCode)).thenThrow(new IllegalArgumentException("Invalid board code")); + + // When & Then + assertThatThrownBy(() -> postManageService.getPostList(0, 10, invalidBoardCode, null, null, null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Invalid board code"); + } + + @Test + void getPostList_WithPagination_ShouldReturnCorrectPage() { + // Given + int page = 1; + int take = 5; + String boardCode = "공지사항게시판"; + + Board board = TestDataFactory.createBoard(boardCode, 1L); + List posts = TestDataFactory.createMultiplePosts(10); + Page postPage = new PageImpl<>(posts.subList(5, 10), PageRequest.of(page, take), 10); + + when(boardReader.getBoardWithBoardCode(boardCode)).thenReturn(board); + when(postReader.getPostListByBoardIdAndGroupCodeAndMemberCode(eq(1L), isNull(), isNull(), any(Pageable.class))) + .thenReturn(postPage); + when(userReader.getUserWithId(anyLong())).thenReturn(TestDataFactory.createUser(1L, "Test User")); + + // When + PostListRes result = postManageService.getPostList(page, take, boardCode, null, null, null); + + // Then + assertThat(result.postListResDto()).hasSize(5); + assertThat(result.pageInfo()) + .satisfies(pageInfo -> { + assertThat(pageInfo.pageNum()).isEqualTo(1); + assertThat(pageInfo.pageSize()).isEqualTo(5); + assertThat(pageInfo.totalElements()).isEqualTo(10); + assertThat(pageInfo.totalPages()).isEqualTo(2); + }); + } + + @Test + void getPostList_WithNullCategory_ShouldNotThrowException() { + // Given + String boardCode = "공지사항게시판"; + Board board = TestDataFactory.createBoard(boardCode, 1L); + Post post = TestDataFactory.createPost(1L, "Test Title", "Test Content", null, "Active"); + Page postPage = new PageImpl<>(List.of(post)); + + when(boardReader.getBoardWithBoardCode(boardCode)).thenReturn(board); + when(postReader.getPostListByBoardIdAndGroupCodeAndMemberCode(eq(1L), isNull(), isNull(), any(Pageable.class))) + .thenReturn(postPage); + when(userReader.getUserWithId(1L)).thenReturn(TestDataFactory.createUser(1L, "Test User")); + + // When & Then + assertThatCode(() -> postManageService.getPostList(0, 10, boardCode, null, null, null)) + .doesNotThrowAnyException(); + } +} + +class TestDataFactory { + static Board createBoard(String name, Long id) { + Board board = mock(Board.class); + when(board.getName()).thenReturn(name); + when(board.getId()).thenReturn(id); + return board; + } + + static Post createPost(Long id, String title, String content, String category, String status) { + Post post = mock(Post.class); + when(post.getId()).thenReturn(id); + when(post.getTitle()).thenReturn(title); + when(post.getContent()).thenReturn(content); + when(post.getCreatedAt()).thenReturn(LocalDateTime.now().toString()); + when(post.getCategory()).thenReturn(category); + when(post.getThumbnailImage()).thenReturn("thumbnail.jpg"); + when(post.getStatus()).thenReturn(status); + when(post.getUserId()).thenReturn(1L); + return post; + } + + static User createUser(Long id, String name) { + User user = mock(User.class); + when(user.getName()).thenReturn(name); + return user; + } + static List createMultiplePosts(int count) { + return IntStream.range(0, count) + .mapToObj(i -> createPost((long) i, "Title " + i, "Content " + i, + Category.values()[i % Category.values().length].getStringCategoryCode(), "Active")) + .collect(Collectors.toList()); + } +} \ No newline at end of file