diff --git a/src/main/java/com/ssafy/ssafsound/domain/board/dto/GetBoardElement.java b/src/main/java/com/ssafy/ssafsound/domain/board/dto/GetBoardElement.java index 5e8349053..cdb1d06cf 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/board/dto/GetBoardElement.java +++ b/src/main/java/com/ssafy/ssafsound/domain/board/dto/GetBoardElement.java @@ -1,23 +1,26 @@ package com.ssafy.ssafsound.domain.board.dto; import com.ssafy.ssafsound.domain.board.domain.Board; + import lombok.Builder; import lombok.Getter; @Getter @Builder public class GetBoardElement { - private Long boardId; - private String title; - private String imageUrl; - private String description; + private Long boardId; + private String title; + private String imageUrl; + private Boolean usedBoard; + private String description; - public static GetBoardElement from(Board board) { - return GetBoardElement.builder() - .boardId(board.getId()) - .title(board.getTitle()) - .imageUrl(board.getImageUrl()) - .description(board.getDescription()) - .build(); - } + public static GetBoardElement from(Board board) { + return GetBoardElement.builder() + .boardId(board.getId()) + .title(board.getTitle()) + .imageUrl(board.getImageUrl()) + .usedBoard(board.getUsedBoard()) + .description(board.getDescription()) + .build(); + } } diff --git a/src/main/java/com/ssafy/ssafsound/domain/board/repository/BoardRepository.java b/src/main/java/com/ssafy/ssafsound/domain/board/repository/BoardRepository.java index a4d630658..f43d630fb 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/board/repository/BoardRepository.java +++ b/src/main/java/com/ssafy/ssafsound/domain/board/repository/BoardRepository.java @@ -1,9 +1,12 @@ package com.ssafy.ssafsound.domain.board.repository; +import java.util.List; + import com.ssafy.ssafsound.domain.board.domain.Board; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface BoardRepository extends JpaRepository { + List findAllByUsedBoardTrue(); } diff --git a/src/main/java/com/ssafy/ssafsound/domain/board/service/BoardService.java b/src/main/java/com/ssafy/ssafsound/domain/board/service/BoardService.java index 39a2bc849..1a114f5f9 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/board/service/BoardService.java +++ b/src/main/java/com/ssafy/ssafsound/domain/board/service/BoardService.java @@ -18,7 +18,7 @@ public class BoardService { @Transactional(readOnly = true) public GetBoardResDto findBoards() { - List boards = boardRepository.findAll(); + List boards = boardRepository.findAllByUsedBoardTrue(); return GetBoardResDto.from(boards); } } diff --git a/src/main/java/com/ssafy/ssafsound/domain/post/domain/Post.java b/src/main/java/com/ssafy/ssafsound/domain/post/domain/Post.java index ddb6132de..c3591e8ba 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/post/domain/Post.java +++ b/src/main/java/com/ssafy/ssafsound/domain/post/domain/Post.java @@ -1,16 +1,30 @@ package com.ssafy.ssafsound.domain.post.domain; +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; + +import org.hibernate.annotations.SQLDelete; +import org.hibernate.annotations.Where; + import com.ssafy.ssafsound.domain.BaseTimeEntity; import com.ssafy.ssafsound.domain.board.domain.Board; import com.ssafy.ssafsound.domain.comment.domain.Comment; import com.ssafy.ssafsound.domain.member.domain.Member; -import lombok.*; -import org.hibernate.annotations.SQLDelete; -import org.hibernate.annotations.Where; -import javax.persistence.*; -import java.util.ArrayList; -import java.util.List; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; @Entity(name = "post") @Getter @@ -21,54 +35,64 @@ @Where(clause = "deleted_post = false") public class Post extends BaseTimeEntity { - @Id - @Column(name = "post_id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @Column - private String title; - - @Column - private String content; - - @Column - private Long view; - - @Builder.Default - @Column - private Boolean deletedPost = Boolean.FALSE; - - @Column - private Boolean anonymity; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "board_id") - private Board board; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") - private Member member; - - @Builder.Default - @OneToMany(mappedBy = "post") - private List images = new ArrayList<>(); - - @Builder.Default - @OneToMany(mappedBy = "post") - private List likes = new ArrayList<>(); - - @Builder.Default - @OneToMany(mappedBy = "post") - private List comments = new ArrayList<>(); - - @Builder.Default - @OneToMany(mappedBy = "post") - private List scraps = new ArrayList<>(); - - public void updatePost(String title, String content, Boolean anonymity){ - this.title = title; - this.content = content; - this.anonymity = anonymity; - } + @Id + @Column(name = "post_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column + private String title; + + @Column + private String content; + + @Column + private Long view; + + @Builder.Default + @Column + private Boolean deletedPost = Boolean.FALSE; + + @Column + private Boolean anonymity; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "board_id") + private Board board; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; + + @Builder.Default + @OneToMany(mappedBy = "post") + private List images = new ArrayList<>(); + + @Builder.Default + @OneToMany(mappedBy = "post") + private List likes = new ArrayList<>(); + + @Builder.Default + @OneToMany(mappedBy = "post") + private List comments = new ArrayList<>(); + + @Builder.Default + @OneToMany(mappedBy = "post") + private List scraps = new ArrayList<>(); + + public void updatePost(String title, String content, Boolean anonymity) { + this.title = title; + this.content = content; + this.anonymity = anonymity; + } + + public static Post of(Board board, Member member, String title, String content, Boolean anonymity) { + return Post.builder() + .board(board) + .member(member) + .title(title) + .content(content) + .anonymity(anonymity) + .build(); + } } diff --git a/src/main/java/com/ssafy/ssafsound/domain/post/domain/PostImage.java b/src/main/java/com/ssafy/ssafsound/domain/post/domain/PostImage.java index 8be0fd5d6..50998b985 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/post/domain/PostImage.java +++ b/src/main/java/com/ssafy/ssafsound/domain/post/domain/PostImage.java @@ -1,34 +1,49 @@ package com.ssafy.ssafsound.domain.post.domain; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import javax.persistence.*; - -@Entity(name="post_image") +@Entity(name = "post_image") @Getter @Builder @NoArgsConstructor @AllArgsConstructor public class PostImage { - @Id - @Column(name = "post_image_id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; + @Id + @Column(name = "post_image_id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "post_id") + private Post post; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "post_id") - private Post post; + @Column + private String imagePath; - @Column - private String imagePath; + @Column + private String imageUrl; - @Column - private String imageUrl; + @Column + private Integer renderOrder; - @Column - private Integer renderOrder; + public static PostImage of(Post post, String imagePath, String imageUrl) { + return PostImage.builder() + .post(post) + .imagePath(imagePath) + .imageUrl(imageUrl) + .build(); + } } diff --git a/src/main/java/com/ssafy/ssafsound/domain/post/dto/ImageInfo.java b/src/main/java/com/ssafy/ssafsound/domain/post/dto/ImageInfo.java index 879244b35..0d3d5c5a3 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/post/dto/ImageInfo.java +++ b/src/main/java/com/ssafy/ssafsound/domain/post/dto/ImageInfo.java @@ -1,10 +1,12 @@ package com.ssafy.ssafsound.domain.post.dto; +import lombok.Builder; import lombok.Getter; import lombok.Setter; @Getter @Setter +@Builder public class ImageInfo { private String imagePath; private String imageUrl; diff --git a/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java index 310849c8b..6a334ca3f 100644 --- a/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java +++ b/src/main/java/com/ssafy/ssafsound/domain/post/service/PostService.java @@ -184,26 +184,17 @@ public PostIdElement writePost(Long boardId, Long loginMemberId, PostPostWriteRe List images = postPostWriteReqDto.getImages(); - Post post = Post.builder() - .board(board) - .member(loginMember) - .title(postPostWriteReqDto.getTitle()) - .content(postPostWriteReqDto.getContent()) - .anonymity(postPostWriteReqDto.isAnonymity()) - .build(); - postRepository.save(post); + Post post = Post.of(board, loginMember, postPostWriteReqDto.getTitle(), postPostWriteReqDto.getContent(), + postPostWriteReqDto.isAnonymity()); + Long postId = postRepository.save(post).getId(); if (images.size() > 0) { for (ImageInfo image : images) { - PostImage postImage = PostImage.builder() - .post(post) - .imagePath(image.getImagePath()) - .imageUrl(image.getImageUrl()) - .build(); + PostImage postImage = PostImage.of(post, image.getImagePath(), image.getImageUrl()); postImageRepository.save(postImage); } } - return new PostIdElement(post.getId()); + return new PostIdElement(postId); } @Transactional diff --git a/src/test/java/com/ssafy/ssafsound/domain/board/controller/BoardControllerTest.java b/src/test/java/com/ssafy/ssafsound/domain/board/controller/BoardControllerTest.java index b2aabb9f4..6e7186031 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/board/controller/BoardControllerTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/board/controller/BoardControllerTest.java @@ -1,23 +1,32 @@ package com.ssafy.ssafsound.domain.board.controller; +import com.ssafy.ssafsound.domain.board.domain.Board; +import com.ssafy.ssafsound.domain.board.dto.GetBoardResDto; import com.ssafy.ssafsound.global.docs.ControllerTest; +import com.ssafy.ssafsound.global.util.fixture.BoardFixture; + import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; import org.springframework.restdocs.payload.JsonFieldType; import static com.ssafy.ssafsound.global.docs.snippet.CookieDescriptionSnippet.requestCookieAccessTokenNeedless; -import static com.ssafy.ssafsound.global.docs.snippet.CookieDescriptionSnippet.requestCookieAccessTokenOptional; -import static com.ssafy.ssafsound.global.util.fixture.BoardFixture.GET_BOARD_RES_DTO1; import static org.mockito.Mockito.doReturn; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import java.util.List; + class BoardControllerTest extends ControllerTest { + private final BoardFixture boardFixture = new BoardFixture(); + @Test @DisplayName("게시판 목록 조회 데이터 반환") public void findBoards() { - doReturn(GET_BOARD_RES_DTO1) + List boards = List.of(boardFixture.getFreeBoard(), boardFixture.getJobBoard()); + GetBoardResDto getBoardResDto = GetBoardResDto.from(boards); + + doReturn(getBoardResDto) .when(boardService) .findBoards(); @@ -33,6 +42,7 @@ public void findBoards() { fieldWithPath("boardId").type(JsonFieldType.NUMBER).description("게시판 목록의 ID"), fieldWithPath("title").type(JsonFieldType.STRING).description("게시판 목록의 제목, 자유 게시판 | 취업 게시판 | 맛집 게시판 | 질문 게시판 | 싸피 예비생 게시판"), fieldWithPath("imageUrl").type(JsonFieldType.STRING).description("게시판 배너 이미지"), + fieldWithPath("usedBoard").type(JsonFieldType.BOOLEAN).description("게시판 사용 여부"), fieldWithPath("description").type(JsonFieldType.STRING).description("게시판의 특성을 설명해주는 설명문") ))); } diff --git a/src/test/java/com/ssafy/ssafsound/domain/board/service/BoardServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/board/service/BoardServiceTest.java index d8840a68c..35571e7da 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/board/service/BoardServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/board/service/BoardServiceTest.java @@ -3,6 +3,9 @@ import com.ssafy.ssafsound.domain.board.domain.Board; import com.ssafy.ssafsound.domain.board.dto.GetBoardResDto; import com.ssafy.ssafsound.domain.board.repository.BoardRepository; +import com.ssafy.ssafsound.domain.post.dto.GetPostResDto; +import com.ssafy.ssafsound.global.util.fixture.BoardFixture; + import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -20,6 +23,8 @@ @ExtendWith(MockitoExtension.class) class BoardServiceTest { + private final BoardFixture boardFixture = new BoardFixture(); + @Mock private BoardRepository boardRepository; @@ -28,22 +33,23 @@ class BoardServiceTest { @Test @DisplayName("게시판 목록 조회가 성공적으로 수행됩니다.") - void Given_Nothing_When_FindBoards_Then_Success() { - List boards = List.of(BOARD_FIXTURE1, BOARD_FIXTURE2); + void Given_Empty_When_FindBoards_Then_Success() { + Board freeBoard = boardFixture.getFreeBoard(); + Board jobBoard = boardFixture.getJobBoard(); + + List boards = List.of(freeBoard, jobBoard); // given - given(boardRepository.findAll()).willReturn(boards); + given(boardRepository.findAllByUsedBoardTrue()).willReturn(boards); // when - GetBoardResDto getBoardResDto = boardService.findBoards(); + GetBoardResDto response = boardService.findBoards(); // then - assertThat(getBoardResDto.getBoards()) - .hasSize(2) - .extracting("title") - .containsExactly(BOARD_FIXTURE1.getTitle(), BOARD_FIXTURE2.getTitle()); + assertThat(response).usingRecursiveComparison() + .isEqualTo(GetBoardResDto.from(boards)); // verify - verify(boardRepository).findAll(); + verify(boardRepository).findAllByUsedBoardTrue(); } } \ No newline at end of file diff --git a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java index 5d82d465d..da0f975f2 100644 --- a/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java +++ b/src/test/java/com/ssafy/ssafsound/domain/post/service/PostServiceTest.java @@ -1,5 +1,6 @@ package com.ssafy.ssafsound.domain.post.service; +import static com.ssafy.ssafsound.domain.member.domain.QMember.*; import static com.ssafy.ssafsound.global.util.fixture.PostFixture.*; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; @@ -15,6 +16,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import com.ssafy.ssafsound.domain.board.domain.Board; import com.ssafy.ssafsound.domain.board.exception.BoardErrorInfo; import com.ssafy.ssafsound.domain.board.exception.BoardException; import com.ssafy.ssafsound.domain.board.repository.BoardRepository; @@ -29,7 +31,9 @@ import com.ssafy.ssafsound.domain.post.dto.GetPostReqDto; import com.ssafy.ssafsound.domain.post.dto.GetPostResDto; import com.ssafy.ssafsound.domain.post.dto.PostCommonLikeResDto; +import com.ssafy.ssafsound.domain.post.dto.PostIdElement; import com.ssafy.ssafsound.domain.post.dto.PostPostScrapResDto; +import com.ssafy.ssafsound.domain.post.dto.PostPostWriteReqDto; import com.ssafy.ssafsound.domain.post.exception.PostErrorInfo; import com.ssafy.ssafsound.domain.post.exception.PostException; import com.ssafy.ssafsound.domain.post.repository.HotPostRepository; @@ -37,7 +41,9 @@ import com.ssafy.ssafsound.domain.post.repository.PostLikeRepository; import com.ssafy.ssafsound.domain.post.repository.PostRepository; import com.ssafy.ssafsound.domain.post.repository.PostScrapRepository; +import com.ssafy.ssafsound.global.util.fixture.BoardFixture; import com.ssafy.ssafsound.global.util.fixture.MemberFixture; +import com.ssafy.ssafsound.global.util.fixture.PostFixture; import com.ssafy.ssafsound.infra.storage.service.AwsS3StorageService; @ExtendWith(MockitoExtension.class) @@ -73,7 +79,9 @@ class PostServiceTest { @InjectMocks private PostService postService; - private MemberFixture memberFixture = new MemberFixture(); + private final MemberFixture memberFixture = new MemberFixture(); + private final BoardFixture boardFixture = new BoardFixture(); + private final PostFixture postFixture = new PostFixture(); @Test @DisplayName("유효한 boardId, cursor, size가 주어졌다면 게시글 목록 조회가 성공합니다.") @@ -102,7 +110,7 @@ void Given_BoardIdAndCursorAndSize_When_findPosts_Then_Success() { @Test @DisplayName("유효하지 않은 boardId가 주어졌다면 게시글 목록 조회에 예외를 발생합니다.") - void Given_BoardId_When_findPosts_Then_Fail() { + void Given_BoardId_When_findPosts_Then_ThrowException() { // given GetPostReqDto getPostReqDto = GetPostReqDto.builder().boardId(100L).cursor(-1L).size(10).build(); @@ -158,7 +166,7 @@ void Given_PostId_When_findPost_Then_Success() { @Test @DisplayName("유효하지 않은 postId가 주어졌다면 게시글 상세보기에 예외를 발생합니다.") - void Given_InvalidPostId_When_findPost_Then_Success() { + void Given_InvalidPostId_When_findPost_Then_ThrowException() { // given Long postId = 100L; @@ -174,7 +182,7 @@ void Given_InvalidPostId_When_findPost_Then_Success() { @Test @DisplayName("로그인 시 유효하지 않은 loginMemberId가 주어졌다면 게시글 상세보기에 예외를 발생합니다.") - void Given_InvalidLoginMemberId_When_findPost_Then_Success() { + void Given_InvalidLoginMemberId_When_findPost_Then_ThrowException() { // given Post post = POST_FIXTURE1; Long memberId = 100L; @@ -254,7 +262,7 @@ void Given_PostIdAndLoginMemberId_When_DeleteLikePost_Then_Success() { @Test @DisplayName("좋아요가 특정 개수를 달성했다면 Hot 게시글로 등록됩니다.") - void Given_PostIdAndLoginMemberId_When_NotExistsHotPost_Then_Success() { + void Given_PostIdAndLoginMemberId_When_likePost_Then_SaveHotPost() { // given Post post = POST_FIXTURE1; Member member = memberFixture.createGeneralMember(); @@ -285,7 +293,7 @@ void Given_PostIdAndLoginMemberId_When_NotExistsHotPost_Then_Success() { @Test @DisplayName("좋아요가 특정 개수를 달성했지만 이미 Hot 게시글이라면 등록되지 않습니다.") - void Given_PostIdAndLoginMemberId_When_ExistsHotPost_Then_Success() { + void Given_PostIdAndLoginMemberId_When_likePost_Then_NotSaveHotPost() { // given Post post = POST_FIXTURE1; Member member = memberFixture.createGeneralMember(); @@ -317,7 +325,7 @@ void Given_PostIdAndLoginMemberId_When_ExistsHotPost_Then_Success() { @Test @DisplayName("유효하지 않은 loginMemberId가 주어졌다면 게시글 좋아요에 예외를 발생합니다.") - void Given_InvalidLoginMemberId_When_likePost_Then_Success() { + void Given_InvalidLoginMemberId_When_likePost_Then_ThrowException() { // given Post post = POST_FIXTURE1; Long memberId = -1L; @@ -335,7 +343,7 @@ void Given_InvalidLoginMemberId_When_likePost_Then_Success() { @Test @DisplayName("유효하지 않은 postId가 주어졌다면 게시글 좋아요에 예외를 발생합니다.") - void Given_InvalidPostId_When_likePost_Then_Success() { + void Given_InvalidPostId_When_likePost_Then_ThrowException() { // given Long postId = -1L; Member member = memberFixture.createGeneralMember(); @@ -354,7 +362,7 @@ void Given_InvalidPostId_When_likePost_Then_Success() { @Test @DisplayName("게시글을 스크랩 하지 않았다면 스크랩이 저장됩니다.") - void Given_PostIdAndLoginMemberId_When_SaveScrapPost_Then_Success() { + void Given_PostIdAndLoginMemberId_When_scrapPost_Then_SaveScrap() { // given Member member = memberFixture.createGeneralMember(); Post post = POST_FIXTURE1; @@ -381,7 +389,7 @@ void Given_PostIdAndLoginMemberId_When_SaveScrapPost_Then_Success() { @Test @DisplayName("게시글을 이미 스크랩 했다면 스크랩이 취소됩니다.") - void Given_PostIdAndLoginMemberId_When_DeleteScrapPost_Then_Success() { + void Given_PostIdAndLoginMemberId_When_scrapPost_Then_CancelScrap() { // given Member member = memberFixture.createGeneralMember(); Post post = POST_FIXTURE1; @@ -410,7 +418,7 @@ void Given_PostIdAndLoginMemberId_When_DeleteScrapPost_Then_Success() { @Test @DisplayName("유효하지 않은 loginMemberId가 주어졌다면 게시글 스크랩에 예외를 발생합니다.") - void Given_InvalidLoginMemberId_When_scrapPost_Then_Success() { + void Given_InvalidLoginMemberId_When_scrapPost_Then_ThrowException() { // given Long memberId = -101L; Post post = POST_FIXTURE1; @@ -428,7 +436,7 @@ void Given_InvalidLoginMemberId_When_scrapPost_Then_Success() { @Test @DisplayName("유효하지 않은 postId가 주어졌다면 게시글 스크랩에 예외를 발생합니다.") - void Given_InvalidPostId_When_scrapPost_Then_Success() { + void Given_InvalidPostId_When_scrapPost_Then_ThrowException() { // given Member member = memberFixture.createGeneralMember(); Long postId = 101021242313L; @@ -447,7 +455,123 @@ void Given_InvalidPostId_When_scrapPost_Then_Success() { } @Test - void writePost() { + @DisplayName("정상적인 boardId, MemberId가 주어졌다면 게시글 쓰기가 성공합니다.(이미지 X)") + void Given_BoardIdAndMemberId_NotImage_When_writePost_Then_Success() { + // given + Board board = boardFixture.getFreeBoard(); + Member member = memberFixture.createGeneralMember(); + Post post = POST_FIXTURE1; + + PostPostWriteReqDto postPostWriteReqDto = PostPostWriteReqDto.builder() + .title(post.getTitle()) + .content(post.getContent()) + .anonymity(post.getAnonymity()) + .images(List.of()) + .build(); + + given(boardRepository.findById(board.getId())).willReturn(Optional.of(board)); + given(memberRepository.findById(member.getId())).willReturn(Optional.of(member)); + given(postRepository.save(any())).willReturn(post); + + // when + PostIdElement response = postService.writePost(board.getId(), member.getId(), postPostWriteReqDto); + + // then + assertThat(response).usingRecursiveComparison() + .isEqualTo(new PostIdElement(post.getId())); + + // verify + verify(boardRepository, times(1)).findById(board.getId()); + verify(memberRepository, times(1)).findById(member.getId()); + verify(postRepository, times(1)).save(any()); + } + + @Test + @DisplayName("정상적인 boardId, MemberId가 주어졌다면 게시글 쓰기가 성공합니다.(이미지 O)") + void Given_BoardIdAndMemberId_Image_When_writePost_Then_Success() { + // given + Board board = boardFixture.getFreeBoard(); + Member member = memberFixture.createGeneralMember(); + Post post = POST_FIXTURE1; + + int size = 2; + PostPostWriteReqDto postPostWriteReqDto = PostPostWriteReqDto.builder() + .title(post.getTitle()) + .content(post.getContent()) + .anonymity(post.getAnonymity()) + .images(PostFixture.createImageInfos(size)) + .build(); + + given(boardRepository.findById(board.getId())).willReturn(Optional.of(board)); + given(memberRepository.findById(member.getId())).willReturn(Optional.of(member)); + given(postRepository.save(any())).willReturn(post); + + // when + PostIdElement response = postService.writePost(board.getId(), member.getId(), postPostWriteReqDto); + + // then + assertThat(response).usingRecursiveComparison() + .isEqualTo(new PostIdElement(post.getId())); + + // verify + verify(boardRepository, times(1)).findById(board.getId()); + verify(memberRepository, times(1)).findById(member.getId()); + verify(postRepository, times(1)).save(any()); + verify(postImageRepository, times(size)).save(any()); + } + + @Test + @DisplayName("유효하지 않은 boardID가 주어졌다면 게시글 쓰기에 예외를 발생합니다.") + void Given_InvalidBoardId_When_writePost_Then_ThrowException() { + // given + Long boardId = 10L; + Member member = memberFixture.createGeneralMember(); + Post post = POST_FIXTURE1; + + PostPostWriteReqDto postPostWriteReqDto = PostPostWriteReqDto.builder() + .title(post.getTitle()) + .content(post.getContent()) + .anonymity(post.getAnonymity()) + .images(List.of()) + .build(); + + given(boardRepository.findById(boardId)).willReturn(Optional.empty()); + + // when, then + BoardException exception = assertThrows(BoardException.class, + () -> postService.writePost(boardId, member.getId(), postPostWriteReqDto)); + assertEquals(BoardErrorInfo.NO_BOARD, exception.getInfo()); + + // verify + verify(boardRepository, times(1)).findById(boardId); + } + + @Test + @DisplayName("유효하지 않은 memberId가 주어졌다면 게시글 쓰기에 예외를 발생합니다.") + void Given_InvalidMemberId_When_writePost_Then_ThrowException() { + // given + Board board = boardFixture.getFreeBoard(); + Long memberId = 100L; + Post post = POST_FIXTURE1; + + PostPostWriteReqDto postPostWriteReqDto = PostPostWriteReqDto.builder() + .title(post.getTitle()) + .content(post.getContent()) + .anonymity(post.getAnonymity()) + .images(List.of()) + .build(); + + given(boardRepository.findById(board.getId())).willReturn(Optional.of(board)); + given(memberRepository.findById(memberId)).willReturn(Optional.empty()); + + // when, then + MemberException exception = assertThrows(MemberException.class, + () -> postService.writePost(board.getId(), memberId, postPostWriteReqDto)); + assertEquals(MemberErrorInfo.MEMBER_NOT_FOUND_BY_ID, exception.getInfo()); + + // verify + verify(boardRepository, times(1)).findById(board.getId()); + verify(memberRepository, times(1)).findById(memberId); } @Test diff --git a/src/test/java/com/ssafy/ssafsound/global/util/fixture/BoardFixture.java b/src/test/java/com/ssafy/ssafsound/global/util/fixture/BoardFixture.java index 6ab3aac5c..87355bedb 100644 --- a/src/test/java/com/ssafy/ssafsound/global/util/fixture/BoardFixture.java +++ b/src/test/java/com/ssafy/ssafsound/global/util/fixture/BoardFixture.java @@ -1,28 +1,66 @@ package com.ssafy.ssafsound.global.util.fixture; import com.ssafy.ssafsound.domain.board.domain.Board; -import com.ssafy.ssafsound.domain.board.dto.GetBoardResDto; - -import java.util.List; public class BoardFixture { - public static final Board BOARD_FIXTURE1 = Board.builder() - .id(1L) - .title("자유 게시판") - .imageUrl("IMAGE URL") - .description("자유롭게 떠드는 공간입니다.") - .build(); + public Board getFreeBoard(){ + return Board.builder() + .id(1L) + .title("자유 게시판") + .imageUrl("IMAGE URL") + .usedBoard(true) + .description("자유롭게 떠드는 공간입니다.") + .build(); + } - public static final Board BOARD_FIXTURE2 = Board.builder() + public Board getJobBoard(){ + return Board.builder() .id(2L) .title("취업 게시판") .imageUrl("IMAGE URL") + .usedBoard(true) .description("취업에 대한 정보를 공유해보세요.") .build(); + } + + public Board getTechBoard(){ + return Board.builder() + .id(3L) + .title("테크 게시판") + .imageUrl("IMAGE URL") + .usedBoard(false) + .description("기술을 공유하세요") + .build(); + } + + public Board getTasteBoard(){ + return Board.builder() + .id(4L) + .title("맛집 게시판") + .imageUrl("IMAGE URL") + .usedBoard(true) + .description("맛집을 공유하세요") + .build(); + } - public static final GetBoardResDto GET_BOARD_RES_DTO1 = GetBoardResDto.from( - List.of(BOARD_FIXTURE1, - BOARD_FIXTURE2) - ); + public Board getQaBoard(){ + return Board.builder() + .id(5L) + .title("질문 게시판") + .imageUrl("IMAGE URL") + .usedBoard(true) + .description("질문을 하세요") + .build(); + } + + public Board getNewCrewBoard(){ + return Board.builder() + .id(6L) + .title("싸피 예비생 게시판") + .imageUrl("IMAGE URL") + .usedBoard(true) + .description("싸피에 대해 궁금한걸 질문하세요") + .build(); + } } diff --git a/src/test/java/com/ssafy/ssafsound/global/util/fixture/PostFixture.java b/src/test/java/com/ssafy/ssafsound/global/util/fixture/PostFixture.java index fbd22e888..4355f7cfc 100644 --- a/src/test/java/com/ssafy/ssafsound/global/util/fixture/PostFixture.java +++ b/src/test/java/com/ssafy/ssafsound/global/util/fixture/PostFixture.java @@ -1,217 +1,233 @@ package com.ssafy.ssafsound.global.util.fixture; -import com.ssafy.ssafsound.domain.post.domain.Post; -import com.ssafy.ssafsound.domain.post.dto.*; - import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; -import static com.ssafy.ssafsound.global.util.fixture.BoardFixture.BOARD_FIXTURE1; -import static com.ssafy.ssafsound.global.util.fixture.BoardFixture.BOARD_FIXTURE2; -import static com.ssafy.ssafsound.global.util.fixture.MemberFixture.*; +import com.ssafy.ssafsound.domain.post.domain.Post; +import com.ssafy.ssafsound.domain.post.dto.GetPostDetailResDto; +import com.ssafy.ssafsound.domain.post.dto.GetPostElement; +import com.ssafy.ssafsound.domain.post.dto.GetPostResDto; +import com.ssafy.ssafsound.domain.post.dto.ImageInfo; +import com.ssafy.ssafsound.domain.post.dto.PostCommonLikeResDto; +import com.ssafy.ssafsound.domain.post.dto.PostIdElement; +import com.ssafy.ssafsound.domain.post.dto.PostPatchUpdateReqDto; +import com.ssafy.ssafsound.domain.post.dto.PostPostScrapResDto; +import com.ssafy.ssafsound.domain.post.dto.PostPostWriteReqDto; public class PostFixture { - private static final MemberFixture memberFixture = new MemberFixture(); - - public static final Post POST_FIXTURE1 = Post.builder() - .id(1L) - .title("싸탈하고 싶다.") - .content("싸탈하고 싶은 밤이네요") - .anonymity(false) - .board(BOARD_FIXTURE1) - .member(memberFixture.createMember()) - .build(); - - public static final Post POST_FIXTURE2 = Post.builder() - .id(2L) - .title("삼성 B형을 봤는데") - .content("결과가 암울해") - .anonymity(true) - .board(BOARD_FIXTURE1) - .member(memberFixture.createMember()) - .build(); - - public static final Post POST_FIXTURE3 = Post.builder() - .id(3L) - .title("안녕하세요 취업 게시판의 첫 글이네요") - .content("취업이 뭐죠??") - .anonymity(true) - .board(BOARD_FIXTURE2) - .member(memberFixture.createMember()) - .build(); - - public static final GetPostElement GET_POST_ELEMENT1 = GetPostElement.builder() - .boardId(1L) - .boardTitle("자유 게시판") - .postId(4L) - .title("싸피 어떤가요??") - .content("저도 싸피에서 교육들으면 개발실력 엄청 오르겠죠?") - .likeCount(11) - .commentCount(29) - .createdAt(LocalDateTime.now()) - .nickname("이용준") - .anonymity(false) - .thumbnail("썸네일 URL") - .build(); - - public static final GetPostElement GET_POST_ELEMENT2 = GetPostElement.builder() - .boardId(1L) - .boardTitle("자유 게시판") - .postId(5L) - .title("삼성 B형 시험을 준비하려면 뭘 해야할까요?") - .content("역시 B형 특강을 열심히 듣는게 맞나요?") - .likeCount(5) - .commentCount(14) - .createdAt(LocalDateTime.now()) - .nickname("익명") - .anonymity(true) - .thumbnail("썸네일 URL") - .build(); - - public static final GetPostElement GET_POST_ELEMENT3 = GetPostElement.builder() - .boardId(1L) - .boardTitle("자유 게시판") - .postId(6L) - .title("안녕하세요 반갑습니다.") - .content("SSAFY 9기 합격했습니다!!") - .likeCount(3) - .commentCount(2) - .createdAt(LocalDateTime.now()) - .nickname("이용준") - .anonymity(false) - .thumbnail("썸네일 URL") - .build(); - - public static final GetPostElement GET_POST_HOT_ELEMENT1 = GetPostElement.builder() - .boardId(2L) - .boardTitle("취업 게시판") - .postId(7L) - .title("취업을 하기 위한 꿀팁") - .content("열심히 SSAFY 9기를 수료하시면 취업에 성공하실겁니다.") - .likeCount(102) - .commentCount(33) - .createdAt(LocalDateTime.now()) - .nickname("이용준") - .anonymity(false) - .thumbnail("썸네일 URL") - .build(); - - public static final GetPostElement GET_POST_HOT_ELEMENT2 = GetPostElement.builder() - .boardId(1L) - .boardTitle("자유 게시판") - .postId(7L) - .title("Hot 게시글에 가는 방법") - .content("은 실력입니다.") - .likeCount(202) - .commentCount(54) - .createdAt(LocalDateTime.now()) - .nickname("익명") - .anonymity(true) - .thumbnail("썸네일 URL") - .build(); - - public static final GetPostElement GET_POST_MY_ELEMENT1 = GetPostElement.builder() - .boardId(1L) - .boardTitle("자유 게시판") - .postId(6L) - .title("안녕하세요 반갑습니다.") - .content("SSAFY 9기 합격했습니다!!") - .likeCount(3) - .commentCount(2) - .createdAt(LocalDateTime.now()) - .nickname("이용준") - .anonymity(false) - .thumbnail("썸네일 URL") - .build(); - - public static final GetPostElement GET_POST_MY_ELEMENT2 = GetPostElement.builder() - .boardId(2L) - .boardTitle("취업 게시판") - .postId(7L) - .title("취업을 하기 위한 꿀팁") - .content("열심히 SSAFY 9기를 수료하시면 취업에 성공하실겁니다.") - .likeCount(102) - .commentCount(33) - .createdAt(LocalDateTime.now()) - .nickname("이용준") - .anonymity(false) - .thumbnail("썸네일 URL") - .build(); - - - public static final GetPostResDto GET_POST_RES_DTO1 = GetPostResDto.ofPosts( - List.of(POST_FIXTURE1, - POST_FIXTURE2), 10); - - public static final GetPostResDto GET_POST_RES_DTO2 = GetPostResDto.ofPosts( - List.of(POST_FIXTURE3), 10); - - public static final GetPostResDto GET_POST_RES_DTO3 = GetPostResDto.builder() - .posts(List.of(GET_POST_ELEMENT1, - GET_POST_ELEMENT2)) - .cursor(null) - .build(); - - public static final GetPostResDto GET_POST_RES_DTO4 = GetPostResDto.builder() - .posts(List.of(GET_POST_ELEMENT3)) - .cursor(null) - .build(); - - public static final GetPostResDto GET_POST_HOT_RES_DTO1 = GetPostResDto.builder() - .posts(List.of(GET_POST_HOT_ELEMENT1, - GET_POST_HOT_ELEMENT2)) - .cursor(null) - .build(); - - public static final GetPostResDto GET_POST_HOT_RES_DTO2 = GetPostResDto.builder() - .posts(List.of(GET_POST_HOT_ELEMENT1)) - .cursor(null) - .build(); - - public static final GetPostResDto GET_POST_MY_RES_DTO1 = GetPostResDto.builder() - .posts(List.of(GET_POST_MY_ELEMENT1, - GET_POST_MY_ELEMENT2)) - .cursor(null) - .build(); - - public static final GetPostResDto GET_POST_MY_SCRAP_RES_DTO = GetPostResDto.builder() - .posts(List.of(GET_POST_ELEMENT2, - GET_POST_ELEMENT1)) - .cursor(null) - .build(); - - public static final GetPostDetailResDto GET_POST_DETAIL_RES_DTO1 = GetPostDetailResDto.of( - POST_FIXTURE1, null); - - public static final GetPostDetailResDto GET_POST_DETAIL_RES_DTO2 = GetPostDetailResDto.of( - POST_FIXTURE2, memberFixture.createMember()); - - public static final PostPostWriteReqDto POST_POST_WRITE_REQ_DTO1 = PostPostWriteReqDto.builder() - .title("안녕하세요 첫 글이네요") - .content("싸피도 드디어 익명 커뮤니티가 생기다니..") - .anonymity(true) - .images(List.of()) - .build(); - - public static final PostPatchUpdateReqDto POST_PATCH_UPDATE_REQ_DTO1 = PostPatchUpdateReqDto.builder() - .title("수정한 게시글의 제목") - .content("수정한 게시글의 내용입니다.") - .anonymity(false) - .images(List.of()) - .build(); - - public static final PostIdElement POST_ID_ELEMENT = PostIdElement.builder() - .postId(1L) - .build(); - - public static final PostCommonLikeResDto POST_POST_LIKE_RES_DTO = PostCommonLikeResDto.builder() - .likeCount(10) - .liked(true) - .build(); - - public static final PostPostScrapResDto POST_POST_SCRAP_RES_DTO = PostPostScrapResDto.builder() - .scrapCount(9) - .scraped(false) - .build(); + private static final MemberFixture memberFixture = new MemberFixture(); + private static final BoardFixture boardFixture = new BoardFixture(); + + public static final Post POST_FIXTURE1 = Post.builder() + .id(1L) + .title("싸탈하고 싶다.") + .content("싸탈하고 싶은 밤이네요") + .anonymity(false) + .board(boardFixture.getFreeBoard()) + .member(memberFixture.createMember()) + .build(); + + public static final Post POST_FIXTURE2 = Post.builder() + .id(2L) + .title("삼성 B형을 봤는데") + .content("결과가 암울해") + .anonymity(true) + .board(boardFixture.getFreeBoard()) + .member(memberFixture.createMember()) + .build(); + + public static final Post POST_FIXTURE3 = Post.builder() + .id(3L) + .title("안녕하세요 취업 게시판의 첫 글이네요") + .content("취업이 뭐죠??") + .anonymity(true) + .board(boardFixture.getJobBoard()) + .member(memberFixture.createMember()) + .build(); + + public static final GetPostElement GET_POST_ELEMENT1 = GetPostElement.builder() + .boardId(1L) + .boardTitle("자유 게시판") + .postId(4L) + .title("싸피 어떤가요??") + .content("저도 싸피에서 교육들으면 개발실력 엄청 오르겠죠?") + .likeCount(11) + .commentCount(29) + .createdAt(LocalDateTime.now()) + .nickname("이용준") + .anonymity(false) + .thumbnail("썸네일 URL") + .build(); + + public static final GetPostElement GET_POST_ELEMENT2 = GetPostElement.builder() + .boardId(1L) + .boardTitle("자유 게시판") + .postId(5L) + .title("삼성 B형 시험을 준비하려면 뭘 해야할까요?") + .content("역시 B형 특강을 열심히 듣는게 맞나요?") + .likeCount(5) + .commentCount(14) + .createdAt(LocalDateTime.now()) + .nickname("익명") + .anonymity(true) + .thumbnail("썸네일 URL") + .build(); + + public static final GetPostElement GET_POST_ELEMENT3 = GetPostElement.builder() + .boardId(1L) + .boardTitle("자유 게시판") + .postId(6L) + .title("안녕하세요 반갑습니다.") + .content("SSAFY 9기 합격했습니다!!") + .likeCount(3) + .commentCount(2) + .createdAt(LocalDateTime.now()) + .nickname("이용준") + .anonymity(false) + .thumbnail("썸네일 URL") + .build(); + + public static final GetPostElement GET_POST_HOT_ELEMENT1 = GetPostElement.builder() + .boardId(2L) + .boardTitle("취업 게시판") + .postId(7L) + .title("취업을 하기 위한 꿀팁") + .content("열심히 SSAFY 9기를 수료하시면 취업에 성공하실겁니다.") + .likeCount(102) + .commentCount(33) + .createdAt(LocalDateTime.now()) + .nickname("이용준") + .anonymity(false) + .thumbnail("썸네일 URL") + .build(); + + public static final GetPostElement GET_POST_HOT_ELEMENT2 = GetPostElement.builder() + .boardId(1L) + .boardTitle("자유 게시판") + .postId(7L) + .title("Hot 게시글에 가는 방법") + .content("은 실력입니다.") + .likeCount(202) + .commentCount(54) + .createdAt(LocalDateTime.now()) + .nickname("익명") + .anonymity(true) + .thumbnail("썸네일 URL") + .build(); + + public static final GetPostElement GET_POST_MY_ELEMENT1 = GetPostElement.builder() + .boardId(1L) + .boardTitle("자유 게시판") + .postId(6L) + .title("안녕하세요 반갑습니다.") + .content("SSAFY 9기 합격했습니다!!") + .likeCount(3) + .commentCount(2) + .createdAt(LocalDateTime.now()) + .nickname("이용준") + .anonymity(false) + .thumbnail("썸네일 URL") + .build(); + + public static final GetPostElement GET_POST_MY_ELEMENT2 = GetPostElement.builder() + .boardId(2L) + .boardTitle("취업 게시판") + .postId(7L) + .title("취업을 하기 위한 꿀팁") + .content("열심히 SSAFY 9기를 수료하시면 취업에 성공하실겁니다.") + .likeCount(102) + .commentCount(33) + .createdAt(LocalDateTime.now()) + .nickname("이용준") + .anonymity(false) + .thumbnail("썸네일 URL") + .build(); + + public static final GetPostResDto GET_POST_RES_DTO1 = GetPostResDto.ofPosts( + List.of(POST_FIXTURE1, + POST_FIXTURE2), 10); + + public static final GetPostResDto GET_POST_RES_DTO2 = GetPostResDto.ofPosts( + List.of(POST_FIXTURE3), 10); + + public static final GetPostResDto GET_POST_RES_DTO3 = GetPostResDto.builder() + .posts(List.of(GET_POST_ELEMENT1, + GET_POST_ELEMENT2)) + .cursor(null) + .build(); + + public static final GetPostResDto GET_POST_RES_DTO4 = GetPostResDto.builder() + .posts(List.of(GET_POST_ELEMENT3)) + .cursor(null) + .build(); + + public static final GetPostResDto GET_POST_HOT_RES_DTO1 = GetPostResDto.builder() + .posts(List.of(GET_POST_HOT_ELEMENT1, + GET_POST_HOT_ELEMENT2)) + .cursor(null) + .build(); + + public static final GetPostResDto GET_POST_HOT_RES_DTO2 = GetPostResDto.builder() + .posts(List.of(GET_POST_HOT_ELEMENT1)) + .cursor(null) + .build(); + + public static final GetPostResDto GET_POST_MY_RES_DTO1 = GetPostResDto.builder() + .posts(List.of(GET_POST_MY_ELEMENT1, + GET_POST_MY_ELEMENT2)) + .cursor(null) + .build(); + + public static final GetPostResDto GET_POST_MY_SCRAP_RES_DTO = GetPostResDto.builder() + .posts(List.of(GET_POST_ELEMENT2, + GET_POST_ELEMENT1)) + .cursor(null) + .build(); + + public static final GetPostDetailResDto GET_POST_DETAIL_RES_DTO1 = GetPostDetailResDto.of( + POST_FIXTURE1, null); + + public static final GetPostDetailResDto GET_POST_DETAIL_RES_DTO2 = GetPostDetailResDto.of( + POST_FIXTURE2, memberFixture.createMember()); + + public static final PostPostWriteReqDto POST_POST_WRITE_REQ_DTO1 = PostPostWriteReqDto.builder() + .title("안녕하세요 첫 글이네요") + .content("싸피도 드디어 익명 커뮤니티가 생기다니..") + .anonymity(true) + .images(List.of()) + .build(); + + public static final PostPatchUpdateReqDto POST_PATCH_UPDATE_REQ_DTO1 = PostPatchUpdateReqDto.builder() + .title("수정한 게시글의 제목") + .content("수정한 게시글의 내용입니다.") + .anonymity(false) + .images(List.of()) + .build(); + + public static final PostIdElement POST_ID_ELEMENT = PostIdElement.builder() + .postId(1L) + .build(); + + public static final PostCommonLikeResDto POST_POST_LIKE_RES_DTO = PostCommonLikeResDto.builder() + .likeCount(10) + .liked(true) + .build(); + + public static final PostPostScrapResDto POST_POST_SCRAP_RES_DTO = PostPostScrapResDto.builder() + .scrapCount(9) + .scraped(false) + .build(); + + public static List createImageInfos(int size) { + List imageInfos = new ArrayList<>(); + for (int i = 0; i < size; i++) { + imageInfos.add(ImageInfo.builder() + .imagePath("imagePath" + i) + .imageUrl("imageUrl" + i) + .build()); + } + return imageInfos; + } }