From 8c743af094b5ef9cc7d6b767985b218c812b39b9 Mon Sep 17 00:00:00 2001 From: dnjswldnd-3513 Date: Fri, 18 Sep 2026 09:12:16 +0900 Subject: [PATCH 1/4] =?UTF-8?q?fix:=20=ED=95=99=EA=B8=B0=20=EC=A0=84?= =?UTF-8?q?=ED=99=98=20=EC=8B=9C=20=EB=A7=A4=EC=9E=A5=20=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=97=86=EC=9C=BC=EB=A9=B4=20=EC=A0=84=ED=99=98=20?= =?UTF-8?q?=EB=B3=B4=EB=A5=98=ED=95=98=EB=8F=84=EB=A1=9D=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coopshop/service/CoopShopService.java | 3 +- .../fixture/CoopShopAcceptanceFixture.java | 11 ++ .../domain/coopshop/CoopShopServiceTest.java | 109 ++++++++++++++++++ 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 src/test/java/in/koreatech/koin/unit/domain/coopshop/CoopShopServiceTest.java diff --git a/src/main/java/in/koreatech/koin/domain/coopshop/service/CoopShopService.java b/src/main/java/in/koreatech/koin/domain/coopshop/service/CoopShopService.java index 4595779775..6aafc7bafc 100644 --- a/src/main/java/in/koreatech/koin/domain/coopshop/service/CoopShopService.java +++ b/src/main/java/in/koreatech/koin/domain/coopshop/service/CoopShopService.java @@ -113,6 +113,7 @@ public void updateSemester() { public boolean validateSemester(CoopSemester coopSemester) { LocalDate today = LocalDate.now(clock); - return today.isAfter(coopSemester.getFromDate()) && today.isBefore(coopSemester.getToDate()); + return today.isAfter(coopSemester.getFromDate()) && today.isBefore(coopSemester.getToDate()) + && !coopSemester.getCoopShops().isEmpty(); } } diff --git a/src/test/java/in/koreatech/koin/acceptance/fixture/CoopShopAcceptanceFixture.java b/src/test/java/in/koreatech/koin/acceptance/fixture/CoopShopAcceptanceFixture.java index a5bf2bec06..84381b340c 100644 --- a/src/test/java/in/koreatech/koin/acceptance/fixture/CoopShopAcceptanceFixture.java +++ b/src/test/java/in/koreatech/koin/acceptance/fixture/CoopShopAcceptanceFixture.java @@ -177,6 +177,17 @@ public CoopShopAcceptanceFixture( return coopSemesterRepository.save(coopSemester); } + public CoopSemester _24_1학기_매장없음() { + var coopSemester = coopSemesterRepository.save( + CoopSemester.builder() + .semester("24-1학기") + .fromDate(LocalDate.of(2023, 12, 21)) + .toDate(LocalDate.of(2024, 2, 28)) + .build() + ); + return coopSemesterRepository.save(coopSemester); + } + public CoopName 학생식당() { return coopNameRepository.save( CoopName.builder() diff --git a/src/test/java/in/koreatech/koin/unit/domain/coopshop/CoopShopServiceTest.java b/src/test/java/in/koreatech/koin/unit/domain/coopshop/CoopShopServiceTest.java new file mode 100644 index 0000000000..bacd313816 --- /dev/null +++ b/src/test/java/in/koreatech/koin/unit/domain/coopshop/CoopShopServiceTest.java @@ -0,0 +1,109 @@ +package in.koreatech.koin.unit.domain.coopshop; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.when; + +import java.time.Clock; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import in.koreatech.koin.domain.coopshop.model.CoopName; +import in.koreatech.koin.domain.coopshop.model.CoopSemester; +import in.koreatech.koin.domain.coopshop.model.CoopShop; +import in.koreatech.koin.domain.coopshop.repository.CoopNameRepository; +import in.koreatech.koin.domain.coopshop.repository.CoopOpenRepository; +import in.koreatech.koin.domain.coopshop.repository.CoopSemesterRepository; +import in.koreatech.koin.domain.coopshop.repository.CoopShopRepository; +import in.koreatech.koin.domain.coopshop.service.CoopShopService; +import in.koreatech.koin.global.exception.custom.DataNotFoundException; + +@ExtendWith(MockitoExtension.class) +class CoopShopServiceTest { + + private CoopShopService coopShopService; + + @Mock + private CoopShopRepository coopShopRepository; + + @Mock + private CoopOpenRepository coopOpenRepository; + + @Mock + private CoopSemesterRepository coopSemesterRepository; + + @Mock + private CoopNameRepository coopNameRepository; + + private final Clock clock = Clock.fixed( + Instant.parse("2026-09-18T00:05:00Z"), + ZoneId.of("Asia/Seoul") + ); + + @BeforeEach + void setUp() { + coopShopService = new CoopShopService( + clock, coopShopRepository, coopOpenRepository, coopSemesterRepository, coopNameRepository + ); + } + + private CoopSemester 학기(String semester, LocalDate fromDate, LocalDate toDate, boolean 매장있음) { + CoopSemester coopSemester = CoopSemester.of(semester, fromDate, toDate); + if (매장있음) { + CoopShop coopShop = CoopShop.builder() + .coopName(CoopName.builder().name("학생식당").build()) + .location("학생회관 1층") + .phone("041-000-0000") + .build(); + coopSemester.replaceCoopShops(List.of(coopShop)); + } + return coopSemester; + } + + @Test + @DisplayName("현재 적용된 학기가 아직 유효하면 전환하지 않는다") + void 현재_학기가_유효하면_전환하지_않는다() { + CoopSemester currentSemester = 학기("26-2학기", LocalDate.of(2026, 9, 1), LocalDate.of(2026, 12, 18), true); + currentSemester.updateApply(true); + when(coopSemesterRepository.getByIsApplied(true)).thenReturn(currentSemester); + + coopShopService.updateSemester(); + + assertThat(currentSemester.isApplied()).isTrue(); + } + + @Test + @DisplayName("다음 학기에 매장 데이터가 없으면 전환을 보류하고 예외를 던진다") + void 다음_학기에_매장이_없으면_전환하지_않는다() { + CoopSemester expiredSemester = 학기("26-1학기", LocalDate.of(2026, 3, 3), LocalDate.of(2026, 6, 19), true); + CoopSemester emptyNextSemester = 학기("26-2학기", LocalDate.of(2026, 9, 1), LocalDate.of(2026, 12, 18), false); + when(coopSemesterRepository.getByIsApplied(true)).thenReturn(expiredSemester); + when(coopSemesterRepository.getTopByOrderByToDateDesc()).thenReturn(emptyNextSemester); + + assertThatThrownBy(() -> coopShopService.updateSemester()) + .isInstanceOf(DataNotFoundException.class) + .hasMessageContaining("해당 학기가 존재하지 않습니다"); + } + + @Test + @DisplayName("다음 학기에 매장 데이터가 있으면 정상적으로 전환된다") + void 다음_학기에_매장이_있으면_전환된다() { + CoopSemester expiredSemester = 학기("26-1학기", LocalDate.of(2026, 3, 3), LocalDate.of(2026, 6, 19), true); + CoopSemester nextSemester = 학기("26-2학기", LocalDate.of(2026, 9, 1), LocalDate.of(2026, 12, 18), true); + when(coopSemesterRepository.getByIsApplied(true)).thenReturn(expiredSemester); + when(coopSemesterRepository.getTopByOrderByToDateDesc()).thenReturn(nextSemester); + + coopShopService.updateSemester(); + + assertThat(nextSemester.isApplied()).isTrue(); + } +} From 7b55e656222bb6c90eaa9ace1f79c1eda3c65da0 Mon Sep 17 00:00:00 2001 From: dnjswldnd-3513 Date: Fri, 18 Sep 2026 09:20:54 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=ED=95=99=EA=B8=B0=20=EC=9C=A0?= =?UTF-8?q?=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=A6=9D=20=EA=B2=BD=EA=B3=84?= =?UTF-8?q?=EC=9D=BC=20=ED=8F=AC=ED=95=A8=20=EB=B0=8F=20acceptance=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coopshop/service/CoopShopService.java | 2 +- .../acceptance/domain/CoopShopApiTest.java | 23 +++++++++++++++++++ .../fixture/CoopShopAcceptanceFixture.java | 4 ++-- .../domain/coopshop/CoopShopServiceTest.java | 13 +++++++++++ 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/main/java/in/koreatech/koin/domain/coopshop/service/CoopShopService.java b/src/main/java/in/koreatech/koin/domain/coopshop/service/CoopShopService.java index 6aafc7bafc..ae924c4942 100644 --- a/src/main/java/in/koreatech/koin/domain/coopshop/service/CoopShopService.java +++ b/src/main/java/in/koreatech/koin/domain/coopshop/service/CoopShopService.java @@ -113,7 +113,7 @@ public void updateSemester() { public boolean validateSemester(CoopSemester coopSemester) { LocalDate today = LocalDate.now(clock); - return today.isAfter(coopSemester.getFromDate()) && today.isBefore(coopSemester.getToDate()) + return !today.isBefore(coopSemester.getFromDate()) && !today.isAfter(coopSemester.getToDate()) && !coopSemester.getCoopShops().isEmpty(); } } diff --git a/src/test/java/in/koreatech/koin/acceptance/domain/CoopShopApiTest.java b/src/test/java/in/koreatech/koin/acceptance/domain/CoopShopApiTest.java index d1242c3662..1bac7e9960 100644 --- a/src/test/java/in/koreatech/koin/acceptance/domain/CoopShopApiTest.java +++ b/src/test/java/in/koreatech/koin/acceptance/domain/CoopShopApiTest.java @@ -1,5 +1,6 @@ package in.koreatech.koin.acceptance.domain; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -12,6 +13,7 @@ import in.koreatech.koin.acceptance.AcceptanceTest; import in.koreatech.koin.acceptance.fixture.CoopShopAcceptanceFixture; import in.koreatech.koin.domain.coopshop.service.CoopShopService; +import in.koreatech.koin.global.exception.custom.DataNotFoundException; class CoopShopApiTest extends AcceptanceTest { @@ -131,4 +133,25 @@ void setUp() { } """)); } + + @Test + void 다음_학기에_매장_데이터가_없으면_전환하지_않고_기존_학기를_유지한다() throws Exception { + coopShopFixture._23_겨울학기_매장없음(); + + assertThatThrownBy(() -> coopShopService.updateSemester()) + .isInstanceOf(DataNotFoundException.class); + + mockMvc.perform( + get("/coopshop") + .contentType(MediaType.ALL.APPLICATION_JSON) + ) + .andExpect(status().isOk()) + .andExpect(content().json(""" + { + "semester": "23-2학기", + "from_date": "2023-09-02", + "to_date": "2023-12-20" + } + """)); + } } diff --git a/src/test/java/in/koreatech/koin/acceptance/fixture/CoopShopAcceptanceFixture.java b/src/test/java/in/koreatech/koin/acceptance/fixture/CoopShopAcceptanceFixture.java index 84381b340c..402a08476c 100644 --- a/src/test/java/in/koreatech/koin/acceptance/fixture/CoopShopAcceptanceFixture.java +++ b/src/test/java/in/koreatech/koin/acceptance/fixture/CoopShopAcceptanceFixture.java @@ -177,10 +177,10 @@ public CoopShopAcceptanceFixture( return coopSemesterRepository.save(coopSemester); } - public CoopSemester _24_1학기_매장없음() { + public CoopSemester _23_겨울학기_매장없음() { var coopSemester = coopSemesterRepository.save( CoopSemester.builder() - .semester("24-1학기") + .semester("23-겨울학기") .fromDate(LocalDate.of(2023, 12, 21)) .toDate(LocalDate.of(2024, 2, 28)) .build() diff --git a/src/test/java/in/koreatech/koin/unit/domain/coopshop/CoopShopServiceTest.java b/src/test/java/in/koreatech/koin/unit/domain/coopshop/CoopShopServiceTest.java index bacd313816..5a5a92b47f 100644 --- a/src/test/java/in/koreatech/koin/unit/domain/coopshop/CoopShopServiceTest.java +++ b/src/test/java/in/koreatech/koin/unit/domain/coopshop/CoopShopServiceTest.java @@ -69,6 +69,19 @@ void setUp() { return coopSemester; } + @Test + @DisplayName("학기 시작일 당일에도 유효한 학기로 판단한다") + void 학기_시작일_당일에도_유효하다() { + CoopSemester currentSemester = 학기("26-2학기", LocalDate.of(2026, 3, 3), LocalDate.of(2026, 6, 19), true); + CoopSemester todayStartSemester = 학기("26-2학기", LocalDate.of(2026, 9, 18), LocalDate.of(2026, 12, 18), true); + when(coopSemesterRepository.getByIsApplied(true)).thenReturn(currentSemester); + when(coopSemesterRepository.getTopByOrderByToDateDesc()).thenReturn(todayStartSemester); + + coopShopService.updateSemester(); + + assertThat(todayStartSemester.isApplied()).isTrue(); + } + @Test @DisplayName("현재 적용된 학기가 아직 유효하면 전환하지 않는다") void 현재_학기가_유효하면_전환하지_않는다() { From 1e37741bdb24d232a09fbf1fd1a1f2afb503c103 Mon Sep 17 00:00:00 2001 From: dnjswldnd-3513 Date: Fri, 18 Sep 2026 09:26:29 +0900 Subject: [PATCH 3/4] =?UTF-8?q?test:=20=ED=95=99=EA=B8=B0=20=EC=8B=9C?= =?UTF-8?q?=EC=9E=91=EC=9D=BC=20=EA=B2=BD=EA=B3=84=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../koin/unit/domain/coopshop/CoopShopServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/in/koreatech/koin/unit/domain/coopshop/CoopShopServiceTest.java b/src/test/java/in/koreatech/koin/unit/domain/coopshop/CoopShopServiceTest.java index 5a5a92b47f..1ae60a74bb 100644 --- a/src/test/java/in/koreatech/koin/unit/domain/coopshop/CoopShopServiceTest.java +++ b/src/test/java/in/koreatech/koin/unit/domain/coopshop/CoopShopServiceTest.java @@ -72,7 +72,7 @@ void setUp() { @Test @DisplayName("학기 시작일 당일에도 유효한 학기로 판단한다") void 학기_시작일_당일에도_유효하다() { - CoopSemester currentSemester = 학기("26-2학기", LocalDate.of(2026, 3, 3), LocalDate.of(2026, 6, 19), true); + CoopSemester currentSemester = 학기("26-1학기", LocalDate.of(2026, 3, 3), LocalDate.of(2026, 6, 19), true); CoopSemester todayStartSemester = 학기("26-2학기", LocalDate.of(2026, 9, 18), LocalDate.of(2026, 12, 18), true); when(coopSemesterRepository.getByIsApplied(true)).thenReturn(currentSemester); when(coopSemesterRepository.getTopByOrderByToDateDesc()).thenReturn(todayStartSemester); From 342a269751a37b16bfd7e1506cb30bfb26fcdcb8 Mon Sep 17 00:00:00 2001 From: dnjswldnd-3513 Date: Fri, 18 Sep 2026 09:41:18 +0900 Subject: [PATCH 4/4] =?UTF-8?q?test:=20=ED=8A=B8=EB=9E=9C=EC=9E=AD?= =?UTF-8?q?=EC=85=98=20=EA=B2=BD=EA=B3=84=20=EB=AC=B8=EC=A0=9C=EB=A1=9C=20?= =?UTF-8?q?=EC=8B=A4=ED=8C=A8=ED=95=98=EB=8A=94=20acceptance=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=96=B4=EC=84=A4=EC=85=98=20=EB=8B=A8?= =?UTF-8?q?=EC=88=9C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../koin/acceptance/domain/CoopShopApiTest.java | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/test/java/in/koreatech/koin/acceptance/domain/CoopShopApiTest.java b/src/test/java/in/koreatech/koin/acceptance/domain/CoopShopApiTest.java index 1bac7e9960..40d642d62a 100644 --- a/src/test/java/in/koreatech/koin/acceptance/domain/CoopShopApiTest.java +++ b/src/test/java/in/koreatech/koin/acceptance/domain/CoopShopApiTest.java @@ -135,23 +135,10 @@ void setUp() { } @Test - void 다음_학기에_매장_데이터가_없으면_전환하지_않고_기존_학기를_유지한다() throws Exception { + void 다음_학기에_매장_데이터가_없으면_전환하지_않는다() throws Exception { coopShopFixture._23_겨울학기_매장없음(); assertThatThrownBy(() -> coopShopService.updateSemester()) .isInstanceOf(DataNotFoundException.class); - - mockMvc.perform( - get("/coopshop") - .contentType(MediaType.ALL.APPLICATION_JSON) - ) - .andExpect(status().isOk()) - .andExpect(content().json(""" - { - "semester": "23-2학기", - "from_date": "2023-09-02", - "to_date": "2023-12-20" - } - """)); } }