diff --git a/backend/src/main/java/moadong/club/entity/Club.java b/backend/src/main/java/moadong/club/entity/Club.java index c9df6fd1f..df0f6e146 100644 --- a/backend/src/main/java/moadong/club/entity/Club.java +++ b/backend/src/main/java/moadong/club/entity/Club.java @@ -1,14 +1,11 @@ package moadong.club.entity; -import java.time.format.DateTimeFormatter; import java.util.List; -import java.util.Locale; import java.util.Map; import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.FirebaseMessagingException; import com.google.firebase.messaging.Message; -import com.google.firebase.messaging.Notification; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -51,7 +48,6 @@ public class Club implements Persistable { @Version private Long version; - public Club() { this.name = ""; this.category = ""; diff --git a/backend/src/main/java/moadong/club/entity/ClubRecruitmentInformation.java b/backend/src/main/java/moadong/club/entity/ClubRecruitmentInformation.java index 9de02b81b..777144393 100644 --- a/backend/src/main/java/moadong/club/entity/ClubRecruitmentInformation.java +++ b/backend/src/main/java/moadong/club/entity/ClubRecruitmentInformation.java @@ -13,6 +13,7 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; +import lombok.Setter; import moadong.club.enums.ClubRecruitmentStatus; import moadong.club.payload.request.ClubInfoRequest; import moadong.club.payload.request.ClubRecruitmentInfoUpdateRequest; @@ -66,6 +67,8 @@ public class ClubRecruitmentInformation { @NotNull private ClubRecruitmentStatus clubRecruitmentStatus; + private LocalDateTime lastModifiedDate; + public void updateLogo(String logo) { this.logo = logo; } @@ -121,4 +124,12 @@ public void update(ClubInfoRequest request) { public void updateCover(String cover) { this.cover = cover; } + + private void setLastModifiedDate(LocalDateTime lastModifiedDate) { + this.lastModifiedDate = lastModifiedDate; + } + + public void updateLastModifiedDate() { + setLastModifiedDate(LocalDateTime.now()); + } } diff --git a/backend/src/main/java/moadong/club/payload/dto/ClubDetailedResult.java b/backend/src/main/java/moadong/club/payload/dto/ClubDetailedResult.java index 37802ac40..58e224e12 100644 --- a/backend/src/main/java/moadong/club/payload/dto/ClubDetailedResult.java +++ b/backend/src/main/java/moadong/club/payload/dto/ClubDetailedResult.java @@ -29,6 +29,7 @@ public record ClubDetailedResult( String category, String division, List faqs, + String lastModifiedDate, List recommendClubs ) { @@ -40,6 +41,12 @@ public static ClubDetailedResult of(Club club, List recommendC period = clubRecruitmentInformation.getRecruitmentStart().format(formatter) + " ~ " + clubRecruitmentInformation.getRecruitmentEnd().format(formatter); } + + String lastModifiedDate = ""; + if (club.getClubRecruitmentInformation().getLastModifiedDate() != null) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm"); + lastModifiedDate = club.getClubRecruitmentInformation().getLastModifiedDate().format(formatter); + } return ClubDetailedResult.builder() .id(club.getId() == null ? "" : club.getId()) .name(club.getName() == null ? "" : club.getName()) @@ -74,6 +81,7 @@ public static ClubDetailedResult of(Club club, List recommendC : club.getSocialLinks()) .faqs(club.getClubRecruitmentInformation().getFaqs() == null ? List.of() : club.getClubRecruitmentInformation().getFaqs()) + .lastModifiedDate(lastModifiedDate) .recommendClubs(recommendClubs) .build(); } diff --git a/backend/src/main/java/moadong/club/service/ClubProfileService.java b/backend/src/main/java/moadong/club/service/ClubProfileService.java index 4759a5566..4f8c6c6ca 100644 --- a/backend/src/main/java/moadong/club/service/ClubProfileService.java +++ b/backend/src/main/java/moadong/club/service/ClubProfileService.java @@ -1,5 +1,6 @@ package moadong.club.service; +import java.time.LocalDateTime; import java.util.List; import lombok.AllArgsConstructor; import moadong.club.entity.Club; @@ -44,6 +45,7 @@ public void updateClubRecruitmentInfo(ClubRecruitmentInfoUpdateRequest request, club.getClubRecruitmentInformation().getRecruitmentStart(), club.getClubRecruitmentInformation().getRecruitmentEnd() ); + club.getClubRecruitmentInformation().updateLastModifiedDate(); clubRepository.save(club); } diff --git a/backend/src/test/java/moadong/club/service/ClubProfileServiceDateTest.java b/backend/src/test/java/moadong/club/service/ClubProfileServiceDateTest.java new file mode 100644 index 000000000..5650b77bd --- /dev/null +++ b/backend/src/test/java/moadong/club/service/ClubProfileServiceDateTest.java @@ -0,0 +1,75 @@ +package moadong.club.service; + +import moadong.club.entity.Club; +import moadong.club.payload.request.ClubRecruitmentInfoUpdateRequest; +import moadong.club.repository.ClubRepository; +import moadong.club.repository.ClubSearchRepository; +import moadong.club.util.RecruitmentStateCalculator; +import moadong.fixture.ClubRequestFixture; +import moadong.fixture.UserFixture; +import moadong.user.payload.CustomUserDetails; +import moadong.util.annotations.UnitTest; +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.Mockito; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; + + +import java.time.LocalDateTime; +import java.util.Optional; + + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +@UnitTest +public class ClubProfileServiceDateTest { + + @InjectMocks + ClubProfileService clubProfileService; + + @Mock + ClubRepository clubRepository; + + @Mock + ClubSearchRepository clubSearchRepository; + + @DisplayName("모집글 수정 시 최근 업데이트 일자를 보여준다") + @Test + void 모집글_수정_시_최근_업데이트_일자를_보여줘야한다(){ + //GIVEN + ClubRecruitmentInfoUpdateRequest request = ClubRequestFixture.defaultRequest(); + CustomUserDetails customUserDetails = UserFixture.createUserDetails("test"); + Club club = new Club(); + when(clubRepository.findClubByUserId(any())).thenReturn(Optional.of(club)); + //updateClubRecruitmentInfo의 RecruitmentStateCalculator 무시 + try (var mocked = Mockito.mockStatic(RecruitmentStateCalculator.class)) { + mocked.when(() -> + RecruitmentStateCalculator.calculate( + Mockito.any(moadong.club.entity.Club.class), + Mockito.any(java.time.ZonedDateTime.class), + Mockito.any(java.time.ZonedDateTime.class) + ) + ).thenAnswer(inv -> null); + + //WHEN + clubProfileService.updateClubRecruitmentInfo(request, customUserDetails); + + //THEN + assertNotNull(club.getClubRecruitmentInformation().getLastModifiedDate()); + //1초 전후 차이로 살펴보기 + LocalDateTime now = LocalDateTime.now(); + assertTrue(club.getClubRecruitmentInformation(). + getLastModifiedDate().isAfter(now.minusSeconds(1))); + assertTrue(club.getClubRecruitmentInformation(). + getLastModifiedDate().isBefore(now.plusSeconds(1))); + } + } +} diff --git a/backend/src/test/java/moadong/fixture/ClubRequestFixture.java b/backend/src/test/java/moadong/fixture/ClubRequestFixture.java index 8d5feef1a..9021fb550 100644 --- a/backend/src/test/java/moadong/fixture/ClubRequestFixture.java +++ b/backend/src/test/java/moadong/fixture/ClubRequestFixture.java @@ -3,7 +3,9 @@ import moadong.club.enums.ClubCategory; import moadong.club.enums.ClubDivision; import moadong.club.payload.request.ClubInfoRequest; +import moadong.club.payload.request.ClubRecruitmentInfoUpdateRequest; +import java.time.LocalDateTime; import java.util.List; import java.util.Map; @@ -21,6 +23,17 @@ public static ClubInfoRequest createValidClubInfoRequest() { ); } + + public static ClubRecruitmentInfoUpdateRequest defaultRequest() { + return new ClubRecruitmentInfoUpdateRequest( + LocalDateTime.now(), + LocalDateTime.now().plusDays(7), + "테스트 대상", + "테스트 설명", + "https://fake-url.com", + List.of() + ); + } //ToDo: 시간 계산법을 LocalDateTime에서 Instant로 변경 후에 활성화할 것 // public static ClubRecruitmentInfoUpdateRequest createValidRequest() { // return new ClubRecruitmentInfoUpdateRequest(