From 32685f02f9b4e1d47319a5b1100b716ed54b48ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8E=E1=85=AC=E1=84=8C=E1=85=AE=E1=86=AB=E1=84=92?= =?UTF-8?q?=E1=85=A9?= Date: Thu, 4 Apr 2024 01:27:07 +0900 Subject: [PATCH 1/4] test: add JsonAssertions --- .../koin/support/JsonAssertions.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/test/java/in/koreatech/koin/support/JsonAssertions.java diff --git a/src/test/java/in/koreatech/koin/support/JsonAssertions.java b/src/test/java/in/koreatech/koin/support/JsonAssertions.java new file mode 100644 index 0000000000..cb6ae055fe --- /dev/null +++ b/src/test/java/in/koreatech/koin/support/JsonAssertions.java @@ -0,0 +1,39 @@ +package in.koreatech.koin.support; + +import java.util.Map; + +import org.assertj.core.api.Assertions; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JsonAssertions { + + + public static JsonStringAssert assertThat(String expect) { + return new JsonStringAssert(expect); + } + + public static class JsonStringAssert { + + private final ObjectMapper objectMapper = new ObjectMapper(); + private final String expect; + + JsonStringAssert(String expect) { + this.expect = expect; + } + + public void isEqualTo(String actual) { + try { + Map responseMap = objectMapper.readValue(expect, new TypeReference<>() { + }); + Map expectedMap = objectMapper.readValue(actual, new TypeReference<>() { + }); + Assertions.assertThat(responseMap).isEqualTo(expectedMap); + } catch (Exception ignored) { + + } + } + + } +} From cd9fce2c2593e21881c77691be580f11de83c5b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8E=E1=85=AC=E1=84=8C=E1=85=AE=E1=86=AB=E1=84=92?= =?UTF-8?q?=E1=85=A9?= Date: Thu, 4 Apr 2024 01:35:56 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20isEvent=20=EA=B0=92=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ownershop/service/OwnerShopService.java | 8 +- .../koin/domain/shop/dto/ShopResponse.java | 14 +- .../repository/EventArticleRepository.java | 8 + .../koin/domain/shop/service/ShopService.java | 6 +- .../koin/acceptance/OwnerShopApiTest.java | 92 ++-- .../koin/acceptance/ShopApiTest.java | 461 +++++++++++++----- .../koin/support/JsonAssertions.java | 2 +- 7 files changed, 432 insertions(+), 159 deletions(-) diff --git a/src/main/java/in/koreatech/koin/domain/ownershop/service/OwnerShopService.java b/src/main/java/in/koreatech/koin/domain/ownershop/service/OwnerShopService.java index d7ca6b9528..7e7930bf80 100644 --- a/src/main/java/in/koreatech/koin/domain/ownershop/service/OwnerShopService.java +++ b/src/main/java/in/koreatech/koin/domain/ownershop/service/OwnerShopService.java @@ -1,5 +1,7 @@ package in.koreatech.koin.domain.ownershop.service; +import java.time.Clock; +import java.time.LocalDate; import java.util.List; import java.util.Objects; @@ -29,6 +31,7 @@ import in.koreatech.koin.domain.shop.model.ShopCategoryMap; import in.koreatech.koin.domain.shop.model.ShopImage; import in.koreatech.koin.domain.shop.model.ShopOpen; +import in.koreatech.koin.domain.shop.repository.EventArticleRepository; import in.koreatech.koin.domain.shop.repository.MenuCategoryMapRepository; import in.koreatech.koin.domain.shop.repository.MenuCategoryRepository; import in.koreatech.koin.domain.shop.repository.MenuDetailRepository; @@ -47,6 +50,7 @@ @Transactional(readOnly = true) public class OwnerShopService { + private final Clock clock; private final ShopRepository shopRepository; private final OwnerRepository ownerRepository; private final ShopOpenRepository shopOpenRepository; @@ -58,6 +62,7 @@ public class OwnerShopService { private final MenuCategoryMapRepository menuCategoryMapRepository; private final MenuImageRepository menuImageRepository; private final MenuDetailRepository menuDetailRepository; + private final EventArticleRepository eventArticleRepository; public OwnerShopsResponse getOwnerShops(Long ownerId) { List shops = shopRepository.findAllByOwnerId(ownerId); @@ -99,7 +104,8 @@ public void createOwnerShops(Long ownerId, OwnerShopsRequest ownerShopsRequest) public ShopResponse getShopByShopId(Long ownerId, Long shopId) { Shop shop = getOwnerShopById(shopId, ownerId); - return ShopResponse.from(shop); + Boolean eventDuration = eventArticleRepository.isEvent(shopId, LocalDate.now(clock)); + return ShopResponse.from(shop, eventDuration); } private Shop getOwnerShopById(Long shopId, Long ownerId) { diff --git a/src/main/java/in/koreatech/koin/domain/shop/dto/ShopResponse.java b/src/main/java/in/koreatech/koin/domain/shop/dto/ShopResponse.java index b63533e28d..536c48248d 100644 --- a/src/main/java/in/koreatech/koin/domain/shop/dto/ShopResponse.java +++ b/src/main/java/in/koreatech/koin/domain/shop/dto/ShopResponse.java @@ -58,11 +58,13 @@ public record ShopResponse( @JsonFormat(pattern = "yyyy-MM-dd") @Schema(example = "2024-03-01", description = "업데이트 날짜") - LocalDateTime updatedAt -) { + LocalDateTime updatedAt, - public static ShopResponse from(Shop shop) { + @Schema(example = "true", description = "상점 이벤트 진행 여부") + Boolean isEvent +) { + public static ShopResponse from(Shop shop, Boolean isEvent) { return new ShopResponse( shop.getAddress(), shop.getDelivery(), @@ -97,7 +99,8 @@ public static ShopResponse from(Shop shop) { shopCategory.getName() ); }).toList(), - shop.getUpdatedAt() + shop.getUpdatedAt(), + isEvent ); } @@ -119,6 +122,7 @@ public record InnerShopOpen( @JsonFormat(pattern = "HH:mm") LocalTime closeTime ) { + public static InnerShopOpen from(ShopOpen shopOpen) { return new InnerShopOpen( shopOpen.getDayOfWeek(), @@ -136,6 +140,7 @@ private record InnerShopCategory( @Schema(example = "중국집", description = "이름") String name ) { + } private record InnerMenuCategory( @@ -145,5 +150,6 @@ private record InnerMenuCategory( @Schema(example = "대표 메뉴", description = "이름") String name ) { + } } diff --git a/src/main/java/in/koreatech/koin/domain/shop/repository/EventArticleRepository.java b/src/main/java/in/koreatech/koin/domain/shop/repository/EventArticleRepository.java index b7647260a9..8ff186b246 100644 --- a/src/main/java/in/koreatech/koin/domain/shop/repository/EventArticleRepository.java +++ b/src/main/java/in/koreatech/koin/domain/shop/repository/EventArticleRepository.java @@ -1,7 +1,9 @@ package in.koreatech.koin.domain.shop.repository; +import java.time.LocalDate; import java.util.List; +import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.Repository; import in.koreatech.koin.domain.shop.model.EventArticle; @@ -12,4 +14,10 @@ public interface EventArticleRepository extends Repository { List findAllByShopId(Long shopId); + @Query(""" + SELECT COUNT(e) > 0 FROM EventArticle e + WHERE :now BETWEEN e.startDate AND e.endDate + AND e.shop.id = :shopId + """) + Boolean isEvent(Long shopId, LocalDate now); } diff --git a/src/main/java/in/koreatech/koin/domain/shop/service/ShopService.java b/src/main/java/in/koreatech/koin/domain/shop/service/ShopService.java index de946f7ec6..b608cf040e 100644 --- a/src/main/java/in/koreatech/koin/domain/shop/service/ShopService.java +++ b/src/main/java/in/koreatech/koin/domain/shop/service/ShopService.java @@ -1,5 +1,7 @@ package in.koreatech.koin.domain.shop.service; +import java.time.Clock; +import java.time.LocalDate; import java.util.List; import org.springframework.stereotype.Service; @@ -30,6 +32,7 @@ @RequiredArgsConstructor public class ShopService { + private final Clock clock; private final MenuRepository menuRepository; private final MenuCategoryRepository menuCategoryRepository; private final ShopRepository shopRepository; @@ -55,7 +58,8 @@ public MenuCategoriesResponse getMenuCategories(Long shopId) { public ShopResponse getShop(Long shopId) { Shop shop = shopRepository.getById(shopId); - return ShopResponse.from(shop); + Boolean eventDuration = eventArticleRepository.isEvent(shopId, LocalDate.now(clock)); + return ShopResponse.from(shop, eventDuration); } public ShopMenuResponse getShopMenu(Long shopId) { diff --git a/src/test/java/in/koreatech/koin/acceptance/OwnerShopApiTest.java b/src/test/java/in/koreatech/koin/acceptance/OwnerShopApiTest.java index f1a32940f7..59152e2fff 100644 --- a/src/test/java/in/koreatech/koin/acceptance/OwnerShopApiTest.java +++ b/src/test/java/in/koreatech/koin/acceptance/OwnerShopApiTest.java @@ -1,10 +1,14 @@ package in.koreatech.koin.acceptance; import static in.koreatech.koin.domain.user.model.UserType.OWNER; +import static java.time.format.DateTimeFormatter.ofPattern; import static org.assertj.core.api.SoftAssertions.assertSoftly; +import static org.mockito.Mockito.when; +import java.time.Clock; import java.time.LocalDate; import java.time.LocalTime; +import java.time.ZonedDateTime; import java.util.List; import org.assertj.core.api.SoftAssertions; @@ -43,6 +47,7 @@ import in.koreatech.koin.domain.user.model.User; import in.koreatech.koin.domain.user.model.UserGender; import in.koreatech.koin.global.auth.JwtProvider; +import in.koreatech.koin.support.JsonAssertions; import io.restassured.RestAssured; import io.restassured.http.ContentType; import io.restassured.response.ExtractableResponse; @@ -93,6 +98,9 @@ class OwnerShopApiTest extends AcceptanceTest { @BeforeEach void setUp() { + when(clock.instant()).thenReturn( + ZonedDateTime.parse("2024-02-21 18:00:00 KST", ofPattern("yyyy-MM-dd " + "HH:mm:ss z")).toInstant()); + when(clock.getZone()).thenReturn(Clock.systemDefaultZone().getZone()); OwnerAttachment attachment = OwnerAttachment.builder() .url("https://test.com/test.jpg") @@ -337,8 +345,8 @@ void getShop() { .dayOfWeek("FRIDAY") .build(); - ShopOpen newShopOpen1 = shopOpenRepository.save(open1); - ShopOpen newShopOpen2 = shopOpenRepository.save(open2); + shopOpenRepository.save(open1); + shopOpenRepository.save(open2); ShopCategoryMap shopCategoryMap1 = ShopCategoryMap.builder() .shop(shop) @@ -350,8 +358,8 @@ void getShop() { .shopCategory(shopCategory2) .build(); - ShopCategoryMap newShopCategoryMap1 = shopCategoryMapRepository.save(shopCategoryMap1); - ShopCategoryMap newShopCategoryMap2 = shopCategoryMapRepository.save(shopCategoryMap2); + shopCategoryMapRepository.save(shopCategoryMap1); + shopCategoryMapRepository.save(shopCategoryMap2); ShopImage shopImage1 = ShopImage.builder() .imageUrl("https://test.com/test1.jpg") @@ -363,14 +371,14 @@ void getShop() { .shop(shop) .build(); - ShopImage newShopImage1 = shopImageRepository.save(shopImage1); - ShopImage newShopImage2 = shopImageRepository.save(shopImage2); + shopImageRepository.save(shopImage1); + shopImageRepository.save(shopImage2); ExtractableResponse response = RestAssured .given() .header("Authorization", "Bearer " + token) .when() - .get("/owner/shops/1") + .get("/owner/shops/{shopId}", shop.getId()) .then() .statusCode(HttpStatus.OK.value()) .extract(); @@ -380,27 +388,53 @@ void getShop() { List savedShopOpens = shopOpenRepository.findAllByShopId(shop.getId()); List savedShopCategoryMaps = shopCategoryMapRepository.findAllByShopId(shop.getId()); - assertSoftly( - softly -> { - softly.assertThat(response.body().jsonPath().getString("address")).isEqualTo(shop.getAddress()); - softly.assertThat(response.body().jsonPath().getBoolean("delivery")).isEqualTo(shop.getDelivery()); - softly.assertThat(response.body().jsonPath().getLong("delivery_price")) - .isEqualTo(shop.getDeliveryPrice()); - softly.assertThat(response.body().jsonPath().getString("description")).isEqualTo(shop.getDescription()); - softly.assertThat(response.body().jsonPath().getLong("id")).isEqualTo(shop.getId()); - softly.assertThat(response.body().jsonPath().getString("name")).isEqualTo(shop.getName()); - softly.assertThat(response.body().jsonPath().getBoolean("pay_bank")).isEqualTo(shop.getPayBank()); - softly.assertThat(response.body().jsonPath().getBoolean("pay_card")).isEqualTo(shop.getPayCard()); - softly.assertThat(response.body().jsonPath().getString("phone")).isEqualTo(shop.getPhone()); - - softly.assertThat(response.body().jsonPath().getList("image_urls")).hasSize(savedShopImages.size()); - softly.assertThat(response.body().jsonPath().getList("menu_categories")) - .hasSize(savedMenuCategories.size()); - softly.assertThat(response.body().jsonPath().getList("open")).hasSize(savedShopOpens.size()); - softly.assertThat(response.body().jsonPath().getList("shop_categories")) - .hasSize(savedShopCategoryMaps.size()); - } - ); + JsonAssertions.assertThat(response.asPrettyString()) + .isEqualTo(""" + { + "address": "대전광역시 유성구 대학로 291", + "delivery": true, + "delivery_price": 3000, + "description": "테스트 상점입니다.", + "id": 1, + "image_urls": [ + "https://test.com/test1.jpg", + "https://test.com/test2.jpg" + ], + "menu_categories": [ + + ], + "name": "테스트 상점", + "open": [ + { + "day_of_week": "MONDAY", + "closed": false, + "open_time": "00:00", + "close_time": "21:00" + }, + { + "day_of_week": "FRIDAY", + "closed": false, + "open_time": "00:00", + "close_time": "00:00" + } + ], + "pay_bank": true, + "pay_card": true, + "phone": "010-1234-5678", + "shop_categories": [ + { + "id": 1, + "name": "테스트1" + }, + { + "id": 2, + "name": "테스트2" + } + ], + "updated_at": "2024-04-04", + "is_event": false + } + """); } @Test @@ -656,7 +690,7 @@ void ownerCannotQueryOtherStoresWithoutPermission() { .given() .header("Authorization", "Bearer " + otherOwnerToken) .when() - .get("/owner/shops/1") + .get("/owner/shops/{shopId}", shop.getId()) .then() .statusCode(HttpStatus.FORBIDDEN.value()) .extract(); diff --git a/src/test/java/in/koreatech/koin/acceptance/ShopApiTest.java b/src/test/java/in/koreatech/koin/acceptance/ShopApiTest.java index 77292804e4..dadb526ab3 100644 --- a/src/test/java/in/koreatech/koin/acceptance/ShopApiTest.java +++ b/src/test/java/in/koreatech/koin/acceptance/ShopApiTest.java @@ -1,6 +1,7 @@ package in.koreatech.koin.acceptance; import static in.koreatech.koin.domain.user.model.UserType.OWNER; +import static in.koreatech.koin.support.JsonAssertions.assertThat; import static java.time.format.DateTimeFormatter.ofPattern; import static org.assertj.core.api.SoftAssertions.assertSoftly; import static org.mockito.Mockito.when; @@ -47,7 +48,7 @@ import in.koreatech.koin.domain.shop.repository.ShopRepository; import in.koreatech.koin.domain.user.model.User; import in.koreatech.koin.domain.user.model.UserGender; -import in.koreatech.koin.domain.user.repository.UserRepository; +import in.koreatech.koin.support.JsonAssertions; import io.restassured.RestAssured; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; @@ -81,9 +82,6 @@ class ShopApiTest extends AcceptanceTest { @Autowired private ShopRepository shopRepository; - @Autowired - private UserRepository userRepository; - @Autowired private EventArticleRepository eventArticleRepository; @@ -91,9 +89,11 @@ class ShopApiTest extends AcceptanceTest { private Shop shop; private Owner owner; - @BeforeEach void setUp() { + when(clock.instant()).thenReturn( + ZonedDateTime.parse("2024-02-21 18:00:00 KST", ofPattern("yyyy-MM-dd " + "HH:mm:ss z")).toInstant()); + when(clock.getZone()).thenReturn(Clock.systemDefaultZone().getZone()); OwnerAttachment attachment = OwnerAttachment.builder() .url("https://test.com/test.jpg") @@ -370,7 +370,7 @@ void findShopMenuCategories() { @Test @DisplayName("특정 상점 조회") - void getShop() { + void getShop() throws Exception { // given ShopOpen open1 = ShopOpen.builder() .openTime(LocalTime.of(0, 0)) @@ -420,37 +420,56 @@ void getShop() { ExtractableResponse response = RestAssured .given() .when() - .get("/shops/1") + .get("/shops/{shopId}", shop.getId()) .then() .statusCode(HttpStatus.OK.value()) .extract(); - List savedShopImages = shopImageRepository.findAllByShopId(shop.getId()); - List savedMenuCategories = menuCategoryRepository.findAllByShopId(shop.getId()); - List savedShopOpens = shopOpenRepository.findAllByShopId(shop.getId()); - List savedShopCategoryMaps = shopCategoryMapRepository.findAllByShopId(shop.getId()); - - assertSoftly( - softly -> { - softly.assertThat(response.body().jsonPath().getString("address")).isEqualTo(shop.getAddress()); - softly.assertThat(response.body().jsonPath().getBoolean("delivery")).isEqualTo(shop.getDelivery()); - softly.assertThat(response.body().jsonPath().getLong("delivery_price")) - .isEqualTo(shop.getDeliveryPrice()); - softly.assertThat(response.body().jsonPath().getString("description")).isEqualTo(shop.getDescription()); - softly.assertThat(response.body().jsonPath().getLong("id")).isEqualTo(shop.getId()); - softly.assertThat(response.body().jsonPath().getString("name")).isEqualTo(shop.getName()); - softly.assertThat(response.body().jsonPath().getBoolean("pay_bank")).isEqualTo(shop.getPayBank()); - softly.assertThat(response.body().jsonPath().getBoolean("pay_card")).isEqualTo(shop.getPayCard()); - softly.assertThat(response.body().jsonPath().getString("phone")).isEqualTo(shop.getPhone()); - - softly.assertThat(response.body().jsonPath().getList("image_urls")).hasSize(savedShopImages.size()); - softly.assertThat(response.body().jsonPath().getList("menu_categories")) - .hasSize(savedMenuCategories.size()); - softly.assertThat(response.body().jsonPath().getList("open")).hasSize(savedShopOpens.size()); - softly.assertThat(response.body().jsonPath().getList("shop_categories")) - .hasSize(savedShopCategoryMaps.size()); - } - ); + assertThat(response.asPrettyString()).isEqualTo(""" + { + "address": "대전광역시 유성구 대학로 291", + "delivery": true, + "delivery_price": 3000, + "description": "테스트 상점입니다.", + "id": 1, + "image_urls": [ + "https://test.com/test1.jpg", + "https://test.com/test2.jpg" + ], + "menu_categories": [ + + ], + "name": "테스트 상점", + "open": [ + { + "day_of_week": "MONDAY", + "closed": false, + "open_time": "00:00", + "close_time": "21:00" + }, + { + "day_of_week": "FRIDAY", + "closed": false, + "open_time": "00:00", + "close_time": "00:00" + } + ], + "pay_bank": true, + "pay_card": true, + "phone": "010-1234-5678", + "shop_categories": [ + { + "id": 1, + "name": "테스트1" + }, + { + "id": 2, + "name": "테스트2" + } + ], + "updated_at": "2024-04-04", + "is_event": false + }"""); } @Test @@ -580,95 +599,84 @@ void getShopMenus() { .statusCode(HttpStatus.OK.value()) .extract(); - SoftAssertions.assertSoftly( - softly -> { - softly.assertThat(response.body().jsonPath().getLong("count")).isEqualTo(3); - softly.assertThat(response.body().jsonPath().getLong("menu_categories[0].id")) - .isEqualTo(menu1.getMenuCategoryMaps().get(0).getMenuCategory().getId()); - softly.assertThat(response.body().jsonPath().getString("menu_categories[0].name")) - .isEqualTo(menu1.getMenuCategoryMaps().get(0).getMenuCategory().getName()); - softly.assertThat(response.body().jsonPath().getString("menu_categories[0].menus[0].description")) - .isEqualTo(menu1.getMenuCategoryMaps().get(0).getMenu().getDescription()); - softly.assertThat(response.body().jsonPath().getLong("menu_categories[0].menus[0].id")) - .isEqualTo(menu1.getMenuCategoryMaps().get(0).getMenu().getId()); - softly.assertThat(response.body().jsonPath().getList("menu_categories[0].menus[0].image_urls")) - .hasSize(2); - softly.assertThat(response.body().jsonPath().getBoolean("menu_categories[0].menus[0].is_hidden")) - .isEqualTo(menu1.getMenuCategoryMaps().get(0).getMenu().getIsHidden()); - softly.assertThat(response.body().jsonPath().getBoolean("menu_categories[0].menus[0].is_single")) - .isEqualTo(false); - softly.assertThat(response.body().jsonPath().getString("menu_categories[0].menus[0].name")) - .isEqualTo(menu1.getMenuCategoryMaps().get(0).getMenu().getName()); - softly.assertThat( - response.body().jsonPath().getString("menu_categories[0].menus[0].option_prices[0].option")) - .isEqualTo(menu1.getMenuCategoryMaps().get(0).getMenu().getMenuOptions().get(0).getOption()); - softly.assertThat( - response.body().jsonPath().getInt("menu_categories[0].menus[0].option_prices[0].price")) - .isEqualTo(menu1.getMenuCategoryMaps().get(0).getMenu().getMenuOptions().get(0).getPrice()); - softly.assertThat( - response.body().jsonPath().getString("menu_categories[0].menus[0].option_prices[1].option")) - .isEqualTo(menu1.getMenuCategoryMaps().get(0).getMenu().getMenuOptions().get(1).getOption()); - softly.assertThat( - response.body().jsonPath().getInt("menu_categories[0].menus[0].option_prices[1].price")) - .isEqualTo(menu1.getMenuCategoryMaps().get(0).getMenu().getMenuOptions().get(1).getPrice()); - softly.assertThat((Object) response.body().jsonPath().get("menu_categories[0].menus[0].single_price")) - .isNull(); - softly.assertThat(response.body().jsonPath().getString("updated_at")) - .isEqualTo(LocalDate.now().toString()); - - softly.assertThat(response.body().jsonPath().getLong("menu_categories[1].id")) - .isEqualTo(menu2.getMenuCategoryMaps().get(0).getMenuCategory().getId()); - softly.assertThat(response.body().jsonPath().getString("menu_categories[1].name")) - .isEqualTo(menu2.getMenuCategoryMaps().get(0).getMenuCategory().getName()); - softly.assertThat(response.body().jsonPath().getString("menu_categories[1].menus[0].description")) - .isEqualTo(menu2.getMenuCategoryMaps().get(0).getMenu().getDescription()); - softly.assertThat(response.body().jsonPath().getLong("menu_categories[1].menus[0].id")) - .isEqualTo(menu2.getMenuCategoryMaps().get(0).getMenu().getId()); - softly.assertThat(response.body().jsonPath().getList("menu_categories[1].menus[0].image_urls")) - .hasSize(2); - softly.assertThat(response.body().jsonPath().getBoolean("menu_categories[1].menus[0].is_hidden")) - .isEqualTo(menu2.getMenuCategoryMaps().get(0).getMenu().getIsHidden()); - softly.assertThat(response.body().jsonPath().getBoolean("menu_categories[1].menus[0].is_single")) - .isEqualTo(false); - softly.assertThat(response.body().jsonPath().getString("menu_categories[1].menus[0].name")) - .isEqualTo(menu2.getMenuCategoryMaps().get(0).getMenu().getName()); - softly.assertThat( - response.body().jsonPath().getString("menu_categories[1].menus[0].option_prices[0].option")) - .isEqualTo(menu2.getMenuCategoryMaps().get(0).getMenu().getMenuOptions().get(0).getOption()); - softly.assertThat( - response.body().jsonPath().getInt("menu_categories[1].menus[0].option_prices[0].price")) - .isEqualTo(menu2.getMenuCategoryMaps().get(0).getMenu().getMenuOptions().get(0).getPrice()); - softly.assertThat( - response.body().jsonPath().getString("menu_categories[1].menus[0].option_prices[1].option")) - .isEqualTo(menu2.getMenuCategoryMaps().get(0).getMenu().getMenuOptions().get(1).getOption()); - softly.assertThat( - response.body().jsonPath().getInt("menu_categories[1].menus[0].option_prices[1].price")) - .isEqualTo(menu2.getMenuCategoryMaps().get(0).getMenu().getMenuOptions().get(1).getPrice()); - softly.assertThat((Object) response.body().jsonPath().get("menu_categories[1].menus[0].single_price")) - .isNull(); - softly.assertThat(response.body().jsonPath().getString("updated_at")) - .isEqualTo(LocalDate.now().toString()); - - softly.assertThat(response.body().jsonPath().getString("menu_categories[1].menus[1].description")) - .isEqualTo(menu3.getMenuCategoryMaps().get(0).getMenu().getDescription()); - softly.assertThat(response.body().jsonPath().getLong("menu_categories[1].menus[1].id")) - .isEqualTo(menu3.getMenuCategoryMaps().get(0).getMenu().getId()); - softly.assertThat(response.body().jsonPath().getList("menu_categories[1].menus[1].image_urls")) - .hasSize(2); - softly.assertThat(response.body().jsonPath().getBoolean("menu_categories[1].menus[1].is_hidden")) - .isEqualTo(menu3.getMenuCategoryMaps().get(0).getMenu().getIsHidden()); - softly.assertThat(response.body().jsonPath().getBoolean("menu_categories[1].menus[1].is_single")) - .isEqualTo(true); - softly.assertThat(response.body().jsonPath().getString("menu_categories[1].menus[1].name")) - .isEqualTo(menu3.getMenuCategoryMaps().get(0).getMenu().getName()); - softly.assertThat(response.body().jsonPath().getString("menu_categories[1].menus[1].option_prices")) - .isEqualTo(null); - softly.assertThat(response.body().jsonPath().getInt("menu_categories[1].menus[1].single_price")) - .isEqualTo(menu3.getMenuCategoryMaps().get(0).getMenu().getMenuOptions().get(0).getPrice()); - softly.assertThat(response.body().jsonPath().getString("updated_at")) - .isEqualTo(LocalDate.now().toString()); - } - ); + JsonAssertions.assertThat(response.asPrettyString()) + .isEqualTo(""" + { + "count": 3, + "menu_categories": [ + { + "id": 1, + "name": "중식", + "menus": [ + { + "id": 1, + "name": "짜장면", + "is_hidden": false, + "is_single": false, + "single_price": null, + "option_prices": [ + { + "option": "일반", + "price": 7000 + }, + { + "option": "곱빼기", + "price": 7500 + } + ], + "description": "맛있는 짜장면", + "image_urls": [ + "https://test.com/test.jpg", + "https://test.com/hello.jpg" + ] + } + ] + }, + { + "id": 2, + "name": "한식", + "menus": [ + { + "id": 2, + "name": "짜장면2", + "is_hidden": false, + "is_single": false, + "single_price": null, + "option_prices": [ + { + "option": "일반", + "price": 7000 + }, + { + "option": "곱빼기", + "price": 7500 + } + ], + "description": "맛있는 짜장면", + "image_urls": [ + "https://test.com/test.jpg", + "https://test.com/hello.jpg" + ] + }, + { + "id": 3, + "name": "짜장면3", + "is_hidden": false, + "is_single": true, + "single_price": 7000, + "option_prices": null, + "description": "맛있는 짜장면", + "image_urls": [ + "https://test.com/test.jpg", + "https://test.com/hello.jpg" + ] + } + ] + } + ], + "updated_at": "2024-04-04" + } + """); } @Test @@ -919,7 +927,6 @@ void getShopEvents() { .when() .get("/shops/{shopId}/events", newShop.getId()) .then() - .log().all() .statusCode(HttpStatus.OK.value()) .extract(); @@ -942,4 +949,212 @@ void getShopEvents() { }""" ); } + + @Test + @DisplayName("이벤트 진행중인 상점의 정보를 조회한다.") + void getShopWithEvents() { + when(clock.instant()).thenReturn( + ZonedDateTime.parse("2024-02-21 18:00:00 KST", ofPattern("yyyy-MM-dd HH:mm:ss z")).toInstant()); + when(clock.getZone()).thenReturn(Clock.systemDefaultZone().getZone()); + + var now = LocalDate.of(2024, 2, 21); + var user = owner.getUser(); + Shop shopRequest = Shop.builder() + .owner(owner) + .name("테스트 상점2") + .internalName("테스트2") + .chosung("테스트") + .phone("010-1234-5678") + .address("대전광역시 유성구 대학로 291") + .description("테스트 상점입니다.") + .delivery(true) + .deliveryPrice(3000L) + .payCard(true) + .payBank(true) + .isDeleted(false) + .isEvent(false) + .remarks("비고") + .hit(0L) + .build(); + Shop newShop = shopRepository.save(shopRequest); + + ShopOpen open1 = ShopOpen.builder() + .openTime(LocalTime.of(0, 0)) + .closeTime(LocalTime.of(21, 0)) + .shop(shop) + .closed(false) + .dayOfWeek("MONDAY") + .build(); + + ShopOpen open2 = ShopOpen.builder() + .openTime(LocalTime.of(0, 0)) + .closeTime(LocalTime.of(0, 0)) + .shop(newShop) + .closed(false) + .dayOfWeek("FRIDAY") + .build(); + + shopOpenRepository.save(open1); + shopOpenRepository.save(open2); + + ShopCategoryMap shopCategoryMap1 = ShopCategoryMap.builder() + .shop(shop) + .shopCategory(shopCategory1) + .build(); + + ShopCategoryMap shopCategoryMap2 = ShopCategoryMap.builder() + .shop(newShop) + .shopCategory(shopCategory2) + .build(); + + shopCategoryMapRepository.save(shopCategoryMap1); + shopCategoryMapRepository.save(shopCategoryMap2); + + ShopImage shopImage1 = ShopImage.builder() + .imageUrl("https://test.com/test1.jpg") + .shop(shop) + .build(); + + ShopImage shopImage2 = ShopImage.builder() + .imageUrl("https://test.com/test2.jpg") + .shop(newShop) + .build(); + + shopImageRepository.save(shopImage1); + shopImageRepository.save(shopImage2); + + EventArticle eventArticle1 = EventArticle.builder() + .shop(newShop) + .title("테스트 이벤트 1") + .content("

테스트 이벤트 내용1

") + .user(user) + .thumbnail("https://test.com/test-thumbnail-1.jpg") + .hit(0) + .ip("123.123.123.11") + .startDate(now) + .endDate(now.plusDays(3)) + .build(); + eventArticleRepository.save(eventArticle1); + + EventArticle eventArticle2 = EventArticle.builder() + .shop(newShop) + .title("테스트 이벤트 2") + .content("

테스트 이벤트 내용2

") + .user(user) + .thumbnail("https://test.com/test-thumbnail-2.jpg") + .hit(0) + .ip("123.123.123.12") + .startDate(now) + .endDate(now.plusDays(3)) + .build(); + eventArticleRepository.save(eventArticle2); + + ExtractableResponse response = RestAssured + .given() + .when() + .get("/shops/{shopId}", newShop.getId()) + .then() + .statusCode(HttpStatus.OK.value()) + .extract(); + + Assertions.assertThat(response.jsonPath().getBoolean("is_event")).isTrue(); + } + + @Test + @DisplayName("이벤트 진행중이지 않은 상점의 정보를 조회한다.") + void getShopWithoutEvents() { + when(clock.instant()).thenReturn( + ZonedDateTime.parse("2024-02-21 18:00:00 KST", ofPattern("yyyy-MM-dd HH:mm:ss z")).toInstant()); + when(clock.getZone()).thenReturn(Clock.systemDefaultZone().getZone()); + + var now = LocalDate.of(2024, 2, 21); + var user = owner.getUser(); + Shop shopRequest = Shop.builder() + .owner(owner) + .name("테스트 상점2") + .internalName("테스트2") + .chosung("테스트") + .phone("010-1234-5678") + .address("대전광역시 유성구 대학로 291") + .description("테스트 상점입니다.") + .delivery(true) + .deliveryPrice(3000L) + .payCard(true) + .payBank(true) + .isDeleted(false) + .isEvent(false) + .remarks("비고") + .hit(0L) + .build(); + Shop newShop = shopRepository.save(shopRequest); + + ShopOpen open1 = ShopOpen.builder() + .openTime(LocalTime.of(0, 0)) + .closeTime(LocalTime.of(21, 0)) + .shop(shop) + .closed(false) + .dayOfWeek("MONDAY") + .build(); + + ShopOpen open2 = ShopOpen.builder() + .openTime(LocalTime.of(0, 0)) + .closeTime(LocalTime.of(0, 0)) + .shop(newShop) + .closed(false) + .dayOfWeek("FRIDAY") + .build(); + + shopOpenRepository.save(open1); + shopOpenRepository.save(open2); + + ShopCategoryMap shopCategoryMap1 = ShopCategoryMap.builder() + .shop(shop) + .shopCategory(shopCategory1) + .build(); + + ShopCategoryMap shopCategoryMap2 = ShopCategoryMap.builder() + .shop(newShop) + .shopCategory(shopCategory2) + .build(); + + shopCategoryMapRepository.save(shopCategoryMap1); + shopCategoryMapRepository.save(shopCategoryMap2); + + ShopImage shopImage1 = ShopImage.builder() + .imageUrl("https://test.com/test1.jpg") + .shop(shop) + .build(); + + ShopImage shopImage2 = ShopImage.builder() + .imageUrl("https://test.com/test2.jpg") + .shop(newShop) + .build(); + + shopImageRepository.save(shopImage1); + shopImageRepository.save(shopImage2); + + EventArticle eventArticle1 = EventArticle.builder() + .shop(newShop) + .title("테스트 이벤트 1") + .content("

테스트 이벤트 내용1

") + .user(user) + .thumbnail("https://test.com/test-thumbnail-1.jpg") + .hit(0) + .ip("123.123.123.11") + .startDate(now.minusDays(5)) + .endDate(now.minusDays(1)) + .build(); + eventArticleRepository.save(eventArticle1); + + ExtractableResponse response = RestAssured + .given() + .when() + .get("/shops/{shopId}", newShop.getId()) + .then() + .statusCode(HttpStatus.OK.value()) + .extract(); + + Assertions.assertThat(response.jsonPath().getBoolean("is_event")).isFalse(); + } + } diff --git a/src/test/java/in/koreatech/koin/support/JsonAssertions.java b/src/test/java/in/koreatech/koin/support/JsonAssertions.java index cb6ae055fe..5766ec5284 100644 --- a/src/test/java/in/koreatech/koin/support/JsonAssertions.java +++ b/src/test/java/in/koreatech/koin/support/JsonAssertions.java @@ -31,7 +31,7 @@ public void isEqualTo(String actual) { }); Assertions.assertThat(responseMap).isEqualTo(expectedMap); } catch (Exception ignored) { - + } } From 47a48f8ea8ef6e9fa3e7406c2f999d603f0e4899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8E=E1=85=AC=E1=84=8C=E1=85=AE=E1=86=AB=E1=84=92?= =?UTF-8?q?=E1=85=A9?= Date: Thu, 4 Apr 2024 01:40:24 +0900 Subject: [PATCH 3/4] =?UTF-8?q?test:=20=EC=9D=B8=EC=9E=90=20=EB=B3=80?= =?UTF-8?q?=EC=88=98=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/in/koreatech/koin/acceptance/ShopApiTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/in/koreatech/koin/acceptance/ShopApiTest.java b/src/test/java/in/koreatech/koin/acceptance/ShopApiTest.java index dadb526ab3..439ae65cb0 100644 --- a/src/test/java/in/koreatech/koin/acceptance/ShopApiTest.java +++ b/src/test/java/in/koreatech/koin/acceptance/ShopApiTest.java @@ -594,7 +594,7 @@ void getShopMenus() { ExtractableResponse response = RestAssured .given() .when() - .get("/shops/1/menus") + .get("/shops/{shopId}/menus", shop.getId()) .then() .statusCode(HttpStatus.OK.value()) .extract(); From ab1d962375097b35be7133e5419f33036feabe8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8E=E1=85=AC=E1=84=8C=E1=85=AE=E1=86=AB=E1=84=92?= =?UTF-8?q?=E1=85=A9?= Date: Fri, 5 Apr 2024 14:20:58 +0900 Subject: [PATCH 4/4] =?UTF-8?q?test:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=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/acceptance/OwnerShopApiTest.java | 93 +++---- .../koin/acceptance/ShopApiTest.java | 250 +++++++++--------- .../koin/support/JsonAssertions.java | 1 - 3 files changed, 174 insertions(+), 170 deletions(-) diff --git a/src/test/java/in/koreatech/koin/acceptance/OwnerShopApiTest.java b/src/test/java/in/koreatech/koin/acceptance/OwnerShopApiTest.java index 59152e2fff..e7f3598625 100644 --- a/src/test/java/in/koreatech/koin/acceptance/OwnerShopApiTest.java +++ b/src/test/java/in/koreatech/koin/acceptance/OwnerShopApiTest.java @@ -7,6 +7,7 @@ import java.time.Clock; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZonedDateTime; import java.util.List; @@ -389,52 +390,52 @@ void getShop() { List savedShopCategoryMaps = shopCategoryMapRepository.findAllByShopId(shop.getId()); JsonAssertions.assertThat(response.asPrettyString()) - .isEqualTo(""" - { - "address": "대전광역시 유성구 대학로 291", - "delivery": true, - "delivery_price": 3000, - "description": "테스트 상점입니다.", - "id": 1, - "image_urls": [ - "https://test.com/test1.jpg", - "https://test.com/test2.jpg" - ], - "menu_categories": [ - - ], - "name": "테스트 상점", - "open": [ - { - "day_of_week": "MONDAY", - "closed": false, - "open_time": "00:00", - "close_time": "21:00" - }, - { - "day_of_week": "FRIDAY", - "closed": false, - "open_time": "00:00", - "close_time": "00:00" - } - ], - "pay_bank": true, - "pay_card": true, - "phone": "010-1234-5678", - "shop_categories": [ - { - "id": 1, - "name": "테스트1" - }, - { - "id": 2, - "name": "테스트2" - } - ], - "updated_at": "2024-04-04", - "is_event": false - } - """); + .isEqualTo(String.format(""" + { + "address": "대전광역시 유성구 대학로 291", + "delivery": true, + "delivery_price": 3000, + "description": "테스트 상점입니다.", + "id": 1, + "image_urls": [ + "https://test.com/test1.jpg", + "https://test.com/test2.jpg" + ], + "menu_categories": [ + + ], + "name": "테스트 상점", + "open": [ + { + "day_of_week": "MONDAY", + "closed": false, + "open_time": "00:00", + "close_time": "21:00" + }, + { + "day_of_week": "FRIDAY", + "closed": false, + "open_time": "00:00", + "close_time": "00:00" + } + ], + "pay_bank": true, + "pay_card": true, + "phone": "010-1234-5678", + "shop_categories": [ + { + "id": 1, + "name": "테스트1" + }, + { + "id": 2, + "name": "테스트2" + } + ], + "updated_at": "%s", + "is_event": false + } + """, LocalDateTime.now().format(ofPattern("yyyy-MM-dd")))); } @Test diff --git a/src/test/java/in/koreatech/koin/acceptance/ShopApiTest.java b/src/test/java/in/koreatech/koin/acceptance/ShopApiTest.java index 439ae65cb0..49e5d36a16 100644 --- a/src/test/java/in/koreatech/koin/acceptance/ShopApiTest.java +++ b/src/test/java/in/koreatech/koin/acceptance/ShopApiTest.java @@ -1,13 +1,13 @@ package in.koreatech.koin.acceptance; import static in.koreatech.koin.domain.user.model.UserType.OWNER; -import static in.koreatech.koin.support.JsonAssertions.assertThat; import static java.time.format.DateTimeFormatter.ofPattern; import static org.assertj.core.api.SoftAssertions.assertSoftly; import static org.mockito.Mockito.when; import java.time.Clock; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZonedDateTime; import java.util.List; @@ -425,51 +425,53 @@ void getShop() throws Exception { .statusCode(HttpStatus.OK.value()) .extract(); - assertThat(response.asPrettyString()).isEqualTo(""" - { - "address": "대전광역시 유성구 대학로 291", - "delivery": true, - "delivery_price": 3000, - "description": "테스트 상점입니다.", - "id": 1, - "image_urls": [ - "https://test.com/test1.jpg", - "https://test.com/test2.jpg" - ], - "menu_categories": [ - - ], - "name": "테스트 상점", - "open": [ - { - "day_of_week": "MONDAY", - "closed": false, - "open_time": "00:00", - "close_time": "21:00" - }, - { - "day_of_week": "FRIDAY", - "closed": false, - "open_time": "00:00", - "close_time": "00:00" - } - ], - "pay_bank": true, - "pay_card": true, - "phone": "010-1234-5678", - "shop_categories": [ - { - "id": 1, - "name": "테스트1" - }, - { - "id": 2, - "name": "테스트2" - } - ], - "updated_at": "2024-04-04", - "is_event": false - }"""); + JsonAssertions.assertThat(response.asPrettyString()) + .isEqualTo(String.format(""" + { + "address": "대전광역시 유성구 대학로 291", + "delivery": true, + "delivery_price": 3000, + "description": "테스트 상점입니다.", + "id": 1, + "image_urls": [ + "https://test.com/test1.jpg", + "https://test.com/test2.jpg" + ], + "menu_categories": [ + + ], + "name": "테스트 상점", + "open": [ + { + "day_of_week": "MONDAY", + "closed": false, + "open_time": "00:00", + "close_time": "21:00" + }, + { + "day_of_week": "FRIDAY", + "closed": false, + "open_time": "00:00", + "close_time": "00:00" + } + ], + "pay_bank": true, + "pay_card": true, + "phone": "010-1234-5678", + "shop_categories": [ + { + "id": 1, + "name": "테스트1" + }, + { + "id": 2, + "name": "테스트2" + } + ], + "updated_at": "%s", + "is_event": false + }""", LocalDateTime.now().format(ofPattern("yyyy-MM-dd"))) + ); } @Test @@ -600,83 +602,85 @@ void getShopMenus() { .extract(); JsonAssertions.assertThat(response.asPrettyString()) - .isEqualTo(""" - { - "count": 3, - "menu_categories": [ - { - "id": 1, - "name": "중식", - "menus": [ - { - "id": 1, - "name": "짜장면", - "is_hidden": false, - "is_single": false, - "single_price": null, - "option_prices": [ - { - "option": "일반", - "price": 7000 - }, - { - "option": "곱빼기", - "price": 7500 - } - ], - "description": "맛있는 짜장면", - "image_urls": [ - "https://test.com/test.jpg", - "https://test.com/hello.jpg" - ] - } - ] - }, - { - "id": 2, - "name": "한식", - "menus": [ - { - "id": 2, - "name": "짜장면2", - "is_hidden": false, - "is_single": false, - "single_price": null, - "option_prices": [ - { - "option": "일반", - "price": 7000 - }, - { - "option": "곱빼기", - "price": 7500 - } - ], - "description": "맛있는 짜장면", - "image_urls": [ - "https://test.com/test.jpg", - "https://test.com/hello.jpg" - ] - }, - { - "id": 3, - "name": "짜장면3", - "is_hidden": false, - "is_single": true, - "single_price": 7000, - "option_prices": null, - "description": "맛있는 짜장면", - "image_urls": [ - "https://test.com/test.jpg", - "https://test.com/hello.jpg" - ] - } - ] - } - ], - "updated_at": "2024-04-04" - } - """); + .isEqualTo(String.format(""" + { + "count": 3, + "menu_categories": [ + { + "id": 1, + "name": "중식", + "menus": [ + { + "id": 1, + "name": "짜장면", + "is_hidden": false, + "is_single": false, + "single_price": null, + "option_prices": [ + { + "option": "일반", + "price": 7000 + }, + { + "option": "곱빼기", + "price": 7500 + } + ], + "description": "맛있는 짜장면", + "image_urls": [ + "https://test.com/test.jpg", + "https://test.com/hello.jpg" + ] + } + ] + }, + { + "id": 2, + "name": "한식", + "menus": [ + { + "id": 2, + "name": "짜장면2", + "is_hidden": false, + "is_single": false, + "single_price": null, + "option_prices": [ + { + "option": "일반", + "price": 7000 + }, + { + "option": "곱빼기", + "price": 7500 + } + ], + "description": "맛있는 짜장면", + "image_urls": [ + "https://test.com/test.jpg", + "https://test.com/hello.jpg" + ] + }, + { + "id": 3, + "name": "짜장면3", + "is_hidden": false, + "is_single": true, + "single_price": 7000, + "option_prices": null, + "description": "맛있는 짜장면", + "image_urls": [ + "https://test.com/test.jpg", + "https://test.com/hello.jpg" + ] + } + ] + } + ], + "updated_at": "%s" + } + """, + LocalDate.now().format(ofPattern("yyyy-MM-dd"))) + ); } @Test diff --git a/src/test/java/in/koreatech/koin/support/JsonAssertions.java b/src/test/java/in/koreatech/koin/support/JsonAssertions.java index 5766ec5284..4896a3ca72 100644 --- a/src/test/java/in/koreatech/koin/support/JsonAssertions.java +++ b/src/test/java/in/koreatech/koin/support/JsonAssertions.java @@ -34,6 +34,5 @@ public void isEqualTo(String actual) { } } - } }