diff --git a/src/main/java/com/projectlyrics/server/domain/banner/domain/Banner.java b/src/main/java/com/projectlyrics/server/domain/banner/domain/Banner.java index 15fb339f..6120c1f0 100644 --- a/src/main/java/com/projectlyrics/server/domain/banner/domain/Banner.java +++ b/src/main/java/com/projectlyrics/server/domain/banner/domain/Banner.java @@ -12,6 +12,7 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; @Getter @Entity @@ -26,15 +27,19 @@ public class Banner extends BaseEntity { private String imageUrl; private String redirectUrl; + @Setter + private LocalDateTime startDate; private LocalDateTime dueDate; private Banner( String imageUrl, String redirectUrl, + LocalDateTime startDate, LocalDateTime dueDate ) { this.imageUrl = imageUrl; this.redirectUrl = redirectUrl; + this.startDate = startDate; this.dueDate = dueDate; } @@ -42,6 +47,7 @@ public static Banner create(BannerCreate bannerCreate) { return new Banner( bannerCreate.imageUrl(), bannerCreate.redirectUrl(), + bannerCreate.startDate(), bannerCreate.dueDate() ); } @@ -51,6 +57,7 @@ public static Banner createWithId(Long id, BannerCreate bannerCreate) { id, bannerCreate.imageUrl(), bannerCreate.redirectUrl(), + bannerCreate.startDate(), bannerCreate.dueDate() ); } diff --git a/src/main/java/com/projectlyrics/server/domain/banner/domain/BannerCreate.java b/src/main/java/com/projectlyrics/server/domain/banner/domain/BannerCreate.java index 6e87ad9d..eff2b2b9 100644 --- a/src/main/java/com/projectlyrics/server/domain/banner/domain/BannerCreate.java +++ b/src/main/java/com/projectlyrics/server/domain/banner/domain/BannerCreate.java @@ -6,12 +6,14 @@ public record BannerCreate( String imageUrl, String redirectUrl, + LocalDateTime startDate, LocalDateTime dueDate ) { public static BannerCreate of(BannerCreateRequest request) { return new BannerCreate( request.imageUrl(), request.redirectUrl(), + request.startDate() == null ? null: request.startDate().atStartOfDay(), request.dueDate() == null ? null: request.dueDate().atStartOfDay() ); } diff --git a/src/main/java/com/projectlyrics/server/domain/banner/dto/request/BannerCreateRequest.java b/src/main/java/com/projectlyrics/server/domain/banner/dto/request/BannerCreateRequest.java index ce548784..7e889902 100644 --- a/src/main/java/com/projectlyrics/server/domain/banner/dto/request/BannerCreateRequest.java +++ b/src/main/java/com/projectlyrics/server/domain/banner/dto/request/BannerCreateRequest.java @@ -7,6 +7,11 @@ public record BannerCreateRequest( String imageUrl, String redirectUrl, @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "Asia/Seoul") - LocalDate dueDate + LocalDate startDate, + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "Asia/Seoul") + LocalDate dueDate, + boolean hideOther, + Long hiddenBannerId + ) { } diff --git a/src/main/java/com/projectlyrics/server/domain/banner/repository/impl/QueryDslBannerQueryRepository.java b/src/main/java/com/projectlyrics/server/domain/banner/repository/impl/QueryDslBannerQueryRepository.java index 130aae97..d9e723b0 100644 --- a/src/main/java/com/projectlyrics/server/domain/banner/repository/impl/QueryDslBannerQueryRepository.java +++ b/src/main/java/com/projectlyrics/server/domain/banner/repository/impl/QueryDslBannerQueryRepository.java @@ -20,7 +20,7 @@ public class QueryDslBannerQueryRepository implements BannerQueryRepository { @Override public Banner findById(Long id) { - return Optional.of( + return Optional.ofNullable( jpaQueryFactory .selectFrom(banner) .where(banner.id.eq(id), @@ -34,6 +34,7 @@ public List findRecentBanners(int size) { return jpaQueryFactory .selectFrom(banner) .where( + banner.startDate.isNull().or(banner.startDate.before(LocalDateTime.now())), banner.dueDate.isNull().or(banner.dueDate.after(LocalDateTime.now())), banner.deletedAt.isNull() ) diff --git a/src/main/java/com/projectlyrics/server/domain/banner/service/BannerCommandService.java b/src/main/java/com/projectlyrics/server/domain/banner/service/BannerCommandService.java index 5370c960..ce1ae15d 100644 --- a/src/main/java/com/projectlyrics/server/domain/banner/service/BannerCommandService.java +++ b/src/main/java/com/projectlyrics/server/domain/banner/service/BannerCommandService.java @@ -4,7 +4,9 @@ import com.projectlyrics.server.domain.banner.domain.BannerCreate; import com.projectlyrics.server.domain.banner.dto.request.BannerCreateRequest; import com.projectlyrics.server.domain.banner.repository.BannerCommandRepository; +import com.projectlyrics.server.domain.banner.repository.BannerQueryRepository; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -13,9 +15,18 @@ @RequiredArgsConstructor public class BannerCommandService { + private final BannerQueryRepository bannerQueryRepository; private final BannerCommandRepository bannerCommandRepository; + @Value("${default_banner_id}") + private Long defaultBannerId; + public Banner create(BannerCreateRequest request) { + if (request.hideOther()) { + Long hiddenBannerId = request.hiddenBannerId() == null ? defaultBannerId : request.hiddenBannerId(); + Banner hiddenBanner = bannerQueryRepository.findById(hiddenBannerId); + hiddenBanner.setStartDate(request.dueDate() == null ? null : request.dueDate().atStartOfDay()); + } return bannerCommandRepository.save(Banner.create(BannerCreate.of(request))); } } diff --git a/src/test/java/com/projectlyrics/server/domain/banner/api/BannerControllerTest.java b/src/test/java/com/projectlyrics/server/domain/banner/api/BannerControllerTest.java index c7798f1f..968d35ec 100644 --- a/src/test/java/com/projectlyrics/server/domain/banner/api/BannerControllerTest.java +++ b/src/test/java/com/projectlyrics/server/domain/banner/api/BannerControllerTest.java @@ -32,7 +32,10 @@ public class BannerControllerTest extends RestDocsTest { BannerCreateRequest request = new BannerCreateRequest( "imageUrl", "redirectUrl", - LocalDate.now() + LocalDate.now(), + LocalDate.now(), + false, + null ); // when, then @@ -55,8 +58,16 @@ private RestDocumentationResultHandler getCreateBannerDocument() { .description("이미지 URL"), fieldWithPath("redirectUrl").type(JsonFieldType.STRING) .description("리다이렉트 URL"), + fieldWithPath("startDate").type(JsonFieldType.STRING) + .description("배너 노출 시작일") + .optional(), fieldWithPath("dueDate").type(JsonFieldType.STRING) .description("배너 노출 마감일") + .optional(), + fieldWithPath("hideOther").type(JsonFieldType.BOOLEAN) + .description("다른 배너를 가릴지 여부"), + fieldWithPath("hiddenBannerId").type(JsonFieldType.NUMBER) + .description("가릴 배너 Id (hideOther가 true일 때만 필요. 또한 입력하지 않을시 yml값 적용됨)") .optional() ) .requestSchema(Schema.schema("Create Banner Request")) diff --git a/src/test/java/com/projectlyrics/server/domain/banner/service/BannerCommandServiceTest.java b/src/test/java/com/projectlyrics/server/domain/banner/service/BannerCommandServiceTest.java index f63baf85..740d19e3 100644 --- a/src/test/java/com/projectlyrics/server/domain/banner/service/BannerCommandServiceTest.java +++ b/src/test/java/com/projectlyrics/server/domain/banner/service/BannerCommandServiceTest.java @@ -26,7 +26,7 @@ public class BannerCommandServiceTest extends IntegrationTest { @Test void 배너를_발행해야_한다() { // given - BannerCreateRequest request = new BannerCreateRequest("imageUrl", "redirectUrl", LocalDate.now()); + BannerCreateRequest request = new BannerCreateRequest("imageUrl", "redirectUrl", LocalDate.now(), LocalDate.now(), false, null); // when Banner banner = sut.create(request); @@ -36,6 +36,58 @@ public class BannerCommandServiceTest extends IntegrationTest { assertAll( () -> assertThat(result.getImageUrl()).isEqualTo(request.imageUrl()), () -> assertThat(result.getRedirectUrl()).isEqualTo(request.redirectUrl()), + () -> assertThat(result.getStartDate()).isEqualTo(request.startDate().atStartOfDay()), + () -> assertThat(result.getDueDate()).isEqualTo(request.dueDate().atStartOfDay()) + ); + } + + @Test + void 배너_발행시_필요에_따라_다른_배너의_startDate를_바꿀_수_있어야_한다() { + // given + Banner hiddenBanner = sut.create(new BannerCreateRequest("imageUrl", "redirectUrl", LocalDate.now().minusDays(2), LocalDate.now(), false, null)); + BannerCreateRequest request = new BannerCreateRequest("imageUrl", "redirectUrl", LocalDate.now(), LocalDate.now().plusDays(1), true, hiddenBanner.getId()); + + // when + sut.create(request); + + // then + Banner result = bannerQueryRepository.findById(hiddenBanner.getId()); + assertAll( + () -> assertThat(result.getStartDate()).isEqualTo(request.dueDate().atStartOfDay()) + ); + } + + @Test + void 배너_발행시_hiddenBannerId가_주어지지_않으면_기본_배너의_startDate를_변경해야_한다() { + // given + // yml에 기본 배너의 id 1로 지정 + sut.create(new BannerCreateRequest("imageUrl", "redirectUrl", LocalDate.now().minusDays(2), LocalDate.now(), false, null)); + BannerCreateRequest request = new BannerCreateRequest("imageUrl", "redirectUrl", LocalDate.now(), LocalDate.now().plusDays(1), true, null); + + // when + sut.create(request); + + // then + Banner result = bannerQueryRepository.findById(1L); + assertAll( + () -> assertThat(result.getStartDate()).isEqualTo(request.dueDate().atStartOfDay()) + ); + } + + @Test + void 시작일자_없이도_배너를_발행해야_한다() { + // given + BannerCreateRequest request = new BannerCreateRequest("imageUrl", "redirectUrl", null, LocalDate.now(), false, null); + + // when + Banner banner = sut.create(request); + + // then + Banner result = bannerQueryRepository.findById(banner.getId()); + assertAll( + () -> assertThat(result.getImageUrl()).isEqualTo(request.imageUrl()), + () -> assertThat(result.getRedirectUrl()).isEqualTo(request.redirectUrl()), + () -> assertThat(result.getStartDate()).isNull(), () -> assertThat(result.getDueDate()).isEqualTo(request.dueDate().atStartOfDay()) ); } @@ -43,7 +95,7 @@ public class BannerCommandServiceTest extends IntegrationTest { @Test void 마감일자_없이도_배너를_발행해야_한다() { // given - BannerCreateRequest request = new BannerCreateRequest("imageUrl", "redirectUrl", null); + BannerCreateRequest request = new BannerCreateRequest("imageUrl", "redirectUrl", LocalDate.now(), null, false, null); // when Banner banner = sut.create(request); @@ -53,6 +105,7 @@ public class BannerCommandServiceTest extends IntegrationTest { assertAll( () -> assertThat(result.getImageUrl()).isEqualTo(request.imageUrl()), () -> assertThat(result.getRedirectUrl()).isEqualTo(request.redirectUrl()), + () -> assertThat(result.getStartDate()).isEqualTo(request.startDate().atStartOfDay()), () -> assertThat(result.getDueDate()).isNull() ); } diff --git a/src/test/java/com/projectlyrics/server/domain/banner/service/BannerQueryServiceTest.java b/src/test/java/com/projectlyrics/server/domain/banner/service/BannerQueryServiceTest.java index 59f132be..19cc9c0f 100644 --- a/src/test/java/com/projectlyrics/server/domain/banner/service/BannerQueryServiceTest.java +++ b/src/test/java/com/projectlyrics/server/domain/banner/service/BannerQueryServiceTest.java @@ -9,10 +9,8 @@ import com.projectlyrics.server.domain.banner.dto.response.BannerGetResponse; import com.projectlyrics.server.domain.banner.repository.BannerCommandRepository; import com.projectlyrics.server.domain.banner.repository.BannerQueryRepository; -import com.projectlyrics.server.domain.user.entity.User; import com.projectlyrics.server.domain.user.repository.UserCommandRepository; import com.projectlyrics.server.support.IntegrationTest; -import com.projectlyrics.server.support.fixture.UserFixture; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; @@ -34,28 +32,43 @@ public class BannerQueryServiceTest extends IntegrationTest { @Autowired BannerQueryService sut; - private User user; - private BannerCreateRequest activeBannerCreateRequest; private BannerCreateRequest expiredBannerCreateRequest; + private BannerCreateRequest upcomingBannerCreateRequest; private BannerCreateRequest bannerCreateRequest; @BeforeEach void setUp() { - user = userCommandRepository.save(UserFixture.create()); activeBannerCreateRequest = new BannerCreateRequest( "imageUrl", "redirectUrl", - LocalDate.now().plusDays(1) + LocalDate.now(), + LocalDate.now().plusDays(1), + false, + null ); expiredBannerCreateRequest = new BannerCreateRequest( "imageUrl", "redirectUrl", - LocalDate.now().minusDays(1) + LocalDate.now().minusDays(2), + LocalDate.now().minusDays(1), + false, + null ); - bannerCreateRequest = new BannerCreateRequest( + upcomingBannerCreateRequest = new BannerCreateRequest( "imageUrl", "redirectUrl", + LocalDate.now().plusDays(1), + LocalDate.now().plusDays(2), + false, + null + ); + bannerCreateRequest = new BannerCreateRequest( + "imageUrl", + "redirectUrl", + null, + null, + false, null ); } @@ -105,7 +118,7 @@ void setUp() { } @Test - void 배너_리스트_조회시_마감기한이_이미_지난_배너는_제외해야_한다() { + void 배너_리스트_조회시_시작기한이_남았거나_마감기한이_이미_지난_배너는_제외해야_한다() { // given List banners = new ArrayList<>(); for (int i=0; i<3; i++) { @@ -117,6 +130,9 @@ void setUp() { for (int i=0; i<5; i++) { banners.add(bannerCommandRepository.save(Banner.create(BannerCreate.of(expiredBannerCreateRequest)))); } + for (int i=0; i<3; i++) { + banners.add(bannerCommandRepository.save(Banner.create(BannerCreate.of(upcomingBannerCreateRequest)))); + } // when List result = sut.getRecentBanners(10); diff --git a/src/test/java/com/projectlyrics/server/support/fixture/BannerFixture.java b/src/test/java/com/projectlyrics/server/support/fixture/BannerFixture.java index a7e6e103..4fb21098 100644 --- a/src/test/java/com/projectlyrics/server/support/fixture/BannerFixture.java +++ b/src/test/java/com/projectlyrics/server/support/fixture/BannerFixture.java @@ -17,6 +17,7 @@ public static Banner create() { new BannerCreate( "imageUrl", "redirectUrl", + LocalDate.now().minusDays(1).atTime(23, 59, 59), LocalDate.now().plusDays(1).atTime(23, 59, 59) ) ); diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index 9a55c1e9..db34d3e1 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -35,6 +35,8 @@ admin: 1 version: 0.0.1 +default_banner_id : 1 + search: api: host: host