diff --git a/build.gradle b/build.gradle index 24e5a665..44742ceb 100644 --- a/build.gradle +++ b/build.gradle @@ -41,6 +41,12 @@ dependencies { // Test testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + testImplementation "org.junit.jupiter:junit-jupiter:5.8.1" + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.springframework.boot:spring-boot-testcontainers' + testImplementation 'org.testcontainers:junit-jupiter' + testImplementation 'org.testcontainers:mysql' + testImplementation 'org.testcontainers:mongodb' // S3 implementation("software.amazon.awssdk:s3:2.31.54") diff --git a/src/main/java/leets/leenk/domain/notification/domain/entity/Notification.java b/src/main/java/leets/leenk/domain/notification/domain/entity/Notification.java index 32c97f77..dd197ced 100644 --- a/src/main/java/leets/leenk/domain/notification/domain/entity/Notification.java +++ b/src/main/java/leets/leenk/domain/notification/domain/entity/Notification.java @@ -1,29 +1,25 @@ package leets.leenk.domain.notification.domain.entity; import leets.leenk.domain.notification.domain.entity.enums.NotificationType; -import org.springframework.data.mongodb.core.mapping.Document; - -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; -import jakarta.persistence.Id; -import leets.leenk.global.common.entity.BaseEntity; +import leets.leenk.global.common.entity.MongoBaseEntity; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.experimental.SuperBuilder; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; @SuperBuilder @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Document(collection = "notifications") -public class Notification extends BaseEntity { +public class Notification extends MongoBaseEntity { @Id private String id; private Long userId; - @Enumerated(EnumType.STRING) private NotificationType notificationType; private Boolean isRead; diff --git a/src/main/java/leets/leenk/global/common/entity/MongoBaseEntity.java b/src/main/java/leets/leenk/global/common/entity/MongoBaseEntity.java new file mode 100644 index 00000000..82ab8d21 --- /dev/null +++ b/src/main/java/leets/leenk/global/common/entity/MongoBaseEntity.java @@ -0,0 +1,21 @@ +package leets.leenk.global.common.entity; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; + +import java.time.LocalDateTime; + +@Getter +@SuperBuilder +@NoArgsConstructor +public abstract class MongoBaseEntity { + + @CreatedDate + private LocalDateTime createDate; + + @LastModifiedDate + private LocalDateTime updateDate; +} \ No newline at end of file diff --git a/src/test/java/leets/leenk/config/MysqlTestConfig.java b/src/test/java/leets/leenk/config/MysqlTestConfig.java new file mode 100644 index 00000000..d67b0e8f --- /dev/null +++ b/src/test/java/leets/leenk/config/MysqlTestConfig.java @@ -0,0 +1,19 @@ +package leets.leenk.config; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.boot.testcontainers.service.connection.ServiceConnection; +import org.springframework.context.annotation.Bean; +import org.testcontainers.containers.MySQLContainer; + +@TestConfiguration +public class MysqlTestConfig { + + private static final String MYSQL_IMAGE = "mysql:8.0.41"; + + @Bean + @ServiceConnection + public MySQLContainer mysqlContainer() { + return new MySQLContainer<>(MYSQL_IMAGE) + .withDatabaseName("testdb"); + } +} \ No newline at end of file diff --git a/src/test/java/leets/leenk/config/TestContainersTest.java b/src/test/java/leets/leenk/config/TestContainersTest.java new file mode 100644 index 00000000..1dadcb37 --- /dev/null +++ b/src/test/java/leets/leenk/config/TestContainersTest.java @@ -0,0 +1,32 @@ +package leets.leenk.config; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ActiveProfiles; +import org.testcontainers.containers.MySQLContainer; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +@Import(MysqlTestConfig.class) +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@ActiveProfiles("test") +class TestContainersTest { + + @Autowired + private MySQLContainer mysqlContainer; + + + @Test + void MySQL_컨테이너_정상_동작_테스트() { + // MySQL 컨테이너 테스트 + assertThat(mysqlContainer).isNotNull(); + assertThat(mysqlContainer.isRunning()).isTrue(); + assertThat(mysqlContainer.getDatabaseName()).isEqualTo("testdb"); + + System.out.println("MySQL Container JDBC URL: " + mysqlContainer.getJdbcUrl()); + } +} \ No newline at end of file diff --git a/src/test/java/leets/leenk/domain/feed/application/FeedUsecaseTest.java b/src/test/java/leets/leenk/domain/feed/application/FeedUsecaseTest.java new file mode 100644 index 00000000..d7968aad --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/application/FeedUsecaseTest.java @@ -0,0 +1,796 @@ +package leets.leenk.domain.feed.application; + +import leets.leenk.domain.feed.application.dto.request.*; +import leets.leenk.domain.feed.application.dto.response.*; +import leets.leenk.domain.feed.application.exception.CommentDeleteNotAllowedException; +import leets.leenk.domain.feed.application.exception.FeedDeleteNotAllowedException; +import leets.leenk.domain.feed.application.exception.FeedUpdateNotAllowedException; +import leets.leenk.domain.feed.application.exception.SelfReactionNotAllowedException; +import leets.leenk.domain.feed.application.mapper.CommentMapper; +import leets.leenk.domain.feed.application.mapper.FeedMapper; +import leets.leenk.domain.feed.application.mapper.FeedUserMapper; +import leets.leenk.domain.feed.application.mapper.ReactionMapper; +import leets.leenk.domain.feed.application.usecase.FeedUsecase; +import leets.leenk.domain.feed.domain.entity.Comment; +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.domain.entity.LinkedUser; +import leets.leenk.domain.feed.domain.entity.Reaction; +import leets.leenk.domain.feed.domain.service.*; +import leets.leenk.domain.feed.domain.service.dto.FeedNavigationResult; +import leets.leenk.domain.feed.test.*; +import leets.leenk.domain.media.application.dto.request.FeedMediaRequest; +import leets.leenk.domain.media.application.mapper.MediaMapper; +import leets.leenk.domain.media.domain.entity.Media; +import leets.leenk.domain.media.domain.entity.enums.MediaType; +import leets.leenk.domain.media.domain.service.MediaDeleteService; +import leets.leenk.domain.media.domain.service.MediaGetService; +import leets.leenk.domain.media.domain.service.MediaSaveService; +import leets.leenk.domain.notification.application.usecase.FeedNotificationUsecase; +import leets.leenk.domain.user.domain.entity.User; +import leets.leenk.domain.user.domain.entity.UserBlock; +import leets.leenk.domain.user.domain.service.NotionDatabaseService; +import leets.leenk.domain.user.domain.service.SlackWebhookService; +import leets.leenk.domain.user.domain.service.blockuser.UserBlockService; +import leets.leenk.domain.user.domain.service.user.UserGetService; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.data.domain.SliceImpl; + +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +public class FeedUsecaseTest { + private static final Logger log = LoggerFactory.getLogger(FeedUsecaseTest.class); + @Mock + private UserGetService userGetService; + @Mock + private UserBlockService userBlockService; + @Mock + private SlackWebhookService slackWebhookService; + @Mock + private NotionDatabaseService notionDatabaseService; + + @Mock + private FeedGetService feedGetService; + @Mock + private FeedSaveService feedSaveService; + @Mock + private FeedUpdateService feedUpdateService; + @Mock + private FeedDeleteService feedDeleteService; + + @Mock + private MediaGetService mediaGetService; + @Mock + private MediaSaveService mediaSaveService; + @Mock + private MediaDeleteService mediaDeleteService; + + @Mock + private LinkedUserGetService linkedUserGetService; + @Mock + private LinkedUserSaveService linkedUserSaveService; + @Mock + private LinkedUserDeleteService linkedUserDeleteService; + + @Mock + private ReactionGetService reactionGetService; + @Mock + private ReactionSaveService reactionSaveService; + + @Mock + private CommentSaveService commentSaveService; + @Mock + private CommentGetService commentGetService; + @Mock + private CommentDeleteService commentDeleteService; + + @Mock + private FeedNotificationUsecase feedNotificationUsecase; + + @Mock + private FeedMapper feedMapper; + @Mock + private MediaMapper mediaMapper; + @Mock + private FeedUserMapper feedUserMapper; + @Mock + private ReactionMapper reactionMapper; + @Mock + private CommentMapper commentMapper; + + @InjectMocks + private FeedUsecase feedUseCase; + + @Test + @DisplayName("차단유저 목록으로 피드 조회 후 미디어 맵핑하여 응답 반환") + void getFeeds() { + // given + long userId = 1L; + int pageNumber = 0; + int pageSize = 10; + + User loginUser = UserTestFixture.createUser(userId, "me"); + given(userGetService.findById(userId)).willReturn(loginUser); + + UserBlock block = mock(UserBlock.class); + given(userBlockService.findAllByBlocker(loginUser)).willReturn(List.of(block)); + + User author = UserTestFixture.createUser(2L, "author"); + Feed feed1 = FeedTestFixture.createFeed(100L, author); + + Slice slice = new SliceImpl<>( + List.of(feed1), + PageRequest.of(pageNumber, pageSize), + false + ); + given(feedGetService.findAll(any(Pageable.class), anyList())).willReturn(slice); + + Media media1 = MediaTestFixture.createMedia(1L, feed1); + given(mediaGetService.findAllByFeeds(List.of(feed1))).willReturn(List.of(media1)); + + FeedListResponse expected = mock(FeedListResponse.class); + given(feedMapper.toFeedListResponse(eq(slice), anyMap())).willReturn(expected); + + // when + FeedListResponse result = feedUseCase.getFeeds(userId, pageNumber, pageSize); + + // then + assertThat(result).isEqualTo(expected); + } + + @Test + @DisplayName("피드, 미디어, 링크, 유저, 댓글 조회 후 상세응답 반환") + void getFeedDetail() { + // given + long feedId = 10L; + + User author = UserTestFixture.createUser(2L, "author"); + Feed feed = FeedTestFixture.createFeed(10L, author); + + Media m1 = MediaTestFixture.createMedia(1L, feed); + List medias = List.of(m1); + + List linkedUsers = List.of(mock(LinkedUser.class)); + List comments = List.of( + CommentTestFixture.createComment(1L, author, feed, "hi") + ); + + given(feedGetService.findById(feedId)).willReturn(feed); + given(mediaGetService.findAllByFeed(feed)).willReturn(medias); + given(linkedUserGetService.findAll(feed)).willReturn(linkedUsers); + given(commentGetService.findAllByFeed(feed)).willReturn(comments); + + FeedDetailResponse expected = mock(FeedDetailResponse.class); + given(feedMapper.toFeedDetailResponse(feed, medias, linkedUsers, comments)).willReturn(expected); + + // when + FeedDetailResponse result = feedUseCase.getFeedDetail(feedId); + + // then + assertThat(result).isEqualTo(expected); + then(feedGetService).should().findById(feedId); + then(mediaGetService).should().findAllByFeed(feed); + then(linkedUserGetService).should().findAll(feed); + then(commentGetService).should().findAllByFeed(feed); + then(feedMapper).should().toFeedDetailResponse(feed, medias, linkedUsers, comments); + } + + @Test + @DisplayName("prevNext 조회 후 모든 피드,미디어, 링크, 유저, 댓글을 조합하여 응답 반환") + void getFeedNavigation1() { + // given + long feedId = 10L; + long currentUserId = 1L; + + User currentUser = UserTestFixture.createUser(currentUserId, "me"); + given(userGetService.findById(currentUserId)).willReturn(currentUser); + + User author = UserTestFixture.createUser(2L, "author"); + Feed currentFeed = FeedTestFixture.createFeed(feedId, author); + given(feedGetService.findById(feedId)).willReturn(currentFeed); + + List blocked = List.of(mock(UserBlock.class)); + given(userBlockService.findAllByBlocker(currentUser)).willReturn(blocked); + + Feed prev1 = FeedTestFixture.createFeed(11L, author); + Feed next1 = FeedTestFixture.createFeed(9L, author); + + given(feedGetService.findPrevFeedsWithHasMore(eq(currentFeed), eq(blocked), eq(1))) + .willReturn(new FeedNavigationResult(List.of(prev1), true)); + given(feedGetService.findNextFeedsWithHasMore(eq(currentFeed), eq(blocked), eq(1))) + .willReturn(new FeedNavigationResult(List.of(next1), false)); + + List allMedias = List.of( + MediaTestFixture.createMedia(1L, currentFeed), + MediaTestFixture.createMedia(2L, prev1), + MediaTestFixture.createMedia(3L, next1) + ); + given(mediaGetService.findAllByFeeds(argThat(list -> list.size() == 3))).willReturn(allMedias); + + given(linkedUserGetService.findAll(any(Feed.class))).willReturn(List.of(mock(LinkedUser.class))); + given(commentGetService.findAllByFeed(any(Feed.class))).willReturn(List.of(mock(Comment.class))); + + FeedNavigationResponse expected = mock(FeedNavigationResponse.class); + given(feedMapper.toFeedNavigationResponse( + eq(currentFeed), + eq(List.of(prev1)), + eq(List.of(next1)), + anyMap(), + anyMap(), + anyMap(), + eq(true), + eq(false) + )).willReturn(expected); + + // when + FeedNavigationResponse result = feedUseCase.getFeedNavigation(feedId, currentUserId, 1, 1); + + // then + assertThat(result).isEqualTo(expected); + + then(feedGetService).should().findById(feedId); + then(userGetService).should().findById(currentUserId); + then(userBlockService).should().findAllByBlocker(currentUser); + + then(feedGetService).should().findPrevFeedsWithHasMore(eq(currentFeed), eq(blocked), eq(1)); + then(feedGetService).should().findNextFeedsWithHasMore(eq(currentFeed), eq(blocked), eq(1)); + + then(mediaGetService).should().findAllByFeeds(anyList()); + + then(linkedUserGetService).should(times(3)).findAll(any(Feed.class)); + then(commentGetService).should(times(3)).findAllByFeed(any(Feed.class)); + + then(feedMapper).should().toFeedNavigationResponse( + eq(currentFeed), + eq(List.of(prev1)), + eq(List.of(next1)), + anyMap(), + anyMap(), + anyMap(), + eq(true), + eq(false) + ); + } + + @Test + @DisplayName("prevNextSize가 null이면 default로_조회") + void getFeedNavigation2() { + // given + long feedId = 10L; + long currentUserId = 1L; + + User me = UserTestFixture.createUser(currentUserId, "me"); + given(userGetService.findById(currentUserId)).willReturn(me); + + User author = UserTestFixture.createUser(2L, "author"); + Feed current = FeedTestFixture.createFeed(feedId, author); + given(feedGetService.findById(feedId)).willReturn(current); + + given(userBlockService.findAllByBlocker(me)).willReturn(List.of()); + + given(feedGetService.findPrevFeedsWithHasMore(eq(current), anyList(), eq(1))) + .willReturn(new FeedNavigationResult(List.of(), false)); + given(feedGetService.findNextFeedsWithHasMore(eq(current), anyList(), eq(1))) + .willReturn(new FeedNavigationResult(List.of(), false)); + + given(mediaGetService.findAllByFeeds(anyList())).willReturn(List.of()); + given(linkedUserGetService.findAll(any(Feed.class))).willReturn(List.of()); + given(commentGetService.findAllByFeed(any(Feed.class))).willReturn(List.of()); + + FeedNavigationResponse expected = mock(FeedNavigationResponse.class); + given(feedMapper.toFeedNavigationResponse(eq(current), eq(List.of()), eq(List.of()), + anyMap(), anyMap(), anyMap(), eq(false), eq(false))).willReturn(expected); + + // when + FeedNavigationResponse result = feedUseCase.getFeedNavigation(feedId, currentUserId, null, null); + + // then + assertThat(result).isEqualTo(expected); + then(feedGetService).should().findPrevFeedsWithHasMore(eq(current), anyList(), eq(1)); + then(feedGetService).should().findNextFeedsWithHasMore(eq(current), anyList(), eq(1)); + } + + @Test + @DisplayName("피드저장, 미디어저장, 링크유저저장, 알림저장") + void uploadFeed() { + // given + long userId = 1L; + User author = UserTestFixture.createUser(userId, "me"); + given(userGetService.findById(userId)).willReturn(author); + + FeedUploadRequest request = new FeedUploadRequest( + "desc", + List.of(new FeedMediaRequest(1, "https://example.com/a.png", MediaType.IMAGE)), + List.of(2L, 3L) + ); + + Feed feed = FeedTestFixture.createFeed(100L, author); + given(feedMapper.toFeed(author, request.description())).willReturn(feed); + + given(mediaMapper.toMedia(eq(feed), any(FeedMediaRequest.class))) + .willReturn(MediaTestFixture.createMedia(1L, feed)); + + User u2 = UserTestFixture.createUser(2L, "u2"); + User u3 = UserTestFixture.createUser(3L, "u3"); + given(userGetService.findAll(request.userIds())).willReturn(List.of(u2, u3)); + + given(feedUserMapper.toLinkedUser(any(User.class), eq(feed))).willReturn(mock(LinkedUser.class)); + + // when + feedUseCase.uploadFeed(userId, request); + + // then + then(feedSaveService).should().save(feed); + then(mediaSaveService).should().saveAll(anyList()); + then(linkedUserSaveService).should().saveAll(anyList()); + + then(feedNotificationUsecase).should().saveNewFeedNotification(feed); + then(feedNotificationUsecase).should().saveTagNotification(eq(feed), anyList(), eq(author)); + } + + @Test + @DisplayName("자기 피드에 공감하면 예외 발생") + void reactToFeed1() { + // given + long userId = 1L; + long feedId = 10L; + + User me = UserTestFixture.createUser(userId, "me"); + Feed myFeed = FeedTestFixture.createFeed(feedId, me); + + given(userGetService.findById(userId)).willReturn(me); + given(feedGetService.findById(feedId)).willReturn(myFeed); + + ReactionRequest request = new ReactionRequest(1L); + + // when & then + assertThatThrownBy(() -> feedUseCase.reactToFeed(userId, feedId, request)) + .isInstanceOf(SelfReactionNotAllowedException.class); + + then(reactionGetService).shouldHaveNoInteractions(); + then(feedUpdateService).shouldHaveNoInteractions(); + } + + @Test + @DisplayName("기존 리액션이 있고 기준치 넘을 시 알림 저장") + void reactToFeed2() { + // given + long userId = 1L; + long feedId = 10L; + + User me = UserTestFixture.createUser(userId, "me"); + User author = UserTestFixture.createUser(2L, "author"); + Feed feed = FeedTestFixture.createFeed(feedId, author); + + given(userGetService.findById(userId)).willReturn(me); + given(feedGetService.findById(feedId)).willReturn(feed); + + Reaction reaction = ReactionTestFixture.createReaction(feed, me, 4); + given(reactionGetService.findByFeedAndUser(feed, me)).willReturn(Optional.of(reaction)); + + ReactionRequest request = new ReactionRequest(1L); + + // when + feedUseCase.reactToFeed(userId, feedId, request); + + // then + then(feedUpdateService).should().updateTotalReaction(feed, reaction, author, 1L); + then(feedNotificationUsecase).should().saveFirstReactionNotification(reaction); + then(feedNotificationUsecase).should().saveReactionCountNotification(feed, 5); + } + + @Test + @DisplayName("기존 리액션이 없으면 업데이트 후 첫 리액션 알림 저장") + void reactToFeed3() { + // given + long userId = 1L; + long feedId = 10L; + + User me = UserTestFixture.createUser(userId, "me"); + User author = UserTestFixture.createUser(2L, "author"); + Feed feed = FeedTestFixture.createFeed(feedId, author); + + given(userGetService.findById(userId)).willReturn(me); + given(feedGetService.findById(feedId)).willReturn(feed); + + given(reactionGetService.findByFeedAndUser(feed, me)).willReturn(Optional.empty()); + + Reaction toSave = ReactionTestFixture.createReaction(feed, me, 0); + Reaction saved = ReactionTestFixture.createReaction(feed, me, 0); + + given(reactionMapper.toReaction(me, feed, 0L)).willReturn(toSave); + given(reactionSaveService.save(toSave)).willReturn(saved); + + ReactionRequest request = new ReactionRequest(1L); + + // when + feedUseCase.reactToFeed(userId, feedId, request); + + // then + then(reactionSaveService).should().save(toSave); + then(feedUpdateService).should().updateTotalReaction(feed, saved, author, 1L); + then(feedNotificationUsecase).should().saveFirstReactionNotification(saved); + then(feedNotificationUsecase).should(never()).saveReactionCountNotification(any(), anyLong()); + } + + @Test + @DisplayName("댓글 생성 후 저장") + void writeComment() { + // given + long userId = 1L; + long feedId = 10L; + + User me = UserTestFixture.createUser(userId, "me"); + User author = UserTestFixture.createUser(2L, "author"); + Feed feed = FeedTestFixture.createFeed(feedId, author); + + given(userGetService.findById(userId)).willReturn(me); + given(feedGetService.findById(feedId)).willReturn(feed); + + CommentWriteRequest request = new CommentWriteRequest("hello"); + Comment comment = CommentTestFixture.createComment(1L, me, feed, "hello"); + given(commentMapper.toComment(me, feed, request)).willReturn(comment); + + // when + feedUseCase.writeComment(userId, feedId, request); + + // then + then(commentSaveService).should().saveComment(comment); + } + + @Test + @DisplayName("리액션 목록 조회 후 응답 반환") + void getReactionUser1() { + // given + long feedId = 10L; + + User author = UserTestFixture.createUser(2L, "author"); + User u1 = UserTestFixture.createUser(1L, "u1"); + User u2 = UserTestFixture.createUser(3L, "u2"); + + Feed feed = FeedTestFixture.createFeed(feedId, author); + + Reaction r1 = ReactionTestFixture.createReaction(feed, u1, 5); + Reaction r2 = ReactionTestFixture.createReaction(feed, u2, 1); + + given(feedGetService.findById(feedId)).willReturn(feed); + given(reactionGetService.findAll(feed)).willReturn(List.of(r1, r2)); + + ReactionUserResponse resp1 = mock(ReactionUserResponse.class); + ReactionUserResponse resp2 = mock(ReactionUserResponse.class); + + given(reactionMapper.toResponse(r1)).willReturn(resp1); + given(reactionMapper.toResponse(r2)).willReturn(resp2); + + // when + List result = feedUseCase.getReactionUser(feedId); + + // then + assertThat(result).containsExactly(resp1, resp2); + then(reactionMapper).should(times(2)).toResponse(any(Reaction.class)); + } + + @Test + @DisplayName("작성자가 아니면 예외발생") + void updateFeed1() { + // given + long userId = 1L; + long feedId = 10L; + + User author = UserTestFixture.createUser(2L, "author"); + User other = UserTestFixture.createUser(userId, "other"); + + Feed feed = FeedTestFixture.createFeed(feedId, author); + + given(feedGetService.findById(feedId)).willReturn(feed); + given(userGetService.findById(userId)).willReturn(other); + + FeedUpdateRequest request = new FeedUpdateRequest("hello", null, null); + + // when & then + assertThatThrownBy(() -> feedUseCase.updateFeed(userId, feedId, request)) + .isInstanceOf(FeedUpdateNotAllowedException.class); + + then(feedUpdateService).shouldHaveNoInteractions(); + then(mediaDeleteService).shouldHaveNoInteractions(); + then(linkedUserDeleteService).shouldHaveNoInteractions(); + } + + @Test + @DisplayName("미디어와 링크 유저 목록이 있으면 기존 삭제 후 새로 저장") + void updateFeed2() { + // given + long userId = 1L; + long feedId = 10L; + + User author = UserTestFixture.createUser(userId, "author"); + Feed feed = FeedTestFixture.createFeed(feedId, author); + + given(feedGetService.findById(feedId)).willReturn(feed); + given(userGetService.findById(userId)).willReturn(author); + + FeedMediaRequest mr = new FeedMediaRequest(1, "https://example.com/a.jpg", MediaType.IMAGE); + FeedUpdateRequest request = new FeedUpdateRequest("new", List.of(mr), List.of(2L)); + + given(mediaMapper.toMedia(eq(feed), eq(mr))).willReturn(MediaTestFixture.createMedia(1L, feed)); + + User u2 = UserTestFixture.createUser(2L, "u2"); + given(userGetService.findAll(request.userIds())).willReturn(List.of(u2)); + given(feedUserMapper.toLinkedUser(any(User.class), eq(feed))).willReturn(mock(LinkedUser.class)); + + // when + feedUseCase.updateFeed(userId, feedId, request); + + // then + then(feedUpdateService).should().update(feed, request); + + then(mediaDeleteService).should().deleteAllByFeed(feed); + then(mediaSaveService).should().saveAll(anyList()); + + then(linkedUserDeleteService).should().deleteAllByFeed(feed); + then(linkedUserSaveService).should().saveAll(anyList()); + } + + @Test + @DisplayName("내 Feeds 응답 매핑") + void getMyFeeds() { + // given + long userId = 1L; + int pageNumber = 0; + int pageSize = 10; + + User user = UserTestFixture.createUser(userId, "me"); + given(userGetService.findById(userId)).willReturn(user); + + Feed f1 = FeedTestFixture.createFeed(100L, user); + + Slice slice = new SliceImpl<>(List.of(f1), PageRequest.of(pageNumber, pageSize), false); + given(feedGetService.findAllByUser(eq(user), any(Pageable.class))).willReturn(slice); + + given(mediaGetService.findAllByFeeds(slice.getContent())) + .willReturn(List.of(MediaTestFixture.createMedia(1L, f1))); + + FeedListResponse expected = mock(FeedListResponse.class); + given(feedMapper.toFeedListResponse(eq(user), eq(slice), anyMap(), eq(true))).willReturn(expected); + + // when + FeedListResponse result = feedUseCase.getMyFeeds(userId, pageNumber, pageSize); + + // then + assertThat(result).isEqualTo(expected); + then(feedMapper).should().toFeedListResponse(eq(user), eq(slice), anyMap(), eq(true)); + } + + @Test + @DisplayName(("다른 사람들 Feeds 응답 매핑")) + void getOtherFeeds() { + // given + long otherUserId = 2L; + int pageNumber = 0; + int pageSize = 10; + + User other = UserTestFixture.createUser(otherUserId, "other"); + given(userGetService.findById(otherUserId)).willReturn(other); + + Feed f1 = FeedTestFixture.createFeed(100L, other); + + Slice slice = new SliceImpl<>(List.of(f1), PageRequest.of(pageNumber, pageSize), false); + given(feedGetService.findAllByUser(eq(other), any(Pageable.class))).willReturn(slice); + + given(mediaGetService.findAllByFeeds(slice.getContent())) + .willReturn(List.of(MediaTestFixture.createMedia(1L, f1))); + + FeedListResponse expected = mock(FeedListResponse.class); + given(feedMapper.toFeedListResponse(eq(other), eq(slice), anyMap(), eq(false))).willReturn(expected); + + // when + FeedListResponse result = feedUseCase.getOthersFeeds(otherUserId, pageNumber, pageSize); + + // then + assertThat(result).isEqualTo(expected); + then(feedMapper).should().toFeedListResponse(eq(other), eq(slice), anyMap(), eq(false)); + } + + @Test + @DisplayName("함깨한 피드 조회 후 매핑하여 응답 변환") + void getLinkedFeeds() { + // given + long userId = 1L; + int pageNumber = 0; + int pageSize = 10; + + User user = UserTestFixture.createUser(userId, "me"); + given(userGetService.findById(userId)).willReturn(user); + + User author = UserTestFixture.createUser(2L, "author"); + Feed f1 = FeedTestFixture.createFeed(100L, author); + + Slice slice = new SliceImpl<>(List.of(f1), PageRequest.of(pageNumber, pageSize), false); + given(linkedUserGetService.findAllByUser(eq(user), any(Pageable.class))).willReturn(slice); + + given(mediaGetService.findAllByFeeds(slice.getContent())) + .willReturn(List.of(MediaTestFixture.createMedia(1L, f1))); + + FeedListResponse expected = mock(FeedListResponse.class); + given(feedMapper.toFeedListResponse(eq(slice), anyMap())).willReturn(expected); + + // when + FeedListResponse result = feedUseCase.getLinkedFeeds(userId, pageNumber, pageSize); + + //then + assertThat(result).isEqualTo(expected); + then(feedMapper).should().toFeedListResponse(eq(slice), anyMap()); + } + + @Test + @DisplayName("전체 유저 조회 후 응답 매핑") + void getAllUser() { + // given + User u1 = UserTestFixture.createUser(1L, "me"); + User u2 = UserTestFixture.createUser(2L, "me2"); + given(userGetService.findAll()).willReturn(List.of(u1, u2)); + + FeedUserResponse r1 = mock(FeedUserResponse.class); + FeedUserResponse r2 = mock(FeedUserResponse.class); + given(feedUserMapper.toFeedUserResponse(eq(u1))).willReturn(r1); + given(feedUserMapper.toFeedUserResponse(eq(u2))).willReturn(r2); + + // when + List result = feedUseCase.getAllUser(); + + // then + assertThat(result).containsExactly(r1, r2); + then(feedUserMapper).should(times(2)).toFeedUserResponse(any(User.class)); + } + + @Test + @DisplayName("페이지로 유저 조회 후 응답 매핑") + void getUsers() { + // given + int pageNumber = 0; + int pageSize = 10; + + User u1 = UserTestFixture.createUser(1L, "me"); + Slice slice = new SliceImpl<>(List.of(u1), PageRequest.of(pageNumber, pageSize), true); + given(userGetService.findAll(any(Pageable.class))).willReturn(slice); + + FeedUserListResponse expected = mock(FeedUserListResponse.class); + given(feedUserMapper.toFeedUserListResponse(slice)).willReturn(expected); + + // when + FeedUserListResponse result = feedUseCase.getUsers(pageNumber, pageSize); + + // then + assertThat(result).isEqualTo(expected); + then(feedUserMapper).should().toFeedUserListResponse(slice); + } + + @Test + @DisplayName("피드 작성자면 피드 삭제") + void deleteFeed1() { + // given + long userId = 1L; + long feedId = 10L; + + User author = UserTestFixture.createUser(userId, "me"); + Feed feed = FeedTestFixture.createFeed(feedId, author); + + given(feedGetService.findById(feedId)).willReturn(feed); + given(userGetService.findById(userId)).willReturn(author); + + // when + feedUseCase.deleteFeed(userId, feedId); + + //then + then(feedDeleteService).should().delete(feed); + } + + @Test + @DisplayName("피드 작성자가 아니면 예외 처리") + void deleteFeed2() { + // given + long userId = 1L; + long feedId = 10L; + + User author = UserTestFixture.createUser(2L, "me"); + User other = UserTestFixture.createUser(userId, "me2"); + + Feed feed = FeedTestFixture.createFeed(feedId, author); + + given(feedGetService.findById(feedId)).willReturn(feed); + given(userGetService.findById(userId)).willReturn(other); + + // when & then + assertThatThrownBy(() -> feedUseCase.deleteFeed(userId, feedId)) + .isInstanceOf(FeedDeleteNotAllowedException.class); + + then(feedDeleteService).shouldHaveNoInteractions(); + } + + @Test + @DisplayName("댓글 작성자면 댓글 삭제") + void deleteComment() { + // given + long userId = 1L; + long commentId = 5L; + + User author = UserTestFixture.createUser(2L, "me"); + User me = UserTestFixture.createUser(userId, "me2"); + Feed feed = FeedTestFixture.createFeed(10L, author); + + Comment comment = CommentTestFixture.createComment(commentId, me, feed, "wq"); + given(userGetService.findById(userId)).willReturn(me); + given(commentGetService.findCommentByIdNotDeleted(commentId)).willReturn(comment); + + // when + feedUseCase.deleteComment(userId, commentId); + + //then + then(commentDeleteService).should().deleteComment(comment); + } + + @Test + @DisplayName("댓글 작성자가 아니면 예외처리") + void deleteComment2() { + // given + long userId = 1L; + long commentId = 5L; + + User author = UserTestFixture.createUser(2L, "me"); + User me = UserTestFixture.createUser(userId, "me2"); + User other = UserTestFixture.createUser(3L, "me3"); + Feed feed = FeedTestFixture.createFeed(10L, author); + + Comment comment = CommentTestFixture.createComment(commentId, other, feed, "wq"); + given(userGetService.findById(userId)).willReturn(me); + given(commentGetService.findCommentByIdNotDeleted(commentId)).willReturn(comment); + + // when & then + assertThatThrownBy(() -> feedUseCase.deleteComment(userId, commentId)) + .isInstanceOf(CommentDeleteNotAllowedException.class); + + then(commentDeleteService).shouldHaveNoInteractions(); + } + + @Test + @DisplayName("노션과 슬랙으로 신고 내용 전송") + void reportFeed() { + // given + long userId = 1L; + long feedId = 10L; + + User me = UserTestFixture.createUser(userId, "me"); + User author = UserTestFixture.createUser(2L, "me"); + Feed feed = FeedTestFixture.createFeed(feedId, author); + + given(userGetService.findById(userId)).willReturn(me); + given(feedGetService.findById(feedId)).willReturn(feed); + + FeedReportRequest request = new FeedReportRequest("신고"); + + // when + feedUseCase.reportFeed(userId, feedId, request); + + // then + then(notionDatabaseService).should().sendFeedReport(request.report(), me.getId(), feed.getId()); + then(slackWebhookService).should().sendFeedReport(request.report()); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/domain/repository/CommentRepositoryTest.java b/src/test/java/leets/leenk/domain/feed/domain/repository/CommentRepositoryTest.java new file mode 100644 index 00000000..ea6d74ba --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/domain/repository/CommentRepositoryTest.java @@ -0,0 +1,119 @@ +package leets.leenk.domain.feed.domain.repository; + +import jakarta.persistence.EntityManager; +import leets.leenk.config.MysqlTestConfig; +import leets.leenk.domain.feed.domain.entity.Comment; +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.test.CommentTestFixture; +import leets.leenk.domain.feed.test.FeedTestFixture; +import leets.leenk.domain.feed.test.UserTestFixture; +import leets.leenk.domain.user.domain.entity.User; +import leets.leenk.domain.user.domain.repository.UserRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ActiveProfiles; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +@ActiveProfiles("test") +@Import(MysqlTestConfig.class) +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +public class CommentRepositoryTest { + @Autowired + EntityManager em; + + @Autowired + private CommentRepository commentRepository; + @Autowired + private UserRepository userRepository; + @Autowired + private FeedRepository feedRepository; + + @Test + @DisplayName("findByCommentIdAndDeletedAtIsNull 테스트") + void findByCommentIdAndDeletedAtIsNull() { + // given + User author = userRepository.save(UserTestFixture.createUser(1L, "me")); + Feed feed = feedRepository.save(FeedTestFixture.createFeed(null, author)); + + Comment notDeleted = commentRepository.save(CommentTestFixture.createComment(null, author, feed, "hi1")); + Comment deleted = commentRepository.save(CommentTestFixture.createComment(null, author, feed, "hi2")); + + flushAndClear(); + + LocalDateTime base = LocalDateTime.of(2025, 12, 22, 16, 0); + + updateCommentDates(notDeleted.getCommentId(), base.plusMinutes(1), null); + updateCommentDates(deleted.getCommentId(), base.plusMinutes(2), base.plusMinutes(1)); + + flushAndClear(); + + // when + Optional notDeletedComment = commentRepository.findByCommentIdAndDeletedAtIsNull(notDeleted.getCommentId()); + Optional deletedComment = commentRepository.findByCommentIdAndDeletedAtIsNull(deleted.getCommentId()); + + // then + assertThat(notDeletedComment).isPresent(); + assertThat(notDeletedComment.get().getComment()).isEqualTo("hi1"); + assertThat(deletedComment).isEmpty(); + } + + @Test + @DisplayName("findAllByFeedAndDeletedAtIsNullOrderByCreateDateDesc 테스트") + void findAllByFeedAndDeletedAtIsNullOrderByCreateDateDesc() { + // given + User author = userRepository.save(UserTestFixture.createUser(1L, "me")); + Feed feed1 = feedRepository.save(FeedTestFixture.createFeed(null, author)); + Feed feed2 = feedRepository.save(FeedTestFixture.createFeed(null, author)); + + Comment c1 = commentRepository.save(CommentTestFixture.createComment(null, author, feed1, "hi1")); + Comment c2 = commentRepository.save(CommentTestFixture.createComment(null, author, feed1, "hi2")); + Comment c3Deleted = commentRepository.save(CommentTestFixture.createComment(null, author, feed1, "hi3")); + Comment other = commentRepository.save(CommentTestFixture.createComment(null, author, feed2, "other")); + + flushAndClear(); + + LocalDateTime base = LocalDateTime.of(2025, 12, 22, 16, 0); + + updateCommentDates(c1.getCommentId(), base.plusMinutes(1), null); + updateCommentDates(c2.getCommentId(), base.plusMinutes(2), null); + updateCommentDates(c3Deleted.getCommentId(), base.plusMinutes(3), base.plusMinutes(3)); + updateCommentDates(other.getCommentId(), base.plusMinutes(4), null); + + flushAndClear(); + + // when + List result = commentRepository.findAllByFeedAndDeletedAtIsNullOrderByCreateDateDesc(feed1); + + // then + assertThat(result).hasSize(2); + assertThat(result.stream().map(Comment::getCommentId).toList()) + .containsExactly(c2.getCommentId(), c1.getCommentId()); + assertThat(result).allSatisfy(comment -> { + assertThat(comment.getFeed().getId()).isEqualTo(feed1.getId()); + assertThat(comment.getDeletedAt()).isNull(); + }); + } + + private void updateCommentDates(Long commentId, LocalDateTime createdDate, LocalDateTime deletedAt) { + em.createQuery("UPDATE Comment c SET c.createDate = :createDate, c.deletedAt = :deletedAt WHERE c.commentId = :id") + .setParameter("createDate", createdDate) + .setParameter("deletedAt", deletedAt) + .setParameter("id", commentId) + .executeUpdate(); + } + + private void flushAndClear() { + em.flush(); + em.clear(); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/domain/repository/FeedRepositoryTest.java b/src/test/java/leets/leenk/domain/feed/domain/repository/FeedRepositoryTest.java new file mode 100644 index 00000000..df6da1c8 --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/domain/repository/FeedRepositoryTest.java @@ -0,0 +1,266 @@ +package leets.leenk.domain.feed.domain.repository; + +import jakarta.persistence.EntityManager; +import leets.leenk.config.MysqlTestConfig; +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.test.FeedTestFixture; +import leets.leenk.domain.feed.test.UserTestFixture; +import leets.leenk.domain.user.domain.entity.User; +import leets.leenk.domain.user.domain.repository.UserRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.Import; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Slice; +import org.springframework.test.context.ActiveProfiles; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +@ActiveProfiles("test") +@Import(MysqlTestConfig.class) +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +public class FeedRepositoryTest { + @Autowired + EntityManager em; + + @Autowired + FeedRepository feedRepository; + + @Autowired + UserRepository userRepository; + + @Test + @DisplayName("저장(save) 및 조회(findById)") + void saveAndFind() { + User author = UserTestFixture.createUser(1L, "me"); + userRepository.save(author); + + Feed feed = FeedTestFixture.createFeed(null, author); + Feed saved = feedRepository.save(feed); + + em.flush(); + em.clear(); + + Feed result = feedRepository.findById(feed.getId()).orElseThrow(); + + assertThat(result.getId()).isEqualTo(saved.getId()); + assertThat(result.getUser().getId()).isEqualTo(author.getId()); + assertThat(result.getDescription()).isEqualTo("desc"); + assertThat(result.getTotalReactionCount()).isEqualTo(0L); + } + + @Test + @DisplayName("findAllByDeletedAtIsNullWithUser 테스트") + void findAllByDeletedAtIsNullWithUser() { + // given + User u1 = userRepository.save(UserTestFixture.createUser(1L, "me")); + User u2 = userRepository.save(UserTestFixture.createUser(2L, "me2")); + + LocalDateTime base = LocalDateTime.of(2025, 12, 22, 15, 0); + + Feed f1 = feedRepository.save(FeedTestFixture.createFeed(null, u1)); + Feed f2 = feedRepository.save(FeedTestFixture.createFeed(null, u1)); + Feed f3 = feedRepository.save(FeedTestFixture.createFeed(null, u1)); + Feed block = feedRepository.save(FeedTestFixture.createFeed(null, u2)); + Feed delete = feedRepository.save(FeedTestFixture.createFeed(null, u1)); + + flushAndClear(); + + updateFeedDates(f1.getId(), base.plusMinutes(1), null); + updateFeedDates(f2.getId(), base.plusMinutes(2), null); + updateFeedDates(f3.getId(), base.plusMinutes(3), null); + updateFeedDates(block.getId(), base.plusMinutes(4), null); + updateFeedDates(delete.getId(), base.plusMinutes(5), base.plusMinutes(6)); + + flushAndClear(); + + // when + Slice slice = feedRepository.findAllByDeletedAtIsNullWithUser( + PageRequest.of(0, 2), + List.of(u2.getId()) + ); + + // then + assertThat(slice.getContent()).hasSize(2); + assertThat(slice.hasNext()).isTrue(); + + List ids = slice.getContent().stream().map(Feed::getId).toList(); + assertThat(ids).containsExactly(f3.getId(), f2.getId()); + + assertThat(slice.getContent()).allSatisfy(feed -> { + assertThat(feed.getDeletedAt()).isNull(); + assertThat(feed.getUser().getId()).isNotEqualTo(u2.getId()); + }); + } + + @Test + @DisplayName("findAllByUserAndDeletedAtIsNull 테스트") + void findAllByUserAndDeletedAtIsNull() { + //given + User me = userRepository.save(UserTestFixture.createUser(3L, "me")); + User other = userRepository.save(UserTestFixture.createUser(4L, "me2")); + + LocalDateTime base = LocalDateTime.of(2025, 12, 22, 16, 0); + + Feed mine1 = feedRepository.save(FeedTestFixture.createFeed(null, me)); + Feed mine2 = feedRepository.save(FeedTestFixture.createFeed(null, me)); + Feed mineDeleted = feedRepository.save(FeedTestFixture.createFeed(null, me)); + Feed other1 = feedRepository.save(FeedTestFixture.createFeed(null, other)); + + flushAndClear(); + + updateFeedDates(mine1.getId(), base.plusMinutes(1), null); + updateFeedDates(mine2.getId(), base.plusMinutes(2), null); + updateFeedDates(mineDeleted.getId(), base.plusMinutes(3), base.plusMinutes(4)); + updateFeedDates(other1.getId(), base.plusMinutes(4), null); + + flushAndClear(); + + // when + Slice slice = feedRepository.findAllByUserAndDeletedAtIsNull(me, PageRequest.of(0, 10)); + + // then + assertThat(slice.getContent()).hasSize(2); + assertThat(slice.getContent().stream().map(Feed::getId).toList()) + .containsExactly(mine2.getId(), mine1.getId()); + assertThat(slice.getContent()).allSatisfy(feed -> { + assertThat(feed.getUser().getName()).isEqualTo(me.getName()); + assertThat(feed.getDeletedAt()).isNull(); + }); + } + + @Test + @DisplayName("findByDeletedAtIsNullAndId 테스트") + void findByDeletedAtIsNullAndId() { + // given + User me = userRepository.save(UserTestFixture.createUser(31L, "me")); + + LocalDateTime base = LocalDateTime.of(2025, 12, 22, 16, 0); + + Feed notDeleted = feedRepository.save(FeedTestFixture.createFeed(null, me)); + Feed Deleted = feedRepository.save(FeedTestFixture.createFeed(null, me)); + + flushAndClear(); + + updateFeedDates(Deleted.getId(), base.plusMinutes(1), base.plusMinutes(2)); + flushAndClear(); + + // when + Optional notDeletedFeed = feedRepository.findByDeletedAtIsNullAndId(notDeleted.getId()); + Optional deletedFeed = feedRepository.findByDeletedAtIsNullAndId(Deleted.getId()); + + // then + assertThat(notDeletedFeed).isPresent(); + assertThat(notDeletedFeed.get().getId()).isEqualTo(notDeleted.getId()); + assertThat(deletedFeed).isEmpty(); + } + + @Test + @DisplayName("findPrevFeeds 테스트") + void findPrevFeeds() { + // given + User me = userRepository.save(UserTestFixture.createUser(5L, "me")); + User blockedUser = userRepository.save(UserTestFixture.createUser(6L, "blocked")); + + LocalDateTime base = LocalDateTime.of(2025, 12, 22, 16, 0); + + Feed feed1 = feedRepository.save(FeedTestFixture.createFeed(null, me)); + Feed feed2 = feedRepository.save(FeedTestFixture.createFeed(null, me)); + Feed feedDeleted = feedRepository.save(FeedTestFixture.createFeed(null, me)); + Feed feed3 = feedRepository.save(FeedTestFixture.createFeed(null, me)); + Feed feedBlocked = feedRepository.save(FeedTestFixture.createFeed(null, blockedUser)); + + + flushAndClear(); + + updateFeedDates(feed1.getId(), base.plusMinutes(1), null); + updateFeedDates(feed2.getId(), base.plusMinutes(1), null); + updateFeedDates(feedDeleted.getId(), base.plusMinutes(2), base.plusMinutes(4)); + updateFeedDates(feed3.getId(), base.plusMinutes(3), null); + updateFeedDates(feedBlocked.getId(), base.plusMinutes(4), null); + + flushAndClear(); + + // when + List prevFeeds = feedRepository.findPrevFeeds( + base, + List.of(blockedUser.getId()), + PageRequest.of(0, 2) + ); + + // then + assertThat(prevFeeds).hasSize(2); + assertThat(prevFeeds.stream().map(Feed::getId).toList()) + .containsExactly(feed1.getId(), feed2.getId()); + assertThat(prevFeeds).allSatisfy(feed -> { + assertThat(feed.getCreateDate()).isAfter(base); + assertThat(feed.getDeletedAt()).isNull(); + assertThat(feed.getUser().getId()).isNotEqualTo(blockedUser.getId()); + }); + } + + @Test + @DisplayName("findNextFeeds 테스트") + void findNextFeeds(){ + // given + User me = userRepository.save(UserTestFixture.createUser(5L, "me")); + User blockedUser = userRepository.save(UserTestFixture.createUser(6L, "blocked")); + + LocalDateTime base = LocalDateTime.of(2025, 12, 22, 16, 0); + + Feed feed1 = feedRepository.save(FeedTestFixture.createFeed(null, me)); + Feed feed2 = feedRepository.save(FeedTestFixture.createFeed(null, me)); + Feed feedDeleted = feedRepository.save(FeedTestFixture.createFeed(null, me)); + Feed feedBlocked = feedRepository.save(FeedTestFixture.createFeed(null, blockedUser)); + Feed feed3 = feedRepository.save(FeedTestFixture.createFeed(null, me)); + + + flushAndClear(); + + updateFeedDates(feed1.getId(), base.minusMinutes(10), null); + updateFeedDates(feed2.getId(), base.minusMinutes(20), null); + updateFeedDates(feedDeleted.getId(), base.minusMinutes(30), base.minusMinutes(29)); + updateFeedDates(feedBlocked.getId(), base.minusMinutes(40), null); + updateFeedDates(feed3.getId(), base.minusMinutes(10), null); + + flushAndClear(); + + // when + List nextFeeds = feedRepository.findNextFeeds( + base, + List.of(blockedUser.getId()), + PageRequest.of(0, 2) + ); + + // then + assertThat(nextFeeds).hasSize(2); + assertThat(nextFeeds.stream().map(Feed::getId).toList()) + .containsExactly(feed1.getId(), feed3.getId()); + assertThat(nextFeeds).allSatisfy(feed -> { + assertThat(feed.getCreateDate()).isBefore(base); + assertThat(feed.getDeletedAt()).isNull(); + assertThat(feed.getUser().getId()).isNotEqualTo(blockedUser.getId()); + }); + } + + private void updateFeedDates(Long feedId, LocalDateTime createdDate, LocalDateTime deletedAt) { + em.createQuery("UPDATE Feed f SET f.createDate = :createDate, f.deletedAt = :deletedAt WHERE f.id = :id") + .setParameter("createDate", createdDate) + .setParameter("deletedAt", deletedAt) + .setParameter("id", feedId) + .executeUpdate(); + } + + private void flushAndClear() { + em.flush(); + em.clear(); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/domain/repository/LinkedUserRepositoryTest.java b/src/test/java/leets/leenk/domain/feed/domain/repository/LinkedUserRepositoryTest.java new file mode 100644 index 00000000..6ae08083 --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/domain/repository/LinkedUserRepositoryTest.java @@ -0,0 +1,151 @@ +package leets.leenk.domain.feed.domain.repository; + +import jakarta.persistence.EntityManager; +import leets.leenk.config.MysqlTestConfig; +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.domain.entity.LinkedUser; +import leets.leenk.domain.feed.test.FeedTestFixture; +import leets.leenk.domain.feed.test.LinkedUserTestFixture; +import leets.leenk.domain.feed.test.UserTestFixture; +import leets.leenk.domain.user.domain.entity.User; +import leets.leenk.domain.user.domain.repository.UserRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.Import; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Slice; +import org.springframework.test.context.ActiveProfiles; + +import java.time.LocalDateTime; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +@ActiveProfiles("test") +@Import(MysqlTestConfig.class) +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +public class LinkedUserRepositoryTest { + @Autowired + EntityManager em; + @Autowired + UserRepository userRepository; + @Autowired + LinkedUserRepository linkedUserRepository; + @Autowired + FeedRepository feedRepository; + + @Test + @DisplayName("findAllByFeed 테스트") + void findAllByFeed() { + // given + User author = userRepository.save(UserTestFixture.createUser(1L, "author")); + User u1 = userRepository.save(UserTestFixture.createUser(2L, "u1")); + User u2 = userRepository.save(UserTestFixture.createUser(3L, "u2")); + User u3 = userRepository.save(UserTestFixture.createUser(4L, "u3")); + + Feed feed = feedRepository.save(FeedTestFixture.createFeed(null, author)); + + LinkedUser l1 = linkedUserRepository.save(LinkedUserTestFixture.createLinkedUser(null, u1, feed)); + LinkedUser l2 = linkedUserRepository.save(LinkedUserTestFixture.createLinkedUser(null, u2, feed)); + LinkedUser l3 = linkedUserRepository.save(LinkedUserTestFixture.createLinkedUser(null, u3, feed)); + + flushAndClear(); + + // when + List result = linkedUserRepository.findAllByFeed(feed); + + // then + assertThat(result.size()).isEqualTo(3); + assertThat(result.stream().map(LinkedUser::getId).toList()) + .containsExactly(l1.getId(), l2.getId(), l3.getId()); + } + + @Test + @DisplayName(("findFeedsByLinkedUser 테스트")) + void findFeedsByLinkedUser() { + // given + User me = userRepository.save(UserTestFixture.createUser(1L, "me")); + User other = userRepository.save(UserTestFixture.createUser(2L, "other")); + + LocalDateTime base = LocalDateTime.of(2025, 12, 22, 16, 0); + + Feed myFeed = saveFeedWithCreateDate( + FeedTestFixture.createFeed(null, me), + base.plusMinutes(1), + null + ); + Feed f1 = saveFeedWithCreateDate( + FeedTestFixture.createFeed(null, other), + base.plusMinutes(2), + null + ); + Feed deleted = saveFeedWithCreateDate( + FeedTestFixture.createFeed(null, other), + base.plusMinutes(3), + base.plusMinutes(4) + ); + + linkedUserRepository.save(LinkedUserTestFixture.createLinkedUser(null, me, myFeed)); + linkedUserRepository.save(LinkedUserTestFixture.createLinkedUser(null, me, f1)); + linkedUserRepository.save(LinkedUserTestFixture.createLinkedUser(null, me, deleted)); + + flushAndClear(); + + // when + Slice slice = linkedUserRepository.findFeedsByLinkedUser(me, PageRequest.of(0, 10)); + + // then + assertThat(slice).hasSize(1); + assertThat(slice.getContent().stream().map(Feed::getId).toList()) + .containsExactly(f1.getId()); + } + + @Test + @DisplayName("deleteAllByFeed 테스트") + void deleteAllByFeed() { + // given + User author = userRepository.save(UserTestFixture.createUser(1L, "author")); + User u1 = userRepository.save(UserTestFixture.createUser(2L, "u1")); + User u2 = userRepository.save(UserTestFixture.createUser(3L, "u2")); + + Feed f1 = feedRepository.save(FeedTestFixture.createFeed(null, author)); + Feed f2 = feedRepository.save(FeedTestFixture.createFeed(null, author)); + + linkedUserRepository.save(LinkedUserTestFixture.createLinkedUser(null, u1, f1)); + linkedUserRepository.save(LinkedUserTestFixture.createLinkedUser(null, u1, f2)); + linkedUserRepository.save(LinkedUserTestFixture.createLinkedUser(null, u2, f1)); + + flushAndClear(); + + // when + linkedUserRepository.deleteAllByFeed(f1); + flushAndClear(); + + //then + assertThat(linkedUserRepository.findAllByFeed(f1)).isEmpty(); + assertThat(linkedUserRepository.findAllByFeed(f2)).hasSize(1); + } + + private Feed saveFeedWithCreateDate(Feed feed, LocalDateTime createDate, LocalDateTime deletedAt) { + Feed saved = feedRepository.save(feed); + flushAndClear(); + + em.createQuery("UPDATE Feed f SET f.createDate = :createDate, f.deletedAt = :deletedAt WHERE f.id = :id") + .setParameter("createDate", createDate) + .setParameter("deletedAt", deletedAt) + .setParameter("id", saved.getId()) + .executeUpdate(); + flushAndClear(); + + return saved; + } + + private void flushAndClear() { + em.flush(); + em.clear(); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/domain/repository/ReactionRepositoryTest.java b/src/test/java/leets/leenk/domain/feed/domain/repository/ReactionRepositoryTest.java new file mode 100644 index 00000000..a25f1eb6 --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/domain/repository/ReactionRepositoryTest.java @@ -0,0 +1,90 @@ +package leets.leenk.domain.feed.domain.repository; + +import jakarta.persistence.EntityManager; +import leets.leenk.config.MysqlTestConfig; +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.domain.entity.Reaction; +import leets.leenk.domain.feed.test.FeedTestFixture; +import leets.leenk.domain.feed.test.ReactionTestFixture; +import leets.leenk.domain.feed.test.UserTestFixture; +import leets.leenk.domain.user.domain.entity.User; +import leets.leenk.domain.user.domain.repository.UserRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ActiveProfiles; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +@ActiveProfiles("test") +@Import(MysqlTestConfig.class) +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +public class ReactionRepositoryTest { + @Autowired + private EntityManager em; + + @Autowired + private ReactionRepository reactionRepository; + @Autowired + private FeedRepository feedRepository; + @Autowired + private UserRepository userRepository; + + @Test + @DisplayName("findByFeedAndUser 테스트") + void findByFeedAndUser() { + // given + User author = userRepository.save(UserTestFixture.createUser(1L, "author")); + User me = userRepository.save(UserTestFixture.createUser(2L, "me")); + + Feed feed = feedRepository.save(FeedTestFixture.createFeed(null, author)); + + Reaction r1 = reactionRepository.save(ReactionTestFixture.createReaction(feed, me, 7L)); + + flushAndClear(); + + // when + Reaction result = reactionRepository.findByFeedAndUser(feed, me).orElseThrow(); + + // then + assertThat(result.getId()).isEqualTo(r1.getId()); + assertThat(result.getReactionCount()).isEqualTo(7L); + } + + @Test + @DisplayName("findAllByFeed 테스트") + void findAllByFeed() { + // given + User author = userRepository.save(UserTestFixture.createUser(1L, "author")); + User u1 = userRepository.save(UserTestFixture.createUser(2L, "u1")); + User u2 = userRepository.save(UserTestFixture.createUser(3L, "u2")); + User u3 = userRepository.save(UserTestFixture.createUser(4L, "u3")); + + Feed feed = feedRepository.save(FeedTestFixture.createFeed(null, author)); + + reactionRepository.save(ReactionTestFixture.createReaction(feed, u1, 7L)); + reactionRepository.save(ReactionTestFixture.createReaction(feed, u2, 7L)); + reactionRepository.save(ReactionTestFixture.createReaction(feed, u3, 7L)); + + flushAndClear(); + + // when + List result = reactionRepository.findAllByFeed(feed); + + // then + assertThat(result.size()).isEqualTo(3); + assertThat(result.stream().map(Reaction::getReactionCount).toList()) + .containsExactly(7L, 7L, 7L); + } + + private void flushAndClear() { + em.flush(); + em.clear(); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/domain/service/CommentDeleteServiceTest.java b/src/test/java/leets/leenk/domain/feed/domain/service/CommentDeleteServiceTest.java new file mode 100644 index 00000000..ae0ce2f4 --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/domain/service/CommentDeleteServiceTest.java @@ -0,0 +1,39 @@ +package leets.leenk.domain.feed.domain.service; + +import leets.leenk.domain.feed.domain.entity.Comment; +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.test.CommentTestFixture; +import leets.leenk.domain.feed.test.FeedTestFixture; +import leets.leenk.domain.feed.test.UserTestFixture; +import leets.leenk.domain.user.domain.entity.User; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CommentDeleteServiceTest { + private final CommentDeleteService commentDeleteService = new CommentDeleteService(); + + @Test + @DisplayName("CommentDeleteService 테스트") + void CommentDeleteService() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Feed feed = FeedTestFixture.createFeed(1L, user); + Comment comment = CommentTestFixture.createComment(null, user, feed, "hi"); + + // when + LocalDateTime start = LocalDateTime.now(); + + commentDeleteService.deleteComment(comment); + + LocalDateTime end = LocalDateTime.now(); + + // then + assertThat(comment.getDeletedAt()).isNotNull(); + assertThat(comment.getDeletedAt()).isAfterOrEqualTo(start); + assertThat(comment.getDeletedAt()).isBeforeOrEqualTo(end); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/domain/service/CommentGetServiceTest.java b/src/test/java/leets/leenk/domain/feed/domain/service/CommentGetServiceTest.java new file mode 100644 index 00000000..1e0e52f7 --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/domain/service/CommentGetServiceTest.java @@ -0,0 +1,85 @@ +package leets.leenk.domain.feed.domain.service; + +import leets.leenk.domain.feed.application.exception.CommentNotFoundException; +import leets.leenk.domain.feed.domain.entity.Comment; +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.domain.repository.CommentRepository; +import leets.leenk.domain.feed.test.CommentTestFixture; +import leets.leenk.domain.feed.test.FeedTestFixture; +import leets.leenk.domain.feed.test.UserTestFixture; +import leets.leenk.domain.user.domain.entity.User; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; + +@ExtendWith(MockitoExtension.class) +public class CommentGetServiceTest { + @Mock + private CommentRepository commentRepository; + + @InjectMocks + private CommentGetService commentGetService; + + @Test + @DisplayName("findCommentByIdNotDeleted 테스트") + void findCommentByIdNotDeleted1() { + //given + User user = UserTestFixture.createUser(1L, "me"); + Feed feed = FeedTestFixture.createFeed(1L, user); + Comment comment = CommentTestFixture.createComment(12L, user, feed, "hi"); + + given(commentRepository.findByCommentIdAndDeletedAtIsNull(12L)) + .willReturn(Optional.of(comment)); + + // when + Comment result = commentGetService.findCommentByIdNotDeleted(12L); + + // then + assertThat(result).isSameAs(comment); + then(commentRepository).should().findByCommentIdAndDeletedAtIsNull(12L); + } + + @Test + @DisplayName("findCommentByIdNotDeleted 테스트 - 예외") + void findCommentByIdNotDeleted2() { + // given + given(commentRepository.findByCommentIdAndDeletedAtIsNull(99L)) + .willReturn(Optional.empty()); + + // when & then + assertThatThrownBy(() -> commentGetService.findCommentByIdNotDeleted(99L)) + .isInstanceOf(CommentNotFoundException.class); + then(commentRepository).should().findByCommentIdAndDeletedAtIsNull(99L); + } + + @Test + @DisplayName("findAllByFeed 테스트") + void findAllByFeed() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Feed feed = FeedTestFixture.createFeed(1L, user); + Comment first = CommentTestFixture.createComment(1L, user, feed, "first"); + Comment second = CommentTestFixture.createComment(2L, user, feed, "second"); + + given(commentRepository.findAllByFeedAndDeletedAtIsNullOrderByCreateDateDesc(feed)) + .willReturn(List.of(first, second)); + + // when + List result = commentGetService.findAllByFeed(feed); + + // then + assertThat(result).containsExactly(first, second); + then(commentRepository).should().findAllByFeedAndDeletedAtIsNullOrderByCreateDateDesc(feed); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/domain/service/CommentSaveServiceTest.java b/src/test/java/leets/leenk/domain/feed/domain/service/CommentSaveServiceTest.java new file mode 100644 index 00000000..bab43bb7 --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/domain/service/CommentSaveServiceTest.java @@ -0,0 +1,41 @@ +package leets.leenk.domain.feed.domain.service; + +import leets.leenk.domain.feed.domain.entity.Comment; +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.domain.repository.CommentRepository; +import leets.leenk.domain.feed.test.CommentTestFixture; +import leets.leenk.domain.feed.test.FeedTestFixture; +import leets.leenk.domain.feed.test.UserTestFixture; +import leets.leenk.domain.user.domain.entity.User; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.mockito.BDDMockito.then; + +@ExtendWith(MockitoExtension.class) +public class CommentSaveServiceTest { + @Mock + private CommentRepository commentRepository; + + @InjectMocks + private CommentSaveService commentSaveService; + + @Test + @DisplayName("saveComment 테스트") + void saveComment() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Feed feed = FeedTestFixture.createFeed(1L, user); + Comment comment = CommentTestFixture.createComment(null, user, feed, "hi"); + + // when + commentSaveService.saveComment(comment); + + // then + then(commentRepository).should().save(comment); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/domain/service/FeedDeleteServiceTest.java b/src/test/java/leets/leenk/domain/feed/domain/service/FeedDeleteServiceTest.java new file mode 100644 index 00000000..b1446f20 --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/domain/service/FeedDeleteServiceTest.java @@ -0,0 +1,36 @@ +package leets.leenk.domain.feed.domain.service; + +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.test.FeedTestFixture; +import leets.leenk.domain.feed.test.UserTestFixture; +import leets.leenk.domain.user.domain.entity.User; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; + +public class FeedDeleteServiceTest { + private final FeedDeleteService feedDeleteService = new FeedDeleteService(); + + @Test + @DisplayName("feedDelete 테스트") + void feedDelete() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Feed feed = FeedTestFixture.createFeed(1L, user); + + // when + LocalDateTime start = LocalDateTime.now(); + + feedDeleteService.delete(feed); + + LocalDateTime end = LocalDateTime.now(); + + // then + assertThat(feed.getDeletedAt()).isNotNull(); + assertThat(feed.getDeletedAt()).isAfterOrEqualTo(start); + assertThat(feed.getDeletedAt()).isBeforeOrEqualTo(end); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/domain/service/FeedGetServiceTest.java b/src/test/java/leets/leenk/domain/feed/domain/service/FeedGetServiceTest.java new file mode 100644 index 00000000..d5d321ed --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/domain/service/FeedGetServiceTest.java @@ -0,0 +1,166 @@ +package leets.leenk.domain.feed.domain.service; + +import leets.leenk.domain.feed.application.exception.FeedNotFoundException; +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.domain.repository.FeedRepository; +import leets.leenk.domain.feed.domain.service.dto.FeedNavigationResult; +import leets.leenk.domain.feed.test.FeedTestFixture; +import leets.leenk.domain.feed.test.UserTestFixture; +import leets.leenk.domain.user.domain.entity.User; +import leets.leenk.domain.user.domain.entity.UserBlock; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.data.domain.SliceImpl; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static leets.leenk.domain.feed.test.FeedTestFixture.createFeedWithCreateDate; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; + +@ExtendWith(MockitoExtension.class) +public class FeedGetServiceTest { + @Mock + private FeedRepository feedRepository; + + @InjectMocks + private FeedGetService feedGetService; + + @Test + @DisplayName("findById 테스트") + void findById1() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Feed feed = FeedTestFixture.createFeed(1L, user); + + given(feedRepository.findByDeletedAtIsNullAndId(1L)) + .willReturn(Optional.of(feed)); + + // when + Feed result = feedGetService.findById(1L); + + // then + assertThat(result).isSameAs(feed); + then(feedRepository).should().findByDeletedAtIsNullAndId(1L); + } + + @Test + @DisplayName("findById 테스트 - 예외") + void findById2() { + // given + given(feedRepository.findByDeletedAtIsNullAndId(99L)) + .willReturn(Optional.empty()); + + // when & then + assertThatThrownBy(() -> feedGetService.findById(99L)) + .isInstanceOf(FeedNotFoundException.class); + then(feedRepository).should().findByDeletedAtIsNullAndId(99L); + } + + @Test + @DisplayName("findAll 테스트") + void findAll() { + // given + User blocker = UserTestFixture.createUser(1L, "blocker"); + User blocked1 = UserTestFixture.createUser(2L, "blocked1"); + User blocked2 = UserTestFixture.createUser(3L, "blocked2"); + List blockedUsers = List.of( + UserBlock.builder().blocker(blocker).blocked(blocked1).build(), + UserBlock.builder().blocker(blocker).blocked(blocked2).build() + ); + + Pageable pageable = PageRequest.of(0, 10); + Slice slice = new SliceImpl<>(List.of()); + + given(feedRepository.findAllByDeletedAtIsNullWithUser(pageable, List.of(2L, 3L))) + .willReturn(slice); + + // when + Slice result = feedGetService.findAll(pageable, blockedUsers); + + // then + assertThat(result).isSameAs(slice); + then(feedRepository).should().findAllByDeletedAtIsNullWithUser(pageable, List.of(2L, 3L)); + } + + @Test + @DisplayName("findAllByUser 테스트") + void findAllByUser() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Pageable pageable = PageRequest.of(0, 5); + Slice slice = new SliceImpl<>(List.of()); + + given(feedRepository.findAllByUserAndDeletedAtIsNull(user, pageable)) + .willReturn(slice); + + // when + Slice result = feedGetService.findAllByUser(user, pageable); + + // then + assertThat(result).isSameAs(slice); + then(feedRepository).should().findAllByUserAndDeletedAtIsNull(user, pageable); + } + + @Test + @DisplayName("findPrevFeedsWithHasMore 테스트") + void findPrevFeedsWithHasMore() { + // given + User user = UserTestFixture.createUser(1L, "me"); + LocalDateTime base = LocalDateTime.of(2025, 12, 22, 16, 0); + Feed current = createFeedWithCreateDate(100L, user, base); + Feed first = createFeedWithCreateDate(1L, user, base.plusMinutes(1)); + Feed second = createFeedWithCreateDate(2L, user, base.plusMinutes(2)); + Feed third = createFeedWithCreateDate(3L, user, base.plusMinutes(3)); + + given(feedRepository.findPrevFeeds(eq(base), isNull(), eq(PageRequest.of(0, 3)))) + .willReturn(new ArrayList<>(List.of(first, second, third))); + + // when + FeedNavigationResult result = feedGetService.findPrevFeedsWithHasMore(current, List.of(), 2); + + // then + assertThat(result.hasMore()).isTrue(); + assertThat(result.feeds()).containsExactly(second, first); + then(feedRepository).should().findPrevFeeds(eq(base), isNull(), eq(PageRequest.of(0, 3))); + } + + @Test + @DisplayName("findNextFeedsWithHasMore 테스트") + void findNextFeedsWithHasMore() { + // given + User user = UserTestFixture.createUser(1L, "me"); + User blocked = UserTestFixture.createUser(2L, "blocked"); + UserBlock block = UserBlock.builder().blocker(user).blocked(blocked).build(); + LocalDateTime base = LocalDateTime.of(2025, 12, 22, 16, 0); + Feed current = createFeedWithCreateDate(100L, user, base); + Feed first = createFeedWithCreateDate(1L, user, base.minusMinutes(1)); + Feed second = createFeedWithCreateDate(2L, user, base.minusMinutes(2)); + Feed third = createFeedWithCreateDate(3L, user, base.minusMinutes(3)); + + given(feedRepository.findNextFeeds(eq(base), eq(List.of(2L)), eq(PageRequest.of(0, 3)))) + .willReturn(new ArrayList<>(List.of(first, second, third))); + + // when + FeedNavigationResult result = feedGetService.findNextFeedsWithHasMore(current, List.of(block), 2); + + // then + assertThat(result.hasMore()).isTrue(); + assertThat(result.feeds()).containsExactly(first, second); + then(feedRepository).should().findNextFeeds(eq(base), eq(List.of(2L)), eq(PageRequest.of(0, 3))); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/domain/service/FeedSaveServiceTest.java b/src/test/java/leets/leenk/domain/feed/domain/service/FeedSaveServiceTest.java new file mode 100644 index 00000000..59f868c1 --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/domain/service/FeedSaveServiceTest.java @@ -0,0 +1,38 @@ +package leets.leenk.domain.feed.domain.service; + +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.domain.repository.FeedRepository; +import leets.leenk.domain.feed.test.FeedTestFixture; +import leets.leenk.domain.feed.test.UserTestFixture; +import leets.leenk.domain.user.domain.entity.User; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.mockito.BDDMockito.then; + +@ExtendWith(MockitoExtension.class) +public class FeedSaveServiceTest { + @Mock + private FeedRepository feedRepository; + + @InjectMocks + private FeedSaveService feedSaveService; + + @Test + @DisplayName("feedSave 테스트") + void feedSave() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Feed feed = FeedTestFixture.createFeed(null, user); + + // when + feedSaveService.save(feed); + + // then + then(feedRepository).should().save(feed); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/domain/service/FeedUpdateServiceTest.java b/src/test/java/leets/leenk/domain/feed/domain/service/FeedUpdateServiceTest.java new file mode 100644 index 00000000..bfcddf8e --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/domain/service/FeedUpdateServiceTest.java @@ -0,0 +1,67 @@ +package leets.leenk.domain.feed.domain.service; + +import leets.leenk.domain.feed.application.dto.request.FeedUpdateRequest; +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.domain.entity.Reaction; +import leets.leenk.domain.feed.test.FeedTestFixture; +import leets.leenk.domain.feed.test.ReactionTestFixture; +import leets.leenk.domain.feed.test.UserTestFixture; +import leets.leenk.domain.user.domain.entity.User; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class FeedUpdateServiceTest { + private final FeedUpdateService feedUpdateService = new FeedUpdateService(); + + @Test + @DisplayName("feedUpdate 테스트") + void feedUpdate1() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Feed feed = FeedTestFixture.createFeed(1L, user); + + FeedUpdateRequest request = new FeedUpdateRequest("\n\nhello\n\n\nworld", null, null); + + // when + feedUpdateService.update(feed, request); + + // then + assertThat(feed.getDescription()).isEqualTo("hello\nworld"); + } + + @Test + @DisplayName("feedUpdate 테스트 - description이 null일 때 유지") + void feedUpdate2() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Feed feed = FeedTestFixture.createFeed(1L, user); + feed.updateDescription("old"); + + FeedUpdateRequest request = new FeedUpdateRequest(null, null, null); + + // when + feedUpdateService.update(feed, request); + + // then + assertThat(feed.getDescription()).isEqualTo("old"); + } + + @Test + @DisplayName("updateTotalReaction 테스트") + void updateTotalReaction() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Feed feed = FeedTestFixture.createFeed(1L, user); + Reaction reaction = ReactionTestFixture.createReaction(feed, user, 2L); + + // when + feedUpdateService.updateTotalReaction(feed, reaction, user, 3L); + + // then + assertThat(feed.getTotalReactionCount()).isEqualTo(3L); + assertThat(reaction.getReactionCount()).isEqualTo(5L); + assertThat(user.getTotalReactionCount()).isEqualTo(3L); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserDeleteServiceTest.java b/src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserDeleteServiceTest.java new file mode 100644 index 00000000..d875159e --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserDeleteServiceTest.java @@ -0,0 +1,39 @@ +package leets.leenk.domain.feed.domain.service; + +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.domain.repository.LinkedUserRepository; +import leets.leenk.domain.feed.test.FeedTestFixture; +import leets.leenk.domain.feed.test.UserTestFixture; +import leets.leenk.domain.user.domain.entity.User; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.mockito.BDDMockito.then; + +@ExtendWith(MockitoExtension.class) +public class LinkedUserDeleteServiceTest { + @Mock + private LinkedUserRepository linkedUserRepository; + + @InjectMocks + private LinkedUserDeleteService linkedUserDeleteService; + + @Test + @DisplayName("deleteAllByFeed 테스트") + void deleteAllByFeed() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Feed feed = FeedTestFixture.createFeed(1L, user); + + // when + linkedUserDeleteService.deleteAllByFeed(feed); + + // then + then(linkedUserRepository).should().deleteAllByFeed(feed); + then(linkedUserRepository).should().flush(); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserGetServiceTest.java b/src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserGetServiceTest.java new file mode 100644 index 00000000..634c739f --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserGetServiceTest.java @@ -0,0 +1,72 @@ +package leets.leenk.domain.feed.domain.service; + +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.domain.entity.LinkedUser; +import leets.leenk.domain.feed.domain.repository.LinkedUserRepository; +import leets.leenk.domain.feed.test.FeedTestFixture; +import leets.leenk.domain.feed.test.LinkedUserTestFixture; +import leets.leenk.domain.feed.test.UserTestFixture; +import leets.leenk.domain.user.domain.entity.User; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.data.domain.SliceImpl; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; + +@ExtendWith(MockitoExtension.class) +public class LinkedUserGetServiceTest { + @Mock + private LinkedUserRepository linkedUserRepository; + + @InjectMocks + private LinkedUserGetService linkedUserGetService; + + @Test + @DisplayName("findAll 테스트") + void findAll() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Feed feed = FeedTestFixture.createFeed(1L, user); + LinkedUser linkedUser = LinkedUserTestFixture.createLinkedUser(1L, user, feed); + List linkedUsers = List.of(linkedUser); + + given(linkedUserRepository.findAllByFeed(feed)).willReturn(linkedUsers); + + // when + List result = linkedUserGetService.findAll(feed); + + // then + assertThat(result).isSameAs(linkedUsers); + then(linkedUserRepository).should().findAllByFeed(feed); + } + + @Test + @DisplayName("findAllByUser 테스트") + void findAllByUser() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Pageable pageable = PageRequest.of(0, 5); + Slice slice = new SliceImpl<>(List.of()); + + given(linkedUserRepository.findFeedsByLinkedUser(user, pageable)) + .willReturn(slice); + + // when + Slice result = linkedUserGetService.findAllByUser(user, pageable); + + // then + assertThat(result).isSameAs(slice); + then(linkedUserRepository).should().findFeedsByLinkedUser(user, pageable); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserSaveServiceTest.java b/src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserSaveServiceTest.java new file mode 100644 index 00000000..f9a69a09 --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/domain/service/LinkedUserSaveServiceTest.java @@ -0,0 +1,59 @@ +package leets.leenk.domain.feed.domain.service; + +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.domain.entity.LinkedUser; +import leets.leenk.domain.feed.domain.repository.LinkedUserRepository; +import leets.leenk.domain.feed.test.FeedTestFixture; +import leets.leenk.domain.feed.test.LinkedUserTestFixture; +import leets.leenk.domain.feed.test.UserTestFixture; +import leets.leenk.domain.user.domain.entity.User; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; + +import static org.mockito.BDDMockito.then; + +@ExtendWith(MockitoExtension.class) +public class LinkedUserSaveServiceTest { + @Mock + private LinkedUserRepository linkedUserRepository; + + @InjectMocks + private LinkedUserSaveService linkedUserSaveService; + + @Test + @DisplayName("linkedUserSave 테스트") + void linkedUserSave() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Feed feed = FeedTestFixture.createFeed(1L, user); + LinkedUser linkedUser = LinkedUserTestFixture.createLinkedUser(null, user, feed); + + // when + linkedUserSaveService.save(linkedUser); + + // then + then(linkedUserRepository).should().save(linkedUser); + } + + @Test + @DisplayName("saveAll 테스트") + void saveAll() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Feed feed = FeedTestFixture.createFeed(1L, user); + LinkedUser linkedUser = LinkedUserTestFixture.createLinkedUser(null, user, feed); + List linkedUsers = List.of(linkedUser); + + // when + linkedUserSaveService.saveAll(linkedUsers); + + // then + then(linkedUserRepository).should().saveAll(linkedUsers); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/domain/service/ReactionGetServiceTest.java b/src/test/java/leets/leenk/domain/feed/domain/service/ReactionGetServiceTest.java new file mode 100644 index 00000000..9187c15e --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/domain/service/ReactionGetServiceTest.java @@ -0,0 +1,69 @@ +package leets.leenk.domain.feed.domain.service; + +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.domain.entity.Reaction; +import leets.leenk.domain.feed.domain.repository.ReactionRepository; +import leets.leenk.domain.feed.test.FeedTestFixture; +import leets.leenk.domain.feed.test.ReactionTestFixture; +import leets.leenk.domain.feed.test.UserTestFixture; +import leets.leenk.domain.user.domain.entity.User; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; + +@ExtendWith(MockitoExtension.class) +public class ReactionGetServiceTest { + @Mock + private ReactionRepository reactionRepository; + + @InjectMocks + private ReactionGetService reactionGetService; + + @Test + @DisplayName("findByFeedAndUser 테스트") + void findByFeedAndUser() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Feed feed = FeedTestFixture.createFeed(1L, user); + Reaction reaction = ReactionTestFixture.createReaction(feed, user, 1L); + + given(reactionRepository.findByFeedAndUser(feed, user)) + .willReturn(Optional.of(reaction)); + + // when + Optional result = reactionGetService.findByFeedAndUser(feed, user); + + // then + assertThat(result).containsSame(reaction); + then(reactionRepository).should().findByFeedAndUser(feed, user); + } + + @Test + @DisplayName("findAll 테스트") + void findAll() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Feed feed = FeedTestFixture.createFeed(1L, user); + Reaction reaction = ReactionTestFixture.createReaction(feed, user, 2L); + List reactions = List.of(reaction); + + given(reactionRepository.findAllByFeed(feed)).willReturn(reactions); + + // when + List result = reactionGetService.findAll(feed); + + // then + assertThat(result).isSameAs(reactions); + then(reactionRepository).should().findAllByFeed(feed); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/domain/service/ReactionSaveServiceTest.java b/src/test/java/leets/leenk/domain/feed/domain/service/ReactionSaveServiceTest.java new file mode 100644 index 00000000..f07d42a0 --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/domain/service/ReactionSaveServiceTest.java @@ -0,0 +1,46 @@ +package leets.leenk.domain.feed.domain.service; + +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.domain.entity.Reaction; +import leets.leenk.domain.feed.domain.repository.ReactionRepository; +import leets.leenk.domain.feed.test.FeedTestFixture; +import leets.leenk.domain.feed.test.ReactionTestFixture; +import leets.leenk.domain.feed.test.UserTestFixture; +import leets.leenk.domain.user.domain.entity.User; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; + +@ExtendWith(MockitoExtension.class) +public class ReactionSaveServiceTest { + @Mock + private ReactionRepository reactionRepository; + + @InjectMocks + private ReactionSaveService reactionSaveService; + + @Test + @DisplayName("reactionSave 테스트") + void reactionSave() { + // given + User user = UserTestFixture.createUser(1L, "me"); + Feed feed = FeedTestFixture.createFeed(1L, user); + Reaction reaction = ReactionTestFixture.createReaction(feed, user, 1L); + + given(reactionRepository.save(reaction)).willReturn(reaction); + + // when + Reaction result = reactionSaveService.save(reaction); + + // then + assertThat(result).isSameAs(reaction); + then(reactionRepository).should().save(reaction); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/test/CommentTestFixture.java b/src/test/java/leets/leenk/domain/feed/test/CommentTestFixture.java new file mode 100644 index 00000000..d0480554 --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/test/CommentTestFixture.java @@ -0,0 +1,16 @@ +package leets.leenk.domain.feed.test; + +import leets.leenk.domain.feed.domain.entity.Comment; +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.user.domain.entity.User; + +public class CommentTestFixture { + public static Comment createComment(Long id, User user, Feed feed, String text) { + return Comment.builder() + .commentId(id) + .user(user) + .feed(feed) + .comment(text) + .build(); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java b/src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java new file mode 100644 index 00000000..4170ceff --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/test/FeedTestFixture.java @@ -0,0 +1,27 @@ +package leets.leenk.domain.feed.test; + +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.user.domain.entity.User; + +import java.time.LocalDateTime; + +public class FeedTestFixture { + public static Feed createFeed(Long id, User author) { + return Feed.builder() + .id(id) + .user(author) + .description("desc") + .totalReactionCount(0L) + .build(); + } + + public static Feed createFeedWithCreateDate(Long id, User user, LocalDateTime createDate) { + return Feed.builder() + .id(id) + .user(user) + .description("desc") + .totalReactionCount(0L) + .createDate(createDate) + .build(); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/test/LinkedUserTestFixture.java b/src/test/java/leets/leenk/domain/feed/test/LinkedUserTestFixture.java new file mode 100644 index 00000000..cf3bbef5 --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/test/LinkedUserTestFixture.java @@ -0,0 +1,15 @@ +package leets.leenk.domain.feed.test; + +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.domain.entity.LinkedUser; +import leets.leenk.domain.user.domain.entity.User; + +public class LinkedUserTestFixture { + public static LinkedUser createLinkedUser(Long id, User user, Feed feed) { + return LinkedUser.builder() + .id(id) + .feed(feed) + .user(user) + .build(); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/test/MediaTestFixture.java b/src/test/java/leets/leenk/domain/feed/test/MediaTestFixture.java new file mode 100644 index 00000000..b71261b2 --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/test/MediaTestFixture.java @@ -0,0 +1,18 @@ +package leets.leenk.domain.feed.test; + +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.media.domain.entity.Media; +import leets.leenk.domain.media.domain.entity.enums.MediaType; + +public class MediaTestFixture { + public static Media createMedia(Long id, Feed feed) { + return Media.builder() + .id(id) + .feed(feed) + .mediaUrl("https://example.com/media.jpg") + .thumbnailUrl("https://example.com/media.jpg") + .mediaType(MediaType.IMAGE) + .position(1) + .build(); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/test/ReactionTestFixture.java b/src/test/java/leets/leenk/domain/feed/test/ReactionTestFixture.java new file mode 100644 index 00000000..43fec97a --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/test/ReactionTestFixture.java @@ -0,0 +1,15 @@ +package leets.leenk.domain.feed.test; + +import leets.leenk.domain.feed.domain.entity.Feed; +import leets.leenk.domain.feed.domain.entity.Reaction; +import leets.leenk.domain.user.domain.entity.User; + +public class ReactionTestFixture { + public static Reaction createReaction(Feed feed, User user, long count) { + return Reaction.builder() + .feed(feed) + .user(user) + .reactionCount(count) + .build(); + } +} diff --git a/src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java b/src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java new file mode 100644 index 00000000..2c4e2eb9 --- /dev/null +++ b/src/test/java/leets/leenk/domain/feed/test/UserTestFixture.java @@ -0,0 +1,14 @@ +package leets.leenk.domain.feed.test; + +import leets.leenk.domain.user.domain.entity.User; + +public class UserTestFixture { + public static User createUser(Long id, String name) { + return User.builder() + .id(id) + .name(name) + .cardinal(1) + .totalReactionCount(0L) + .build(); + } +} diff --git a/src/test/resources/application-test.yml b/src/test/resources/application-test.yml new file mode 100644 index 00000000..f613e859 --- /dev/null +++ b/src/test/resources/application-test.yml @@ -0,0 +1,9 @@ +spring: + jpa: + hibernate: + ddl-auto: create-drop + show-sql: true + properties: + hibernate: + format_sql: true + dialect: org.hibernate.dialect.MySQL8Dialect \ No newline at end of file