From 154cb8a183b458b56fa34e1cbd4402c11cd13223 Mon Sep 17 00:00:00 2001 From: Jungseok Sung Date: Sat, 15 Apr 2023 16:01:05 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20=EA=B3=B5=EA=B0=84=20=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4=20=EC=A0=81=EC=9A=A9=20=EC=82=AC=EC=9A=A9=EC=84=B1=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0=20(#963)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 공간 예약 조건에 우선순위 개념 추가 우선순위를 가지는 조건이 모든 조건중에 우선적으로 적용된다 * feat: priority 중복 검증 로직 추가 * refactor: priority -> order 로 네이밍 변경 priority 는 높은 숫자가 우선인지 낮은숫자가 우선인지 모호할 수 있음 네이밍을 order로 하여 낮은 순서부터 우선순위를 가지는 점을 명백히 한다 * feat: settings flatten 메서드 생성 setting 검증의 용이함을 위해서 setting overwrite의 개념을 평탄화 하여 나타내주는 메서드 * feat: setting 예약 조건 요약 API 추가 * fix: test fail 수정 * test: settings flatten 관련 테스트 작성 * test: setting 요약 조회 API 인수 테스트 작성 * fix: SettingRequest DTO priorityOrder 필드명 변경 * fix: 클라측으로 반환시 priorityOrder 의 역순으로 정렬해서 반환 * refactor: 특정 요일에 대한 세팅만 추출해서 머지하도록 수정 예약 조건 검증 시, 요일에 대한 '실질적' 세팅 객체를 만들어서 검증 * feat: setting summary api - flat setting summary 요청 시, setting merge 로직 추가 * fix: setting summary api 에러 수정 Setting View Type 에 따른 로직 분기 ENUM으로 처리 * test: setting controller test case 고도화 * docs: flyway script 초기 priority order 값 수정 * feat: 예약 검증 관련 에러 메세지 수정 --- backend/src/docs/asciidoc/setting.adoc | 27 ++ .../controller/SettingController.java | 39 +++ .../zzimkkong/domain/EnabledDayOfWeek.java | 16 +- .../woowacourse/zzimkkong/domain/Setting.java | 173 ++++++++++++- .../zzimkkong/domain/SettingViewType.java | 84 +++++++ .../zzimkkong/domain/Settings.java | 228 ++++++++++++----- .../woowacourse/zzimkkong/domain/Space.java | 1 + .../zzimkkong/domain/TimeSlot.java | 68 +++++- .../zzimkkong/domain/TimeUnit.java | 45 ++++ .../dto/DuplicateSettingOrderValidator.java | 25 ++ .../dto/NotDuplicatedSettingOrder.java | 23 ++ .../zzimkkong/dto/TimeUnitValidator.java | 7 +- .../zzimkkong/dto/ValidatorMessage.java | 4 +- .../zzimkkong/dto/space/SettingRequest.java | 11 +- .../zzimkkong/dto/space/SettingResponse.java | 10 +- .../dto/space/SettingsSummaryResponse.java | 18 ++ .../dto/space/SpaceCreateUpdateRequest.java | 4 +- .../dto/space/SpaceFindDetailResponse.java | 5 +- .../exception/ZzimkkongException.java | 12 +- .../InvalidStartEndTimeException.java | 18 +- .../setting/InvalidOrderException.java | 10 + .../setting/NoSettingAvailableException.java | 2 +- .../setting/SettingConflictException.java | 17 -- .../datetime/TimeZoneUtils.java | 11 +- .../zzimkkong/service/ReservationService.java | 6 +- .../zzimkkong/service/SettingService.java | 45 ++++ .../zzimkkong/service/SpaceService.java | 4 +- .../migration/prod/V22__setting_priority.sql | 2 + .../zzimkkong/controller/AcceptanceTest.java | 6 +- .../controller/AdminControllerTest.java | 3 +- .../GuestReservationControllerTest.java | 6 +- .../controller/GuestSpaceControllerTest.java | 6 +- .../ManagerReservationControllerTest.java | 6 +- .../ManagerSpaceControllerTest.java | 16 +- .../controller/PresetControllerTest.java | 4 +- .../controller/SettingControllerTest.java | 230 ++++++++++++++++++ .../zzimkkong/domain/PresetTest.java | 1 + .../zzimkkong/domain/SettingTest.java | 107 ++++++++ .../zzimkkong/domain/SettingsTest.java | 134 ++++++++-- .../zzimkkong/domain/SpaceTest.java | 22 +- .../zzimkkong/domain/TimeSlotTest.java | 78 ++++++ .../zzimkkong/domain/TimeUnitTest.java | 85 ++++++- .../dto/PresetCreateRequestTest.java | 3 +- .../zzimkkong/dto/RequestTest.java | 3 +- .../zzimkkong/dto/SettingRequestTest.java | 6 +- .../repository/MapRepositoryTest.java | 6 +- .../ReservationRepositoryImplTest.java | 3 +- .../repository/ReservationRepositoryTest.java | 6 +- .../repository/SpaceRepositoryTest.java | 6 +- .../zzimkkong/service/AdminServiceTest.java | 6 +- .../service/GuestReservationServiceTest.java | 19 +- .../ManagerReservationServiceTest.java | 19 +- .../zzimkkong/service/MapServiceTest.java | 6 +- .../zzimkkong/service/PresetServiceTest.java | 4 +- .../zzimkkong/service/SpaceServiceTest.java | 12 +- 55 files changed, 1508 insertions(+), 210 deletions(-) create mode 100644 backend/src/docs/asciidoc/setting.adoc create mode 100644 backend/src/main/java/com/woowacourse/zzimkkong/controller/SettingController.java create mode 100644 backend/src/main/java/com/woowacourse/zzimkkong/domain/SettingViewType.java create mode 100644 backend/src/main/java/com/woowacourse/zzimkkong/dto/DuplicateSettingOrderValidator.java create mode 100644 backend/src/main/java/com/woowacourse/zzimkkong/dto/NotDuplicatedSettingOrder.java create mode 100644 backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingsSummaryResponse.java create mode 100644 backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/InvalidOrderException.java delete mode 100644 backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/SettingConflictException.java create mode 100644 backend/src/main/java/com/woowacourse/zzimkkong/service/SettingService.java create mode 100644 backend/src/main/resources/db/migration/prod/V22__setting_priority.sql create mode 100644 backend/src/test/java/com/woowacourse/zzimkkong/controller/SettingControllerTest.java diff --git a/backend/src/docs/asciidoc/setting.adoc b/backend/src/docs/asciidoc/setting.adoc new file mode 100644 index 000000000..7df2933a2 --- /dev/null +++ b/backend/src/docs/asciidoc/setting.adoc @@ -0,0 +1,27 @@ +== Setting(공간 예약 조건) + +=== 특정 날짜 예약 조건 조회 (예약자 view 용 = flat) +==== Request +include::{snippets}/setting/get_flat/http-request.adoc[] +==== Response +include::{snippets}/setting/get_flat/http-response.adoc[] + +=== 특정 날짜 예약 조건 조회 (관리자 view 용 = stack) +==== 공간 관리자 +===== Request +include::{snippets}/setting/get_stack/http-request.adoc[] +===== Response +include::{snippets}/setting/get_stack/http-response.adoc[] + +=== 전체 예약 조건 조회 (예약자 view 용 = flat) +==== Request +include::{snippets}/setting/get_flat_all/http-request.adoc[] +==== Response +include::{snippets}/setting/get_flat_all/http-response.adoc[] + +=== 전체 예약 조건 조회 (관리자 view 용 = stack) +==== 공간 관리자 +===== Request +include::{snippets}/setting/get_stack_all/http-request.adoc[] +===== Response +include::{snippets}/setting/get_stack_all/http-response.adoc[] \ No newline at end of file diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/controller/SettingController.java b/backend/src/main/java/com/woowacourse/zzimkkong/controller/SettingController.java new file mode 100644 index 000000000..8f19f6b79 --- /dev/null +++ b/backend/src/main/java/com/woowacourse/zzimkkong/controller/SettingController.java @@ -0,0 +1,39 @@ +package com.woowacourse.zzimkkong.controller; + +import com.woowacourse.zzimkkong.config.logaspect.LogMethodExecutionTime; +import com.woowacourse.zzimkkong.dto.space.SettingsSummaryResponse; +import com.woowacourse.zzimkkong.domain.SettingViewType; +import com.woowacourse.zzimkkong.infrastructure.datetime.TimeZoneUtils; +import com.woowacourse.zzimkkong.service.SettingService; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.time.ZonedDateTime; + +import static com.woowacourse.zzimkkong.dto.ValidatorMessage.DATETIME_FORMAT; + +@LogMethodExecutionTime(group = "controller") +@RestController +@RequestMapping("/api/maps/{mapId}/spaces/{spaceId}/settings") +public class SettingController { + private final SettingService settingService; + + public SettingController(final SettingService settingService) { + this.settingService = settingService; + } + + @GetMapping("/summary") + public ResponseEntity getSettingsSummary( + @PathVariable final Long mapId, + @PathVariable final Long spaceId, + @RequestParam(required = false) @DateTimeFormat(pattern = DATETIME_FORMAT) final ZonedDateTime selectedDateTime, + @RequestParam(required = false, defaultValue = "FLAT") final String settingViewType) { + SettingsSummaryResponse settingsSummaryResponse = settingService.getSettingsSummary( + mapId, + spaceId, + TimeZoneUtils.convertToUTC(selectedDateTime), + settingViewType); + return ResponseEntity.ok().body(settingsSummaryResponse); + } +} diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/domain/EnabledDayOfWeek.java b/backend/src/main/java/com/woowacourse/zzimkkong/domain/EnabledDayOfWeek.java index 97131b92c..d9cd3b7fc 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/domain/EnabledDayOfWeek.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/domain/EnabledDayOfWeek.java @@ -1,6 +1,7 @@ package com.woowacourse.zzimkkong.domain; import com.woowacourse.zzimkkong.exception.setting.NoSuchEnabledDayOfWeekException; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import java.util.Arrays; @@ -8,14 +9,15 @@ import java.util.stream.Collectors; @Slf4j +@Getter public enum EnabledDayOfWeek { - MONDAY("월"), - TUESDAY("화"), - WEDNESDAY("수"), - THURSDAY("목"), - FRIDAY("금"), - SATURDAY("토"), - SUNDAY("일"); + MONDAY("월요일"), + TUESDAY("화요일"), + WEDNESDAY("수요일"), + THURSDAY("목요일"), + FRIDAY("금요일"), + SATURDAY("토요일"), + SUNDAY("일요일"); private final String displayName; diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/domain/Setting.java b/backend/src/main/java/com/woowacourse/zzimkkong/domain/Setting.java index 99e4791cd..7eb0026e3 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/domain/Setting.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/domain/Setting.java @@ -1,18 +1,26 @@ package com.woowacourse.zzimkkong.domain; +import com.woowacourse.zzimkkong.exception.setting.InvalidOrderException; import com.woowacourse.zzimkkong.exception.space.InvalidMinimumMaximumTimeUnitException; import com.woowacourse.zzimkkong.exception.space.NotEnoughAvailableTimeException; import com.woowacourse.zzimkkong.exception.space.TimeUnitInconsistencyException; import com.woowacourse.zzimkkong.exception.space.TimeUnitMismatchException; -import lombok.*; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import net.logstash.logback.encoder.org.apache.commons.lang3.StringUtils; +import org.springframework.util.CollectionUtils; import javax.persistence.*; import java.time.DayOfWeek; import java.time.LocalTime; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Locale; import java.util.stream.Collectors; +import static com.woowacourse.zzimkkong.dto.ValidatorMessage.INVALID_SETTING_ORDER_MESSAGE; import static com.woowacourse.zzimkkong.infrastructure.message.MessageUtils.LINE_SEPARATOR; @Builder @@ -20,6 +28,9 @@ @NoArgsConstructor @Entity public class Setting { + public static final int FLAT_PRIORITY_ORDER = -1; + public static final long FLAT_SETTING_ID = 0L; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -57,6 +68,9 @@ public class Setting { @Column(nullable = false) private String enabledDayOfWeek; + @Column(nullable = false) + private Integer priorityOrder; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "space_id", foreignKey = @ForeignKey(name = "fk_setting_space"), nullable = false) private Space space; @@ -68,6 +82,7 @@ public Setting( final TimeUnit reservationMinimumTimeUnit, final TimeUnit reservationMaximumTimeUnit, final String enabledDayOfWeek, + final Integer priorityOrder, final Space space) { this.id = id; this.settingTimeSlot = settingTimeSlot; @@ -75,11 +90,24 @@ public Setting( this.reservationMinimumTimeUnit = reservationMinimumTimeUnit; this.reservationMaximumTimeUnit = reservationMaximumTimeUnit; this.enabledDayOfWeek = enabledDayOfWeek; + this.priorityOrder = priorityOrder; this.space = space; validateSetting(); } + public Setting createSettingBasedOn(final TimeSlot timeSlot, final EnabledDayOfWeek dayOfWeek) { + return Setting.builder() + .id(this.getId()) + .settingTimeSlot(timeSlot) + .reservationTimeUnit(this.getReservationTimeUnit()) + .reservationMinimumTimeUnit(this.getReservationMinimumTimeUnit()) + .reservationMaximumTimeUnit(this.getReservationMaximumTimeUnit()) + .enabledDayOfWeek(dayOfWeek.name().toLowerCase(Locale.ROOT)) + .priorityOrder(this.getPriorityOrder()) + .build(); + } + private void validateSetting() { if (settingTimeSlot.isNotDivisibleBy(reservationTimeUnit)) { throw new TimeUnitMismatchException(); @@ -96,6 +124,10 @@ private void validateSetting() { if (settingTimeSlot.isDurationShorterThan(reservationMaximumTimeUnit)) { throw new NotEnoughAvailableTimeException(); } + + if (priorityOrder == null || priorityOrder < FLAT_PRIORITY_ORDER) { + throw new InvalidOrderException(INVALID_SETTING_ORDER_MESSAGE); + } } public LocalTime getSettingStartTime() { @@ -124,14 +156,8 @@ private boolean isNotConsistentTimeUnit() { } public boolean hasConflictWith(final Setting that) { - List thisEnabledDayOfWeek = Arrays.stream(this.enabledDayOfWeek.split(Space.DELIMITER)) - .map(String::trim) - .map(EnabledDayOfWeek::from) - .collect(Collectors.toList()); - boolean enabledDayOfWeekMatch = Arrays.stream(that.enabledDayOfWeek.split(Space.DELIMITER)) - .map(String::trim) - .map(EnabledDayOfWeek::from) - .anyMatch(thisEnabledDayOfWeek::contains); + List thisEnabledDayOfWeek = this.getEnabledDayOfWeekList(); + boolean enabledDayOfWeekMatch = that.getEnabledDayOfWeekList().stream().anyMatch(thisEnabledDayOfWeek::contains); return this.settingTimeSlot.hasConflictWith(that.settingTimeSlot) && enabledDayOfWeekMatch; } @@ -157,9 +183,136 @@ public void updateSpace(final Space space) { this.space = space; } + public List getEnabledDayOfWeekList() { + return Arrays.stream(this.enabledDayOfWeek.split(Space.DELIMITER)) + .map(String::trim) + .map(EnabledDayOfWeek::from) + .collect(Collectors.toList()); + } + + /** + * 2023.04.02 기준 + * 인자로 주어진 settings 의 조건들에 배타적인 (겹치지 않는) 새로운 setting slot 리스트를 생성한다 + * 기존 setting 을 조각내어 새로운 여러개의 (transient) setting 을 생성한다 + * + * @param settings 서로 시간대와 요일이 겹치지 않는 (= flat 한) setting 들 + * @return List of Setting Slot (조각 내어진 세팅 슬롯들) + */ + + public List extractExclusiveSettingSlots(final List settings) { + List exclusiveSettingSlots = List.of(Setting.builder() + .id(FLAT_SETTING_ID) + .settingTimeSlot(this.settingTimeSlot) + .reservationTimeUnit(this.reservationTimeUnit) + .reservationMinimumTimeUnit(this.reservationMinimumTimeUnit) + .reservationMaximumTimeUnit(this.reservationMaximumTimeUnit) + .enabledDayOfWeek(this.enabledDayOfWeek) + .priorityOrder(FLAT_PRIORITY_ORDER) + .space(this.space) + .build()); + for (Setting setting : settings) { + List newExclusiveSettingSlots = new ArrayList<>(); + for (Setting exclusiveSettingSlot : exclusiveSettingSlots) { + newExclusiveSettingSlots.addAll(exclusiveSettingSlot.extractNewExclusiveSettingSlots(setting)); + } + exclusiveSettingSlots = newExclusiveSettingSlots; + } + return exclusiveSettingSlots; + } + + private List extractNewExclusiveSettingSlots(final Setting setting) { + if (!this.hasConflictWith(setting)) { + return List.of(this); + } + + List newExclusiveSettingSlots = new ArrayList<>(); + + List exclusiveTimeSlots = this.settingTimeSlot.extractExclusiveTimeSlots(setting.settingTimeSlot); + for (TimeSlot exclusiveTimeSlot : exclusiveTimeSlots) { + TimeUnit adjustedIntervalTimeUnit = this.reservationTimeUnit.getAdjustedIntervalTimeUnit(exclusiveTimeSlot); + + Setting survivedSettingSlot = Setting.builder() + .id(FLAT_SETTING_ID) + .settingTimeSlot(exclusiveTimeSlot) + .reservationTimeUnit(adjustedIntervalTimeUnit) + .reservationMinimumTimeUnit( + this.reservationMinimumTimeUnit.getAdjustedTimeUnit( + exclusiveTimeSlot, + adjustedIntervalTimeUnit)) + .reservationMaximumTimeUnit( + this.reservationMaximumTimeUnit.getAdjustedTimeUnit( + exclusiveTimeSlot, + adjustedIntervalTimeUnit)) + .enabledDayOfWeek(this.enabledDayOfWeek) + .priorityOrder(FLAT_PRIORITY_ORDER) + .space(this.space) + .build(); + + newExclusiveSettingSlots.add(survivedSettingSlot); + } + + List conflictingSettingEnabledDayOfWeek = setting.getEnabledDayOfWeekList(); + List exclusiveEnabledDayOfWeek = this.getEnabledDayOfWeekList() + .stream() + .filter(dayOfWeek -> !conflictingSettingEnabledDayOfWeek.contains(dayOfWeek)) + .collect(Collectors.toList()); + + if (!CollectionUtils.isEmpty(exclusiveEnabledDayOfWeek)) { + TimeSlot overlappingTimeSlot = this.settingTimeSlot.extractOverlappingTimeSlot(setting.settingTimeSlot); + String nonConflictingDayOfWeek = exclusiveEnabledDayOfWeek.stream() + .map(dayOfWeek -> dayOfWeek.name().toLowerCase(Locale.ROOT)) + .collect(Collectors.joining(",")); + TimeUnit adjustedIntervalTimeUnit = this.reservationTimeUnit.getAdjustedIntervalTimeUnit(overlappingTimeSlot); + + Setting survivedSettingSlot = Setting.builder() + .id(FLAT_SETTING_ID) + .settingTimeSlot(overlappingTimeSlot) + .reservationTimeUnit(adjustedIntervalTimeUnit) + .reservationMinimumTimeUnit( + this.reservationMinimumTimeUnit.getAdjustedTimeUnit( + overlappingTimeSlot, + adjustedIntervalTimeUnit)) + .reservationMaximumTimeUnit( + this.reservationMaximumTimeUnit.getAdjustedTimeUnit( + overlappingTimeSlot, + adjustedIntervalTimeUnit)) + .enabledDayOfWeek(nonConflictingDayOfWeek) + .priorityOrder(FLAT_PRIORITY_ORDER) + .space(this.space) + .build(); + newExclusiveSettingSlots.add(survivedSettingSlot); + } + + return newExclusiveSettingSlots; + } + + public String toSummaryWithoutDayOfWeek(final Boolean flat) { + String priority = "[우선순위 " + priorityOrder.toString() + "] "; + if (flat) { + priority = StringUtils.EMPTY; + } + return String.format("%s%s (최소 %s, 최대 %s, 예약 단위 %s)", + priority, + settingTimeSlot.toString(), + reservationMinimumTimeUnit.toString(), + reservationMaximumTimeUnit.toString(), + reservationTimeUnit.toString()); + } + + public boolean canMergeIgnoringDayOfWeek(final Setting that) { + return this.settingTimeSlot.isExtendableWith(that.settingTimeSlot) + && this.reservationTimeUnit.equals(that.reservationTimeUnit) + && this.reservationMinimumTimeUnit.equals(that.reservationMinimumTimeUnit) + && this.reservationMaximumTimeUnit.equals(that.reservationMaximumTimeUnit); + } + + public boolean isFlattenedSetting() { + return FLAT_PRIORITY_ORDER == this.priorityOrder; + } + @Override public String toString() { - return "예약 가능한 요일: " + + return "예약 요일: " + EnabledDayOfWeek.getDisplayNames(enabledDayOfWeek) + LINE_SEPARATOR + "예약 가능한 시간대: " + diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/domain/SettingViewType.java b/backend/src/main/java/com/woowacourse/zzimkkong/domain/SettingViewType.java new file mode 100644 index 000000000..c7168493f --- /dev/null +++ b/backend/src/main/java/com/woowacourse/zzimkkong/domain/SettingViewType.java @@ -0,0 +1,84 @@ +package com.woowacourse.zzimkkong.domain; + +import com.woowacourse.zzimkkong.exception.ZzimkkongException; +import com.woowacourse.zzimkkong.infrastructure.datetime.TimeZoneUtils; +import org.springframework.http.HttpStatus; + +import java.time.DayOfWeek; +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.function.BiFunction; +import java.util.function.BiPredicate; + +/** + * {@link SettingViewType#STACK_SINGLE}: 맵 관리자가 설정한 특정 요일의 예약 조건 그대로 보여준다 (겹치는 조건 O). 관리자들을 위한 view + * {@link SettingViewType#STACK_ALL}: 맵 관리자가 설정한 모든 요일의 예약 조건 그대로 보여준다 (겹치는 조건 O). 관리자들을 위한 view + * {@link SettingViewType#FLAT_SINGLE}: 특정 요일의 예약 조건을 평탄화 하여 보여준다 (겹치는 조건 X). 예약자들을 위한 view + * {@link SettingViewType#FLAT_ALL}: 모든 요일의 예약 조건을 평탄화 하여 보여준다 (겹치는 조건 X). 예약자들을 위한 view + * - {@link com.woowacourse.zzimkkong.domain.Settings#flatten()} 메서드 참고 + */ +public enum SettingViewType { + FLAT_SINGLE( + (dateTime, viewType) -> dateTime != null && "FLAT".equals(viewType), + SettingViewType::getFlatSingleSummary), + STACK_SINGLE( + (dateTime, viewType) -> dateTime != null && "STACK".equals(viewType), + SettingViewType::getStackSingleSummary), + FLAT_ALL( + (dateTime, viewType) -> dateTime == null && "FLAT".equals(viewType), + SettingViewType::getFlatAllSummary), + STACK_ALL( + (dateTime, viewType) -> dateTime == null && "STACK".equals(viewType), + SettingViewType::getStackAllSummary); + + private final BiPredicate expression; + private final BiFunction function; + + SettingViewType(final BiPredicate expression, final BiFunction function) { + this.expression = expression; + this.function = function; + } + + public static SettingViewType of(final LocalDateTime dateTime, final String viewType) { + return Arrays.stream(values()) + .filter(settingViewType -> settingViewType.expression.test(dateTime, viewType)) + .findFirst() + .orElseThrow(() -> new ZzimkkongException(HttpStatus.BAD_REQUEST)); + } + + public String getSummary(final Space space, final LocalDateTime dateTime) { + return function.apply(space, dateTime); + } + + private static String getFlatSingleSummary(final Space space, final LocalDateTime dateTime) { + Settings spaceSettings = space.getSpaceSettings(); + DayOfWeek dayOfWeek = TimeZoneUtils.convertTo(dateTime, space.getMap().getServiceZone()) + .toLocalDate() + .getDayOfWeek(); + + spaceSettings.flatten(); + + return spaceSettings.getSummaryOn(EnabledDayOfWeek.from(dayOfWeek.name())); + } + + private static String getStackSingleSummary(final Space space, final LocalDateTime dateTime) { + Settings spaceSettings = space.getSpaceSettings(); + DayOfWeek dayOfWeek = TimeZoneUtils.convertTo(dateTime, space.getMap().getServiceZone()) + .toLocalDate() + .getDayOfWeek(); + + return spaceSettings.getSummaryOn(EnabledDayOfWeek.from(dayOfWeek.name())); + } + + private static String getFlatAllSummary(final Space space, final LocalDateTime dateTime) { + Settings spaceSettings = space.getSpaceSettings(); + + spaceSettings.flatten(); + + return spaceSettings.getSummary(); + } + + private static String getStackAllSummary(final Space space, final LocalDateTime dateTime) { + return space.getSpaceSettings().getSummary(); + } +} diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/domain/Settings.java b/backend/src/main/java/com/woowacourse/zzimkkong/domain/Settings.java index 917ddad57..0637c5273 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/domain/Settings.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/domain/Settings.java @@ -1,7 +1,8 @@ package com.woowacourse.zzimkkong.domain; import com.woowacourse.zzimkkong.dto.space.SettingRequest; -import com.woowacourse.zzimkkong.exception.setting.SettingConflictException; +import com.woowacourse.zzimkkong.exception.ZzimkkongException; +import com.woowacourse.zzimkkong.exception.setting.InvalidOrderException; import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.util.CollectionUtils; @@ -9,13 +10,10 @@ import javax.persistence.*; import java.time.DayOfWeek; import java.time.LocalTime; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; -import java.util.stream.IntStream; +import static com.woowacourse.zzimkkong.dto.ValidatorMessage.DUPLICATE_SETTING_ORDER_MESSAGE; import static com.woowacourse.zzimkkong.infrastructure.message.MessageUtils.LINE_SEPARATOR; @Getter @@ -27,10 +25,8 @@ public class Settings { @OneToMany(mappedBy = "space", cascade = CascadeType.PERSIST, fetch = FetchType.LAZY, orphanRemoval = true) private List settings = new ArrayList<>(); - public Settings(final List settings) { + private Settings(final List settings) { this.settings = new ArrayList<>(settings); - sort(); - validateConflicts(); } public static Settings from(final List settingRequests) { @@ -44,34 +40,61 @@ public static Settings from(final List settingRequests) { .reservationMinimumTimeUnit(TimeUnit.from(settingRequest.getReservationMinimumTimeUnit())) .reservationMaximumTimeUnit(TimeUnit.from(settingRequest.getReservationMaximumTimeUnit())) .enabledDayOfWeek(settingRequest.enabledDayOfWeekAsString()) + .priorityOrder(settingRequest.getPriorityOrder()) .build()) .collect(Collectors.toList()); - return new Settings(settings); + return toPrioritizedSettings(settings); + } + + public static Settings toPrioritizedSettings(final List settings) { + Settings newSettings = new Settings(settings); + newSettings.validateOrderConflict(); + newSettings.sortByPriorityOrder(); + return newSettings; + } + + public static Settings toFlattenedSettings(final List settings) { + Settings newSettings = new Settings(settings); + if (newSettings.isFlat()) { + return newSettings; + } + newSettings.validateOrderConflict(); + newSettings.sortByPriorityOrder(); + newSettings.flatten(); + return newSettings; } public void add(final Setting setting) { + if (isFlat()) { + throw new ZzimkkongException(); + } settings.add(setting); - sort(); - validateConflicts(); + validateOrderConflict(); + sortByPriorityOrder(); } public void addAll(final List newSettings) { + if (isFlat()) { + throw new ZzimkkongException(); + } settings.addAll(newSettings); - sort(); - validateConflicts(); + validateOrderConflict(); + sortByPriorityOrder(); } public Settings getSettingsByTimeSlotAndDayOfWeek(final TimeSlot timeSlot, final DayOfWeek dayOfWeek) { - List filteredSettings = this.settings.stream() + List relevantSettings = this.settings.stream() .filter(setting -> setting.supports(timeSlot, dayOfWeek)) .collect(Collectors.toList()); - return new Settings(filteredSettings); + return toFlattenedSettings(relevantSettings).getMergedSettings( + EnabledDayOfWeek.from( + dayOfWeek.name().toLowerCase(Locale.ROOT))); } - public boolean cannotAcceptDueToAvailableTime(final TimeSlot timeSlot) { - return getAvailableTimeSlots().stream().allMatch(timeSlot::isNotWithin); + public boolean cannotAcceptDueToAvailableTime(final TimeSlot timeSlot, final DayOfWeek dayOfWeek) { + return getAvailableTimeSlots(dayOfWeek).stream().allMatch(timeSlot::isNotWithin); } public boolean isEmpty() { @@ -83,14 +106,17 @@ public boolean haveMultipleSettings() { } /** - * settings 중 조건에 위배되는 예약이 불가능한 시간 대역을 반환한다 + * settings 중 예약이 불가능한 시간 대역을 반환한다 */ - public List getUnavailableTimeSlots() { + public List getUnavailableTimeSlots(final DayOfWeek dayOfWeek) { + Settings flatSettings = toFlattenedSettings(this.settings).getMergedSettings( + EnabledDayOfWeek.from(dayOfWeek.name().toLowerCase(Locale.ROOT))); + List unavailableTimeSlots = new ArrayList<>(); LocalTime unavailableStartTime = LocalTime.MIN; LocalTime unavailableEndTime = TimeSlot.MAX_TIME; - for (int i = 0; i < settings.size(); i++) { - TimeSlot settingTimeSlot = settings.get(i).getSettingTimeSlot(); + for (int i = 0; i < flatSettings.settings.size(); i++) { + TimeSlot settingTimeSlot = flatSettings.settings.get(i).getSettingTimeSlot(); unavailableEndTime = settingTimeSlot.getStartTime(); if (!unavailableStartTime.equals(unavailableEndTime)) { @@ -100,7 +126,7 @@ public List getUnavailableTimeSlots() { unavailableStartTime = settingTimeSlot.getEndTime(); unavailableEndTime = TimeSlot.MAX_TIME; - if (i == settings.size() - 1) { + if (i == flatSettings.settings.size() - 1) { unavailableTimeSlots.add(TimeSlot.of(unavailableStartTime, unavailableEndTime)); } } @@ -113,68 +139,150 @@ public List getUnavailableTimeSlots() { } /** - * settings 중 조건에 위배되지 않는 예약 가능한 시간 대역을 반환한다 + * settings 중 예약 가능한 시간 대역을 반환한다 */ - private List getAvailableTimeSlots() { - if (!haveMultipleSettings()) { + private List getAvailableTimeSlots(final DayOfWeek dayOfWeek) { + if (isFlat()) { return settings.stream() .map(Setting::getSettingTimeSlot) .collect(Collectors.toList()); } + return toFlattenedSettings(this.settings).getMergedSettings( + EnabledDayOfWeek.from( + dayOfWeek.name().toLowerCase(Locale.ROOT))) + .settings + .stream() + .map(Setting::getSettingTimeSlot) + .collect(Collectors.toList()); + } + + /** + * 2023.04.02 기준 + * 공간의 예약 조건은 서로 겹쳐질 (중복될) 수 있으며, 각각 우선순위 (order)를 가진다. + * 우선순위가 높은 예약조건을 우선시하여 검증한다. + * 비즈니스 로직을 단순화 시키기 위해, flatten 메서드로 겹쳐진 예약 조건들을 '동등한 우선순위를 가진 겹치지 않은 상태 (= flat 한 상태)' 로 변환한다. + *

+ * flatten 과정을 거치면 settings 의 모든 setting 들은: + * - {@link Setting#settingTimeSlot}, {@link Setting#enabledDayOfWeek} 두 조건이 서로 겹치지 않는다 + * - id = {@link Setting#FLAT_SETTING_ID} (실제 존재하는 세팅이 아닌 추상적인 transient entity 임을 명시하기 위함) + * - order = {@link Setting#FLAT_PRIORITY_ORDER} (동등한 우선순위) + * - settingStartTime 기준으로 오름차순 정렬된다 + * + */ + public void flatten() { + List flatSettings = new ArrayList<>(); + for (Setting setting : settings) { + List exclusiveSettingSlots = setting.extractExclusiveSettingSlots(new ArrayList<>(flatSettings)); + flatSettings.addAll(exclusiveSettingSlots); + } + this.settings = flatSettings; + sortByTime(); + } + + public String getSummary() { + StringBuilder stringBuilder = new StringBuilder(); + for (EnabledDayOfWeek dayOfWeek : EnabledDayOfWeek.values()) { + stringBuilder.append(getSummaryOn(dayOfWeek)); + } + return stringBuilder.toString(); + } + + public String getSummaryOn(final EnabledDayOfWeek dayOfWeek) { + List settingsOnDayOfWeek = settings.stream() + .filter(setting -> setting.getEnabledDayOfWeekList().contains(dayOfWeek)) + .collect(Collectors.toList()); + + if (CollectionUtils.isEmpty(settingsOnDayOfWeek)) { + return "[" + dayOfWeek.getDisplayName() + "] 이용 불가" + LINE_SEPARATOR; + } + + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("[") + .append(dayOfWeek.getDisplayName()) + .append("]") + .append(LINE_SEPARATOR); + + boolean flat = isFlat(); + if (flat) { + settingsOnDayOfWeek = new Settings(settingsOnDayOfWeek).getMergedSettings(dayOfWeek).settings; + } + for (Setting setting : settingsOnDayOfWeek) { + stringBuilder.append(setting.toSummaryWithoutDayOfWeek(flat)) + .append(LINE_SEPARATOR); + } + return stringBuilder.toString(); + } + + public Settings getMergedSettings(final EnabledDayOfWeek dayOfWeek) { + if (CollectionUtils.isEmpty(this.settings)) { + return new Settings(); + } + + Settings flatSettings = toFlattenedSettings(this.settings); - List availableTimeSlots = new ArrayList<>(); - LocalTime candidateStartTime = settings.get(0).getSettingStartTime(); - LocalTime candidateEndTime = settings.get(0).getSettingEndTime(); - TimeSlot candidateAvailableTimeSlot = TimeSlot.of(candidateStartTime, candidateEndTime); - boolean onExtension; - for (int i = 1; i < settings.size(); i++) { - TimeSlot currentAvailableTimeSlot = settings.get(i).getSettingTimeSlot(); + List mergedSettings = new ArrayList<>(); + Setting startSetting = flatSettings.settings.get(0); + if (!flatSettings.haveMultipleSettings()) { + return new Settings( + List.of( + startSetting.createSettingBasedOn( + startSetting.getSettingTimeSlot(), + dayOfWeek))); + } - if (candidateAvailableTimeSlot.isExtendableWith(currentAvailableTimeSlot)) { - onExtension = true; + for (int i = 1; i < flatSettings.settings.size(); i++) { + Setting endSetting = flatSettings.settings.get(i); + + if (startSetting.canMergeIgnoringDayOfWeek(endSetting)) { + startSetting = startSetting.createSettingBasedOn( + TimeSlot.of(startSetting.getSettingStartTime(), endSetting.getSettingEndTime()), + dayOfWeek); } else { - availableTimeSlots.add(candidateAvailableTimeSlot); - onExtension = false; + mergedSettings.add(startSetting.createSettingBasedOn(startSetting.getSettingTimeSlot(), dayOfWeek)); + startSetting = endSetting; } - if (!onExtension) { - candidateStartTime = currentAvailableTimeSlot.getStartTime(); + if (i == flatSettings.settings.size() - 1) { + mergedSettings.add(startSetting.createSettingBasedOn(startSetting.getSettingTimeSlot(), dayOfWeek)); } - candidateEndTime = currentAvailableTimeSlot.getEndTime(); - candidateAvailableTimeSlot = TimeSlot.of(candidateStartTime, candidateEndTime); + } + return new Settings(mergedSettings); + } - if (i == settings.size() - 1) { - availableTimeSlots.add(TimeSlot.of(candidateStartTime, candidateEndTime)); - } + private void validateOrderConflict() { + Set uniquePriorities = settings.stream() + .map(Setting::getPriorityOrder) + .collect(Collectors.toSet()); + + if (settings.size() != uniquePriorities.size()) { + throw new InvalidOrderException(DUPLICATE_SETTING_ORDER_MESSAGE); } + } - return availableTimeSlots; + private boolean isFlat() { + return settings.size() >= 1 && settings.stream().allMatch(Setting::isFlattenedSetting); } public void clear() { settings.clear(); } - @PostLoad - public void postLoad(){ - sort(); + + public void reverseSortByPriorityOrder() { + settings.sort(Comparator.comparing(Setting::getPriorityOrder).reversed()); } - private void sort() { + private void sortByPriorityOrder() { + settings.sort(Comparator.comparing(Setting::getPriorityOrder)); + } + + private void sortByTime() { settings.sort(Comparator.comparing(Setting::getSettingStartTime)); } - private void validateConflicts() { - IntStream.range(0, settings.size() - 1) - .mapToObj(i -> Map.entry(settings.get(i), settings.get(i + 1))) - .collect(Collectors.toList()) - .forEach(pair -> { - Setting currentSetting = pair.getKey(); - Setting nextSetting = pair.getValue(); - if (currentSetting.hasConflictWith(nextSetting)) { - throw new SettingConflictException(currentSetting, nextSetting); - } - }); + @PostLoad + public void postLoad() { + sortByPriorityOrder(); } @Override diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/domain/Space.java b/backend/src/main/java/com/woowacourse/zzimkkong/domain/Space.java index dc162bb62..82ade787f 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/domain/Space.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/domain/Space.java @@ -9,6 +9,7 @@ import javax.persistence.*; import java.time.DayOfWeek; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; @Getter diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/domain/TimeSlot.java b/backend/src/main/java/com/woowacourse/zzimkkong/domain/TimeSlot.java index 4c77ecc5b..456ee15e4 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/domain/TimeSlot.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/domain/TimeSlot.java @@ -10,6 +10,8 @@ import javax.persistence.Embeddable; import java.time.LocalTime; import java.time.temporal.ChronoUnit; +import java.util.Collections; +import java.util.List; @Getter @NoArgsConstructor @@ -62,10 +64,16 @@ public boolean isDurationLongerThan(final TimeUnit timeUnit) { return timeUnit.isShorterThan(getDurationMinute()); } + public boolean contains(final TimeSlot that) { + boolean equalOrAfterStartTime = that.startTime.equals(this.startTime) || that.startTime.isAfter(this.startTime); + boolean equalOrBeforeEndTime = that.endTime.equals(this.endTime) || that.endTime.isBefore(this.endTime); + return equalOrAfterStartTime && equalOrBeforeEndTime; + } + public boolean isNotWithin(final TimeSlot that) { - boolean isEqualOrAfterStartTime = this.startTime.equals(that.startTime) || this.startTime.isAfter(that.startTime); - boolean isEqualOrBeforeEndTime = this.endTime.equals(that.endTime) || this.endTime.isBefore(that.endTime); - return !(isEqualOrAfterStartTime && isEqualOrBeforeEndTime); + boolean equalOrAfterStartTime = this.startTime.equals(that.startTime) || this.startTime.isAfter(that.startTime); + boolean equalOrBeforeEndTime = this.endTime.equals(that.endTime) || this.endTime.isBefore(that.endTime); + return !(equalOrAfterStartTime && equalOrBeforeEndTime); } public boolean isExtendableWith(final TimeSlot that) { @@ -88,6 +96,60 @@ private TimeUnit getDurationMinute() { return TimeUnit.from(ChronoUnit.MINUTES.between(startTime, endTime)); } + public TimeSlot extractOverlappingTimeSlot(final TimeSlot that) { + if (!this.hasConflictWith(that)) { + return null; + } + + if (that.contains(this)) { + return this; + } + + if (this.hasLeftSkewedConflictWith(that)) { + return TimeSlot.of(that.startTime, this.endTime); + } + + if (this.hasRightSkewedConflictWith(that)) { + return TimeSlot.of(this.startTime, that.endTime); + } + + return TimeSlot.of(that.startTime, that.endTime); + } + + public List extractExclusiveTimeSlots(final TimeSlot that) { + if (!this.hasConflictWith(that)) { + return List.of(this); + } + + if (that.contains(this)) { + return Collections.emptyList(); + } + + if (this.hasLeftSkewedConflictWith(that)) { + return List.of(TimeSlot.of(this.startTime, that.startTime)); + } + + if (this.hasRightSkewedConflictWith(that)) { + return List.of(TimeSlot.of(that.endTime, this.endTime)); + } + + return List.of( + TimeSlot.of(this.startTime, that.startTime), + TimeSlot.of(that.endTime, this.endTime)); + } + + private boolean hasLeftSkewedConflictWith(final TimeSlot that) { + return this.startTime.isBefore(that.startTime) + && ((this.endTime.isAfter(that.startTime) && this.endTime.isBefore(that.endTime)) + || this.endTime.equals(that.endTime)); + } + + private boolean hasRightSkewedConflictWith(final TimeSlot that) { + return ((this.startTime.isAfter(that.startTime) && this.startTime.isBefore(that.endTime)) + || this.startTime.equals(that.startTime)) + && this.endTime.isAfter(that.endTime); + } + @Override public String toString() { String endTimeAsString = endTime.toString(); diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/domain/TimeUnit.java b/backend/src/main/java/com/woowacourse/zzimkkong/domain/TimeUnit.java index b8cd8ee3b..d2eb0f1cf 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/domain/TimeUnit.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/domain/TimeUnit.java @@ -1,5 +1,6 @@ package com.woowacourse.zzimkkong.domain; +import com.woowacourse.zzimkkong.exception.ZzimkkongException; import com.woowacourse.zzimkkong.exception.reservation.IllegalTimeUnitValueException; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -8,6 +9,8 @@ import javax.persistence.Column; import javax.persistence.Embeddable; import java.time.LocalTime; +import java.util.Comparator; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -16,6 +19,8 @@ @EqualsAndHashCode @Embeddable public class TimeUnit { + public static final List INTERVAL_TIME_UNITS = List.of(5, 10, 30, 60); + public static final Integer MINIMUM_TIME_UNIT = 5; private static final Integer MINIMUM_TIME = 0; private static final Map cache = new ConcurrentHashMap<>(); @@ -77,4 +82,44 @@ public String toString() { return String.format("%d시간 %d분", hours, minutes); } + + public TimeUnit getAdjustedIntervalTimeUnit(final TimeSlot timeSlot) { + if (timeSlot.isNotDivisibleBy(this)) { + return INTERVAL_TIME_UNITS.stream() + .sorted(Comparator.reverseOrder()) + .map(TimeUnit::from) + .filter(timeUnit -> !timeSlot.isNotDivisibleBy(timeUnit)) + .findFirst() + .orElseThrow(ZzimkkongException::new); + } + return this; + } + + public TimeUnit getAdjustedTimeUnit(final TimeSlot timeSlot, final TimeUnit intervalTimeUnit) { + if (this.isShorterThan(intervalTimeUnit)) { + return intervalTimeUnit; + } + + TimeUnit candidateMinimumTimeUnit = this; + if (!this.isDivisibleBy(intervalTimeUnit)) { + candidateMinimumTimeUnit = getNextDivisibleTimeUnit(intervalTimeUnit); + } + while (timeSlot.isDurationShorterThan(candidateMinimumTimeUnit)) { + candidateMinimumTimeUnit = candidateMinimumTimeUnit.minus(intervalTimeUnit); + } + return candidateMinimumTimeUnit; + } + + private TimeUnit getNextDivisibleTimeUnit(final TimeUnit timeUnit) { + TimeUnit minimumTimeUnit = cache.get(MINIMUM_TIME_UNIT); + TimeUnit candidateTimeUnit = this; + while (!candidateTimeUnit.isDivisibleBy(timeUnit)) { + candidateTimeUnit = this.minus(minimumTimeUnit); + } + return candidateTimeUnit; + } + + private TimeUnit minus(final TimeUnit timeUnit) { + return TimeUnit.from(this.minutes - timeUnit.minutes); + } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/DuplicateSettingOrderValidator.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/DuplicateSettingOrderValidator.java new file mode 100644 index 000000000..333267739 --- /dev/null +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/DuplicateSettingOrderValidator.java @@ -0,0 +1,25 @@ +package com.woowacourse.zzimkkong.dto; + +import com.woowacourse.zzimkkong.dto.space.SettingRequest; +import org.springframework.util.CollectionUtils; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class DuplicateSettingOrderValidator implements ConstraintValidator> { + @Override + public boolean isValid(final List value, final ConstraintValidatorContext context) { + if (CollectionUtils.isEmpty(value)) { + return true; + } + + Set uniquePriorities = value.stream() + .map(SettingRequest::getPriorityOrder) + .collect(Collectors.toSet()); + + return value.size() == uniquePriorities.size(); + } +} diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/NotDuplicatedSettingOrder.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/NotDuplicatedSettingOrder.java new file mode 100644 index 000000000..ae84b3600 --- /dev/null +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/NotDuplicatedSettingOrder.java @@ -0,0 +1,23 @@ +package com.woowacourse.zzimkkong.dto; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static com.woowacourse.zzimkkong.dto.ValidatorMessage.DUPLICATE_SETTING_ORDER_MESSAGE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Constraint(validatedBy = DuplicateSettingOrderValidator.class) +@Target(ElementType.FIELD) +@Retention(RUNTIME) +@Documented +public @interface NotDuplicatedSettingOrder { + String message() default DUPLICATE_SETTING_ORDER_MESSAGE; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/TimeUnitValidator.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/TimeUnitValidator.java index 9486b38a1..b4c634b85 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/TimeUnitValidator.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/TimeUnitValidator.java @@ -2,17 +2,16 @@ import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; -import java.util.List; -public class TimeUnitValidator implements ConstraintValidator { - private static final List TIME_UNITS = List.of(5, 10, 30, 60); +import static com.woowacourse.zzimkkong.domain.TimeUnit.INTERVAL_TIME_UNITS; +public class TimeUnitValidator implements ConstraintValidator { @Override public boolean isValid(Integer value, ConstraintValidatorContext context) { if(value == null){ return true; } - return TIME_UNITS.contains(value); + return INTERVAL_TIME_UNITS.contains(value); } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/ValidatorMessage.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/ValidatorMessage.java index 1598d78d0..9a8d9f3de 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/ValidatorMessage.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/ValidatorMessage.java @@ -15,9 +15,11 @@ private ValidatorMessage() { public static final String NOTICE_MESSAGE = "공지사항은 100자 이내로 작성 가능합니다."; public static final String FORMAT_MESSAGE = "날짜 및 시간 데이터 형식이 올바르지 않습니다."; public static final String DAY_OF_WEEK_MESSAGE = "올바른 요일 형식이 아닙니다."; - public static final String SERVER_ERROR_MESSAGE = "일시적으로 접속이 원활하지 않습니다. 잠시 후 다시 이용해 주시기 바랍니다."; public static final String TIME_UNIT_MESSAGE = "시간 단위는 10, 30, 60, 120입니다."; public static final String SETTING_COUNT_MESSAGE = "공간의 예약 조건이 최소 1개는 존재해야 합니다."; + public static final String INVALID_SETTING_ORDER_MESSAGE = "공간 예약 조건 우선순위 값이 올바르지 않습니다."; + public static final String DUPLICATE_SETTING_ORDER_MESSAGE = "공간 예약 조건 우선순위 값은 서로 중복될 수 없습니다."; + public static final String SERVER_ERROR_MESSAGE = "일시적으로 접속이 원활하지 않습니다. 잠시 후 다시 이용해 주시기 바랍니다."; public static final String DATE_FORMAT = "yyyy-MM-dd"; public static final String TIME_FORMAT = "HH:mm:ss"; diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingRequest.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingRequest.java index 7d1bfe162..4a694fcf0 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingRequest.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingRequest.java @@ -6,9 +6,11 @@ import lombok.Getter; import lombok.NoArgsConstructor; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; import java.time.LocalTime; -import static com.woowacourse.zzimkkong.dto.ValidatorMessage.TIME_FORMAT; +import static com.woowacourse.zzimkkong.dto.ValidatorMessage.*; @Getter @NoArgsConstructor @@ -29,19 +31,24 @@ public class SettingRequest { private EnabledDayOfWeekDto enabledDayOfWeek = new EnabledDayOfWeekDto(); + @Min(value = 0, message = INVALID_SETTING_ORDER_MESSAGE) + private Integer priorityOrder = 0; + public SettingRequest( final LocalTime settingStartTime, final LocalTime settingEndTime, final Integer reservationTimeUnit, final Integer reservationMinimumTimeUnit, final Integer reservationMaximumTimeUnit, - final EnabledDayOfWeekDto enabledDayOfWeek) { + final EnabledDayOfWeekDto enabledDayOfWeek, + final Integer priorityOrder) { this.settingStartTime = settingStartTime; this.settingEndTime = settingEndTime; this.reservationTimeUnit = reservationTimeUnit; this.reservationMinimumTimeUnit = reservationMinimumTimeUnit; this.reservationMaximumTimeUnit = reservationMaximumTimeUnit; this.enabledDayOfWeek = enabledDayOfWeek; + this.priorityOrder = priorityOrder; } public String enabledDayOfWeekAsString() { diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingResponse.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingResponse.java index 2064c9258..6ab432893 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingResponse.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingResponse.java @@ -35,6 +35,9 @@ public class SettingResponse { @JsonProperty private EnabledDayOfWeekDto enabledDayOfWeek; + @JsonProperty + private Integer priorityOrder; + protected SettingResponse( final Long settingId, final LocalTime settingStartTime, @@ -42,7 +45,8 @@ protected SettingResponse( final Integer reservationTimeUnit, final Integer reservationMinimumTimeUnit, final Integer reservationMaximumTimeUnit, - final EnabledDayOfWeekDto enabledDayOfWeek) { + final EnabledDayOfWeekDto enabledDayOfWeek, + final Integer priorityOrder) { this.settingId = settingId; this.settingStartTime = settingStartTime; this.settingEndTime = settingEndTime; @@ -50,6 +54,7 @@ protected SettingResponse( this.reservationMinimumTimeUnit = reservationMinimumTimeUnit; this.reservationMaximumTimeUnit = reservationMaximumTimeUnit; this.enabledDayOfWeek = enabledDayOfWeek; + this.priorityOrder = priorityOrder; } public static SettingResponse from(final Setting setting) { @@ -60,7 +65,8 @@ public static SettingResponse from(final Setting setting) { setting.getReservationTimeUnitAsInt(), setting.getReservationMinimumTimeUnitAsInt(), setting.getReservationMaximumTimeUnitAsInt(), - EnabledDayOfWeekDto.from(setting.getEnabledDayOfWeek()) + EnabledDayOfWeekDto.from(setting.getEnabledDayOfWeek()), + setting.getPriorityOrder() ); } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingsSummaryResponse.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingsSummaryResponse.java new file mode 100644 index 000000000..aa357b5b9 --- /dev/null +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingsSummaryResponse.java @@ -0,0 +1,18 @@ +package com.woowacourse.zzimkkong.dto.space; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class SettingsSummaryResponse { + private String summary; + + private SettingsSummaryResponse(final String summary) { + this.summary = summary; + } + + public static SettingsSummaryResponse from(final String summary) { + return new SettingsSummaryResponse(summary); + } +} diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SpaceCreateUpdateRequest.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SpaceCreateUpdateRequest.java index e901fee55..3e0fc9919 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SpaceCreateUpdateRequest.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SpaceCreateUpdateRequest.java @@ -1,6 +1,7 @@ package com.woowacourse.zzimkkong.dto.space; import com.woowacourse.zzimkkong.domain.Settings; +import com.woowacourse.zzimkkong.dto.NotDuplicatedSettingOrder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -33,8 +34,9 @@ public class SpaceCreateUpdateRequest { @NotNull(message = SETTING_COUNT_MESSAGE) @Size(min = Settings.MINIMUM_SETTING_COUNT, message = SETTING_COUNT_MESSAGE) + @NotDuplicatedSettingOrder @Valid - private List settings = Arrays.asList(new SettingRequest()); + private List settings = List.of(new SettingRequest()); public SpaceCreateUpdateRequest( final String name, diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SpaceFindDetailResponse.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SpaceFindDetailResponse.java index 131c144bb..3b1c95020 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SpaceFindDetailResponse.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SpaceFindDetailResponse.java @@ -1,5 +1,6 @@ package com.woowacourse.zzimkkong.dto.space; +import com.woowacourse.zzimkkong.domain.Settings; import com.woowacourse.zzimkkong.domain.Space; import lombok.Getter; import lombok.NoArgsConstructor; @@ -41,7 +42,9 @@ public static SpaceFindDetailResponse from(final Space space) { } protected static List getSettingResponses(final Space space) { - return space.getSpaceSettings().getSettings() + Settings spaceSettings = space.getSpaceSettings(); + spaceSettings.reverseSortByPriorityOrder(); + return spaceSettings.getSettings() .stream() .map(SettingResponse::from) .collect(Collectors.toList()); diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/exception/ZzimkkongException.java b/backend/src/main/java/com/woowacourse/zzimkkong/exception/ZzimkkongException.java index 2f0ad05fc..301baeead 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/exception/ZzimkkongException.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/exception/ZzimkkongException.java @@ -3,21 +3,23 @@ import lombok.Getter; import org.springframework.http.HttpStatus; +import static com.woowacourse.zzimkkong.dto.ValidatorMessage.SERVER_ERROR_MESSAGE; import static com.woowacourse.zzimkkong.infrastructure.message.MessageUtils.LINE_SEPARATOR; @Getter public class ZzimkkongException extends RuntimeException { - private static final String DEFAULT_MESSAGE = "일시적으로 접속이 원활하지 않습니다. 찜꽁 서비스 팀에 문의 부탁드립니다." + - LINE_SEPARATOR + - "Contact : sunnyk5780@gmail.com / jssung@sk.com"; - private final HttpStatus status; public ZzimkkongException() { - super(DEFAULT_MESSAGE); + super(SERVER_ERROR_MESSAGE); this.status = HttpStatus.INTERNAL_SERVER_ERROR; } + public ZzimkkongException(final HttpStatus status) { + super(SERVER_ERROR_MESSAGE); + this.status = status; + } + public ZzimkkongException(final String message, final HttpStatus status) { super(message); this.status = status; diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/exception/reservation/InvalidStartEndTimeException.java b/backend/src/main/java/com/woowacourse/zzimkkong/exception/reservation/InvalidStartEndTimeException.java index aac7b2fc3..93de33e4e 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/exception/reservation/InvalidStartEndTimeException.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/exception/reservation/InvalidStartEndTimeException.java @@ -1,10 +1,10 @@ package com.woowacourse.zzimkkong.exception.reservation; -import com.woowacourse.zzimkkong.domain.Settings; import com.woowacourse.zzimkkong.domain.TimeSlot; import com.woowacourse.zzimkkong.exception.ZzimkkongException; import org.springframework.http.HttpStatus; +import java.util.List; import java.util.stream.Collectors; import static com.woowacourse.zzimkkong.infrastructure.message.MessageUtils.LINE_SEPARATOR; @@ -17,14 +17,16 @@ public class InvalidStartEndTimeException extends ZzimkkongException { LINE_SEPARATOR + "예약 불가 시간대: %s"; - public InvalidStartEndTimeException(Settings settings, TimeSlot reservationTimeSlot) { + public InvalidStartEndTimeException( + final List unavailableTimeSlots, + final TimeSlot reservationTimeSlot) { super(String.format( - MESSAGE_FORMAT, - reservationTimeSlot, - settings.getUnavailableTimeSlots() - .stream() - .map(TimeSlot::toString) - .collect(Collectors.joining(", "))), + MESSAGE_FORMAT, + reservationTimeSlot, + unavailableTimeSlots + .stream() + .map(TimeSlot::toString) + .collect(Collectors.joining(", "))), HttpStatus.BAD_REQUEST); } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/InvalidOrderException.java b/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/InvalidOrderException.java new file mode 100644 index 000000000..09703e305 --- /dev/null +++ b/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/InvalidOrderException.java @@ -0,0 +1,10 @@ +package com.woowacourse.zzimkkong.exception.setting; + +import com.woowacourse.zzimkkong.exception.ZzimkkongException; +import org.springframework.http.HttpStatus; + +public class InvalidOrderException extends ZzimkkongException { + public InvalidOrderException(String message) { + super(message, HttpStatus.INTERNAL_SERVER_ERROR); + } +} diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/NoSettingAvailableException.java b/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/NoSettingAvailableException.java index 98868c798..70f934662 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/NoSettingAvailableException.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/NoSettingAvailableException.java @@ -15,7 +15,7 @@ public class NoSettingAvailableException extends ZzimkkongException { "%s"; public NoSettingAvailableException(final Space space) { - super(String.format(MESSAGE_FORMAT, space.getName(), space.getSpaceSettings()), + super(String.format(MESSAGE_FORMAT, space.getName(), space.getSpaceSettings().getSummary()), HttpStatus.BAD_REQUEST); } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/SettingConflictException.java b/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/SettingConflictException.java deleted file mode 100644 index b78e44c3b..000000000 --- a/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/SettingConflictException.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.woowacourse.zzimkkong.exception.setting; - -import com.woowacourse.zzimkkong.domain.Setting; -import com.woowacourse.zzimkkong.exception.ZzimkkongException; -import org.springframework.http.HttpStatus; - -public class SettingConflictException extends ZzimkkongException { - private static final String MESSAGE_FORMAT = "공간 예약 조건들의 시간대가 겹칩니다. \n겹치는 시간대 정보: %s VS %s"; - - public SettingConflictException(final Setting currentSetting, final Setting nextSetting) { - super(String.format( - MESSAGE_FORMAT, - currentSetting.getSettingTimeSlot(), - nextSetting.getSettingTimeSlot()), - HttpStatus.NOT_FOUND); - } -} diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/infrastructure/datetime/TimeZoneUtils.java b/backend/src/main/java/com/woowacourse/zzimkkong/infrastructure/datetime/TimeZoneUtils.java index a7b53f66f..0b7abaceb 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/infrastructure/datetime/TimeZoneUtils.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/infrastructure/datetime/TimeZoneUtils.java @@ -10,13 +10,22 @@ public class TimeZoneUtils { public static final TimeZone UTC = TimeZone.getTimeZone("UTC"); - public static LocalDateTime convertTo(final LocalDateTime dateTime, final ServiceZone serviceZone) { + public static LocalDateTime convertTo(final LocalDateTime dateTime, ServiceZone serviceZone) { + if (dateTime == null) { + return null; + } + if (serviceZone == null) { + serviceZone = ServiceZone.KOREA; + } return dateTime.atZone(UTC.toZoneId()) .withZoneSameInstant(ZoneId.of(serviceZone.getTimeZone())) .toLocalDateTime(); } public static LocalDateTime convertToUTC(final ZonedDateTime zonedDateTime) { + if (zonedDateTime == null) { + return null; + } return zonedDateTime.withZoneSameInstant(UTC.toZoneId()).toLocalDateTime(); } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/service/ReservationService.java b/backend/src/main/java/com/woowacourse/zzimkkong/service/ReservationService.java index 6d9bdb11c..dd34a7593 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/service/ReservationService.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/service/ReservationService.java @@ -289,7 +289,9 @@ private void validateSpaceSetting(final Space space, final Reservation reservati DayOfWeek dayOfWeek = reservation.getDayOfWeek(); Settings relevantSettings = space.getRelevantSettings(timeSlot, dayOfWeek); + if (relevantSettings.isEmpty()) { + space.getSpaceSettings().flatten(); throw new NoSettingAvailableException(space); } @@ -298,8 +300,8 @@ private void validateSpaceSetting(final Space space, final Reservation reservati throw new MultipleSettingsException(relevantSettings); } - if (relevantSettings.cannotAcceptDueToAvailableTime(timeSlot)) { - throw new InvalidStartEndTimeException(relevantSettings, timeSlot); + if (relevantSettings.cannotAcceptDueToAvailableTime(timeSlot, dayOfWeek)) { + throw new InvalidStartEndTimeException(relevantSettings.getUnavailableTimeSlots(dayOfWeek), timeSlot); } // TODO: 2023/02/09 기준, 예약은 하나의 세팅만 걸쳐야한다 diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/service/SettingService.java b/backend/src/main/java/com/woowacourse/zzimkkong/service/SettingService.java new file mode 100644 index 000000000..d1d27d6fb --- /dev/null +++ b/backend/src/main/java/com/woowacourse/zzimkkong/service/SettingService.java @@ -0,0 +1,45 @@ +package com.woowacourse.zzimkkong.service; + + +import com.woowacourse.zzimkkong.domain.EnabledDayOfWeek; +import com.woowacourse.zzimkkong.domain.Map; +import com.woowacourse.zzimkkong.domain.Settings; +import com.woowacourse.zzimkkong.domain.Space; +import com.woowacourse.zzimkkong.domain.SettingViewType; +import com.woowacourse.zzimkkong.dto.space.SettingsSummaryResponse; +import com.woowacourse.zzimkkong.exception.map.NoSuchMapException; +import com.woowacourse.zzimkkong.exception.space.NoSuchSpaceException; +import com.woowacourse.zzimkkong.infrastructure.datetime.TimeZoneUtils; +import com.woowacourse.zzimkkong.repository.MapRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.DayOfWeek; +import java.time.LocalDateTime; +import java.util.Locale; + +@Service +@Transactional(readOnly = true) +public class SettingService { + private final MapRepository maps; + + public SettingService(final MapRepository maps) { + this.maps = maps; + } + + public SettingsSummaryResponse getSettingsSummary( + final Long mapId, + final Long spaceId, + final LocalDateTime selectedDateTime, + final String settingViewType) { + Map map = maps.findByIdFetch(mapId) + .orElseThrow(NoSuchMapException::new); + Space space = map.findSpaceById(spaceId) + .orElseThrow(NoSuchSpaceException::new); + + String summary = SettingViewType.of(selectedDateTime, settingViewType) + .getSummary(space, selectedDateTime); + + return SettingsSummaryResponse.from(summary); + } +} diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/service/SpaceService.java b/backend/src/main/java/com/woowacourse/zzimkkong/service/SpaceService.java index d62744881..fa1acd0f8 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/service/SpaceService.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/service/SpaceService.java @@ -15,8 +15,6 @@ import java.time.DayOfWeek; import java.time.LocalDateTime; -import java.util.AbstractMap; -import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -203,7 +201,7 @@ private Boolean isSpaceSettingViolated(final Space space, final ReservationTime return relevantSettings.isEmpty() || relevantSettings.haveMultipleSettings() || - relevantSettings.cannotAcceptDueToAvailableTime(timeSlot) || + relevantSettings.cannotAcceptDueToAvailableTime(timeSlot, dayOfWeek) || relevantSettings.getSettings().get(0).cannotAcceptDueToTimeUnit(timeSlot) || relevantSettings.getSettings().get(0).cannotAcceptDueToMinimumTimeUnit(timeSlot) || relevantSettings.getSettings().get(0).cannotAcceptDueToMaximumTimeUnit(timeSlot) || diff --git a/backend/src/main/resources/db/migration/prod/V22__setting_priority.sql b/backend/src/main/resources/db/migration/prod/V22__setting_priority.sql new file mode 100644 index 000000000..eca795436 --- /dev/null +++ b/backend/src/main/resources/db/migration/prod/V22__setting_priority.sql @@ -0,0 +1,2 @@ +ALTER TABLE setting ADD COLUMN priority_order integer not null; +UPDATE setting SET priority_order = 0; \ No newline at end of file diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/AcceptanceTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/AcceptanceTest.java index 64288d218..286c29eaa 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/controller/AcceptanceTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/controller/AcceptanceTest.java @@ -50,7 +50,8 @@ class AcceptanceTest { BE_RESERVATION_TIME_UNIT.getMinutes(), BE_RESERVATION_MINIMUM_TIME_UNIT.getMinutes(), BE_RESERVATION_MAXIMUM_TIME_UNIT.getMinutes(), - EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK) + EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK), + 0 ); protected final SpaceCreateUpdateRequest beSpaceCreateUpdateRequest = new SpaceCreateUpdateRequest( BE_NAME, @@ -66,7 +67,8 @@ class AcceptanceTest { FE_RESERVATION_TIME_UNIT.getMinutes(), FE_RESERVATION_MINIMUM_TIME_UNIT.getMinutes(), FE_RESERVATION_MAXIMUM_TIME_UNIT.getMinutes(), - EnabledDayOfWeekDto.from(FE_ENABLED_DAY_OF_WEEK) + EnabledDayOfWeekDto.from(FE_ENABLED_DAY_OF_WEEK), + 0 ); protected final SpaceCreateUpdateRequest feSpaceCreateUpdateRequest = new SpaceCreateUpdateRequest( FE_NAME, diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/AdminControllerTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/AdminControllerTest.java index b316f21ba..50feec673 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/controller/AdminControllerTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/controller/AdminControllerTest.java @@ -56,6 +56,7 @@ class AdminControllerTest extends AcceptanceTest { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); private static final Space BE = Space.builder() .name(BE_NAME) @@ -63,7 +64,7 @@ class AdminControllerTest extends AcceptanceTest { .map(LUTHER) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(BE_SETTING))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(BE_SETTING))) .build(); private static String token; diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestReservationControllerTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestReservationControllerTest.java index fa619a15f..2697e23b2 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestReservationControllerTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestReservationControllerTest.java @@ -94,6 +94,7 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); be = Space.builder() @@ -102,7 +103,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(beSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) .build(); Setting feSetting = Setting.builder() @@ -113,6 +114,7 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); fe = Space.builder() @@ -122,7 +124,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(feSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) .build(); saveExampleReservations(); diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestSpaceControllerTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestSpaceControllerTest.java index f08f1dc90..fad43578e 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestSpaceControllerTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestSpaceControllerTest.java @@ -58,6 +58,7 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); Setting feSetting = Setting.builder() @@ -68,6 +69,7 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); be = Space.builder() @@ -77,7 +79,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(beSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) .build(); fe = Space.builder() @@ -87,7 +89,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(feSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) .build(); } diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/ManagerReservationControllerTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/ManagerReservationControllerTest.java index 51cdfc315..1ba13320b 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/controller/ManagerReservationControllerTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/controller/ManagerReservationControllerTest.java @@ -86,6 +86,7 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); be = Space.builder() @@ -94,7 +95,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(beSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) .build(); Setting feSetting = Setting.builder() @@ -105,6 +106,7 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); fe = Space.builder() @@ -114,7 +116,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(feSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) .build(); saveExampleReservations(); diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/ManagerSpaceControllerTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/ManagerSpaceControllerTest.java index 64d753ea8..a2373a90d 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/controller/ManagerSpaceControllerTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/controller/ManagerSpaceControllerTest.java @@ -53,6 +53,7 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); Setting feSetting = Setting.builder() @@ -63,6 +64,7 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); be = Space.builder() @@ -72,7 +74,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(beSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) .build(); fe = Space.builder() @@ -82,7 +84,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(feSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) .build(); } @@ -96,7 +98,8 @@ void save() { 30, 60, 120, - EnabledDayOfWeekDto.from("monday, tuesday, wednesday, thursday, friday, saturday, sunday") + EnabledDayOfWeekDto.from("monday, tuesday, wednesday, thursday, friday, saturday, sunday"), + 1 ); SpaceCreateUpdateRequest newSpaceCreateUpdateRequest = new SpaceCreateUpdateRequest( @@ -125,6 +128,7 @@ void save_default() { null, null, null, + null, null ); @@ -145,12 +149,13 @@ void save_default() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek("monday, tuesday, wednesday, thursday, friday, saturday, sunday") + .priorityOrder(0) .build(); Space defaultSpace = Space.builder() .name(defaultSpaceCreateUpdateRequest.getName()) .color(defaultSpaceCreateUpdateRequest.getColor()) - .spaceSettings(new Settings(List.of(defaultSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(defaultSetting))) .reservationEnable(true) .area(SPACE_DRAWING) .build(); @@ -212,7 +217,8 @@ void update() { 30, 60, 120, - EnabledDayOfWeekDto.from("monday, tuesday, wednesday, thursday, friday, saturday, sunday") + EnabledDayOfWeekDto.from("monday, tuesday, wednesday, thursday, friday, saturday, sunday"), + 1 ); SpaceCreateUpdateRequest updateSpaceCreateUpdateRequest = new SpaceCreateUpdateRequest( diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/PresetControllerTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/PresetControllerTest.java index 12ae9bbd6..e235ab3b1 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/controller/PresetControllerTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/controller/PresetControllerTest.java @@ -46,6 +46,7 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); settingRequest = new SettingRequest( @@ -54,7 +55,8 @@ void setUp() { BE_RESERVATION_TIME_UNIT.getMinutes(), BE_RESERVATION_MINIMUM_TIME_UNIT.getMinutes(), BE_RESERVATION_MAXIMUM_TIME_UNIT.getMinutes(), - EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK) + EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK), + 0 ); presetCreateRequest = new PresetCreateRequest(PRESET_NAME1, settingRequest); } diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/SettingControllerTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/SettingControllerTest.java new file mode 100644 index 000000000..727977f36 --- /dev/null +++ b/backend/src/test/java/com/woowacourse/zzimkkong/controller/SettingControllerTest.java @@ -0,0 +1,230 @@ +package com.woowacourse.zzimkkong.controller; + +import com.woowacourse.zzimkkong.domain.*; +import com.woowacourse.zzimkkong.dto.space.EnabledDayOfWeekDto; +import com.woowacourse.zzimkkong.dto.space.SettingRequest; +import com.woowacourse.zzimkkong.dto.space.SettingsSummaryResponse; +import com.woowacourse.zzimkkong.dto.space.SpaceCreateUpdateRequest; +import io.restassured.RestAssured; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; + +import java.time.LocalTime; +import java.util.List; + +import static com.woowacourse.zzimkkong.Constants.*; +import static com.woowacourse.zzimkkong.DocumentUtils.*; +import static com.woowacourse.zzimkkong.controller.ManagerSpaceControllerTest.saveSpace; +import static com.woowacourse.zzimkkong.controller.MapControllerTest.saveMap; +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.document; + +public class SettingControllerTest extends AcceptanceTest { + private String spaceApi; + private String lutherId; + private Long beSpaceId; + private Space be; + private Space fe; + + private final SettingRequest beSettingRequest = new SettingRequest( + BE_AVAILABLE_START_TIME, + BE_AVAILABLE_END_TIME, + BE_RESERVATION_TIME_UNIT.getMinutes(), + BE_RESERVATION_MINIMUM_TIME_UNIT.getMinutes(), + BE_RESERVATION_MAXIMUM_TIME_UNIT.getMinutes(), + EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK), + 1 + ); + private final SettingRequest beSettingRequest2 = new SettingRequest( + LocalTime.of(11, 0), + LocalTime.of(15, 0), + TimeUnit.from(5).getMinutes(), + TimeUnit.from(30).getMinutes(), + TimeUnit.from(60).getMinutes(), + EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK), + 0 + ); + private final SpaceCreateUpdateRequest beSpaceCreateUpdateRequestUpgraded = new SpaceCreateUpdateRequest( + BE_NAME, + BE_COLOR, + SPACE_DRAWING, + MAP_SVG, + BE_RESERVATION_ENABLE, + List.of(beSettingRequest, beSettingRequest2) + ); + + @BeforeEach + void setUp() { + lutherId = saveMap("/api/managers/maps", mapCreateUpdateRequest).header("location").split("/")[4]; + spaceApi = "/api/managers/maps/" + lutherId + "/spaces"; + ExtractableResponse saveBeSpaceResponse = saveSpace(spaceApi, beSpaceCreateUpdateRequestUpgraded); + ExtractableResponse saveFe1SpaceResponse = saveSpace(spaceApi, feSpaceCreateUpdateRequest); + + beSpaceId = Long.valueOf(saveBeSpaceResponse.header("location").split("/")[6]); + Long feSpaceId = Long.valueOf(saveFe1SpaceResponse.header("location").split("/")[6]); + + Member pobi = Member.builder() + .email(EMAIL) + .userName(POBI) + .emoji(ProfileEmoji.MAN_DARK_SKIN_TONE_TECHNOLOGIST) + .password(passwordEncoder.encode(PW)) + .organization(ORGANIZATION) + .build(); + Map luther = new Map(LUTHER_NAME, MAP_DRAWING_DATA, MAP_SVG, pobi); + Setting beSetting = Setting.builder() + .settingTimeSlot(TimeSlot.of( + BE_AVAILABLE_START_TIME, + BE_AVAILABLE_END_TIME)) + .reservationTimeUnit(BE_RESERVATION_TIME_UNIT) + .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) + .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) + .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(1) + .build(); + + + Setting beSetting2 = Setting.builder() + .settingTimeSlot(TimeSlot.of( + LocalTime.of(11, 0), + LocalTime.of(15, 0))) + .reservationTimeUnit(TimeUnit.from(5)) + .reservationMinimumTimeUnit(TimeUnit.from(30)) + .reservationMaximumTimeUnit(TimeUnit.from(60)) + .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) + .build(); + + Setting feSetting = Setting.builder() + .settingTimeSlot(TimeSlot.of( + FE_AVAILABLE_START_TIME, + FE_AVAILABLE_END_TIME)) + .reservationTimeUnit(FE_RESERVATION_TIME_UNIT) + .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) + .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) + .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) + .build(); + + be = Space.builder() + .id(beSpaceId) + .name(BE_NAME) + .color(BE_COLOR) + .map(luther) + .area(SPACE_DRAWING) + .reservationEnable(BE_RESERVATION_ENABLE) + .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting, beSetting2))) + .build(); + + fe = Space.builder() + .id(feSpaceId) + .name(FE_NAME) + .color(FE_COLOR) + .map(luther) + .area(SPACE_DRAWING) + .reservationEnable(FE_RESERVATION_ENABLE) + .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) + .build(); + } + + @Test + @DisplayName("특정 맵 특정 공간의 예약자들을 위한 (flat) 특정 일자의 예약 조건 (setting) 요약 메세지를 조회한다") + void find_flat() { + // given + String api = "/api/maps/" + lutherId + "/spaces/" + beSpaceId + "/settings/summary"; + + // when + ExtractableResponse response = findFlat(api); + SettingsSummaryResponse actualResponse = response.as(SettingsSummaryResponse.class); + + // then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + } + + @Test + @DisplayName("특정 맵 특정 공간의 관리자들을 위한 (stack) 특정 일자의 예약 조건 (setting) 요약 메세지를 조회한다") + void find_stack() { + // given + String api = "/api/maps/" + lutherId + "/spaces/" + beSpaceId + "/settings/summary"; + + // when + ExtractableResponse response = findStack(api); + + // then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + } + + @Test + @DisplayName("특정 맵 특정 공간의 예약자들을 위한 (flat) 전체 예약 조건 (setting) 요약 메세지를 조회한다") + void find_flat_all() { + // given + String api = "/api/maps/" + lutherId + "/spaces/" + beSpaceId + "/settings/summary"; + + // when + ExtractableResponse response = findFlatAll(api); + + // then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + } + + @Test + @DisplayName("특정 맵 특정 공간의 관리자들을 위한 (stack) 전체 예약 조건 (setting) 요약 메세지를 조회한다") + void find_stack_all() { + // given + String api = "/api/maps/" + lutherId + "/spaces/" + beSpaceId + "/settings/summary"; + + // when + ExtractableResponse response = findStackAll(api); + + // then + assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); + } + + static ExtractableResponse findFlat(final String api) { + return RestAssured + .given(getRequestSpecification()).log().all() + .accept("application/json") + .param("selectedDateTime", BE_AM_TEN_ELEVEN_START_TIME_KST.toLocalDate() + "T12:00:00+09:00") + .filter(document("setting/get_flat", getRequestPreprocessor(), getResponsePreprocessor())) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .when().get(api) + .then().log().all().extract(); + } + + static ExtractableResponse findStack(final String api) { + return RestAssured + .given(getRequestSpecification()).log().all() + .accept("application/json") + .param("selectedDateTime", BE_AM_TEN_ELEVEN_START_TIME_KST.toLocalDate() + "T12:00:00+09:00") + .param("settingViewType", "STACK") + .filter(document("setting/get_stack", getRequestPreprocessor(), getResponsePreprocessor())) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .when().get(api) + .then().log().all().extract(); + } + + static ExtractableResponse findFlatAll(final String api) { + return RestAssured + .given(getRequestSpecification()).log().all() + .accept("application/json") + .filter(document("setting/get_flat_all", getRequestPreprocessor(), getResponsePreprocessor())) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .when().get(api) + .then().log().all().extract(); + } + + static ExtractableResponse findStackAll(final String api) { + return RestAssured + .given(getRequestSpecification()).log().all() + .accept("application/json") + .param("settingViewType", "STACK") + .filter(document("setting/get_stack_all", getRequestPreprocessor(), getResponsePreprocessor())) + .contentType(MediaType.APPLICATION_JSON_VALUE) + .when().get(api) + .then().log().all().extract(); + } +} diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/domain/PresetTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/domain/PresetTest.java index 1a962cc38..61ade78ee 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/domain/PresetTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/domain/PresetTest.java @@ -15,6 +15,7 @@ class PresetTest { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); @Test diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/domain/SettingTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/domain/SettingTest.java index 14831c6f5..f0b30faf6 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/domain/SettingTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/domain/SettingTest.java @@ -7,13 +7,19 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; import java.time.DayOfWeek; import java.time.LocalTime; +import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; import static com.woowacourse.zzimkkong.Constants.*; +import static com.woowacourse.zzimkkong.domain.Setting.FLAT_PRIORITY_ORDER; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; @@ -30,6 +36,7 @@ void name() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build()); } @@ -73,6 +80,7 @@ void timeUnitMismatch_ok(int startMinute, int endMinute, int timeUnit) { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build()); } @@ -117,6 +125,7 @@ void supports_dayOfWeek_settingExists(DayOfWeek dayOfWeek) { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek("monday, wednesday") + .priorityOrder(0) .build(); assertThat(setting.supports(reservationTimeSlot, dayOfWeek)).isTrue(); @@ -133,8 +142,106 @@ void supports_dayOfWeek_settingDoesNotExist(DayOfWeek dayOfWeek) { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek("monday, wednesday") + .priorityOrder(0) .build(); assertThat(setting.supports(reservationTimeSlot, dayOfWeek)).isFalse(); } + + @ParameterizedTest + @DisplayName("인자로 주어진 settings 의 조건들에 배타적인 (겹치지 않는) 새로운 setting slot 리스트를 생성한다") + @MethodSource("provideSettings") + void extractExclusiveSettingSlots(List settings, List expected) { + Setting setting = Setting.builder() + .settingTimeSlot(TimeSlot.of( + LocalTime.of(10, 0), + LocalTime.of(11, 0))) + .reservationTimeUnit(TimeUnit.from(10)) + .reservationMinimumTimeUnit(TimeUnit.from(10)) + .reservationMaximumTimeUnit(TimeUnit.from(30)) + .enabledDayOfWeek("monday,tuesday,wednesday,thursday,friday,saturday,sunday") + .priorityOrder(0) + .build(); + + List actual = setting.extractExclusiveSettingSlots(settings); + assertThat(actual).usingRecursiveComparison() + .ignoringCollectionOrder() + .ignoringExpectedNullFields() + .isEqualTo(expected); + } + + private static Stream provideSettings() { + return Stream.of( + Arguments.of( + List.of( + Setting.builder() + .settingTimeSlot(TimeSlot.of( + LocalTime.of(9, 30), + LocalTime.of(10, 30))) + .reservationTimeUnit(TimeUnit.from(10)) + .reservationMinimumTimeUnit(TimeUnit.from(10)) + .reservationMaximumTimeUnit(TimeUnit.from(30)) + .enabledDayOfWeek("monday,tuesday,wednesday,thursday,friday,saturday,sunday") + .priorityOrder(FLAT_PRIORITY_ORDER) + .build(), + Setting.builder() + .settingTimeSlot(TimeSlot.of( + LocalTime.of(10, 30), + LocalTime.of(11, 0))) + .reservationTimeUnit(TimeUnit.from(10)) + .reservationMinimumTimeUnit(TimeUnit.from(10)) + .reservationMaximumTimeUnit(TimeUnit.from(30)) + .enabledDayOfWeek("monday,tuesday,wednesday,thursday,friday,saturday,sunday") + .priorityOrder(FLAT_PRIORITY_ORDER) + .build() + ), + Collections.emptyList()), + Arguments.of( + List.of( + Setting.builder() + .settingTimeSlot(TimeSlot.of( + LocalTime.of(9, 30), + LocalTime.of(10, 30))) + .reservationTimeUnit(TimeUnit.from(10)) + .reservationMinimumTimeUnit(TimeUnit.from(10)) + .reservationMaximumTimeUnit(TimeUnit.from(30)) + .enabledDayOfWeek("monday,tuesday,wednesday") + .priorityOrder(FLAT_PRIORITY_ORDER) + .build(), + Setting.builder() + .settingTimeSlot(TimeSlot.of( + LocalTime.of(10, 30), + LocalTime.of(11, 0))) + .reservationTimeUnit(TimeUnit.from(10)) + .reservationMinimumTimeUnit(TimeUnit.from(10)) + .reservationMaximumTimeUnit(TimeUnit.from(30)) + .enabledDayOfWeek("thursday,friday,saturday,sunday") + .priorityOrder(FLAT_PRIORITY_ORDER) + .build() + ), + List.of( + Setting.builder() + .settingTimeSlot(TimeSlot.of( + LocalTime.of(10, 30), + LocalTime.of(11, 0))) + .reservationTimeUnit(TimeUnit.from(10)) + .reservationMinimumTimeUnit(TimeUnit.from(10)) + .reservationMaximumTimeUnit(TimeUnit.from(30)) + .enabledDayOfWeek("monday,tuesday,wednesday") + .priorityOrder(FLAT_PRIORITY_ORDER) + .build(), + Setting.builder() + .settingTimeSlot(TimeSlot.of( + LocalTime.of(10, 0), + LocalTime.of(10, 30))) + .reservationTimeUnit(TimeUnit.from(10)) + .reservationMinimumTimeUnit(TimeUnit.from(10)) + .reservationMaximumTimeUnit(TimeUnit.from(30)) + .enabledDayOfWeek("thursday,friday,saturday,sunday") + .priorityOrder(FLAT_PRIORITY_ORDER) + .build() + )) + ); + } } + diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/domain/SettingsTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/domain/SettingsTest.java index cd3f5b155..12781f78c 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/domain/SettingsTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/domain/SettingsTest.java @@ -11,9 +11,12 @@ import java.time.LocalTime; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.stream.Stream; import static com.woowacourse.zzimkkong.Constants.*; +import static com.woowacourse.zzimkkong.domain.Setting.FLAT_PRIORITY_ORDER; +import static com.woowacourse.zzimkkong.domain.Setting.FLAT_SETTING_ID; import static org.assertj.core.api.Assertions.assertThat; class SettingsTest { @@ -26,33 +29,36 @@ class SettingsTest { void setUp() { setting1 = Setting.builder() .settingTimeSlot(TimeSlot.of( - LocalTime.of(10,0), - LocalTime.of(13,0))) + LocalTime.of(10, 0), + LocalTime.of(13, 0))) .reservationTimeUnit(BE_RESERVATION_TIME_UNIT) .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); setting2 = Setting.builder() .settingTimeSlot(TimeSlot.of( - LocalTime.of(14,0), - LocalTime.of(16,0))) + LocalTime.of(14, 0), + LocalTime.of(16, 0))) .reservationTimeUnit(BE_RESERVATION_TIME_UNIT) .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(1) .build(); setting3 = Setting.builder() .settingTimeSlot(TimeSlot.of( - LocalTime.of(16,0), - LocalTime.of(20,0))) + LocalTime.of(16, 0), + LocalTime.of(20, 0))) .reservationTimeUnit(BE_RESERVATION_TIME_UNIT) .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(2) .build(); - settings = new Settings(List.of(setting1, setting2, setting3)); + settings = Settings.toPrioritizedSettings(List.of(setting1, setting2, setting3)); } @ParameterizedTest @@ -67,7 +73,9 @@ void getSettingsByTimeSlotAndDayOfWeek(TimeSlot reservationTimeSlot, Settings ex @DisplayName("예약 가능한 시간대에 속한 예약이면 false, 아니면 true") @MethodSource("provideArgumentsForCannotAcceptDueToAvailableTime") void cannotAcceptDueToAvailableTime(TimeSlot reservationTimeSlot, boolean expectedResult) { - boolean result = this.settings.cannotAcceptDueToAvailableTime(reservationTimeSlot); + boolean result = this.settings.cannotAcceptDueToAvailableTime( + reservationTimeSlot, + DayOfWeek.MONDAY); assertThat(result).isEqualTo(expectedResult); } @@ -80,61 +88,135 @@ void getUnavailableTimeSlots() { TimeSlot.of(LocalTime.of(20, 0), TimeSlot.MAX_TIME) ); - assertThat(settings.getUnavailableTimeSlots()).usingRecursiveComparison().isEqualTo(expectedResult); + assertThat(settings.getUnavailableTimeSlots(DayOfWeek.MONDAY)).usingRecursiveComparison().isEqualTo(expectedResult); + } + + @Test + @DisplayName("겹쳐진 예약 조건들을 '동등한 우선순위를 가진 겹치지 않은 상태 (= flat 한 상태)' 로 변환한다") + void flatten() { + Settings settings = Settings.toPrioritizedSettings(List.of( + Setting.builder() + .settingTimeSlot(TimeSlot.of( + LocalTime.of(11, 0), + LocalTime.of(12, 0))) + .reservationTimeUnit(TimeUnit.from(10)) + .reservationMinimumTimeUnit(TimeUnit.from(10)) + .reservationMaximumTimeUnit(TimeUnit.from(30)) + .enabledDayOfWeek("monday,tuesday,wednesday") + .priorityOrder(0) + .build(), + Setting.builder() + .settingTimeSlot(TimeSlot.of( + LocalTime.of(10, 0), + LocalTime.of(13, 0))) + .reservationTimeUnit(TimeUnit.from(10)) + .reservationMinimumTimeUnit(TimeUnit.from(10)) + .reservationMaximumTimeUnit(TimeUnit.from(30)) + .enabledDayOfWeek("monday,tuesday,wednesday,thursday,friday,saturday,sunday") + .priorityOrder(1) + .build() + )); + + settings.flatten(); + + List expected = List.of( + Setting.builder() + .settingTimeSlot(TimeSlot.of( + LocalTime.of(10, 0), + LocalTime.of(11, 0))) + .reservationTimeUnit(TimeUnit.from(10)) + .reservationMinimumTimeUnit(TimeUnit.from(10)) + .reservationMaximumTimeUnit(TimeUnit.from(30)) + .enabledDayOfWeek("monday,tuesday,wednesday,thursday,friday,saturday,sunday") + .priorityOrder(FLAT_PRIORITY_ORDER) + .build(), + Setting.builder() + .settingTimeSlot(TimeSlot.of( + LocalTime.of(11, 0), + LocalTime.of(12, 0))) + .reservationTimeUnit(TimeUnit.from(10)) + .reservationMinimumTimeUnit(TimeUnit.from(10)) + .reservationMaximumTimeUnit(TimeUnit.from(30)) + .enabledDayOfWeek("monday,tuesday,wednesday") + .priorityOrder(FLAT_PRIORITY_ORDER) + .build(), + Setting.builder() + .settingTimeSlot(TimeSlot.of( + LocalTime.of(11, 0), + LocalTime.of(12, 0))) + .reservationTimeUnit(TimeUnit.from(10)) + .reservationMinimumTimeUnit(TimeUnit.from(10)) + .reservationMaximumTimeUnit(TimeUnit.from(30)) + .enabledDayOfWeek("thursday,friday,saturday,sunday") + .priorityOrder(FLAT_PRIORITY_ORDER) + .build(), + Setting.builder() + .settingTimeSlot(TimeSlot.of( + LocalTime.of(12, 0), + LocalTime.of(13, 0))) + .reservationTimeUnit(TimeUnit.from(10)) + .reservationMinimumTimeUnit(TimeUnit.from(10)) + .reservationMaximumTimeUnit(TimeUnit.from(30)) + .enabledDayOfWeek("monday,tuesday,wednesday,thursday,friday,saturday,sunday") + .priorityOrder(FLAT_PRIORITY_ORDER) + .build() + ); + + assertThat(settings.getSettings()).usingRecursiveComparison() + .ignoringCollectionOrder() + .ignoringExpectedNullFields() + .isEqualTo(expected); } private static Stream provideArgumentsForGetSettingsByTimeSlotAndDayOfWeek() { return Stream.of( Arguments.of( TimeSlot.of(LocalTime.of(8, 0), LocalTime.of(10, 0)), - new Settings(Collections.emptyList())), + Settings.toFlattenedSettings(Collections.emptyList())), Arguments.of( TimeSlot.of(LocalTime.of(8, 0), LocalTime.of(11, 0)), - new Settings(List.of( + Settings.toFlattenedSettings(List.of( Setting.builder() + .id(FLAT_SETTING_ID) .settingTimeSlot(TimeSlot.of( LocalTime.of(10, 0), LocalTime.of(13, 0))) .reservationTimeUnit(BE_RESERVATION_TIME_UNIT) .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) - .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .enabledDayOfWeek(EnabledDayOfWeek.FRIDAY.name().toLowerCase(Locale.ROOT)) + .priorityOrder(FLAT_PRIORITY_ORDER) .build()))), Arguments.of( TimeSlot.of(LocalTime.of(13, 0), LocalTime.of(14, 0)), - new Settings(Collections.emptyList())), + Settings.toFlattenedSettings(Collections.emptyList())), Arguments.of( TimeSlot.of(LocalTime.of(13, 30), LocalTime.of(15, 0)), - new Settings(List.of( + Settings.toFlattenedSettings(List.of( Setting.builder() + .id(FLAT_SETTING_ID) .settingTimeSlot(TimeSlot.of( LocalTime.of(14, 0), LocalTime.of(16, 0))) .reservationTimeUnit(BE_RESERVATION_TIME_UNIT) .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) - .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .enabledDayOfWeek(EnabledDayOfWeek.FRIDAY.name().toLowerCase(Locale.ROOT)) + .priorityOrder(FLAT_PRIORITY_ORDER) .build()))), Arguments.of( TimeSlot.of(LocalTime.of(15, 0), LocalTime.of(23, 0)), - new Settings(List.of( + Settings.toFlattenedSettings(List.of( Setting.builder() + .id(FLAT_SETTING_ID) .settingTimeSlot(TimeSlot.of( LocalTime.of(14, 0), - LocalTime.of(16, 0))) - .reservationTimeUnit(BE_RESERVATION_TIME_UNIT) - .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) - .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) - .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .build(), - Setting.builder() - .settingTimeSlot(TimeSlot.of( - LocalTime.of(16, 0), LocalTime.of(20, 0))) .reservationTimeUnit(BE_RESERVATION_TIME_UNIT) .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) - .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .enabledDayOfWeek(EnabledDayOfWeek.FRIDAY.name().toLowerCase(Locale.ROOT)) + .priorityOrder(FLAT_PRIORITY_ORDER) .build())))); } diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/domain/SpaceTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/domain/SpaceTest.java index 707b6ff06..301d1c1df 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/domain/SpaceTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/domain/SpaceTest.java @@ -24,6 +24,7 @@ class SpaceTest { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); private static final Setting setting2 = Setting.builder() .settingTimeSlot(TimeSlot.of( @@ -33,6 +34,7 @@ class SpaceTest { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(1) .build(); @Test @@ -54,8 +56,9 @@ void update() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); - Settings settings = new Settings(Arrays.asList(setting)); + Settings settings = Settings.toPrioritizedSettings(Arrays.asList(setting)); Space space = Space.builder() .name("와우") .color("색깔입니다") @@ -73,8 +76,9 @@ void update() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); - Settings updateSettings = new Settings(Arrays.asList(setting)); + Settings updateSettings = Settings.toPrioritizedSettings(Arrays.asList(setting)); Space updateSpace = Space.builder() .name("우와") .color("색깔") @@ -110,8 +114,9 @@ void isUnableToReserve() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); - Settings settings = new Settings(Arrays.asList(reservationEnableSetting)); + Settings settings = Settings.toPrioritizedSettings(Arrays.asList(reservationEnableSetting)); Space reservationEnableSpace = Space.builder() .spaceSettings(settings) .reservationEnable(true) @@ -131,8 +136,9 @@ void isUnableToReserveFail() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); - Settings settings = new Settings(Arrays.asList(reservationUnableSetting)); + Settings settings = Settings.toPrioritizedSettings(Arrays.asList(reservationUnableSetting)); Space reservationUnableSpace = Space.builder() .spaceSettings(settings) .reservationEnable(false) @@ -148,7 +154,7 @@ void isNotBetweenAvailableTime(TimeSlot reservationTimeSlot, DayOfWeek dayofWeek // setting1: 10 ~ 14 // setting2: 15 ~ 18 Space space = Space.builder() - .spaceSettings(new Settings(Arrays.asList(setting1, setting2))) + .spaceSettings(Settings.toPrioritizedSettings(Arrays.asList(setting1, setting2))) .build(); Settings relevantSettings = space.getRelevantSettings(reservationTimeSlot, dayofWeek); @@ -168,13 +174,13 @@ private static Stream provideReservationInfo() { LocalTime.of(10, 0), LocalTime.of(12, 0)), DayOfWeek.MONDAY, - new Settings(List.of(setting1))), + Settings.toFlattenedSettings(List.of(setting1)).getMergedSettings(EnabledDayOfWeek.MONDAY)), Arguments.of( TimeSlot.of( LocalTime.of(12, 0), LocalTime.of(15, 0)), DayOfWeek.MONDAY, - new Settings(List.of(setting1))), + Settings.toFlattenedSettings(List.of(setting1)).getMergedSettings(EnabledDayOfWeek.MONDAY)), Arguments.of( TimeSlot.of( LocalTime.of(14, 0), @@ -186,6 +192,6 @@ private static Stream provideReservationInfo() { LocalTime.of(15, 0), LocalTime.of(19, 0)), DayOfWeek.MONDAY, - new Settings(List.of(setting2)))); + Settings.toFlattenedSettings(List.of(setting2)).getMergedSettings(EnabledDayOfWeek.MONDAY))); } } diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/domain/TimeSlotTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/domain/TimeSlotTest.java index 560725b21..bea805188 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/domain/TimeSlotTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/domain/TimeSlotTest.java @@ -9,6 +9,8 @@ import org.junit.jupiter.params.provider.MethodSource; import java.time.LocalTime; +import java.util.Collections; +import java.util.List; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; @@ -77,6 +79,25 @@ void isNotWithin( assertThat(thisTimeSlot.isNotWithin(thatTimeSlot)).isEqualTo(expectedResult); } + @ParameterizedTest + @DisplayName("두 TimeSlot 이 주어질 떄, 겹치는 부분을 반환한다") + @MethodSource("provideOverlappingTimeSlot") + void extractOverlappingTimeSlot( + final TimeSlot thisTimeSlot, + final TimeSlot thatTimeSlot, + final TimeSlot expectedResult) { + assertThat(thisTimeSlot.extractOverlappingTimeSlot(thatTimeSlot)).isEqualTo(expectedResult); + } + + @ParameterizedTest + @DisplayName("두 TimeSlot 이 주어질 때, 메서드를 호출하는 TimeSlot 이 인자로 들어가는 TimeSlot 에 배타적인 (겹치지 않는) 부분을 반환한다") + @MethodSource("provideExclusiveTimeSlots") + void extractExclusiveTimeSlots(final TimeSlot thisTimeSlot, + final TimeSlot thatTimeSlot, + final List expectedResult) { + assertThat(thisTimeSlot.extractExclusiveTimeSlots(thatTimeSlot)).isEqualTo(expectedResult); + } + private static Stream provideStartAndEndTime_endTimeEqualOrShorterThanStartTime() { return Stream.of( Arguments.of(LocalTime.of(10, 0), LocalTime.of(9, 0)), @@ -149,4 +170,61 @@ private static Stream provideTimeSlotArguments_isNotWithin() { false) ); } + + private static Stream provideOverlappingTimeSlot() { + return Stream.of( + Arguments.of( + TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 5)), + TimeSlot.of(LocalTime.of(10, 5), LocalTime.of(10, 10)), + null), + Arguments.of( + TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 30)), + TimeSlot.of(LocalTime.of(10, 20), LocalTime.of(10, 40)), + TimeSlot.of(LocalTime.of(10, 20), LocalTime.of(10, 30))), + Arguments.of( + TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 30)), + TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(11, 0)), + TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 30))), + Arguments.of( + TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 0)), + TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 30)), + TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 0))), + Arguments.of( + TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 0)), + TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(11, 30)), + TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 0))) + ); + } + + private static Stream provideExclusiveTimeSlots() { + return Stream.of( + Arguments.of( + TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 5)), + TimeSlot.of(LocalTime.of(10, 5), LocalTime.of(10, 10)), + List.of(TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 5)))), + Arguments.of( + TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 30)), + TimeSlot.of(LocalTime.of(10, 20), LocalTime.of(10, 40)), + List.of(TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 20)))), + Arguments.of( + TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 30)), + TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(11, 0)), + Collections.emptyList()), + Arguments.of( + TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 0)), + TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 30)), + Collections.emptyList()), + Arguments.of( + TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 0)), + TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(11, 30)), + Collections.emptyList()), + Arguments.of( + TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(11, 30)), + TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 0)), + List.of( + TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 30)), + TimeSlot.of(LocalTime.of(11, 0), LocalTime.of(11, 30)) + )) + ); + } } \ No newline at end of file diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/domain/TimeUnitTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/domain/TimeUnitTest.java index 6ef96ed30..5fbac2d41 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/domain/TimeUnitTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/domain/TimeUnitTest.java @@ -4,9 +4,14 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; +import java.time.LocalTime; +import java.util.stream.Stream; + import static com.woowacourse.zzimkkong.domain.TimeUnit.MINIMUM_TIME_UNIT; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -60,4 +65,82 @@ void isShorterThan(final int minutes1, final int minutes2, final boolean expecte boolean actualResult = thisTimeUnit.isShorterThan(thatTimeUnit); assertThat(actualResult).isEqualTo(expectedResult); } -} \ No newline at end of file + + @ParameterizedTest + @DisplayName("timeSlot duration 에 맞는 예약 시간 단위를 반환한다. divisible by minimum possible time unit (i.e. 5)") + @MethodSource("provideTimeSlots1") + void getAdjustedIntervalTimeUnit(TimeUnit initialTimeUnit, TimeSlot timeSlot, TimeUnit expected) { + TimeUnit actual = initialTimeUnit.getAdjustedIntervalTimeUnit(timeSlot); + assertThat(actual).isEqualTo(expected); + } + + @ParameterizedTest + @DisplayName("timeSlot duration 에 맞는 예약 (최소, 최대) 가능 시간을 반환한다. divisible by interval time unit & shorter than duration length") + @MethodSource("provideTimeSlots2") + void getAdjustedTimeUnit(TimeUnit initialTimeUnit, TimeUnit intervalTimeUnit, TimeSlot timeSlot, TimeUnit expected) { + TimeUnit actual = initialTimeUnit.getAdjustedTimeUnit(timeSlot, intervalTimeUnit); + assertThat(actual).isEqualTo(expected); + } + + private static Stream provideTimeSlots1() { + return Stream.of( + Arguments.of( + TimeUnit.from(60), + TimeSlot.of( + LocalTime.of(10, 0), + LocalTime.of(11, 30)), + TimeUnit.from(30) + ), + Arguments.of( + TimeUnit.from(60), + TimeSlot.of( + LocalTime.of(10, 0), + LocalTime.of(11, 0)), + TimeUnit.from(60) + ), + Arguments.of( + TimeUnit.from(60), + TimeSlot.of( + LocalTime.of(10, 0), + LocalTime.of(10, 20)), + TimeUnit.from(10) + ), + Arguments.of( + TimeUnit.from(60), + TimeSlot.of( + LocalTime.of(10, 0), + LocalTime.of(10, 30)), + TimeUnit.from(30) + ) + ); + } + + private static Stream provideTimeSlots2() { + return Stream.of( + Arguments.of( + TimeUnit.from(60), + TimeUnit.from(10), + TimeSlot.of( + LocalTime.of(10, 0), + LocalTime.of(11, 30)), + TimeUnit.from(60) + ), + Arguments.of( + TimeUnit.from(60), + TimeUnit.from(30), + TimeSlot.of( + LocalTime.of(10, 0), + LocalTime.of(10, 30)), + TimeUnit.from(30) + ), + Arguments.of( + TimeUnit.from(10), + TimeUnit.from(5), + TimeSlot.of( + LocalTime.of(10, 0), + LocalTime.of(10, 5)), + TimeUnit.from(5) + ) + ); + } +} diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/dto/PresetCreateRequestTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/dto/PresetCreateRequestTest.java index 460ebdfc7..95e3972d3 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/dto/PresetCreateRequestTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/dto/PresetCreateRequestTest.java @@ -19,7 +19,8 @@ class PresetCreateRequestTest extends RequestTest { BE_RESERVATION_TIME_UNIT.getMinutes(), BE_RESERVATION_MINIMUM_TIME_UNIT.getMinutes(), BE_RESERVATION_MAXIMUM_TIME_UNIT.getMinutes(), - EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK) + EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK), + 0 ); @ParameterizedTest diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/dto/RequestTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/dto/RequestTest.java index efb5381e6..5df20077d 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/dto/RequestTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/dto/RequestTest.java @@ -20,7 +20,8 @@ class RequestTest { BE_RESERVATION_TIME_UNIT.getMinutes(), BE_RESERVATION_MINIMUM_TIME_UNIT.getMinutes(), BE_RESERVATION_MAXIMUM_TIME_UNIT.getMinutes(), - EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK) + EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK), + 0 ); @BeforeAll diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/dto/SettingRequestTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/dto/SettingRequestTest.java index 430383cae..1791d3ffa 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/dto/SettingRequestTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/dto/SettingRequestTest.java @@ -23,7 +23,8 @@ void invalidTimeUnit(int timeUnit) { timeUnit, 60, 120, - EnabledDayOfWeekDto.from("Monday, Tuesday") + EnabledDayOfWeekDto.from("Monday, Tuesday"), + 0 ); assertThat(getConstraintViolations(settingRequest).stream() @@ -42,7 +43,8 @@ void validTimeUnit(Integer timeUnit) { timeUnit, 60, 120, - EnabledDayOfWeekDto.from("Monday, Tuesday") + EnabledDayOfWeekDto.from("Monday, Tuesday"), + 0 ); assertThat(getConstraintViolations(settingRequest).stream() diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/repository/MapRepositoryTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/repository/MapRepositoryTest.java index e9e8ddb5d..e66c17beb 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/repository/MapRepositoryTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/repository/MapRepositoryTest.java @@ -104,6 +104,7 @@ void findByIdFetchJoinSpace() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); Space be = Space.builder() @@ -111,7 +112,7 @@ void findByIdFetchJoinSpace() { .color(BE_COLOR) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(beSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) .map(luther) .build(); @@ -123,6 +124,7 @@ void findByIdFetchJoinSpace() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); Space fe = Space.builder() @@ -131,7 +133,7 @@ void findByIdFetchJoinSpace() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(feSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) .build(); spaces.save(be); diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/repository/ReservationRepositoryImplTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/repository/ReservationRepositoryImplTest.java index d2b48d7da..032f64851 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/repository/ReservationRepositoryImplTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/repository/ReservationRepositoryImplTest.java @@ -38,6 +38,7 @@ void existsReservationsByMember(boolean isReservationExists) { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); Space be = Space.builder() @@ -45,7 +46,7 @@ void existsReservationsByMember(boolean isReservationExists) { .color(BE_COLOR) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(beSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) .map(luther) .build(); diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/repository/ReservationRepositoryTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/repository/ReservationRepositoryTest.java index 655cbf72e..3eaf14862 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/repository/ReservationRepositoryTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/repository/ReservationRepositoryTest.java @@ -52,6 +52,7 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); be = Space.builder() @@ -60,7 +61,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(beSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) .build(); Setting feSetting = Setting.builder() @@ -71,6 +72,7 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); fe = Space.builder() @@ -79,7 +81,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(feSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) .build(); members.save(pobi); diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/repository/SpaceRepositoryTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/repository/SpaceRepositoryTest.java index 4beff107d..42eb67441 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/repository/SpaceRepositoryTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/repository/SpaceRepositoryTest.java @@ -38,6 +38,7 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); be = Space.builder() @@ -45,7 +46,7 @@ void setUp() { .color(BE_COLOR) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(beSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) .map(luther) .build(); @@ -57,6 +58,7 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); fe = Space.builder() @@ -65,7 +67,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(feSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) .build(); members.save(pobi); diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/service/AdminServiceTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/service/AdminServiceTest.java index c1d23e4a0..3d5867269 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/service/AdminServiceTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/service/AdminServiceTest.java @@ -123,6 +123,7 @@ void findSpaces() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); Space be = Space.builder() @@ -131,7 +132,7 @@ void findSpaces() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(beSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) .build(); PageRequest pageRequest = PageRequest.of(0, 20, Sort.unsorted()); @@ -164,6 +165,7 @@ void findReservations() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); Space be = Space.builder() @@ -172,7 +174,7 @@ void findReservations() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(beSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) .build(); Reservation beAmZeroOne = Reservation.builder() diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/service/GuestReservationServiceTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/service/GuestReservationServiceTest.java index 8c049963d..9de5dd739 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/service/GuestReservationServiceTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/service/GuestReservationServiceTest.java @@ -79,6 +79,7 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); be = Space.builder() @@ -87,7 +88,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(beSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) .build(); Setting feSetting = Setting.builder() @@ -98,6 +99,7 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); fe = Space.builder() @@ -107,7 +109,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(feSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) .build(); beAmZeroOne = Reservation.builder() @@ -343,6 +345,7 @@ void saveReservationUnable() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); Space closedSpace = Space.builder() @@ -352,7 +355,7 @@ void saveReservationUnable() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(false) - .spaceSettings(new Settings(List.of(setting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) .build(); given(maps.findByIdFetch(anyLong())) @@ -382,6 +385,7 @@ void saveIllegalDayOfWeek() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek(THE_DAY_AFTER_TOMORROW.plusDays(1L).getDayOfWeek().name()) + .priorityOrder(0) .build(); Space invalidDayOfWeekSpace = Space.builder() @@ -391,7 +395,7 @@ void saveIllegalDayOfWeek() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(true) - .spaceSettings(new Settings(List.of(setting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) .build(); given(maps.findByIdFetch(anyLong())) @@ -497,6 +501,7 @@ void saveUpdateReservationMultipleSettings(int startHour, int endHour) { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(60)) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(1) .build()); given(maps.findByIdFetch(anyLong())) .willReturn(Optional.of(luther)); @@ -1163,6 +1168,7 @@ void updateReservationUnable() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); Space closedSpace = Space.builder() @@ -1172,7 +1178,7 @@ void updateReservationUnable() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(false) - .spaceSettings(new Settings(List.of(setting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) .build(); given(maps.findByIdFetch(anyLong())) @@ -1207,6 +1213,7 @@ void updateIllegalDayOfWeek() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek(THE_DAY_AFTER_TOMORROW.plusDays(1L).getDayOfWeek().name()) + .priorityOrder(0) .build(); Space invalidDayOfWeekSpace = Space.builder() @@ -1216,7 +1223,7 @@ void updateIllegalDayOfWeek() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(true) - .spaceSettings(new Settings(List.of(setting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) .build(); given(maps.findByIdFetch(anyLong())) diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/service/ManagerReservationServiceTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/service/ManagerReservationServiceTest.java index 432abf567..65d20031b 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/service/ManagerReservationServiceTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/service/ManagerReservationServiceTest.java @@ -95,6 +95,7 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); be = Space.builder() @@ -103,7 +104,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(beSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) .build(); Setting feSetting = Setting.builder() @@ -114,6 +115,7 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); fe = Space.builder() @@ -123,7 +125,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(feSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) .build(); beAmZeroOne = Reservation.builder() @@ -408,6 +410,7 @@ void saveReservationUnable() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); Space closedSpace = Space.builder() @@ -417,7 +420,7 @@ void saveReservationUnable() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(false) - .spaceSettings(new Settings(List.of(setting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) .build(); given(maps.findByIdFetch(anyLong())) @@ -449,6 +452,7 @@ void saveIllegalDayOfWeek() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek(THE_DAY_AFTER_TOMORROW.plusDays(1L).getDayOfWeek().name()) + .priorityOrder(0) .build(); Space invalidDayOfWeekSpace = Space.builder() @@ -458,7 +462,7 @@ void saveIllegalDayOfWeek() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(true) - .spaceSettings(new Settings(List.of(setting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) .build(); given(maps.findByIdFetch(anyLong())) @@ -568,6 +572,7 @@ void saveUpdateReservationMultipleSettings(int startHour, int endHour) { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(60)) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(1) .build()); given(maps.findByIdFetch(anyLong())) .willReturn(Optional.of(luther)); @@ -1361,6 +1366,7 @@ void updateReservationUnable() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); Space closedSpace = Space.builder() @@ -1370,7 +1376,7 @@ void updateReservationUnable() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(false) - .spaceSettings(new Settings(List.of(setting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) .build(); @@ -1407,6 +1413,7 @@ void updateIllegalDayOfWeek() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek(THE_DAY_AFTER_TOMORROW.plusDays(1L).getDayOfWeek().name()) + .priorityOrder(0) .build(); Space invalidDayOfWeekSpace = Space.builder() @@ -1416,7 +1423,7 @@ void updateIllegalDayOfWeek() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(true) - .spaceSettings(new Settings(List.of(setting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) .build(); diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/service/MapServiceTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/service/MapServiceTest.java index bc4987e3c..feb7abf7b 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/service/MapServiceTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/service/MapServiceTest.java @@ -62,6 +62,7 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); Space be = Space.builder() @@ -70,7 +71,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(beSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) .build(); Setting feSetting = Setting.builder() @@ -81,6 +82,7 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); Space fe = Space.builder() @@ -90,7 +92,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(feSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) .build(); } diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/service/PresetServiceTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/service/PresetServiceTest.java index a77320142..effd8ecee 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/service/PresetServiceTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/service/PresetServiceTest.java @@ -39,7 +39,8 @@ class PresetServiceTest extends ServiceTest { BE_RESERVATION_TIME_UNIT.getMinutes(), BE_RESERVATION_MINIMUM_TIME_UNIT.getMinutes(), BE_RESERVATION_MAXIMUM_TIME_UNIT.getMinutes(), - EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK) + EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK), + 0 ); private final Setting setting = Setting.builder() @@ -50,6 +51,7 @@ class PresetServiceTest extends ServiceTest { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); private Member pobi; diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/service/SpaceServiceTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/service/SpaceServiceTest.java index ba5cfe405..987e41e21 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/service/SpaceServiceTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/service/SpaceServiceTest.java @@ -38,7 +38,8 @@ class SpaceServiceTest extends ServiceTest { BE_RESERVATION_TIME_UNIT.getMinutes(), BE_RESERVATION_MINIMUM_TIME_UNIT.getMinutes(), BE_RESERVATION_MAXIMUM_TIME_UNIT.getMinutes(), - EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK) + EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK), + 0 ); private final SpaceCreateUpdateRequest spaceCreateUpdateRequest = new SpaceCreateUpdateRequest( @@ -100,6 +101,7 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); be = Space.builder() @@ -108,7 +110,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(beSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) .build(); Setting feSetting = Setting.builder() @@ -119,6 +121,7 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); fe = Space.builder() @@ -128,7 +131,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(feSetting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) .build(); lutherId = luther.getId(); @@ -149,6 +152,7 @@ void save() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .priorityOrder(0) .build(); Space newSpace = Space.builder() @@ -157,7 +161,7 @@ void save() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(new Settings(List.of(setting))) + .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) .build(); given(maps.findById(anyLong())) From 55f4f0b8fe435fa5bbf90bfd4c2704f1ef03def5 Mon Sep 17 00:00:00 2001 From: Jungseok Sung Date: Sat, 15 Apr 2023 16:01:21 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20=EA=B3=B5=EA=B0=84=20=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4=20=EC=A0=81=EC=9A=A9=20=EC=82=AC=EC=9A=A9=EC=84=B1=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0=20(FE)=20(#964)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: setting summary query 모든 예약 폼에 적용 서버측의 API 에서 받아온 메세지를 그대로 뿌려준다 * feat: 공간 예약 조건 우선순위 필드 추가해서 API 쏘도록 변경 마지막에 생선된 조건이 우선 적용됨 (= 낮은 priorityOrder) * feat: 공간 수정 페이지에 안내문구 추가 * feat: 예약 조건 텍스트 보여주는 형식 수정 * feat: 공간 수정 화면에서 예약 조건 설정 관련 부가 기능 추가 현재 적용된 예약 조건 확인 기능 추가, 안내 메세지 추가 --- frontend/src/__mocks__/mockData.ts | 1 + frontend/src/api/setting.ts | 25 ++++++++ .../components/Modal/SummaryModal.styles.ts | 58 +++++++++++++++++++ .../src/components/Modal/SummaryModal.tsx | 53 +++++++++++++++++ frontend/src/hooks/query/useSettingSummary.ts | 17 ++++++ .../GuestMap/units/ReservationForm.styled.ts | 28 ++++++--- .../pages/GuestMap/units/ReservationForm.tsx | 44 +++++++------- .../GuestReservation/GuestReservation.tsx | 4 ++ .../units/GuestReservationForm.styles.ts | 10 ++-- .../units/GuestReservationForm.tsx | 46 +++++++-------- .../units/MemberGuestReservationForm.tsx | 44 +++++++------- .../ManagerReservation/ManagerReservation.tsx | 1 + .../units/ManagerReservationForm.styles.ts | 10 ++-- .../units/ManagerReservationForm.tsx | 47 +++++++-------- .../ManagerSpaceEditor/ManagerSpaceEditor.tsx | 2 + frontend/src/pages/ManagerSpaceEditor/data.ts | 2 + .../providers/SpaceFormProvider.tsx | 5 ++ .../ManagerSpaceEditor/units/Form.styles.ts | 20 +++++++ .../pages/ManagerSpaceEditor/units/Form.tsx | 35 ++++++++++- .../pages/ManagerSpaceEditor/units/Preset.tsx | 2 +- .../units/SettingSummaryPopup.styles.ts | 13 +++++ .../units/SettingSummaryPopup.tsx | 40 +++++++++++++ frontend/src/types/common.ts | 1 + frontend/src/types/response.ts | 6 +- 24 files changed, 399 insertions(+), 115 deletions(-) create mode 100644 frontend/src/api/setting.ts create mode 100644 frontend/src/components/Modal/SummaryModal.styles.ts create mode 100644 frontend/src/components/Modal/SummaryModal.tsx create mode 100644 frontend/src/hooks/query/useSettingSummary.ts create mode 100644 frontend/src/pages/ManagerSpaceEditor/units/SettingSummaryPopup.styles.ts create mode 100644 frontend/src/pages/ManagerSpaceEditor/units/SettingSummaryPopup.tsx diff --git a/frontend/src/__mocks__/mockData.ts b/frontend/src/__mocks__/mockData.ts index fbfaa317f..bb28c703b 100644 --- a/frontend/src/__mocks__/mockData.ts +++ b/frontend/src/__mocks__/mockData.ts @@ -53,6 +53,7 @@ export const spaces: Spaces = { reservationTimeUnit: 10, reservationMinimumTimeUnit: 10, reservationMaximumTimeUnit: 1440, + priorityOrder: 0, enabledDayOfWeek: { monday: true, tuesday: true, diff --git a/frontend/src/api/setting.ts b/frontend/src/api/setting.ts new file mode 100644 index 000000000..467fe7b10 --- /dev/null +++ b/frontend/src/api/setting.ts @@ -0,0 +1,25 @@ +import { QS } from '@toss/utils'; +import { MapItem, Space } from '../types/common'; +import { QuerySettingSummarySuccess } from '../types/response'; +import api from './api'; + +export interface QuerySettingSummaryParams { + mapId: MapItem['mapId']; + spaceId: Space['id']; + selectedDateTime: string | null; + settingViewType: string | null; +} + +export const querySettingSummary = ({ + mapId, + spaceId, + selectedDateTime, + settingViewType, +}: QuerySettingSummaryParams) => { + return api.get( + `/maps/${mapId}/spaces/${spaceId}/settings/summary${QS.create({ + selectedDateTime: selectedDateTime, + settingViewType: settingViewType, + })}` + ); +}; diff --git a/frontend/src/components/Modal/SummaryModal.styles.ts b/frontend/src/components/Modal/SummaryModal.styles.ts new file mode 100644 index 000000000..5a026617a --- /dev/null +++ b/frontend/src/components/Modal/SummaryModal.styles.ts @@ -0,0 +1,58 @@ +import styled from 'styled-components'; +import { Z_INDEX } from 'constants/style'; + +interface Props { + open?: boolean; +} + +export const Overlay = styled.div` + display: ${({ open }) => (open ? 'flex' : 'none')}; + position: fixed; + justify-content: center; + align-items: center; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: ${({ theme }) => theme.modalOverlay}; + z-index: ${Z_INDEX.MODAL_OVERLAY}; + overflow: scroll; +`; + +export const Modal = styled.div` + width: 80%; + max-height: 70%; + min-width: 320px; + max-width: 768px; + position: absolute; + border-radius: 4px; + background-color: ${({ theme }) => theme.white}; + overflow: auto; +`; + +export const CloseButton = styled.button` + position: absolute; + padding: 0.5rem; + top: 0.5rem; + right: 1.5rem; + width: 1rem; + cursor: pointer; + border: none; + background: none; + + &:hover { + opacity: 0.7; + } +`; + +export const Inner = styled.div` + padding: 0.5rem 1rem; +`; + +export const Header = styled.h2` + font-weight: 700; + padding: 1rem; + margin-bottom: 0.5rem; +`; + +export const Content = styled.div``; diff --git a/frontend/src/components/Modal/SummaryModal.tsx b/frontend/src/components/Modal/SummaryModal.tsx new file mode 100644 index 000000000..b27e5f8f0 --- /dev/null +++ b/frontend/src/components/Modal/SummaryModal.tsx @@ -0,0 +1,53 @@ +import { MouseEventHandler, PropsWithChildren } from 'react'; +import { createPortal } from 'react-dom'; +import { ReactComponent as CloseIcon } from 'assets/svg/close.svg'; +import * as Styled from './SummaryModal.styles'; + +export interface Props { + open: boolean; + isClosableDimmer?: boolean; + showCloseButton?: boolean; + onClose: () => void; +} + +let modalRoot = document.getElementById('modal'); + +const SummaryModal = ({ + open, + isClosableDimmer, + showCloseButton, + onClose, + children, +}: PropsWithChildren): JSX.Element => { + if (modalRoot === null) { + modalRoot = document.createElement('div'); + modalRoot.setAttribute('id', 'modal'); + document.body.appendChild(modalRoot); + } + + const handleMouseDownOverlay: MouseEventHandler = ({ target, currentTarget }) => { + if (isClosableDimmer && target === currentTarget) { + onClose(); + } + }; + + return createPortal( + + + {open && showCloseButton && ( + + + + )} + {open && children} + + , + modalRoot + ); +}; + +SummaryModal.Inner = Styled.Inner; +SummaryModal.Header = Styled.Header; +SummaryModal.Content = Styled.Content; + +export default SummaryModal; diff --git a/frontend/src/hooks/query/useSettingSummary.ts b/frontend/src/hooks/query/useSettingSummary.ts new file mode 100644 index 000000000..aa2b257e1 --- /dev/null +++ b/frontend/src/hooks/query/useSettingSummary.ts @@ -0,0 +1,17 @@ +import { AxiosError, AxiosResponse } from 'axios'; +import { QueryKey, useQuery, UseQueryOptions, UseQueryResult } from 'react-query'; +import { ErrorResponse, QuerySettingSummarySuccess } from 'types/response'; +import { querySettingSummary, QuerySettingSummaryParams } from '../../api/setting'; + +const useSettingSummary = >( + params: QuerySettingSummaryParams, + options?: UseQueryOptions< + AxiosResponse, + AxiosError, + TData, + [QueryKey, QuerySettingSummaryParams] + > +): UseQueryResult> => + useQuery(['getSettingSummary', params], () => querySettingSummary(params), options); + +export default useSettingSummary; diff --git a/frontend/src/pages/GuestMap/units/ReservationForm.styled.ts b/frontend/src/pages/GuestMap/units/ReservationForm.styled.ts index 2c2d31f78..3983cc782 100644 --- a/frontend/src/pages/GuestMap/units/ReservationForm.styled.ts +++ b/frontend/src/pages/GuestMap/units/ReservationForm.styled.ts @@ -32,23 +32,33 @@ export const InputsRow = styled.div` } `; -export const TimeFormMessageWrapper = styled.div` +export const SettingSummaryWrapper = styled.div` display: flex; + flex-direction: column; gap: 0.25rem; margin-top: 0.5rem; `; -export const TimeFormMessageList = styled.div` - display: flex; - flex-direction: column; - gap: 4px; +/** + * 세팅이 많아질 경우를 대비 (펼치기, 접기 용도) + */ +export const PartialSettingSummary = styled.p` + height: 80px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: horizontal; + white-space: pre-line; + line-height: normal; + font-size: 0.75rem; + color: ${({ theme }) => theme.gray[500]}; `; -export const TimeFormMessage = styled.p<{ fontWeight?: string }>` - left: 0.75rem; - bottom: -1rem; +export const SettingSummary = styled.p<{ fontWeight?: string }>` + white-space: pre-line; + line-height: normal; font-size: 0.75rem; - height: 1em; color: ${({ theme }) => theme.gray[500]}; ${({ fontWeight }) => fontWeight && `font-weight: ${fontWeight}`}; `; diff --git a/frontend/src/pages/GuestMap/units/ReservationForm.tsx b/frontend/src/pages/GuestMap/units/ReservationForm.tsx index fd998eb75..2cc3265d7 100644 --- a/frontend/src/pages/GuestMap/units/ReservationForm.tsx +++ b/frontend/src/pages/GuestMap/units/ReservationForm.tsx @@ -1,6 +1,6 @@ import { AxiosError } from 'axios'; import dayjs from 'dayjs'; -import React, { useContext } from 'react'; +import React, { useContext, useState } from 'react'; import { useMutation } from 'react-query'; import { useHistory } from 'react-router-dom'; import { @@ -23,8 +23,9 @@ import useMember from 'hooks/query/useMember'; import { AccessTokenContext } from 'providers/AccessTokenProvider'; import { MapItem } from 'types/common'; import { ErrorResponse } from 'types/response'; -import { formatTimePrettier, formatTimeWithSecond, isPastDate } from 'utils/datetime'; +import { formatTimeWithSecond, isPastDate } from 'utils/datetime'; import { isNullish } from 'utils/type'; +import useSettingSummary from '../../../hooks/query/useSettingSummary'; import { GuestMapFormContext } from '../providers/GuestMapFormProvider'; import * as Styled from './ReservationForm.styled'; @@ -64,6 +65,19 @@ const ReservationForm = ({ map }: Props) => { ); }; + const getSettingsSummary = useSettingSummary( + { + mapId: map?.mapId, + spaceId: parseInt(selectedSpaceId), + selectedDateTime: `${formValues.date}T${formatTimeWithSecond( + timePicker?.range.start ?? dayjs().tz() + )}${DATE.TIMEZONE_OFFSET}`, + settingViewType: 'FLAT', + }, + { enabled: selectedSpaceId !== null && !isNaN(parseInt(selectedSpaceId)) } + ); + const settingsSummary = getSettingsSummary.data?.data?.summary ?? ''; + const onSuccessCreateReservation = ( _: unknown, { reservation }: PostGuestReservationParams | PostMemberGuestReservationParams @@ -165,28 +179,10 @@ const ReservationForm = ({ map }: Props) => { /> )} {spacesMap?.[Number(selectedSpaceId)] && ( - - 예약 가능 시간 - - {spacesMap[Number(selectedSpaceId)].settings.map( - ( - { - settingStartTime, - settingEndTime, - reservationMaximumTimeUnit, - reservationMinimumTimeUnit, - }, - index - ) => ( - - {settingStartTime.slice(0, 5)} ~ {settingEndTime.slice(0, 5)} - (최소 {formatTimePrettier(reservationMinimumTimeUnit)}, 최대{' '} - {formatTimePrettier(reservationMaximumTimeUnit)}) - - ) - )}{' '} - - + + 예약 가능 시간 + {settingsSummary} + )} diff --git a/frontend/src/pages/GuestReservation/GuestReservation.tsx b/frontend/src/pages/GuestReservation/GuestReservation.tsx index 6e736ec8a..04cb5e756 100644 --- a/frontend/src/pages/GuestReservation/GuestReservation.tsx +++ b/frontend/src/pages/GuestReservation/GuestReservation.tsx @@ -289,6 +289,8 @@ const GuestReservation = (): JSX.Element => { { ) : ( ` + white-space: pre-line; + line-height: normal; font-size: 0.75rem; - height: 1em; color: ${({ theme }) => theme.gray[500]}; + ${({ fontWeight }) => fontWeight && `font-weight: ${fontWeight}`}; `; export const ButtonWrapper = styled.div` diff --git a/frontend/src/pages/GuestReservation/units/GuestReservationForm.tsx b/frontend/src/pages/GuestReservation/units/GuestReservationForm.tsx index cb0a049bf..7fce7d116 100644 --- a/frontend/src/pages/GuestReservation/units/GuestReservationForm.tsx +++ b/frontend/src/pages/GuestReservation/units/GuestReservationForm.tsx @@ -1,3 +1,4 @@ +import dayjs from 'dayjs'; import React, { ChangeEventHandler, useMemo } from 'react'; import { ReactComponent as CalendarIcon } from 'assets/svg/calendar.svg'; import Input from 'components/Input/Input'; @@ -14,15 +15,17 @@ import { Reservation, Space } from 'types/common'; import { convertSettingTimeToMinutes, convertTimeToMinutes, - formatTimePrettier, formatTimeWithSecond, isPastDate, } from 'utils/datetime'; +import useSettingSummary from '../../../hooks/query/useSettingSummary'; import { EditGuestReservationParams } from '../GuestReservation'; import * as Styled from './GuestReservationForm.styles'; interface Props { isEditMode: boolean; + mapId: number; + spaceId: number; space: Pick; reservation?: Reservation; date: string; @@ -41,6 +44,8 @@ interface Form { const GuestReservationForm = ({ isEditMode, + mapId, + spaceId, space, date, reservation, @@ -79,6 +84,19 @@ const GuestReservationForm = ({ initialEndTime: !!reservation ? new Date(reservation.endDateTime) : undefined, }); + const getSettingsSummary = useSettingSummary( + { + mapId, + spaceId, + selectedDateTime: `${date}T${formatTimeWithSecond(range.start ?? dayjs().tz())}${ + DATE.TIMEZONE_OFFSET + }`, + settingViewType: 'FLAT', + }, + {} + ); + const settingsSummary = getSettingsSummary.data?.data?.summary ?? ''; + const [{ name, description, password }, onChangeForm] = useInputs

({ name: reservation?.name ?? '', description: reservation?.description ?? '', @@ -151,28 +169,10 @@ const GuestReservationForm = ({ onChange={onChange} onCloseOptions={onCloseOptions} /> - - 예약 가능 시간 - {space.settings.map( - ( - { - settingStartTime, - settingEndTime, - reservationMaximumTimeUnit, - reservationMinimumTimeUnit, - }, - index - ) => { - return ( - - {settingStartTime.slice(0, 5)} ~ {settingEndTime.slice(0, 5)} - (최소 {formatTimePrettier(reservationMinimumTimeUnit)}, 최대{' '} - {formatTimePrettier(reservationMaximumTimeUnit)}) - - ); - } - )} - + + 예약 가능 시간 + {settingsSummary} + ; + spaceId: number; + mapId: number; reservation?: Reservation; date: string; userName: string; @@ -39,6 +42,8 @@ interface Form { const MemberGuestReservationForm = ({ isEditMode, + mapId, + spaceId, space, date, reservation, @@ -78,6 +83,19 @@ const MemberGuestReservationForm = ({ initialEndTime: !!reservation ? new Date(reservation.endDateTime) : undefined, }); + const getSettingsSummary = useSettingSummary( + { + mapId, + spaceId, + selectedDateTime: `${date}T${formatTimeWithSecond(range.start ?? dayjs().tz())}${ + DATE.TIMEZONE_OFFSET + }`, + settingViewType: 'FLAT', + }, + {} + ); + const settingsSummary = getSettingsSummary.data?.data?.summary ?? ''; + const [{ description }, onChangeForm] = useInputs({ description: reservation?.description ?? '', }); @@ -139,26 +157,10 @@ const MemberGuestReservationForm = ({ onChange={onChange} onCloseOptions={onCloseOptions} /> - - 예약 가능 시간 - {space.settings.map( - ( - { - settingStartTime, - settingEndTime, - reservationMaximumTimeUnit, - reservationMinimumTimeUnit, - }, - index - ) => ( - - {settingStartTime.slice(0, 5)} ~ {settingEndTime.slice(0, 5)} - (최소 {formatTimePrettier(reservationMinimumTimeUnit)}, 최대{' '} - {formatTimePrettier(reservationMaximumTimeUnit)}) - - ) - )} - + + 예약 가능 시간 + {settingsSummary} + diff --git a/frontend/src/pages/ManagerReservation/ManagerReservation.tsx b/frontend/src/pages/ManagerReservation/ManagerReservation.tsx index 3ad8e947d..e6928382b 100644 --- a/frontend/src/pages/ManagerReservation/ManagerReservation.tsx +++ b/frontend/src/pages/ManagerReservation/ManagerReservation.tsx @@ -150,6 +150,7 @@ const ManagerReservation = (): JSX.Element => { ` + white-space: pre-line; + line-height: normal; font-size: 0.75rem; - height: 1em; color: ${({ theme }) => theme.gray[500]}; + ${({ fontWeight }) => fontWeight && `font-weight: ${fontWeight}`}; `; diff --git a/frontend/src/pages/ManagerReservation/units/ManagerReservationForm.tsx b/frontend/src/pages/ManagerReservation/units/ManagerReservationForm.tsx index 8b93291aa..125f8def3 100644 --- a/frontend/src/pages/ManagerReservation/units/ManagerReservationForm.tsx +++ b/frontend/src/pages/ManagerReservation/units/ManagerReservationForm.tsx @@ -1,4 +1,5 @@ -import { ChangeEventHandler, useMemo } from 'react'; +import dayjs from 'dayjs'; +import React, { ChangeEventHandler, useMemo, useState } from 'react'; import { ReactComponent as CalendarIcon } from 'assets/svg/calendar.svg'; import Button from 'components/Button/Button'; import Input from 'components/Input/Input'; @@ -15,14 +16,15 @@ import { ManagerSpaceAPI, Reservation } from 'types/common'; import { convertSettingTimeToMinutes, convertTimeToMinutes, - formatTimePrettier, formatTimeWithSecond, } from 'utils/datetime'; +import useSettingSummary from '../../../hooks/query/useSettingSummary'; import { CreateReservationParams, EditReservationParams } from '../ManagerReservation'; import * as Styled from './ManagerReservationForm.styles'; interface Props { isEditMode: boolean; + mapId: number; space: ManagerSpaceAPI; reservation?: Reservation; date: string; @@ -39,6 +41,7 @@ interface Form { const ManagerReservationForm = ({ isEditMode, + mapId, space, date, reservation, @@ -78,6 +81,19 @@ const ManagerReservationForm = ({ initialEndTime: !!reservation ? new Date(reservation.endDateTime) : undefined, }); + const getSettingsSummary = useSettingSummary( + { + mapId, + spaceId: space?.id, + selectedDateTime: `${date}T${formatTimeWithSecond(range.start ?? dayjs().tz())}${ + DATE.TIMEZONE_OFFSET + }`, + settingViewType: 'FLAT', + }, + {} + ); + const settingsSummary = getSettingsSummary.data?.data?.summary ?? ''; + const [{ name, description, password }, onChangeForm] = useInputs({ name: reservation?.name ?? '', description: reservation?.description ?? '', @@ -164,29 +180,10 @@ const ManagerReservationForm = ({ onChange={onChange} onCloseOptions={onCloseOptions} /> - - - 예약 가능 시간 - {space.settings.map( - ( - { - settingStartTime, - settingEndTime, - reservationMaximumTimeUnit, - reservationMinimumTimeUnit, - }, - index - ) => { - return ( - - {settingStartTime.slice(0, 5)} ~ {settingEndTime.slice(0, 5)} - (최소 {formatTimePrettier(reservationMinimumTimeUnit)}, 최대{' '} - {formatTimePrettier(reservationMaximumTimeUnit)}) - - ); - } - )} - + + 예약 가능 시간 + {settingsSummary} + {isEditMode || ( diff --git a/frontend/src/pages/ManagerSpaceEditor/ManagerSpaceEditor.tsx b/frontend/src/pages/ManagerSpaceEditor/ManagerSpaceEditor.tsx index 8366ec476..63b60130b 100644 --- a/frontend/src/pages/ManagerSpaceEditor/ManagerSpaceEditor.tsx +++ b/frontend/src/pages/ManagerSpaceEditor/ManagerSpaceEditor.tsx @@ -109,6 +109,8 @@ const ManagerSpaceEditor = (): JSX.Element => { }, }); + // TODO: handleCreateSpace, handleUpdateSpace 시 priorityOrder 고려해서 request 발송 + // TODO: const handleCreateSpace = (data: Omit) => createSpace.mutate({ mapId: Number(mapId), ...data }); diff --git a/frontend/src/pages/ManagerSpaceEditor/data.ts b/frontend/src/pages/ManagerSpaceEditor/data.ts index 607dde757..281a05a37 100644 --- a/frontend/src/pages/ManagerSpaceEditor/data.ts +++ b/frontend/src/pages/ManagerSpaceEditor/data.ts @@ -23,6 +23,7 @@ export interface SpaceFormValue { saturday: boolean; sunday: boolean; }; + priorityOrder: number; }[]; } @@ -45,6 +46,7 @@ export const initialSpaceFormValueSetting = { reservationMinimumTimeUnit: 10, reservationMaximumTimeUnit: 120, enabledDayOfWeek: initialEnabledDayOfWeek, + priorityOrder: 0, }; export const initialSpaceFormValue: Omit = { diff --git a/frontend/src/pages/ManagerSpaceEditor/providers/SpaceFormProvider.tsx b/frontend/src/pages/ManagerSpaceEditor/providers/SpaceFormProvider.tsx index 2495e9d64..92a51f1e6 100644 --- a/frontend/src/pages/ManagerSpaceEditor/providers/SpaceFormProvider.tsx +++ b/frontend/src/pages/ManagerSpaceEditor/providers/SpaceFormProvider.tsx @@ -107,6 +107,11 @@ const SpaceFormProvider = ({ children }: Props): JSX.Element => { const getRequestValues = () => { const todayDate = formatDate(new Date()); + for (let i = 0; i < values.settings.length; i++) { + const setting = values.settings[i]; + setting['priorityOrder'] = values.settings.length - (i + 1); + } + return { space: { ...values, diff --git a/frontend/src/pages/ManagerSpaceEditor/units/Form.styles.ts b/frontend/src/pages/ManagerSpaceEditor/units/Form.styles.ts index 7682a1468..dcfb45d30 100644 --- a/frontend/src/pages/ManagerSpaceEditor/units/Form.styles.ts +++ b/frontend/src/pages/ManagerSpaceEditor/units/Form.styles.ts @@ -32,6 +32,26 @@ export const TitleContainer = styled.div` margin-bottom: 1rem; `; +export const InfoMessageWrapper = styled.div` + display: flex; + flex-direction: column; + gap: 0.25rem; + margin-top: 0.5rem; + justify-content: space-between; + margin-bottom: 2rem; +`; + +export const InfoMessage = styled.p<{ fontWeight?: string }>` + left: 0.75rem; + bottom: -1.5rem; + font-size: 0.75rem; + height: 1.5em; + white-space: pre-line; + line-height: normal; + color: ${({ theme }) => theme.gray[500]}; + ${({ fontWeight }) => fontWeight && `font-weight: ${fontWeight}`}; +`; + export const ContentsContainer = styled.div` display: flex; flex-direction: column; diff --git a/frontend/src/pages/ManagerSpaceEditor/units/Form.tsx b/frontend/src/pages/ManagerSpaceEditor/units/Form.tsx index 58fbd748a..dc75c5114 100644 --- a/frontend/src/pages/ManagerSpaceEditor/units/Form.tsx +++ b/frontend/src/pages/ManagerSpaceEditor/units/Form.tsx @@ -1,4 +1,11 @@ -import { Dispatch, FormEventHandler, SetStateAction, useEffect, useRef } from 'react'; +import React, { + Dispatch, + FormEventHandler, + SetStateAction, + useEffect, + useRef, + useState, +} from 'react'; import { DeleteManagerSpaceParams, PostManagerSpaceParams, @@ -23,6 +30,7 @@ import * as Styled from './Form.styles'; import FormDayOfWeekSelect from './FormDayOfWeekSelect'; import FormTimeUnitSelect from './FormTimeUnitSelect'; import Preset from './Preset'; +import SettingSummaryPopup from './SettingSummaryPopup'; interface Props { modeState: [Mode, Dispatch>]; @@ -48,6 +56,7 @@ const Form = ({ const nameInputRef = useRef(null); const [mode, setMode] = modeState; + const [settingSummaryPopupOpen, setSettingSummaryPopupOpen] = useState(false); const { values, @@ -185,7 +194,31 @@ const Form = ({ 예약 조건 + {selectedSpaceId != null && ( + + )} + + + 예약 조건이 서로 겹칠 시, 뒷 순서의 예약 조건이 앞 순서의 예약 조건을 덮어씁니다. + + + {settingSummaryPopupOpen && selectedSpaceId != null && ( + setSettingSummaryPopupOpen(false)} + mapId={Number(window.location.pathname.split('/', 3).pop())} + spaceId={selectedSpaceId} + /> + )} {values.settings.map((_, index) => ( diff --git a/frontend/src/pages/ManagerSpaceEditor/units/Preset.tsx b/frontend/src/pages/ManagerSpaceEditor/units/Preset.tsx index 23f18b4b6..f26e257f3 100644 --- a/frontend/src/pages/ManagerSpaceEditor/units/Preset.tsx +++ b/frontend/src/pages/ManagerSpaceEditor/units/Preset.tsx @@ -72,7 +72,7 @@ const Preset = (): JSX.Element => { ...values, settings: values.settings.map((setting, index) => { if (index === selectedSettingIndex) { - return rest; + return { ...rest, priorityOrder: 0 }; } return setting; diff --git a/frontend/src/pages/ManagerSpaceEditor/units/SettingSummaryPopup.styles.ts b/frontend/src/pages/ManagerSpaceEditor/units/SettingSummaryPopup.styles.ts new file mode 100644 index 000000000..12eb86cb8 --- /dev/null +++ b/frontend/src/pages/ManagerSpaceEditor/units/SettingSummaryPopup.styles.ts @@ -0,0 +1,13 @@ +import styled from 'styled-components'; + +export const SettingSummaryPopupWrapper = styled.div` + padding: 2rem 3rem; +`; + +export const SettingSummary = styled.p<{ fontWeight?: string }>` + white-space: pre-line; + line-height: normal; + font-size: 0.75rem; + color: ${({ theme }) => theme.gray[500]}; + ${({ fontWeight }) => fontWeight && `font-weight: ${fontWeight}`}; +`; diff --git a/frontend/src/pages/ManagerSpaceEditor/units/SettingSummaryPopup.tsx b/frontend/src/pages/ManagerSpaceEditor/units/SettingSummaryPopup.tsx new file mode 100644 index 000000000..bc3fcfabc --- /dev/null +++ b/frontend/src/pages/ManagerSpaceEditor/units/SettingSummaryPopup.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import Modal from '../../../components/Modal/Modal'; +import SummaryModal from '../../../components/Modal/SummaryModal'; +import useSettingSummary from '../../../hooks/query/useSettingSummary'; +import * as Styled from './SettingSummaryPopup.styles'; + +interface SettingSummaryProps { + mapId: number; + spaceId: number; + open: boolean; + onClose: () => void; +} + +const SettingSummaryPopup = ({ + mapId, + spaceId, + open, + onClose, +}: SettingSummaryProps): JSX.Element => { + const getSettingsSummary = useSettingSummary( + { + mapId, + spaceId, + selectedDateTime: null, + settingViewType: 'FLAT', + }, + {} + ); + const settingsSummary = getSettingsSummary.data?.data?.summary ?? ''; + + return ( + + + {settingsSummary} + + + ); +}; + +export default SettingSummaryPopup; diff --git a/frontend/src/types/common.ts b/frontend/src/types/common.ts index a76c21dc1..03b622d8d 100644 --- a/frontend/src/types/common.ts +++ b/frontend/src/types/common.ts @@ -112,6 +112,7 @@ export interface SpaceSetting { saturday: boolean; sunday: boolean; }; + priorityOrder: number; } export interface Preset { diff --git a/frontend/src/types/response.ts b/frontend/src/types/response.ts index 41594e0ff..6a5bcbdd6 100644 --- a/frontend/src/types/response.ts +++ b/frontend/src/types/response.ts @@ -1,5 +1,4 @@ import { - Area, Emoji, ManagerSpaceAPI, MapItem, @@ -53,6 +52,7 @@ export interface QueryManagerMapsSuccess { export interface QueryManagerSpaceReservationsSuccess { reservations: Reservation[]; } + export interface QueryManagerMapReservationsSuccess { data: SpaceReservation[]; } @@ -91,3 +91,7 @@ export interface QueryMemberReservationsSuccess { hasNext: boolean; pageNumber: number; } + +export interface QuerySettingSummarySuccess { + summary: string; +} From 6492aefa0d5e9e09d605f1eaf78c02e1ceecaaeb Mon Sep 17 00:00:00 2001 From: sakjung Date: Thu, 3 Aug 2023 20:47:45 +0900 Subject: [PATCH 3/7] =?UTF-8?q?Revert=20"feat:=20=EA=B3=B5=EA=B0=84=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=20=EC=A0=81=EC=9A=A9=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=84=B1=20=EA=B0=9C=EC=84=A0=20(FE)=20(#964)"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 55f4f0b8fe435fa5bbf90bfd4c2704f1ef03def5. --- frontend/src/__mocks__/mockData.ts | 1 - frontend/src/api/setting.ts | 25 -------- .../components/Modal/SummaryModal.styles.ts | 58 ------------------- .../src/components/Modal/SummaryModal.tsx | 53 ----------------- frontend/src/hooks/query/useSettingSummary.ts | 17 ------ .../GuestMap/units/ReservationForm.styled.ts | 28 +++------ .../pages/GuestMap/units/ReservationForm.tsx | 44 +++++++------- .../GuestReservation/GuestReservation.tsx | 4 -- .../units/GuestReservationForm.styles.ts | 10 ++-- .../units/GuestReservationForm.tsx | 46 +++++++-------- .../units/MemberGuestReservationForm.tsx | 44 +++++++------- .../ManagerReservation/ManagerReservation.tsx | 1 - .../units/ManagerReservationForm.styles.ts | 10 ++-- .../units/ManagerReservationForm.tsx | 47 ++++++++------- .../ManagerSpaceEditor/ManagerSpaceEditor.tsx | 2 - frontend/src/pages/ManagerSpaceEditor/data.ts | 2 - .../providers/SpaceFormProvider.tsx | 5 -- .../ManagerSpaceEditor/units/Form.styles.ts | 20 ------- .../pages/ManagerSpaceEditor/units/Form.tsx | 35 +---------- .../pages/ManagerSpaceEditor/units/Preset.tsx | 2 +- .../units/SettingSummaryPopup.styles.ts | 13 ----- .../units/SettingSummaryPopup.tsx | 40 ------------- frontend/src/types/common.ts | 1 - frontend/src/types/response.ts | 6 +- 24 files changed, 115 insertions(+), 399 deletions(-) delete mode 100644 frontend/src/api/setting.ts delete mode 100644 frontend/src/components/Modal/SummaryModal.styles.ts delete mode 100644 frontend/src/components/Modal/SummaryModal.tsx delete mode 100644 frontend/src/hooks/query/useSettingSummary.ts delete mode 100644 frontend/src/pages/ManagerSpaceEditor/units/SettingSummaryPopup.styles.ts delete mode 100644 frontend/src/pages/ManagerSpaceEditor/units/SettingSummaryPopup.tsx diff --git a/frontend/src/__mocks__/mockData.ts b/frontend/src/__mocks__/mockData.ts index bb28c703b..fbfaa317f 100644 --- a/frontend/src/__mocks__/mockData.ts +++ b/frontend/src/__mocks__/mockData.ts @@ -53,7 +53,6 @@ export const spaces: Spaces = { reservationTimeUnit: 10, reservationMinimumTimeUnit: 10, reservationMaximumTimeUnit: 1440, - priorityOrder: 0, enabledDayOfWeek: { monday: true, tuesday: true, diff --git a/frontend/src/api/setting.ts b/frontend/src/api/setting.ts deleted file mode 100644 index 467fe7b10..000000000 --- a/frontend/src/api/setting.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { QS } from '@toss/utils'; -import { MapItem, Space } from '../types/common'; -import { QuerySettingSummarySuccess } from '../types/response'; -import api from './api'; - -export interface QuerySettingSummaryParams { - mapId: MapItem['mapId']; - spaceId: Space['id']; - selectedDateTime: string | null; - settingViewType: string | null; -} - -export const querySettingSummary = ({ - mapId, - spaceId, - selectedDateTime, - settingViewType, -}: QuerySettingSummaryParams) => { - return api.get( - `/maps/${mapId}/spaces/${spaceId}/settings/summary${QS.create({ - selectedDateTime: selectedDateTime, - settingViewType: settingViewType, - })}` - ); -}; diff --git a/frontend/src/components/Modal/SummaryModal.styles.ts b/frontend/src/components/Modal/SummaryModal.styles.ts deleted file mode 100644 index 5a026617a..000000000 --- a/frontend/src/components/Modal/SummaryModal.styles.ts +++ /dev/null @@ -1,58 +0,0 @@ -import styled from 'styled-components'; -import { Z_INDEX } from 'constants/style'; - -interface Props { - open?: boolean; -} - -export const Overlay = styled.div` - display: ${({ open }) => (open ? 'flex' : 'none')}; - position: fixed; - justify-content: center; - align-items: center; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: ${({ theme }) => theme.modalOverlay}; - z-index: ${Z_INDEX.MODAL_OVERLAY}; - overflow: scroll; -`; - -export const Modal = styled.div` - width: 80%; - max-height: 70%; - min-width: 320px; - max-width: 768px; - position: absolute; - border-radius: 4px; - background-color: ${({ theme }) => theme.white}; - overflow: auto; -`; - -export const CloseButton = styled.button` - position: absolute; - padding: 0.5rem; - top: 0.5rem; - right: 1.5rem; - width: 1rem; - cursor: pointer; - border: none; - background: none; - - &:hover { - opacity: 0.7; - } -`; - -export const Inner = styled.div` - padding: 0.5rem 1rem; -`; - -export const Header = styled.h2` - font-weight: 700; - padding: 1rem; - margin-bottom: 0.5rem; -`; - -export const Content = styled.div``; diff --git a/frontend/src/components/Modal/SummaryModal.tsx b/frontend/src/components/Modal/SummaryModal.tsx deleted file mode 100644 index b27e5f8f0..000000000 --- a/frontend/src/components/Modal/SummaryModal.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { MouseEventHandler, PropsWithChildren } from 'react'; -import { createPortal } from 'react-dom'; -import { ReactComponent as CloseIcon } from 'assets/svg/close.svg'; -import * as Styled from './SummaryModal.styles'; - -export interface Props { - open: boolean; - isClosableDimmer?: boolean; - showCloseButton?: boolean; - onClose: () => void; -} - -let modalRoot = document.getElementById('modal'); - -const SummaryModal = ({ - open, - isClosableDimmer, - showCloseButton, - onClose, - children, -}: PropsWithChildren): JSX.Element => { - if (modalRoot === null) { - modalRoot = document.createElement('div'); - modalRoot.setAttribute('id', 'modal'); - document.body.appendChild(modalRoot); - } - - const handleMouseDownOverlay: MouseEventHandler = ({ target, currentTarget }) => { - if (isClosableDimmer && target === currentTarget) { - onClose(); - } - }; - - return createPortal( - - - {open && showCloseButton && ( - - - - )} - {open && children} - - , - modalRoot - ); -}; - -SummaryModal.Inner = Styled.Inner; -SummaryModal.Header = Styled.Header; -SummaryModal.Content = Styled.Content; - -export default SummaryModal; diff --git a/frontend/src/hooks/query/useSettingSummary.ts b/frontend/src/hooks/query/useSettingSummary.ts deleted file mode 100644 index aa2b257e1..000000000 --- a/frontend/src/hooks/query/useSettingSummary.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { AxiosError, AxiosResponse } from 'axios'; -import { QueryKey, useQuery, UseQueryOptions, UseQueryResult } from 'react-query'; -import { ErrorResponse, QuerySettingSummarySuccess } from 'types/response'; -import { querySettingSummary, QuerySettingSummaryParams } from '../../api/setting'; - -const useSettingSummary = >( - params: QuerySettingSummaryParams, - options?: UseQueryOptions< - AxiosResponse, - AxiosError, - TData, - [QueryKey, QuerySettingSummaryParams] - > -): UseQueryResult> => - useQuery(['getSettingSummary', params], () => querySettingSummary(params), options); - -export default useSettingSummary; diff --git a/frontend/src/pages/GuestMap/units/ReservationForm.styled.ts b/frontend/src/pages/GuestMap/units/ReservationForm.styled.ts index 3983cc782..2c2d31f78 100644 --- a/frontend/src/pages/GuestMap/units/ReservationForm.styled.ts +++ b/frontend/src/pages/GuestMap/units/ReservationForm.styled.ts @@ -32,33 +32,23 @@ export const InputsRow = styled.div` } `; -export const SettingSummaryWrapper = styled.div` +export const TimeFormMessageWrapper = styled.div` display: flex; - flex-direction: column; gap: 0.25rem; margin-top: 0.5rem; `; -/** - * 세팅이 많아질 경우를 대비 (펼치기, 접기 용도) - */ -export const PartialSettingSummary = styled.p` - height: 80px; - overflow: hidden; - text-overflow: ellipsis; - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: horizontal; - white-space: pre-line; - line-height: normal; - font-size: 0.75rem; - color: ${({ theme }) => theme.gray[500]}; +export const TimeFormMessageList = styled.div` + display: flex; + flex-direction: column; + gap: 4px; `; -export const SettingSummary = styled.p<{ fontWeight?: string }>` - white-space: pre-line; - line-height: normal; +export const TimeFormMessage = styled.p<{ fontWeight?: string }>` + left: 0.75rem; + bottom: -1rem; font-size: 0.75rem; + height: 1em; color: ${({ theme }) => theme.gray[500]}; ${({ fontWeight }) => fontWeight && `font-weight: ${fontWeight}`}; `; diff --git a/frontend/src/pages/GuestMap/units/ReservationForm.tsx b/frontend/src/pages/GuestMap/units/ReservationForm.tsx index 2cc3265d7..fd998eb75 100644 --- a/frontend/src/pages/GuestMap/units/ReservationForm.tsx +++ b/frontend/src/pages/GuestMap/units/ReservationForm.tsx @@ -1,6 +1,6 @@ import { AxiosError } from 'axios'; import dayjs from 'dayjs'; -import React, { useContext, useState } from 'react'; +import React, { useContext } from 'react'; import { useMutation } from 'react-query'; import { useHistory } from 'react-router-dom'; import { @@ -23,9 +23,8 @@ import useMember from 'hooks/query/useMember'; import { AccessTokenContext } from 'providers/AccessTokenProvider'; import { MapItem } from 'types/common'; import { ErrorResponse } from 'types/response'; -import { formatTimeWithSecond, isPastDate } from 'utils/datetime'; +import { formatTimePrettier, formatTimeWithSecond, isPastDate } from 'utils/datetime'; import { isNullish } from 'utils/type'; -import useSettingSummary from '../../../hooks/query/useSettingSummary'; import { GuestMapFormContext } from '../providers/GuestMapFormProvider'; import * as Styled from './ReservationForm.styled'; @@ -65,19 +64,6 @@ const ReservationForm = ({ map }: Props) => { ); }; - const getSettingsSummary = useSettingSummary( - { - mapId: map?.mapId, - spaceId: parseInt(selectedSpaceId), - selectedDateTime: `${formValues.date}T${formatTimeWithSecond( - timePicker?.range.start ?? dayjs().tz() - )}${DATE.TIMEZONE_OFFSET}`, - settingViewType: 'FLAT', - }, - { enabled: selectedSpaceId !== null && !isNaN(parseInt(selectedSpaceId)) } - ); - const settingsSummary = getSettingsSummary.data?.data?.summary ?? ''; - const onSuccessCreateReservation = ( _: unknown, { reservation }: PostGuestReservationParams | PostMemberGuestReservationParams @@ -179,10 +165,28 @@ const ReservationForm = ({ map }: Props) => { /> )} {spacesMap?.[Number(selectedSpaceId)] && ( - - 예약 가능 시간 - {settingsSummary} - + + 예약 가능 시간 + + {spacesMap[Number(selectedSpaceId)].settings.map( + ( + { + settingStartTime, + settingEndTime, + reservationMaximumTimeUnit, + reservationMinimumTimeUnit, + }, + index + ) => ( + + {settingStartTime.slice(0, 5)} ~ {settingEndTime.slice(0, 5)} + (최소 {formatTimePrettier(reservationMinimumTimeUnit)}, 최대{' '} + {formatTimePrettier(reservationMaximumTimeUnit)}) + + ) + )}{' '} + + )} diff --git a/frontend/src/pages/GuestReservation/GuestReservation.tsx b/frontend/src/pages/GuestReservation/GuestReservation.tsx index 04cb5e756..6e736ec8a 100644 --- a/frontend/src/pages/GuestReservation/GuestReservation.tsx +++ b/frontend/src/pages/GuestReservation/GuestReservation.tsx @@ -289,8 +289,6 @@ const GuestReservation = (): JSX.Element => { { ) : ( ` - white-space: pre-line; - line-height: normal; +export const TimeFormMessage = styled.p` + left: 0.75rem; + bottom: -1rem; font-size: 0.75rem; + height: 1em; color: ${({ theme }) => theme.gray[500]}; - ${({ fontWeight }) => fontWeight && `font-weight: ${fontWeight}`}; `; export const ButtonWrapper = styled.div` diff --git a/frontend/src/pages/GuestReservation/units/GuestReservationForm.tsx b/frontend/src/pages/GuestReservation/units/GuestReservationForm.tsx index 7fce7d116..cb0a049bf 100644 --- a/frontend/src/pages/GuestReservation/units/GuestReservationForm.tsx +++ b/frontend/src/pages/GuestReservation/units/GuestReservationForm.tsx @@ -1,4 +1,3 @@ -import dayjs from 'dayjs'; import React, { ChangeEventHandler, useMemo } from 'react'; import { ReactComponent as CalendarIcon } from 'assets/svg/calendar.svg'; import Input from 'components/Input/Input'; @@ -15,17 +14,15 @@ import { Reservation, Space } from 'types/common'; import { convertSettingTimeToMinutes, convertTimeToMinutes, + formatTimePrettier, formatTimeWithSecond, isPastDate, } from 'utils/datetime'; -import useSettingSummary from '../../../hooks/query/useSettingSummary'; import { EditGuestReservationParams } from '../GuestReservation'; import * as Styled from './GuestReservationForm.styles'; interface Props { isEditMode: boolean; - mapId: number; - spaceId: number; space: Pick; reservation?: Reservation; date: string; @@ -44,8 +41,6 @@ interface Form { const GuestReservationForm = ({ isEditMode, - mapId, - spaceId, space, date, reservation, @@ -84,19 +79,6 @@ const GuestReservationForm = ({ initialEndTime: !!reservation ? new Date(reservation.endDateTime) : undefined, }); - const getSettingsSummary = useSettingSummary( - { - mapId, - spaceId, - selectedDateTime: `${date}T${formatTimeWithSecond(range.start ?? dayjs().tz())}${ - DATE.TIMEZONE_OFFSET - }`, - settingViewType: 'FLAT', - }, - {} - ); - const settingsSummary = getSettingsSummary.data?.data?.summary ?? ''; - const [{ name, description, password }, onChangeForm] = useInputs({ name: reservation?.name ?? '', description: reservation?.description ?? '', @@ -169,10 +151,28 @@ const GuestReservationForm = ({ onChange={onChange} onCloseOptions={onCloseOptions} /> - - 예약 가능 시간 - {settingsSummary} - + + 예약 가능 시간 + {space.settings.map( + ( + { + settingStartTime, + settingEndTime, + reservationMaximumTimeUnit, + reservationMinimumTimeUnit, + }, + index + ) => { + return ( + + {settingStartTime.slice(0, 5)} ~ {settingEndTime.slice(0, 5)} + (최소 {formatTimePrettier(reservationMinimumTimeUnit)}, 최대{' '} + {formatTimePrettier(reservationMaximumTimeUnit)}) + + ); + } + )} + ; - spaceId: number; - mapId: number; reservation?: Reservation; date: string; userName: string; @@ -42,8 +39,6 @@ interface Form { const MemberGuestReservationForm = ({ isEditMode, - mapId, - spaceId, space, date, reservation, @@ -83,19 +78,6 @@ const MemberGuestReservationForm = ({ initialEndTime: !!reservation ? new Date(reservation.endDateTime) : undefined, }); - const getSettingsSummary = useSettingSummary( - { - mapId, - spaceId, - selectedDateTime: `${date}T${formatTimeWithSecond(range.start ?? dayjs().tz())}${ - DATE.TIMEZONE_OFFSET - }`, - settingViewType: 'FLAT', - }, - {} - ); - const settingsSummary = getSettingsSummary.data?.data?.summary ?? ''; - const [{ description }, onChangeForm] = useInputs({ description: reservation?.description ?? '', }); @@ -157,10 +139,26 @@ const MemberGuestReservationForm = ({ onChange={onChange} onCloseOptions={onCloseOptions} /> - - 예약 가능 시간 - {settingsSummary} - + + 예약 가능 시간 + {space.settings.map( + ( + { + settingStartTime, + settingEndTime, + reservationMaximumTimeUnit, + reservationMinimumTimeUnit, + }, + index + ) => ( + + {settingStartTime.slice(0, 5)} ~ {settingEndTime.slice(0, 5)} + (최소 {formatTimePrettier(reservationMinimumTimeUnit)}, 최대{' '} + {formatTimePrettier(reservationMaximumTimeUnit)}) + + ) + )} + diff --git a/frontend/src/pages/ManagerReservation/ManagerReservation.tsx b/frontend/src/pages/ManagerReservation/ManagerReservation.tsx index e6928382b..3ad8e947d 100644 --- a/frontend/src/pages/ManagerReservation/ManagerReservation.tsx +++ b/frontend/src/pages/ManagerReservation/ManagerReservation.tsx @@ -150,7 +150,6 @@ const ManagerReservation = (): JSX.Element => { ` - white-space: pre-line; - line-height: normal; +export const TimeFormMessage = styled.p` + left: 0.75rem; + bottom: -1rem; font-size: 0.75rem; + height: 1em; color: ${({ theme }) => theme.gray[500]}; - ${({ fontWeight }) => fontWeight && `font-weight: ${fontWeight}`}; `; diff --git a/frontend/src/pages/ManagerReservation/units/ManagerReservationForm.tsx b/frontend/src/pages/ManagerReservation/units/ManagerReservationForm.tsx index 125f8def3..8b93291aa 100644 --- a/frontend/src/pages/ManagerReservation/units/ManagerReservationForm.tsx +++ b/frontend/src/pages/ManagerReservation/units/ManagerReservationForm.tsx @@ -1,5 +1,4 @@ -import dayjs from 'dayjs'; -import React, { ChangeEventHandler, useMemo, useState } from 'react'; +import { ChangeEventHandler, useMemo } from 'react'; import { ReactComponent as CalendarIcon } from 'assets/svg/calendar.svg'; import Button from 'components/Button/Button'; import Input from 'components/Input/Input'; @@ -16,15 +15,14 @@ import { ManagerSpaceAPI, Reservation } from 'types/common'; import { convertSettingTimeToMinutes, convertTimeToMinutes, + formatTimePrettier, formatTimeWithSecond, } from 'utils/datetime'; -import useSettingSummary from '../../../hooks/query/useSettingSummary'; import { CreateReservationParams, EditReservationParams } from '../ManagerReservation'; import * as Styled from './ManagerReservationForm.styles'; interface Props { isEditMode: boolean; - mapId: number; space: ManagerSpaceAPI; reservation?: Reservation; date: string; @@ -41,7 +39,6 @@ interface Form { const ManagerReservationForm = ({ isEditMode, - mapId, space, date, reservation, @@ -81,19 +78,6 @@ const ManagerReservationForm = ({ initialEndTime: !!reservation ? new Date(reservation.endDateTime) : undefined, }); - const getSettingsSummary = useSettingSummary( - { - mapId, - spaceId: space?.id, - selectedDateTime: `${date}T${formatTimeWithSecond(range.start ?? dayjs().tz())}${ - DATE.TIMEZONE_OFFSET - }`, - settingViewType: 'FLAT', - }, - {} - ); - const settingsSummary = getSettingsSummary.data?.data?.summary ?? ''; - const [{ name, description, password }, onChangeForm] = useInputs({ name: reservation?.name ?? '', description: reservation?.description ?? '', @@ -180,10 +164,29 @@ const ManagerReservationForm = ({ onChange={onChange} onCloseOptions={onCloseOptions} /> - - 예약 가능 시간 - {settingsSummary} - + + + 예약 가능 시간 + {space.settings.map( + ( + { + settingStartTime, + settingEndTime, + reservationMaximumTimeUnit, + reservationMinimumTimeUnit, + }, + index + ) => { + return ( + + {settingStartTime.slice(0, 5)} ~ {settingEndTime.slice(0, 5)} + (최소 {formatTimePrettier(reservationMinimumTimeUnit)}, 최대{' '} + {formatTimePrettier(reservationMaximumTimeUnit)}) + + ); + } + )} + {isEditMode || ( diff --git a/frontend/src/pages/ManagerSpaceEditor/ManagerSpaceEditor.tsx b/frontend/src/pages/ManagerSpaceEditor/ManagerSpaceEditor.tsx index 63b60130b..8366ec476 100644 --- a/frontend/src/pages/ManagerSpaceEditor/ManagerSpaceEditor.tsx +++ b/frontend/src/pages/ManagerSpaceEditor/ManagerSpaceEditor.tsx @@ -109,8 +109,6 @@ const ManagerSpaceEditor = (): JSX.Element => { }, }); - // TODO: handleCreateSpace, handleUpdateSpace 시 priorityOrder 고려해서 request 발송 - // TODO: const handleCreateSpace = (data: Omit) => createSpace.mutate({ mapId: Number(mapId), ...data }); diff --git a/frontend/src/pages/ManagerSpaceEditor/data.ts b/frontend/src/pages/ManagerSpaceEditor/data.ts index 281a05a37..607dde757 100644 --- a/frontend/src/pages/ManagerSpaceEditor/data.ts +++ b/frontend/src/pages/ManagerSpaceEditor/data.ts @@ -23,7 +23,6 @@ export interface SpaceFormValue { saturday: boolean; sunday: boolean; }; - priorityOrder: number; }[]; } @@ -46,7 +45,6 @@ export const initialSpaceFormValueSetting = { reservationMinimumTimeUnit: 10, reservationMaximumTimeUnit: 120, enabledDayOfWeek: initialEnabledDayOfWeek, - priorityOrder: 0, }; export const initialSpaceFormValue: Omit = { diff --git a/frontend/src/pages/ManagerSpaceEditor/providers/SpaceFormProvider.tsx b/frontend/src/pages/ManagerSpaceEditor/providers/SpaceFormProvider.tsx index 92a51f1e6..2495e9d64 100644 --- a/frontend/src/pages/ManagerSpaceEditor/providers/SpaceFormProvider.tsx +++ b/frontend/src/pages/ManagerSpaceEditor/providers/SpaceFormProvider.tsx @@ -107,11 +107,6 @@ const SpaceFormProvider = ({ children }: Props): JSX.Element => { const getRequestValues = () => { const todayDate = formatDate(new Date()); - for (let i = 0; i < values.settings.length; i++) { - const setting = values.settings[i]; - setting['priorityOrder'] = values.settings.length - (i + 1); - } - return { space: { ...values, diff --git a/frontend/src/pages/ManagerSpaceEditor/units/Form.styles.ts b/frontend/src/pages/ManagerSpaceEditor/units/Form.styles.ts index dcfb45d30..7682a1468 100644 --- a/frontend/src/pages/ManagerSpaceEditor/units/Form.styles.ts +++ b/frontend/src/pages/ManagerSpaceEditor/units/Form.styles.ts @@ -32,26 +32,6 @@ export const TitleContainer = styled.div` margin-bottom: 1rem; `; -export const InfoMessageWrapper = styled.div` - display: flex; - flex-direction: column; - gap: 0.25rem; - margin-top: 0.5rem; - justify-content: space-between; - margin-bottom: 2rem; -`; - -export const InfoMessage = styled.p<{ fontWeight?: string }>` - left: 0.75rem; - bottom: -1.5rem; - font-size: 0.75rem; - height: 1.5em; - white-space: pre-line; - line-height: normal; - color: ${({ theme }) => theme.gray[500]}; - ${({ fontWeight }) => fontWeight && `font-weight: ${fontWeight}`}; -`; - export const ContentsContainer = styled.div` display: flex; flex-direction: column; diff --git a/frontend/src/pages/ManagerSpaceEditor/units/Form.tsx b/frontend/src/pages/ManagerSpaceEditor/units/Form.tsx index dc75c5114..58fbd748a 100644 --- a/frontend/src/pages/ManagerSpaceEditor/units/Form.tsx +++ b/frontend/src/pages/ManagerSpaceEditor/units/Form.tsx @@ -1,11 +1,4 @@ -import React, { - Dispatch, - FormEventHandler, - SetStateAction, - useEffect, - useRef, - useState, -} from 'react'; +import { Dispatch, FormEventHandler, SetStateAction, useEffect, useRef } from 'react'; import { DeleteManagerSpaceParams, PostManagerSpaceParams, @@ -30,7 +23,6 @@ import * as Styled from './Form.styles'; import FormDayOfWeekSelect from './FormDayOfWeekSelect'; import FormTimeUnitSelect from './FormTimeUnitSelect'; import Preset from './Preset'; -import SettingSummaryPopup from './SettingSummaryPopup'; interface Props { modeState: [Mode, Dispatch>]; @@ -56,7 +48,6 @@ const Form = ({ const nameInputRef = useRef(null); const [mode, setMode] = modeState; - const [settingSummaryPopupOpen, setSettingSummaryPopupOpen] = useState(false); const { values, @@ -194,31 +185,7 @@ const Form = ({ 예약 조건 - {selectedSpaceId != null && ( - - )} - - - 예약 조건이 서로 겹칠 시, 뒷 순서의 예약 조건이 앞 순서의 예약 조건을 덮어씁니다. - - - {settingSummaryPopupOpen && selectedSpaceId != null && ( - setSettingSummaryPopupOpen(false)} - mapId={Number(window.location.pathname.split('/', 3).pop())} - spaceId={selectedSpaceId} - /> - )} {values.settings.map((_, index) => ( diff --git a/frontend/src/pages/ManagerSpaceEditor/units/Preset.tsx b/frontend/src/pages/ManagerSpaceEditor/units/Preset.tsx index f26e257f3..23f18b4b6 100644 --- a/frontend/src/pages/ManagerSpaceEditor/units/Preset.tsx +++ b/frontend/src/pages/ManagerSpaceEditor/units/Preset.tsx @@ -72,7 +72,7 @@ const Preset = (): JSX.Element => { ...values, settings: values.settings.map((setting, index) => { if (index === selectedSettingIndex) { - return { ...rest, priorityOrder: 0 }; + return rest; } return setting; diff --git a/frontend/src/pages/ManagerSpaceEditor/units/SettingSummaryPopup.styles.ts b/frontend/src/pages/ManagerSpaceEditor/units/SettingSummaryPopup.styles.ts deleted file mode 100644 index 12eb86cb8..000000000 --- a/frontend/src/pages/ManagerSpaceEditor/units/SettingSummaryPopup.styles.ts +++ /dev/null @@ -1,13 +0,0 @@ -import styled from 'styled-components'; - -export const SettingSummaryPopupWrapper = styled.div` - padding: 2rem 3rem; -`; - -export const SettingSummary = styled.p<{ fontWeight?: string }>` - white-space: pre-line; - line-height: normal; - font-size: 0.75rem; - color: ${({ theme }) => theme.gray[500]}; - ${({ fontWeight }) => fontWeight && `font-weight: ${fontWeight}`}; -`; diff --git a/frontend/src/pages/ManagerSpaceEditor/units/SettingSummaryPopup.tsx b/frontend/src/pages/ManagerSpaceEditor/units/SettingSummaryPopup.tsx deleted file mode 100644 index bc3fcfabc..000000000 --- a/frontend/src/pages/ManagerSpaceEditor/units/SettingSummaryPopup.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import React from 'react'; -import Modal from '../../../components/Modal/Modal'; -import SummaryModal from '../../../components/Modal/SummaryModal'; -import useSettingSummary from '../../../hooks/query/useSettingSummary'; -import * as Styled from './SettingSummaryPopup.styles'; - -interface SettingSummaryProps { - mapId: number; - spaceId: number; - open: boolean; - onClose: () => void; -} - -const SettingSummaryPopup = ({ - mapId, - spaceId, - open, - onClose, -}: SettingSummaryProps): JSX.Element => { - const getSettingsSummary = useSettingSummary( - { - mapId, - spaceId, - selectedDateTime: null, - settingViewType: 'FLAT', - }, - {} - ); - const settingsSummary = getSettingsSummary.data?.data?.summary ?? ''; - - return ( - - - {settingsSummary} - - - ); -}; - -export default SettingSummaryPopup; diff --git a/frontend/src/types/common.ts b/frontend/src/types/common.ts index 03b622d8d..a76c21dc1 100644 --- a/frontend/src/types/common.ts +++ b/frontend/src/types/common.ts @@ -112,7 +112,6 @@ export interface SpaceSetting { saturday: boolean; sunday: boolean; }; - priorityOrder: number; } export interface Preset { diff --git a/frontend/src/types/response.ts b/frontend/src/types/response.ts index 6a5bcbdd6..41594e0ff 100644 --- a/frontend/src/types/response.ts +++ b/frontend/src/types/response.ts @@ -1,4 +1,5 @@ import { + Area, Emoji, ManagerSpaceAPI, MapItem, @@ -52,7 +53,6 @@ export interface QueryManagerMapsSuccess { export interface QueryManagerSpaceReservationsSuccess { reservations: Reservation[]; } - export interface QueryManagerMapReservationsSuccess { data: SpaceReservation[]; } @@ -91,7 +91,3 @@ export interface QueryMemberReservationsSuccess { hasNext: boolean; pageNumber: number; } - -export interface QuerySettingSummarySuccess { - summary: string; -} From 1e6c3255130405c7274d08a696747321cae584b1 Mon Sep 17 00:00:00 2001 From: sakjung Date: Thu, 3 Aug 2023 20:47:55 +0900 Subject: [PATCH 4/7] =?UTF-8?q?Revert=20"feat:=20=EA=B3=B5=EA=B0=84=20?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=20=EC=A0=81=EC=9A=A9=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EC=84=B1=20=EA=B0=9C=EC=84=A0=20(#963)"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 154cb8a183b458b56fa34e1cbd4402c11cd13223. --- backend/src/docs/asciidoc/setting.adoc | 27 -- .../controller/SettingController.java | 39 --- .../zzimkkong/domain/EnabledDayOfWeek.java | 16 +- .../woowacourse/zzimkkong/domain/Setting.java | 173 +------------ .../zzimkkong/domain/SettingViewType.java | 84 ------- .../zzimkkong/domain/Settings.java | 228 +++++------------ .../woowacourse/zzimkkong/domain/Space.java | 1 - .../zzimkkong/domain/TimeSlot.java | 68 +----- .../zzimkkong/domain/TimeUnit.java | 45 ---- .../dto/DuplicateSettingOrderValidator.java | 25 -- .../dto/NotDuplicatedSettingOrder.java | 23 -- .../zzimkkong/dto/TimeUnitValidator.java | 7 +- .../zzimkkong/dto/ValidatorMessage.java | 4 +- .../zzimkkong/dto/space/SettingRequest.java | 11 +- .../zzimkkong/dto/space/SettingResponse.java | 10 +- .../dto/space/SettingsSummaryResponse.java | 18 -- .../dto/space/SpaceCreateUpdateRequest.java | 4 +- .../dto/space/SpaceFindDetailResponse.java | 5 +- .../exception/ZzimkkongException.java | 12 +- .../InvalidStartEndTimeException.java | 18 +- .../setting/InvalidOrderException.java | 10 - .../setting/NoSettingAvailableException.java | 2 +- .../setting/SettingConflictException.java | 17 ++ .../datetime/TimeZoneUtils.java | 11 +- .../zzimkkong/service/ReservationService.java | 6 +- .../zzimkkong/service/SettingService.java | 45 ---- .../zzimkkong/service/SpaceService.java | 4 +- .../migration/prod/V22__setting_priority.sql | 2 - .../zzimkkong/controller/AcceptanceTest.java | 6 +- .../controller/AdminControllerTest.java | 3 +- .../GuestReservationControllerTest.java | 6 +- .../controller/GuestSpaceControllerTest.java | 6 +- .../ManagerReservationControllerTest.java | 6 +- .../ManagerSpaceControllerTest.java | 16 +- .../controller/PresetControllerTest.java | 4 +- .../controller/SettingControllerTest.java | 230 ------------------ .../zzimkkong/domain/PresetTest.java | 1 - .../zzimkkong/domain/SettingTest.java | 107 -------- .../zzimkkong/domain/SettingsTest.java | 134 ++-------- .../zzimkkong/domain/SpaceTest.java | 22 +- .../zzimkkong/domain/TimeSlotTest.java | 78 ------ .../zzimkkong/domain/TimeUnitTest.java | 85 +------ .../dto/PresetCreateRequestTest.java | 3 +- .../zzimkkong/dto/RequestTest.java | 3 +- .../zzimkkong/dto/SettingRequestTest.java | 6 +- .../repository/MapRepositoryTest.java | 6 +- .../ReservationRepositoryImplTest.java | 3 +- .../repository/ReservationRepositoryTest.java | 6 +- .../repository/SpaceRepositoryTest.java | 6 +- .../zzimkkong/service/AdminServiceTest.java | 6 +- .../service/GuestReservationServiceTest.java | 19 +- .../ManagerReservationServiceTest.java | 19 +- .../zzimkkong/service/MapServiceTest.java | 6 +- .../zzimkkong/service/PresetServiceTest.java | 4 +- .../zzimkkong/service/SpaceServiceTest.java | 12 +- 55 files changed, 210 insertions(+), 1508 deletions(-) delete mode 100644 backend/src/docs/asciidoc/setting.adoc delete mode 100644 backend/src/main/java/com/woowacourse/zzimkkong/controller/SettingController.java delete mode 100644 backend/src/main/java/com/woowacourse/zzimkkong/domain/SettingViewType.java delete mode 100644 backend/src/main/java/com/woowacourse/zzimkkong/dto/DuplicateSettingOrderValidator.java delete mode 100644 backend/src/main/java/com/woowacourse/zzimkkong/dto/NotDuplicatedSettingOrder.java delete mode 100644 backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingsSummaryResponse.java delete mode 100644 backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/InvalidOrderException.java create mode 100644 backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/SettingConflictException.java delete mode 100644 backend/src/main/java/com/woowacourse/zzimkkong/service/SettingService.java delete mode 100644 backend/src/main/resources/db/migration/prod/V22__setting_priority.sql delete mode 100644 backend/src/test/java/com/woowacourse/zzimkkong/controller/SettingControllerTest.java diff --git a/backend/src/docs/asciidoc/setting.adoc b/backend/src/docs/asciidoc/setting.adoc deleted file mode 100644 index 7df2933a2..000000000 --- a/backend/src/docs/asciidoc/setting.adoc +++ /dev/null @@ -1,27 +0,0 @@ -== Setting(공간 예약 조건) - -=== 특정 날짜 예약 조건 조회 (예약자 view 용 = flat) -==== Request -include::{snippets}/setting/get_flat/http-request.adoc[] -==== Response -include::{snippets}/setting/get_flat/http-response.adoc[] - -=== 특정 날짜 예약 조건 조회 (관리자 view 용 = stack) -==== 공간 관리자 -===== Request -include::{snippets}/setting/get_stack/http-request.adoc[] -===== Response -include::{snippets}/setting/get_stack/http-response.adoc[] - -=== 전체 예약 조건 조회 (예약자 view 용 = flat) -==== Request -include::{snippets}/setting/get_flat_all/http-request.adoc[] -==== Response -include::{snippets}/setting/get_flat_all/http-response.adoc[] - -=== 전체 예약 조건 조회 (관리자 view 용 = stack) -==== 공간 관리자 -===== Request -include::{snippets}/setting/get_stack_all/http-request.adoc[] -===== Response -include::{snippets}/setting/get_stack_all/http-response.adoc[] \ No newline at end of file diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/controller/SettingController.java b/backend/src/main/java/com/woowacourse/zzimkkong/controller/SettingController.java deleted file mode 100644 index 8f19f6b79..000000000 --- a/backend/src/main/java/com/woowacourse/zzimkkong/controller/SettingController.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.woowacourse.zzimkkong.controller; - -import com.woowacourse.zzimkkong.config.logaspect.LogMethodExecutionTime; -import com.woowacourse.zzimkkong.dto.space.SettingsSummaryResponse; -import com.woowacourse.zzimkkong.domain.SettingViewType; -import com.woowacourse.zzimkkong.infrastructure.datetime.TimeZoneUtils; -import com.woowacourse.zzimkkong.service.SettingService; -import org.springframework.format.annotation.DateTimeFormat; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -import java.time.ZonedDateTime; - -import static com.woowacourse.zzimkkong.dto.ValidatorMessage.DATETIME_FORMAT; - -@LogMethodExecutionTime(group = "controller") -@RestController -@RequestMapping("/api/maps/{mapId}/spaces/{spaceId}/settings") -public class SettingController { - private final SettingService settingService; - - public SettingController(final SettingService settingService) { - this.settingService = settingService; - } - - @GetMapping("/summary") - public ResponseEntity getSettingsSummary( - @PathVariable final Long mapId, - @PathVariable final Long spaceId, - @RequestParam(required = false) @DateTimeFormat(pattern = DATETIME_FORMAT) final ZonedDateTime selectedDateTime, - @RequestParam(required = false, defaultValue = "FLAT") final String settingViewType) { - SettingsSummaryResponse settingsSummaryResponse = settingService.getSettingsSummary( - mapId, - spaceId, - TimeZoneUtils.convertToUTC(selectedDateTime), - settingViewType); - return ResponseEntity.ok().body(settingsSummaryResponse); - } -} diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/domain/EnabledDayOfWeek.java b/backend/src/main/java/com/woowacourse/zzimkkong/domain/EnabledDayOfWeek.java index d9cd3b7fc..97131b92c 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/domain/EnabledDayOfWeek.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/domain/EnabledDayOfWeek.java @@ -1,7 +1,6 @@ package com.woowacourse.zzimkkong.domain; import com.woowacourse.zzimkkong.exception.setting.NoSuchEnabledDayOfWeekException; -import lombok.Getter; import lombok.extern.slf4j.Slf4j; import java.util.Arrays; @@ -9,15 +8,14 @@ import java.util.stream.Collectors; @Slf4j -@Getter public enum EnabledDayOfWeek { - MONDAY("월요일"), - TUESDAY("화요일"), - WEDNESDAY("수요일"), - THURSDAY("목요일"), - FRIDAY("금요일"), - SATURDAY("토요일"), - SUNDAY("일요일"); + MONDAY("월"), + TUESDAY("화"), + WEDNESDAY("수"), + THURSDAY("목"), + FRIDAY("금"), + SATURDAY("토"), + SUNDAY("일"); private final String displayName; diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/domain/Setting.java b/backend/src/main/java/com/woowacourse/zzimkkong/domain/Setting.java index 7eb0026e3..99e4791cd 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/domain/Setting.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/domain/Setting.java @@ -1,26 +1,18 @@ package com.woowacourse.zzimkkong.domain; -import com.woowacourse.zzimkkong.exception.setting.InvalidOrderException; import com.woowacourse.zzimkkong.exception.space.InvalidMinimumMaximumTimeUnitException; import com.woowacourse.zzimkkong.exception.space.NotEnoughAvailableTimeException; import com.woowacourse.zzimkkong.exception.space.TimeUnitInconsistencyException; import com.woowacourse.zzimkkong.exception.space.TimeUnitMismatchException; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import net.logstash.logback.encoder.org.apache.commons.lang3.StringUtils; -import org.springframework.util.CollectionUtils; +import lombok.*; import javax.persistence.*; import java.time.DayOfWeek; import java.time.LocalTime; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Locale; import java.util.stream.Collectors; -import static com.woowacourse.zzimkkong.dto.ValidatorMessage.INVALID_SETTING_ORDER_MESSAGE; import static com.woowacourse.zzimkkong.infrastructure.message.MessageUtils.LINE_SEPARATOR; @Builder @@ -28,9 +20,6 @@ @NoArgsConstructor @Entity public class Setting { - public static final int FLAT_PRIORITY_ORDER = -1; - public static final long FLAT_SETTING_ID = 0L; - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -68,9 +57,6 @@ public class Setting { @Column(nullable = false) private String enabledDayOfWeek; - @Column(nullable = false) - private Integer priorityOrder; - @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "space_id", foreignKey = @ForeignKey(name = "fk_setting_space"), nullable = false) private Space space; @@ -82,7 +68,6 @@ public Setting( final TimeUnit reservationMinimumTimeUnit, final TimeUnit reservationMaximumTimeUnit, final String enabledDayOfWeek, - final Integer priorityOrder, final Space space) { this.id = id; this.settingTimeSlot = settingTimeSlot; @@ -90,24 +75,11 @@ public Setting( this.reservationMinimumTimeUnit = reservationMinimumTimeUnit; this.reservationMaximumTimeUnit = reservationMaximumTimeUnit; this.enabledDayOfWeek = enabledDayOfWeek; - this.priorityOrder = priorityOrder; this.space = space; validateSetting(); } - public Setting createSettingBasedOn(final TimeSlot timeSlot, final EnabledDayOfWeek dayOfWeek) { - return Setting.builder() - .id(this.getId()) - .settingTimeSlot(timeSlot) - .reservationTimeUnit(this.getReservationTimeUnit()) - .reservationMinimumTimeUnit(this.getReservationMinimumTimeUnit()) - .reservationMaximumTimeUnit(this.getReservationMaximumTimeUnit()) - .enabledDayOfWeek(dayOfWeek.name().toLowerCase(Locale.ROOT)) - .priorityOrder(this.getPriorityOrder()) - .build(); - } - private void validateSetting() { if (settingTimeSlot.isNotDivisibleBy(reservationTimeUnit)) { throw new TimeUnitMismatchException(); @@ -124,10 +96,6 @@ private void validateSetting() { if (settingTimeSlot.isDurationShorterThan(reservationMaximumTimeUnit)) { throw new NotEnoughAvailableTimeException(); } - - if (priorityOrder == null || priorityOrder < FLAT_PRIORITY_ORDER) { - throw new InvalidOrderException(INVALID_SETTING_ORDER_MESSAGE); - } } public LocalTime getSettingStartTime() { @@ -156,8 +124,14 @@ private boolean isNotConsistentTimeUnit() { } public boolean hasConflictWith(final Setting that) { - List thisEnabledDayOfWeek = this.getEnabledDayOfWeekList(); - boolean enabledDayOfWeekMatch = that.getEnabledDayOfWeekList().stream().anyMatch(thisEnabledDayOfWeek::contains); + List thisEnabledDayOfWeek = Arrays.stream(this.enabledDayOfWeek.split(Space.DELIMITER)) + .map(String::trim) + .map(EnabledDayOfWeek::from) + .collect(Collectors.toList()); + boolean enabledDayOfWeekMatch = Arrays.stream(that.enabledDayOfWeek.split(Space.DELIMITER)) + .map(String::trim) + .map(EnabledDayOfWeek::from) + .anyMatch(thisEnabledDayOfWeek::contains); return this.settingTimeSlot.hasConflictWith(that.settingTimeSlot) && enabledDayOfWeekMatch; } @@ -183,136 +157,9 @@ public void updateSpace(final Space space) { this.space = space; } - public List getEnabledDayOfWeekList() { - return Arrays.stream(this.enabledDayOfWeek.split(Space.DELIMITER)) - .map(String::trim) - .map(EnabledDayOfWeek::from) - .collect(Collectors.toList()); - } - - /** - * 2023.04.02 기준 - * 인자로 주어진 settings 의 조건들에 배타적인 (겹치지 않는) 새로운 setting slot 리스트를 생성한다 - * 기존 setting 을 조각내어 새로운 여러개의 (transient) setting 을 생성한다 - * - * @param settings 서로 시간대와 요일이 겹치지 않는 (= flat 한) setting 들 - * @return List of Setting Slot (조각 내어진 세팅 슬롯들) - */ - - public List extractExclusiveSettingSlots(final List settings) { - List exclusiveSettingSlots = List.of(Setting.builder() - .id(FLAT_SETTING_ID) - .settingTimeSlot(this.settingTimeSlot) - .reservationTimeUnit(this.reservationTimeUnit) - .reservationMinimumTimeUnit(this.reservationMinimumTimeUnit) - .reservationMaximumTimeUnit(this.reservationMaximumTimeUnit) - .enabledDayOfWeek(this.enabledDayOfWeek) - .priorityOrder(FLAT_PRIORITY_ORDER) - .space(this.space) - .build()); - for (Setting setting : settings) { - List newExclusiveSettingSlots = new ArrayList<>(); - for (Setting exclusiveSettingSlot : exclusiveSettingSlots) { - newExclusiveSettingSlots.addAll(exclusiveSettingSlot.extractNewExclusiveSettingSlots(setting)); - } - exclusiveSettingSlots = newExclusiveSettingSlots; - } - return exclusiveSettingSlots; - } - - private List extractNewExclusiveSettingSlots(final Setting setting) { - if (!this.hasConflictWith(setting)) { - return List.of(this); - } - - List newExclusiveSettingSlots = new ArrayList<>(); - - List exclusiveTimeSlots = this.settingTimeSlot.extractExclusiveTimeSlots(setting.settingTimeSlot); - for (TimeSlot exclusiveTimeSlot : exclusiveTimeSlots) { - TimeUnit adjustedIntervalTimeUnit = this.reservationTimeUnit.getAdjustedIntervalTimeUnit(exclusiveTimeSlot); - - Setting survivedSettingSlot = Setting.builder() - .id(FLAT_SETTING_ID) - .settingTimeSlot(exclusiveTimeSlot) - .reservationTimeUnit(adjustedIntervalTimeUnit) - .reservationMinimumTimeUnit( - this.reservationMinimumTimeUnit.getAdjustedTimeUnit( - exclusiveTimeSlot, - adjustedIntervalTimeUnit)) - .reservationMaximumTimeUnit( - this.reservationMaximumTimeUnit.getAdjustedTimeUnit( - exclusiveTimeSlot, - adjustedIntervalTimeUnit)) - .enabledDayOfWeek(this.enabledDayOfWeek) - .priorityOrder(FLAT_PRIORITY_ORDER) - .space(this.space) - .build(); - - newExclusiveSettingSlots.add(survivedSettingSlot); - } - - List conflictingSettingEnabledDayOfWeek = setting.getEnabledDayOfWeekList(); - List exclusiveEnabledDayOfWeek = this.getEnabledDayOfWeekList() - .stream() - .filter(dayOfWeek -> !conflictingSettingEnabledDayOfWeek.contains(dayOfWeek)) - .collect(Collectors.toList()); - - if (!CollectionUtils.isEmpty(exclusiveEnabledDayOfWeek)) { - TimeSlot overlappingTimeSlot = this.settingTimeSlot.extractOverlappingTimeSlot(setting.settingTimeSlot); - String nonConflictingDayOfWeek = exclusiveEnabledDayOfWeek.stream() - .map(dayOfWeek -> dayOfWeek.name().toLowerCase(Locale.ROOT)) - .collect(Collectors.joining(",")); - TimeUnit adjustedIntervalTimeUnit = this.reservationTimeUnit.getAdjustedIntervalTimeUnit(overlappingTimeSlot); - - Setting survivedSettingSlot = Setting.builder() - .id(FLAT_SETTING_ID) - .settingTimeSlot(overlappingTimeSlot) - .reservationTimeUnit(adjustedIntervalTimeUnit) - .reservationMinimumTimeUnit( - this.reservationMinimumTimeUnit.getAdjustedTimeUnit( - overlappingTimeSlot, - adjustedIntervalTimeUnit)) - .reservationMaximumTimeUnit( - this.reservationMaximumTimeUnit.getAdjustedTimeUnit( - overlappingTimeSlot, - adjustedIntervalTimeUnit)) - .enabledDayOfWeek(nonConflictingDayOfWeek) - .priorityOrder(FLAT_PRIORITY_ORDER) - .space(this.space) - .build(); - newExclusiveSettingSlots.add(survivedSettingSlot); - } - - return newExclusiveSettingSlots; - } - - public String toSummaryWithoutDayOfWeek(final Boolean flat) { - String priority = "[우선순위 " + priorityOrder.toString() + "] "; - if (flat) { - priority = StringUtils.EMPTY; - } - return String.format("%s%s (최소 %s, 최대 %s, 예약 단위 %s)", - priority, - settingTimeSlot.toString(), - reservationMinimumTimeUnit.toString(), - reservationMaximumTimeUnit.toString(), - reservationTimeUnit.toString()); - } - - public boolean canMergeIgnoringDayOfWeek(final Setting that) { - return this.settingTimeSlot.isExtendableWith(that.settingTimeSlot) - && this.reservationTimeUnit.equals(that.reservationTimeUnit) - && this.reservationMinimumTimeUnit.equals(that.reservationMinimumTimeUnit) - && this.reservationMaximumTimeUnit.equals(that.reservationMaximumTimeUnit); - } - - public boolean isFlattenedSetting() { - return FLAT_PRIORITY_ORDER == this.priorityOrder; - } - @Override public String toString() { - return "예약 요일: " + + return "예약 가능한 요일: " + EnabledDayOfWeek.getDisplayNames(enabledDayOfWeek) + LINE_SEPARATOR + "예약 가능한 시간대: " + diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/domain/SettingViewType.java b/backend/src/main/java/com/woowacourse/zzimkkong/domain/SettingViewType.java deleted file mode 100644 index c7168493f..000000000 --- a/backend/src/main/java/com/woowacourse/zzimkkong/domain/SettingViewType.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.woowacourse.zzimkkong.domain; - -import com.woowacourse.zzimkkong.exception.ZzimkkongException; -import com.woowacourse.zzimkkong.infrastructure.datetime.TimeZoneUtils; -import org.springframework.http.HttpStatus; - -import java.time.DayOfWeek; -import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.function.BiFunction; -import java.util.function.BiPredicate; - -/** - * {@link SettingViewType#STACK_SINGLE}: 맵 관리자가 설정한 특정 요일의 예약 조건 그대로 보여준다 (겹치는 조건 O). 관리자들을 위한 view - * {@link SettingViewType#STACK_ALL}: 맵 관리자가 설정한 모든 요일의 예약 조건 그대로 보여준다 (겹치는 조건 O). 관리자들을 위한 view - * {@link SettingViewType#FLAT_SINGLE}: 특정 요일의 예약 조건을 평탄화 하여 보여준다 (겹치는 조건 X). 예약자들을 위한 view - * {@link SettingViewType#FLAT_ALL}: 모든 요일의 예약 조건을 평탄화 하여 보여준다 (겹치는 조건 X). 예약자들을 위한 view - * - {@link com.woowacourse.zzimkkong.domain.Settings#flatten()} 메서드 참고 - */ -public enum SettingViewType { - FLAT_SINGLE( - (dateTime, viewType) -> dateTime != null && "FLAT".equals(viewType), - SettingViewType::getFlatSingleSummary), - STACK_SINGLE( - (dateTime, viewType) -> dateTime != null && "STACK".equals(viewType), - SettingViewType::getStackSingleSummary), - FLAT_ALL( - (dateTime, viewType) -> dateTime == null && "FLAT".equals(viewType), - SettingViewType::getFlatAllSummary), - STACK_ALL( - (dateTime, viewType) -> dateTime == null && "STACK".equals(viewType), - SettingViewType::getStackAllSummary); - - private final BiPredicate expression; - private final BiFunction function; - - SettingViewType(final BiPredicate expression, final BiFunction function) { - this.expression = expression; - this.function = function; - } - - public static SettingViewType of(final LocalDateTime dateTime, final String viewType) { - return Arrays.stream(values()) - .filter(settingViewType -> settingViewType.expression.test(dateTime, viewType)) - .findFirst() - .orElseThrow(() -> new ZzimkkongException(HttpStatus.BAD_REQUEST)); - } - - public String getSummary(final Space space, final LocalDateTime dateTime) { - return function.apply(space, dateTime); - } - - private static String getFlatSingleSummary(final Space space, final LocalDateTime dateTime) { - Settings spaceSettings = space.getSpaceSettings(); - DayOfWeek dayOfWeek = TimeZoneUtils.convertTo(dateTime, space.getMap().getServiceZone()) - .toLocalDate() - .getDayOfWeek(); - - spaceSettings.flatten(); - - return spaceSettings.getSummaryOn(EnabledDayOfWeek.from(dayOfWeek.name())); - } - - private static String getStackSingleSummary(final Space space, final LocalDateTime dateTime) { - Settings spaceSettings = space.getSpaceSettings(); - DayOfWeek dayOfWeek = TimeZoneUtils.convertTo(dateTime, space.getMap().getServiceZone()) - .toLocalDate() - .getDayOfWeek(); - - return spaceSettings.getSummaryOn(EnabledDayOfWeek.from(dayOfWeek.name())); - } - - private static String getFlatAllSummary(final Space space, final LocalDateTime dateTime) { - Settings spaceSettings = space.getSpaceSettings(); - - spaceSettings.flatten(); - - return spaceSettings.getSummary(); - } - - private static String getStackAllSummary(final Space space, final LocalDateTime dateTime) { - return space.getSpaceSettings().getSummary(); - } -} diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/domain/Settings.java b/backend/src/main/java/com/woowacourse/zzimkkong/domain/Settings.java index 0637c5273..917ddad57 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/domain/Settings.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/domain/Settings.java @@ -1,8 +1,7 @@ package com.woowacourse.zzimkkong.domain; import com.woowacourse.zzimkkong.dto.space.SettingRequest; -import com.woowacourse.zzimkkong.exception.ZzimkkongException; -import com.woowacourse.zzimkkong.exception.setting.InvalidOrderException; +import com.woowacourse.zzimkkong.exception.setting.SettingConflictException; import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.util.CollectionUtils; @@ -10,10 +9,13 @@ import javax.persistence.*; import java.time.DayOfWeek; import java.time.LocalTime; -import java.util.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; +import java.util.stream.IntStream; -import static com.woowacourse.zzimkkong.dto.ValidatorMessage.DUPLICATE_SETTING_ORDER_MESSAGE; import static com.woowacourse.zzimkkong.infrastructure.message.MessageUtils.LINE_SEPARATOR; @Getter @@ -25,8 +27,10 @@ public class Settings { @OneToMany(mappedBy = "space", cascade = CascadeType.PERSIST, fetch = FetchType.LAZY, orphanRemoval = true) private List settings = new ArrayList<>(); - private Settings(final List settings) { + public Settings(final List settings) { this.settings = new ArrayList<>(settings); + sort(); + validateConflicts(); } public static Settings from(final List settingRequests) { @@ -40,61 +44,34 @@ public static Settings from(final List settingRequests) { .reservationMinimumTimeUnit(TimeUnit.from(settingRequest.getReservationMinimumTimeUnit())) .reservationMaximumTimeUnit(TimeUnit.from(settingRequest.getReservationMaximumTimeUnit())) .enabledDayOfWeek(settingRequest.enabledDayOfWeekAsString()) - .priorityOrder(settingRequest.getPriorityOrder()) .build()) .collect(Collectors.toList()); - return toPrioritizedSettings(settings); - } - - public static Settings toPrioritizedSettings(final List settings) { - Settings newSettings = new Settings(settings); - newSettings.validateOrderConflict(); - newSettings.sortByPriorityOrder(); - return newSettings; - } - - public static Settings toFlattenedSettings(final List settings) { - Settings newSettings = new Settings(settings); - if (newSettings.isFlat()) { - return newSettings; - } - newSettings.validateOrderConflict(); - newSettings.sortByPriorityOrder(); - newSettings.flatten(); - return newSettings; + return new Settings(settings); } public void add(final Setting setting) { - if (isFlat()) { - throw new ZzimkkongException(); - } settings.add(setting); - validateOrderConflict(); - sortByPriorityOrder(); + sort(); + validateConflicts(); } public void addAll(final List newSettings) { - if (isFlat()) { - throw new ZzimkkongException(); - } settings.addAll(newSettings); - validateOrderConflict(); - sortByPriorityOrder(); + sort(); + validateConflicts(); } public Settings getSettingsByTimeSlotAndDayOfWeek(final TimeSlot timeSlot, final DayOfWeek dayOfWeek) { - List relevantSettings = this.settings.stream() + List filteredSettings = this.settings.stream() .filter(setting -> setting.supports(timeSlot, dayOfWeek)) .collect(Collectors.toList()); - return toFlattenedSettings(relevantSettings).getMergedSettings( - EnabledDayOfWeek.from( - dayOfWeek.name().toLowerCase(Locale.ROOT))); + return new Settings(filteredSettings); } - public boolean cannotAcceptDueToAvailableTime(final TimeSlot timeSlot, final DayOfWeek dayOfWeek) { - return getAvailableTimeSlots(dayOfWeek).stream().allMatch(timeSlot::isNotWithin); + public boolean cannotAcceptDueToAvailableTime(final TimeSlot timeSlot) { + return getAvailableTimeSlots().stream().allMatch(timeSlot::isNotWithin); } public boolean isEmpty() { @@ -106,17 +83,14 @@ public boolean haveMultipleSettings() { } /** - * settings 중 예약이 불가능한 시간 대역을 반환한다 + * settings 중 조건에 위배되는 예약이 불가능한 시간 대역을 반환한다 */ - public List getUnavailableTimeSlots(final DayOfWeek dayOfWeek) { - Settings flatSettings = toFlattenedSettings(this.settings).getMergedSettings( - EnabledDayOfWeek.from(dayOfWeek.name().toLowerCase(Locale.ROOT))); - + public List getUnavailableTimeSlots() { List unavailableTimeSlots = new ArrayList<>(); LocalTime unavailableStartTime = LocalTime.MIN; LocalTime unavailableEndTime = TimeSlot.MAX_TIME; - for (int i = 0; i < flatSettings.settings.size(); i++) { - TimeSlot settingTimeSlot = flatSettings.settings.get(i).getSettingTimeSlot(); + for (int i = 0; i < settings.size(); i++) { + TimeSlot settingTimeSlot = settings.get(i).getSettingTimeSlot(); unavailableEndTime = settingTimeSlot.getStartTime(); if (!unavailableStartTime.equals(unavailableEndTime)) { @@ -126,7 +100,7 @@ public List getUnavailableTimeSlots(final DayOfWeek dayOfWeek) { unavailableStartTime = settingTimeSlot.getEndTime(); unavailableEndTime = TimeSlot.MAX_TIME; - if (i == flatSettings.settings.size() - 1) { + if (i == settings.size() - 1) { unavailableTimeSlots.add(TimeSlot.of(unavailableStartTime, unavailableEndTime)); } } @@ -139,150 +113,68 @@ public List getUnavailableTimeSlots(final DayOfWeek dayOfWeek) { } /** - * settings 중 예약 가능한 시간 대역을 반환한다 + * settings 중 조건에 위배되지 않는 예약 가능한 시간 대역을 반환한다 */ - private List getAvailableTimeSlots(final DayOfWeek dayOfWeek) { - if (isFlat()) { + private List getAvailableTimeSlots() { + if (!haveMultipleSettings()) { return settings.stream() .map(Setting::getSettingTimeSlot) .collect(Collectors.toList()); } - return toFlattenedSettings(this.settings).getMergedSettings( - EnabledDayOfWeek.from( - dayOfWeek.name().toLowerCase(Locale.ROOT))) - .settings - .stream() - .map(Setting::getSettingTimeSlot) - .collect(Collectors.toList()); - } - - /** - * 2023.04.02 기준 - * 공간의 예약 조건은 서로 겹쳐질 (중복될) 수 있으며, 각각 우선순위 (order)를 가진다. - * 우선순위가 높은 예약조건을 우선시하여 검증한다. - * 비즈니스 로직을 단순화 시키기 위해, flatten 메서드로 겹쳐진 예약 조건들을 '동등한 우선순위를 가진 겹치지 않은 상태 (= flat 한 상태)' 로 변환한다. - *

- * flatten 과정을 거치면 settings 의 모든 setting 들은: - * - {@link Setting#settingTimeSlot}, {@link Setting#enabledDayOfWeek} 두 조건이 서로 겹치지 않는다 - * - id = {@link Setting#FLAT_SETTING_ID} (실제 존재하는 세팅이 아닌 추상적인 transient entity 임을 명시하기 위함) - * - order = {@link Setting#FLAT_PRIORITY_ORDER} (동등한 우선순위) - * - settingStartTime 기준으로 오름차순 정렬된다 - * - */ - public void flatten() { - List flatSettings = new ArrayList<>(); - for (Setting setting : settings) { - List exclusiveSettingSlots = setting.extractExclusiveSettingSlots(new ArrayList<>(flatSettings)); - flatSettings.addAll(exclusiveSettingSlots); - } - this.settings = flatSettings; - sortByTime(); - } - - public String getSummary() { - StringBuilder stringBuilder = new StringBuilder(); - for (EnabledDayOfWeek dayOfWeek : EnabledDayOfWeek.values()) { - stringBuilder.append(getSummaryOn(dayOfWeek)); - } - return stringBuilder.toString(); - } - - public String getSummaryOn(final EnabledDayOfWeek dayOfWeek) { - List settingsOnDayOfWeek = settings.stream() - .filter(setting -> setting.getEnabledDayOfWeekList().contains(dayOfWeek)) - .collect(Collectors.toList()); - - if (CollectionUtils.isEmpty(settingsOnDayOfWeek)) { - return "[" + dayOfWeek.getDisplayName() + "] 이용 불가" + LINE_SEPARATOR; - } - - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("[") - .append(dayOfWeek.getDisplayName()) - .append("]") - .append(LINE_SEPARATOR); - - boolean flat = isFlat(); - if (flat) { - settingsOnDayOfWeek = new Settings(settingsOnDayOfWeek).getMergedSettings(dayOfWeek).settings; - } - for (Setting setting : settingsOnDayOfWeek) { - stringBuilder.append(setting.toSummaryWithoutDayOfWeek(flat)) - .append(LINE_SEPARATOR); - } - return stringBuilder.toString(); - } - - public Settings getMergedSettings(final EnabledDayOfWeek dayOfWeek) { - if (CollectionUtils.isEmpty(this.settings)) { - return new Settings(); - } - - Settings flatSettings = toFlattenedSettings(this.settings); - List mergedSettings = new ArrayList<>(); - Setting startSetting = flatSettings.settings.get(0); - if (!flatSettings.haveMultipleSettings()) { - return new Settings( - List.of( - startSetting.createSettingBasedOn( - startSetting.getSettingTimeSlot(), - dayOfWeek))); - } + List availableTimeSlots = new ArrayList<>(); + LocalTime candidateStartTime = settings.get(0).getSettingStartTime(); + LocalTime candidateEndTime = settings.get(0).getSettingEndTime(); + TimeSlot candidateAvailableTimeSlot = TimeSlot.of(candidateStartTime, candidateEndTime); + boolean onExtension; + for (int i = 1; i < settings.size(); i++) { + TimeSlot currentAvailableTimeSlot = settings.get(i).getSettingTimeSlot(); - for (int i = 1; i < flatSettings.settings.size(); i++) { - Setting endSetting = flatSettings.settings.get(i); - - if (startSetting.canMergeIgnoringDayOfWeek(endSetting)) { - startSetting = startSetting.createSettingBasedOn( - TimeSlot.of(startSetting.getSettingStartTime(), endSetting.getSettingEndTime()), - dayOfWeek); + if (candidateAvailableTimeSlot.isExtendableWith(currentAvailableTimeSlot)) { + onExtension = true; } else { - mergedSettings.add(startSetting.createSettingBasedOn(startSetting.getSettingTimeSlot(), dayOfWeek)); - startSetting = endSetting; + availableTimeSlots.add(candidateAvailableTimeSlot); + onExtension = false; } - if (i == flatSettings.settings.size() - 1) { - mergedSettings.add(startSetting.createSettingBasedOn(startSetting.getSettingTimeSlot(), dayOfWeek)); + if (!onExtension) { + candidateStartTime = currentAvailableTimeSlot.getStartTime(); } - } - return new Settings(mergedSettings); - } + candidateEndTime = currentAvailableTimeSlot.getEndTime(); + candidateAvailableTimeSlot = TimeSlot.of(candidateStartTime, candidateEndTime); - private void validateOrderConflict() { - Set uniquePriorities = settings.stream() - .map(Setting::getPriorityOrder) - .collect(Collectors.toSet()); - - if (settings.size() != uniquePriorities.size()) { - throw new InvalidOrderException(DUPLICATE_SETTING_ORDER_MESSAGE); + if (i == settings.size() - 1) { + availableTimeSlots.add(TimeSlot.of(candidateStartTime, candidateEndTime)); + } } - } - private boolean isFlat() { - return settings.size() >= 1 && settings.stream().allMatch(Setting::isFlattenedSetting); + return availableTimeSlots; } public void clear() { settings.clear(); } - - public void reverseSortByPriorityOrder() { - settings.sort(Comparator.comparing(Setting::getPriorityOrder).reversed()); - } - - private void sortByPriorityOrder() { - settings.sort(Comparator.comparing(Setting::getPriorityOrder)); + @PostLoad + public void postLoad(){ + sort(); } - private void sortByTime() { + private void sort() { settings.sort(Comparator.comparing(Setting::getSettingStartTime)); } - @PostLoad - public void postLoad() { - sortByPriorityOrder(); + private void validateConflicts() { + IntStream.range(0, settings.size() - 1) + .mapToObj(i -> Map.entry(settings.get(i), settings.get(i + 1))) + .collect(Collectors.toList()) + .forEach(pair -> { + Setting currentSetting = pair.getKey(); + Setting nextSetting = pair.getValue(); + if (currentSetting.hasConflictWith(nextSetting)) { + throw new SettingConflictException(currentSetting, nextSetting); + } + }); } @Override diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/domain/Space.java b/backend/src/main/java/com/woowacourse/zzimkkong/domain/Space.java index 82ade787f..dc162bb62 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/domain/Space.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/domain/Space.java @@ -9,7 +9,6 @@ import javax.persistence.*; import java.time.DayOfWeek; import java.util.ArrayList; -import java.util.Comparator; import java.util.List; @Getter diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/domain/TimeSlot.java b/backend/src/main/java/com/woowacourse/zzimkkong/domain/TimeSlot.java index 456ee15e4..4c77ecc5b 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/domain/TimeSlot.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/domain/TimeSlot.java @@ -10,8 +10,6 @@ import javax.persistence.Embeddable; import java.time.LocalTime; import java.time.temporal.ChronoUnit; -import java.util.Collections; -import java.util.List; @Getter @NoArgsConstructor @@ -64,16 +62,10 @@ public boolean isDurationLongerThan(final TimeUnit timeUnit) { return timeUnit.isShorterThan(getDurationMinute()); } - public boolean contains(final TimeSlot that) { - boolean equalOrAfterStartTime = that.startTime.equals(this.startTime) || that.startTime.isAfter(this.startTime); - boolean equalOrBeforeEndTime = that.endTime.equals(this.endTime) || that.endTime.isBefore(this.endTime); - return equalOrAfterStartTime && equalOrBeforeEndTime; - } - public boolean isNotWithin(final TimeSlot that) { - boolean equalOrAfterStartTime = this.startTime.equals(that.startTime) || this.startTime.isAfter(that.startTime); - boolean equalOrBeforeEndTime = this.endTime.equals(that.endTime) || this.endTime.isBefore(that.endTime); - return !(equalOrAfterStartTime && equalOrBeforeEndTime); + boolean isEqualOrAfterStartTime = this.startTime.equals(that.startTime) || this.startTime.isAfter(that.startTime); + boolean isEqualOrBeforeEndTime = this.endTime.equals(that.endTime) || this.endTime.isBefore(that.endTime); + return !(isEqualOrAfterStartTime && isEqualOrBeforeEndTime); } public boolean isExtendableWith(final TimeSlot that) { @@ -96,60 +88,6 @@ private TimeUnit getDurationMinute() { return TimeUnit.from(ChronoUnit.MINUTES.between(startTime, endTime)); } - public TimeSlot extractOverlappingTimeSlot(final TimeSlot that) { - if (!this.hasConflictWith(that)) { - return null; - } - - if (that.contains(this)) { - return this; - } - - if (this.hasLeftSkewedConflictWith(that)) { - return TimeSlot.of(that.startTime, this.endTime); - } - - if (this.hasRightSkewedConflictWith(that)) { - return TimeSlot.of(this.startTime, that.endTime); - } - - return TimeSlot.of(that.startTime, that.endTime); - } - - public List extractExclusiveTimeSlots(final TimeSlot that) { - if (!this.hasConflictWith(that)) { - return List.of(this); - } - - if (that.contains(this)) { - return Collections.emptyList(); - } - - if (this.hasLeftSkewedConflictWith(that)) { - return List.of(TimeSlot.of(this.startTime, that.startTime)); - } - - if (this.hasRightSkewedConflictWith(that)) { - return List.of(TimeSlot.of(that.endTime, this.endTime)); - } - - return List.of( - TimeSlot.of(this.startTime, that.startTime), - TimeSlot.of(that.endTime, this.endTime)); - } - - private boolean hasLeftSkewedConflictWith(final TimeSlot that) { - return this.startTime.isBefore(that.startTime) - && ((this.endTime.isAfter(that.startTime) && this.endTime.isBefore(that.endTime)) - || this.endTime.equals(that.endTime)); - } - - private boolean hasRightSkewedConflictWith(final TimeSlot that) { - return ((this.startTime.isAfter(that.startTime) && this.startTime.isBefore(that.endTime)) - || this.startTime.equals(that.startTime)) - && this.endTime.isAfter(that.endTime); - } - @Override public String toString() { String endTimeAsString = endTime.toString(); diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/domain/TimeUnit.java b/backend/src/main/java/com/woowacourse/zzimkkong/domain/TimeUnit.java index d2eb0f1cf..b8cd8ee3b 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/domain/TimeUnit.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/domain/TimeUnit.java @@ -1,6 +1,5 @@ package com.woowacourse.zzimkkong.domain; -import com.woowacourse.zzimkkong.exception.ZzimkkongException; import com.woowacourse.zzimkkong.exception.reservation.IllegalTimeUnitValueException; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -9,8 +8,6 @@ import javax.persistence.Column; import javax.persistence.Embeddable; import java.time.LocalTime; -import java.util.Comparator; -import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -19,8 +16,6 @@ @EqualsAndHashCode @Embeddable public class TimeUnit { - public static final List INTERVAL_TIME_UNITS = List.of(5, 10, 30, 60); - public static final Integer MINIMUM_TIME_UNIT = 5; private static final Integer MINIMUM_TIME = 0; private static final Map cache = new ConcurrentHashMap<>(); @@ -82,44 +77,4 @@ public String toString() { return String.format("%d시간 %d분", hours, minutes); } - - public TimeUnit getAdjustedIntervalTimeUnit(final TimeSlot timeSlot) { - if (timeSlot.isNotDivisibleBy(this)) { - return INTERVAL_TIME_UNITS.stream() - .sorted(Comparator.reverseOrder()) - .map(TimeUnit::from) - .filter(timeUnit -> !timeSlot.isNotDivisibleBy(timeUnit)) - .findFirst() - .orElseThrow(ZzimkkongException::new); - } - return this; - } - - public TimeUnit getAdjustedTimeUnit(final TimeSlot timeSlot, final TimeUnit intervalTimeUnit) { - if (this.isShorterThan(intervalTimeUnit)) { - return intervalTimeUnit; - } - - TimeUnit candidateMinimumTimeUnit = this; - if (!this.isDivisibleBy(intervalTimeUnit)) { - candidateMinimumTimeUnit = getNextDivisibleTimeUnit(intervalTimeUnit); - } - while (timeSlot.isDurationShorterThan(candidateMinimumTimeUnit)) { - candidateMinimumTimeUnit = candidateMinimumTimeUnit.minus(intervalTimeUnit); - } - return candidateMinimumTimeUnit; - } - - private TimeUnit getNextDivisibleTimeUnit(final TimeUnit timeUnit) { - TimeUnit minimumTimeUnit = cache.get(MINIMUM_TIME_UNIT); - TimeUnit candidateTimeUnit = this; - while (!candidateTimeUnit.isDivisibleBy(timeUnit)) { - candidateTimeUnit = this.minus(minimumTimeUnit); - } - return candidateTimeUnit; - } - - private TimeUnit minus(final TimeUnit timeUnit) { - return TimeUnit.from(this.minutes - timeUnit.minutes); - } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/DuplicateSettingOrderValidator.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/DuplicateSettingOrderValidator.java deleted file mode 100644 index 333267739..000000000 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/DuplicateSettingOrderValidator.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.woowacourse.zzimkkong.dto; - -import com.woowacourse.zzimkkong.dto.space.SettingRequest; -import org.springframework.util.CollectionUtils; - -import javax.validation.ConstraintValidator; -import javax.validation.ConstraintValidatorContext; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -public class DuplicateSettingOrderValidator implements ConstraintValidator> { - @Override - public boolean isValid(final List value, final ConstraintValidatorContext context) { - if (CollectionUtils.isEmpty(value)) { - return true; - } - - Set uniquePriorities = value.stream() - .map(SettingRequest::getPriorityOrder) - .collect(Collectors.toSet()); - - return value.size() == uniquePriorities.size(); - } -} diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/NotDuplicatedSettingOrder.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/NotDuplicatedSettingOrder.java deleted file mode 100644 index ae84b3600..000000000 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/NotDuplicatedSettingOrder.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.woowacourse.zzimkkong.dto; - -import javax.validation.Constraint; -import javax.validation.Payload; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -import static com.woowacourse.zzimkkong.dto.ValidatorMessage.DUPLICATE_SETTING_ORDER_MESSAGE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -@Constraint(validatedBy = DuplicateSettingOrderValidator.class) -@Target(ElementType.FIELD) -@Retention(RUNTIME) -@Documented -public @interface NotDuplicatedSettingOrder { - String message() default DUPLICATE_SETTING_ORDER_MESSAGE; - - Class[] groups() default {}; - - Class[] payload() default {}; -} diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/TimeUnitValidator.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/TimeUnitValidator.java index b4c634b85..9486b38a1 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/TimeUnitValidator.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/TimeUnitValidator.java @@ -2,16 +2,17 @@ import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; - -import static com.woowacourse.zzimkkong.domain.TimeUnit.INTERVAL_TIME_UNITS; +import java.util.List; public class TimeUnitValidator implements ConstraintValidator { + private static final List TIME_UNITS = List.of(5, 10, 30, 60); + @Override public boolean isValid(Integer value, ConstraintValidatorContext context) { if(value == null){ return true; } - return INTERVAL_TIME_UNITS.contains(value); + return TIME_UNITS.contains(value); } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/ValidatorMessage.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/ValidatorMessage.java index 9a8d9f3de..1598d78d0 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/ValidatorMessage.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/ValidatorMessage.java @@ -15,11 +15,9 @@ private ValidatorMessage() { public static final String NOTICE_MESSAGE = "공지사항은 100자 이내로 작성 가능합니다."; public static final String FORMAT_MESSAGE = "날짜 및 시간 데이터 형식이 올바르지 않습니다."; public static final String DAY_OF_WEEK_MESSAGE = "올바른 요일 형식이 아닙니다."; + public static final String SERVER_ERROR_MESSAGE = "일시적으로 접속이 원활하지 않습니다. 잠시 후 다시 이용해 주시기 바랍니다."; public static final String TIME_UNIT_MESSAGE = "시간 단위는 10, 30, 60, 120입니다."; public static final String SETTING_COUNT_MESSAGE = "공간의 예약 조건이 최소 1개는 존재해야 합니다."; - public static final String INVALID_SETTING_ORDER_MESSAGE = "공간 예약 조건 우선순위 값이 올바르지 않습니다."; - public static final String DUPLICATE_SETTING_ORDER_MESSAGE = "공간 예약 조건 우선순위 값은 서로 중복될 수 없습니다."; - public static final String SERVER_ERROR_MESSAGE = "일시적으로 접속이 원활하지 않습니다. 잠시 후 다시 이용해 주시기 바랍니다."; public static final String DATE_FORMAT = "yyyy-MM-dd"; public static final String TIME_FORMAT = "HH:mm:ss"; diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingRequest.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingRequest.java index 4a694fcf0..7d1bfe162 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingRequest.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingRequest.java @@ -6,11 +6,9 @@ import lombok.Getter; import lombok.NoArgsConstructor; -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; import java.time.LocalTime; -import static com.woowacourse.zzimkkong.dto.ValidatorMessage.*; +import static com.woowacourse.zzimkkong.dto.ValidatorMessage.TIME_FORMAT; @Getter @NoArgsConstructor @@ -31,24 +29,19 @@ public class SettingRequest { private EnabledDayOfWeekDto enabledDayOfWeek = new EnabledDayOfWeekDto(); - @Min(value = 0, message = INVALID_SETTING_ORDER_MESSAGE) - private Integer priorityOrder = 0; - public SettingRequest( final LocalTime settingStartTime, final LocalTime settingEndTime, final Integer reservationTimeUnit, final Integer reservationMinimumTimeUnit, final Integer reservationMaximumTimeUnit, - final EnabledDayOfWeekDto enabledDayOfWeek, - final Integer priorityOrder) { + final EnabledDayOfWeekDto enabledDayOfWeek) { this.settingStartTime = settingStartTime; this.settingEndTime = settingEndTime; this.reservationTimeUnit = reservationTimeUnit; this.reservationMinimumTimeUnit = reservationMinimumTimeUnit; this.reservationMaximumTimeUnit = reservationMaximumTimeUnit; this.enabledDayOfWeek = enabledDayOfWeek; - this.priorityOrder = priorityOrder; } public String enabledDayOfWeekAsString() { diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingResponse.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingResponse.java index 6ab432893..2064c9258 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingResponse.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingResponse.java @@ -35,9 +35,6 @@ public class SettingResponse { @JsonProperty private EnabledDayOfWeekDto enabledDayOfWeek; - @JsonProperty - private Integer priorityOrder; - protected SettingResponse( final Long settingId, final LocalTime settingStartTime, @@ -45,8 +42,7 @@ protected SettingResponse( final Integer reservationTimeUnit, final Integer reservationMinimumTimeUnit, final Integer reservationMaximumTimeUnit, - final EnabledDayOfWeekDto enabledDayOfWeek, - final Integer priorityOrder) { + final EnabledDayOfWeekDto enabledDayOfWeek) { this.settingId = settingId; this.settingStartTime = settingStartTime; this.settingEndTime = settingEndTime; @@ -54,7 +50,6 @@ protected SettingResponse( this.reservationMinimumTimeUnit = reservationMinimumTimeUnit; this.reservationMaximumTimeUnit = reservationMaximumTimeUnit; this.enabledDayOfWeek = enabledDayOfWeek; - this.priorityOrder = priorityOrder; } public static SettingResponse from(final Setting setting) { @@ -65,8 +60,7 @@ public static SettingResponse from(final Setting setting) { setting.getReservationTimeUnitAsInt(), setting.getReservationMinimumTimeUnitAsInt(), setting.getReservationMaximumTimeUnitAsInt(), - EnabledDayOfWeekDto.from(setting.getEnabledDayOfWeek()), - setting.getPriorityOrder() + EnabledDayOfWeekDto.from(setting.getEnabledDayOfWeek()) ); } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingsSummaryResponse.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingsSummaryResponse.java deleted file mode 100644 index aa357b5b9..000000000 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SettingsSummaryResponse.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.woowacourse.zzimkkong.dto.space; - -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@NoArgsConstructor -public class SettingsSummaryResponse { - private String summary; - - private SettingsSummaryResponse(final String summary) { - this.summary = summary; - } - - public static SettingsSummaryResponse from(final String summary) { - return new SettingsSummaryResponse(summary); - } -} diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SpaceCreateUpdateRequest.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SpaceCreateUpdateRequest.java index 3e0fc9919..e901fee55 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SpaceCreateUpdateRequest.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SpaceCreateUpdateRequest.java @@ -1,7 +1,6 @@ package com.woowacourse.zzimkkong.dto.space; import com.woowacourse.zzimkkong.domain.Settings; -import com.woowacourse.zzimkkong.dto.NotDuplicatedSettingOrder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -34,9 +33,8 @@ public class SpaceCreateUpdateRequest { @NotNull(message = SETTING_COUNT_MESSAGE) @Size(min = Settings.MINIMUM_SETTING_COUNT, message = SETTING_COUNT_MESSAGE) - @NotDuplicatedSettingOrder @Valid - private List settings = List.of(new SettingRequest()); + private List settings = Arrays.asList(new SettingRequest()); public SpaceCreateUpdateRequest( final String name, diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SpaceFindDetailResponse.java b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SpaceFindDetailResponse.java index 3b1c95020..131c144bb 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SpaceFindDetailResponse.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/dto/space/SpaceFindDetailResponse.java @@ -1,6 +1,5 @@ package com.woowacourse.zzimkkong.dto.space; -import com.woowacourse.zzimkkong.domain.Settings; import com.woowacourse.zzimkkong.domain.Space; import lombok.Getter; import lombok.NoArgsConstructor; @@ -42,9 +41,7 @@ public static SpaceFindDetailResponse from(final Space space) { } protected static List getSettingResponses(final Space space) { - Settings spaceSettings = space.getSpaceSettings(); - spaceSettings.reverseSortByPriorityOrder(); - return spaceSettings.getSettings() + return space.getSpaceSettings().getSettings() .stream() .map(SettingResponse::from) .collect(Collectors.toList()); diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/exception/ZzimkkongException.java b/backend/src/main/java/com/woowacourse/zzimkkong/exception/ZzimkkongException.java index 301baeead..2f0ad05fc 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/exception/ZzimkkongException.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/exception/ZzimkkongException.java @@ -3,23 +3,21 @@ import lombok.Getter; import org.springframework.http.HttpStatus; -import static com.woowacourse.zzimkkong.dto.ValidatorMessage.SERVER_ERROR_MESSAGE; import static com.woowacourse.zzimkkong.infrastructure.message.MessageUtils.LINE_SEPARATOR; @Getter public class ZzimkkongException extends RuntimeException { + private static final String DEFAULT_MESSAGE = "일시적으로 접속이 원활하지 않습니다. 찜꽁 서비스 팀에 문의 부탁드립니다." + + LINE_SEPARATOR + + "Contact : sunnyk5780@gmail.com / jssung@sk.com"; + private final HttpStatus status; public ZzimkkongException() { - super(SERVER_ERROR_MESSAGE); + super(DEFAULT_MESSAGE); this.status = HttpStatus.INTERNAL_SERVER_ERROR; } - public ZzimkkongException(final HttpStatus status) { - super(SERVER_ERROR_MESSAGE); - this.status = status; - } - public ZzimkkongException(final String message, final HttpStatus status) { super(message); this.status = status; diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/exception/reservation/InvalidStartEndTimeException.java b/backend/src/main/java/com/woowacourse/zzimkkong/exception/reservation/InvalidStartEndTimeException.java index 93de33e4e..aac7b2fc3 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/exception/reservation/InvalidStartEndTimeException.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/exception/reservation/InvalidStartEndTimeException.java @@ -1,10 +1,10 @@ package com.woowacourse.zzimkkong.exception.reservation; +import com.woowacourse.zzimkkong.domain.Settings; import com.woowacourse.zzimkkong.domain.TimeSlot; import com.woowacourse.zzimkkong.exception.ZzimkkongException; import org.springframework.http.HttpStatus; -import java.util.List; import java.util.stream.Collectors; import static com.woowacourse.zzimkkong.infrastructure.message.MessageUtils.LINE_SEPARATOR; @@ -17,16 +17,14 @@ public class InvalidStartEndTimeException extends ZzimkkongException { LINE_SEPARATOR + "예약 불가 시간대: %s"; - public InvalidStartEndTimeException( - final List unavailableTimeSlots, - final TimeSlot reservationTimeSlot) { + public InvalidStartEndTimeException(Settings settings, TimeSlot reservationTimeSlot) { super(String.format( - MESSAGE_FORMAT, - reservationTimeSlot, - unavailableTimeSlots - .stream() - .map(TimeSlot::toString) - .collect(Collectors.joining(", "))), + MESSAGE_FORMAT, + reservationTimeSlot, + settings.getUnavailableTimeSlots() + .stream() + .map(TimeSlot::toString) + .collect(Collectors.joining(", "))), HttpStatus.BAD_REQUEST); } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/InvalidOrderException.java b/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/InvalidOrderException.java deleted file mode 100644 index 09703e305..000000000 --- a/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/InvalidOrderException.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.woowacourse.zzimkkong.exception.setting; - -import com.woowacourse.zzimkkong.exception.ZzimkkongException; -import org.springframework.http.HttpStatus; - -public class InvalidOrderException extends ZzimkkongException { - public InvalidOrderException(String message) { - super(message, HttpStatus.INTERNAL_SERVER_ERROR); - } -} diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/NoSettingAvailableException.java b/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/NoSettingAvailableException.java index 70f934662..98868c798 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/NoSettingAvailableException.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/NoSettingAvailableException.java @@ -15,7 +15,7 @@ public class NoSettingAvailableException extends ZzimkkongException { "%s"; public NoSettingAvailableException(final Space space) { - super(String.format(MESSAGE_FORMAT, space.getName(), space.getSpaceSettings().getSummary()), + super(String.format(MESSAGE_FORMAT, space.getName(), space.getSpaceSettings()), HttpStatus.BAD_REQUEST); } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/SettingConflictException.java b/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/SettingConflictException.java new file mode 100644 index 000000000..b78e44c3b --- /dev/null +++ b/backend/src/main/java/com/woowacourse/zzimkkong/exception/setting/SettingConflictException.java @@ -0,0 +1,17 @@ +package com.woowacourse.zzimkkong.exception.setting; + +import com.woowacourse.zzimkkong.domain.Setting; +import com.woowacourse.zzimkkong.exception.ZzimkkongException; +import org.springframework.http.HttpStatus; + +public class SettingConflictException extends ZzimkkongException { + private static final String MESSAGE_FORMAT = "공간 예약 조건들의 시간대가 겹칩니다. \n겹치는 시간대 정보: %s VS %s"; + + public SettingConflictException(final Setting currentSetting, final Setting nextSetting) { + super(String.format( + MESSAGE_FORMAT, + currentSetting.getSettingTimeSlot(), + nextSetting.getSettingTimeSlot()), + HttpStatus.NOT_FOUND); + } +} diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/infrastructure/datetime/TimeZoneUtils.java b/backend/src/main/java/com/woowacourse/zzimkkong/infrastructure/datetime/TimeZoneUtils.java index 0b7abaceb..a7b53f66f 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/infrastructure/datetime/TimeZoneUtils.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/infrastructure/datetime/TimeZoneUtils.java @@ -10,22 +10,13 @@ public class TimeZoneUtils { public static final TimeZone UTC = TimeZone.getTimeZone("UTC"); - public static LocalDateTime convertTo(final LocalDateTime dateTime, ServiceZone serviceZone) { - if (dateTime == null) { - return null; - } - if (serviceZone == null) { - serviceZone = ServiceZone.KOREA; - } + public static LocalDateTime convertTo(final LocalDateTime dateTime, final ServiceZone serviceZone) { return dateTime.atZone(UTC.toZoneId()) .withZoneSameInstant(ZoneId.of(serviceZone.getTimeZone())) .toLocalDateTime(); } public static LocalDateTime convertToUTC(final ZonedDateTime zonedDateTime) { - if (zonedDateTime == null) { - return null; - } return zonedDateTime.withZoneSameInstant(UTC.toZoneId()).toLocalDateTime(); } } diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/service/ReservationService.java b/backend/src/main/java/com/woowacourse/zzimkkong/service/ReservationService.java index dd34a7593..6d9bdb11c 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/service/ReservationService.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/service/ReservationService.java @@ -289,9 +289,7 @@ private void validateSpaceSetting(final Space space, final Reservation reservati DayOfWeek dayOfWeek = reservation.getDayOfWeek(); Settings relevantSettings = space.getRelevantSettings(timeSlot, dayOfWeek); - if (relevantSettings.isEmpty()) { - space.getSpaceSettings().flatten(); throw new NoSettingAvailableException(space); } @@ -300,8 +298,8 @@ private void validateSpaceSetting(final Space space, final Reservation reservati throw new MultipleSettingsException(relevantSettings); } - if (relevantSettings.cannotAcceptDueToAvailableTime(timeSlot, dayOfWeek)) { - throw new InvalidStartEndTimeException(relevantSettings.getUnavailableTimeSlots(dayOfWeek), timeSlot); + if (relevantSettings.cannotAcceptDueToAvailableTime(timeSlot)) { + throw new InvalidStartEndTimeException(relevantSettings, timeSlot); } // TODO: 2023/02/09 기준, 예약은 하나의 세팅만 걸쳐야한다 diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/service/SettingService.java b/backend/src/main/java/com/woowacourse/zzimkkong/service/SettingService.java deleted file mode 100644 index d1d27d6fb..000000000 --- a/backend/src/main/java/com/woowacourse/zzimkkong/service/SettingService.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.woowacourse.zzimkkong.service; - - -import com.woowacourse.zzimkkong.domain.EnabledDayOfWeek; -import com.woowacourse.zzimkkong.domain.Map; -import com.woowacourse.zzimkkong.domain.Settings; -import com.woowacourse.zzimkkong.domain.Space; -import com.woowacourse.zzimkkong.domain.SettingViewType; -import com.woowacourse.zzimkkong.dto.space.SettingsSummaryResponse; -import com.woowacourse.zzimkkong.exception.map.NoSuchMapException; -import com.woowacourse.zzimkkong.exception.space.NoSuchSpaceException; -import com.woowacourse.zzimkkong.infrastructure.datetime.TimeZoneUtils; -import com.woowacourse.zzimkkong.repository.MapRepository; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.DayOfWeek; -import java.time.LocalDateTime; -import java.util.Locale; - -@Service -@Transactional(readOnly = true) -public class SettingService { - private final MapRepository maps; - - public SettingService(final MapRepository maps) { - this.maps = maps; - } - - public SettingsSummaryResponse getSettingsSummary( - final Long mapId, - final Long spaceId, - final LocalDateTime selectedDateTime, - final String settingViewType) { - Map map = maps.findByIdFetch(mapId) - .orElseThrow(NoSuchMapException::new); - Space space = map.findSpaceById(spaceId) - .orElseThrow(NoSuchSpaceException::new); - - String summary = SettingViewType.of(selectedDateTime, settingViewType) - .getSummary(space, selectedDateTime); - - return SettingsSummaryResponse.from(summary); - } -} diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/service/SpaceService.java b/backend/src/main/java/com/woowacourse/zzimkkong/service/SpaceService.java index fa1acd0f8..d62744881 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/service/SpaceService.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/service/SpaceService.java @@ -15,6 +15,8 @@ import java.time.DayOfWeek; import java.time.LocalDateTime; +import java.util.AbstractMap; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -201,7 +203,7 @@ private Boolean isSpaceSettingViolated(final Space space, final ReservationTime return relevantSettings.isEmpty() || relevantSettings.haveMultipleSettings() || - relevantSettings.cannotAcceptDueToAvailableTime(timeSlot, dayOfWeek) || + relevantSettings.cannotAcceptDueToAvailableTime(timeSlot) || relevantSettings.getSettings().get(0).cannotAcceptDueToTimeUnit(timeSlot) || relevantSettings.getSettings().get(0).cannotAcceptDueToMinimumTimeUnit(timeSlot) || relevantSettings.getSettings().get(0).cannotAcceptDueToMaximumTimeUnit(timeSlot) || diff --git a/backend/src/main/resources/db/migration/prod/V22__setting_priority.sql b/backend/src/main/resources/db/migration/prod/V22__setting_priority.sql deleted file mode 100644 index eca795436..000000000 --- a/backend/src/main/resources/db/migration/prod/V22__setting_priority.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE setting ADD COLUMN priority_order integer not null; -UPDATE setting SET priority_order = 0; \ No newline at end of file diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/AcceptanceTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/AcceptanceTest.java index 286c29eaa..64288d218 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/controller/AcceptanceTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/controller/AcceptanceTest.java @@ -50,8 +50,7 @@ class AcceptanceTest { BE_RESERVATION_TIME_UNIT.getMinutes(), BE_RESERVATION_MINIMUM_TIME_UNIT.getMinutes(), BE_RESERVATION_MAXIMUM_TIME_UNIT.getMinutes(), - EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK), - 0 + EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK) ); protected final SpaceCreateUpdateRequest beSpaceCreateUpdateRequest = new SpaceCreateUpdateRequest( BE_NAME, @@ -67,8 +66,7 @@ class AcceptanceTest { FE_RESERVATION_TIME_UNIT.getMinutes(), FE_RESERVATION_MINIMUM_TIME_UNIT.getMinutes(), FE_RESERVATION_MAXIMUM_TIME_UNIT.getMinutes(), - EnabledDayOfWeekDto.from(FE_ENABLED_DAY_OF_WEEK), - 0 + EnabledDayOfWeekDto.from(FE_ENABLED_DAY_OF_WEEK) ); protected final SpaceCreateUpdateRequest feSpaceCreateUpdateRequest = new SpaceCreateUpdateRequest( FE_NAME, diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/AdminControllerTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/AdminControllerTest.java index 50feec673..b316f21ba 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/controller/AdminControllerTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/controller/AdminControllerTest.java @@ -56,7 +56,6 @@ class AdminControllerTest extends AcceptanceTest { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); private static final Space BE = Space.builder() .name(BE_NAME) @@ -64,7 +63,7 @@ class AdminControllerTest extends AcceptanceTest { .map(LUTHER) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(BE_SETTING))) + .spaceSettings(new Settings(List.of(BE_SETTING))) .build(); private static String token; diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestReservationControllerTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestReservationControllerTest.java index 2697e23b2..fa619a15f 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestReservationControllerTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestReservationControllerTest.java @@ -94,7 +94,6 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); be = Space.builder() @@ -103,7 +102,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) + .spaceSettings(new Settings(List.of(beSetting))) .build(); Setting feSetting = Setting.builder() @@ -114,7 +113,6 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); fe = Space.builder() @@ -124,7 +122,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) + .spaceSettings(new Settings(List.of(feSetting))) .build(); saveExampleReservations(); diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestSpaceControllerTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestSpaceControllerTest.java index fad43578e..f08f1dc90 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestSpaceControllerTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/controller/GuestSpaceControllerTest.java @@ -58,7 +58,6 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); Setting feSetting = Setting.builder() @@ -69,7 +68,6 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); be = Space.builder() @@ -79,7 +77,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) + .spaceSettings(new Settings(List.of(beSetting))) .build(); fe = Space.builder() @@ -89,7 +87,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) + .spaceSettings(new Settings(List.of(feSetting))) .build(); } diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/ManagerReservationControllerTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/ManagerReservationControllerTest.java index 1ba13320b..51cdfc315 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/controller/ManagerReservationControllerTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/controller/ManagerReservationControllerTest.java @@ -86,7 +86,6 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); be = Space.builder() @@ -95,7 +94,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) + .spaceSettings(new Settings(List.of(beSetting))) .build(); Setting feSetting = Setting.builder() @@ -106,7 +105,6 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); fe = Space.builder() @@ -116,7 +114,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) + .spaceSettings(new Settings(List.of(feSetting))) .build(); saveExampleReservations(); diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/ManagerSpaceControllerTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/ManagerSpaceControllerTest.java index a2373a90d..64d753ea8 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/controller/ManagerSpaceControllerTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/controller/ManagerSpaceControllerTest.java @@ -53,7 +53,6 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); Setting feSetting = Setting.builder() @@ -64,7 +63,6 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); be = Space.builder() @@ -74,7 +72,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) + .spaceSettings(new Settings(List.of(beSetting))) .build(); fe = Space.builder() @@ -84,7 +82,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) + .spaceSettings(new Settings(List.of(feSetting))) .build(); } @@ -98,8 +96,7 @@ void save() { 30, 60, 120, - EnabledDayOfWeekDto.from("monday, tuesday, wednesday, thursday, friday, saturday, sunday"), - 1 + EnabledDayOfWeekDto.from("monday, tuesday, wednesday, thursday, friday, saturday, sunday") ); SpaceCreateUpdateRequest newSpaceCreateUpdateRequest = new SpaceCreateUpdateRequest( @@ -128,7 +125,6 @@ void save_default() { null, null, null, - null, null ); @@ -149,13 +145,12 @@ void save_default() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek("monday, tuesday, wednesday, thursday, friday, saturday, sunday") - .priorityOrder(0) .build(); Space defaultSpace = Space.builder() .name(defaultSpaceCreateUpdateRequest.getName()) .color(defaultSpaceCreateUpdateRequest.getColor()) - .spaceSettings(Settings.toPrioritizedSettings(List.of(defaultSetting))) + .spaceSettings(new Settings(List.of(defaultSetting))) .reservationEnable(true) .area(SPACE_DRAWING) .build(); @@ -217,8 +212,7 @@ void update() { 30, 60, 120, - EnabledDayOfWeekDto.from("monday, tuesday, wednesday, thursday, friday, saturday, sunday"), - 1 + EnabledDayOfWeekDto.from("monday, tuesday, wednesday, thursday, friday, saturday, sunday") ); SpaceCreateUpdateRequest updateSpaceCreateUpdateRequest = new SpaceCreateUpdateRequest( diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/PresetControllerTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/PresetControllerTest.java index e235ab3b1..12ae9bbd6 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/controller/PresetControllerTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/controller/PresetControllerTest.java @@ -46,7 +46,6 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); settingRequest = new SettingRequest( @@ -55,8 +54,7 @@ void setUp() { BE_RESERVATION_TIME_UNIT.getMinutes(), BE_RESERVATION_MINIMUM_TIME_UNIT.getMinutes(), BE_RESERVATION_MAXIMUM_TIME_UNIT.getMinutes(), - EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK), - 0 + EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK) ); presetCreateRequest = new PresetCreateRequest(PRESET_NAME1, settingRequest); } diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/controller/SettingControllerTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/controller/SettingControllerTest.java deleted file mode 100644 index 727977f36..000000000 --- a/backend/src/test/java/com/woowacourse/zzimkkong/controller/SettingControllerTest.java +++ /dev/null @@ -1,230 +0,0 @@ -package com.woowacourse.zzimkkong.controller; - -import com.woowacourse.zzimkkong.domain.*; -import com.woowacourse.zzimkkong.dto.space.EnabledDayOfWeekDto; -import com.woowacourse.zzimkkong.dto.space.SettingRequest; -import com.woowacourse.zzimkkong.dto.space.SettingsSummaryResponse; -import com.woowacourse.zzimkkong.dto.space.SpaceCreateUpdateRequest; -import io.restassured.RestAssured; -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; - -import java.time.LocalTime; -import java.util.List; - -import static com.woowacourse.zzimkkong.Constants.*; -import static com.woowacourse.zzimkkong.DocumentUtils.*; -import static com.woowacourse.zzimkkong.controller.ManagerSpaceControllerTest.saveSpace; -import static com.woowacourse.zzimkkong.controller.MapControllerTest.saveMap; -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.document; - -public class SettingControllerTest extends AcceptanceTest { - private String spaceApi; - private String lutherId; - private Long beSpaceId; - private Space be; - private Space fe; - - private final SettingRequest beSettingRequest = new SettingRequest( - BE_AVAILABLE_START_TIME, - BE_AVAILABLE_END_TIME, - BE_RESERVATION_TIME_UNIT.getMinutes(), - BE_RESERVATION_MINIMUM_TIME_UNIT.getMinutes(), - BE_RESERVATION_MAXIMUM_TIME_UNIT.getMinutes(), - EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK), - 1 - ); - private final SettingRequest beSettingRequest2 = new SettingRequest( - LocalTime.of(11, 0), - LocalTime.of(15, 0), - TimeUnit.from(5).getMinutes(), - TimeUnit.from(30).getMinutes(), - TimeUnit.from(60).getMinutes(), - EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK), - 0 - ); - private final SpaceCreateUpdateRequest beSpaceCreateUpdateRequestUpgraded = new SpaceCreateUpdateRequest( - BE_NAME, - BE_COLOR, - SPACE_DRAWING, - MAP_SVG, - BE_RESERVATION_ENABLE, - List.of(beSettingRequest, beSettingRequest2) - ); - - @BeforeEach - void setUp() { - lutherId = saveMap("/api/managers/maps", mapCreateUpdateRequest).header("location").split("/")[4]; - spaceApi = "/api/managers/maps/" + lutherId + "/spaces"; - ExtractableResponse saveBeSpaceResponse = saveSpace(spaceApi, beSpaceCreateUpdateRequestUpgraded); - ExtractableResponse saveFe1SpaceResponse = saveSpace(spaceApi, feSpaceCreateUpdateRequest); - - beSpaceId = Long.valueOf(saveBeSpaceResponse.header("location").split("/")[6]); - Long feSpaceId = Long.valueOf(saveFe1SpaceResponse.header("location").split("/")[6]); - - Member pobi = Member.builder() - .email(EMAIL) - .userName(POBI) - .emoji(ProfileEmoji.MAN_DARK_SKIN_TONE_TECHNOLOGIST) - .password(passwordEncoder.encode(PW)) - .organization(ORGANIZATION) - .build(); - Map luther = new Map(LUTHER_NAME, MAP_DRAWING_DATA, MAP_SVG, pobi); - Setting beSetting = Setting.builder() - .settingTimeSlot(TimeSlot.of( - BE_AVAILABLE_START_TIME, - BE_AVAILABLE_END_TIME)) - .reservationTimeUnit(BE_RESERVATION_TIME_UNIT) - .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) - .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) - .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(1) - .build(); - - - Setting beSetting2 = Setting.builder() - .settingTimeSlot(TimeSlot.of( - LocalTime.of(11, 0), - LocalTime.of(15, 0))) - .reservationTimeUnit(TimeUnit.from(5)) - .reservationMinimumTimeUnit(TimeUnit.from(30)) - .reservationMaximumTimeUnit(TimeUnit.from(60)) - .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) - .build(); - - Setting feSetting = Setting.builder() - .settingTimeSlot(TimeSlot.of( - FE_AVAILABLE_START_TIME, - FE_AVAILABLE_END_TIME)) - .reservationTimeUnit(FE_RESERVATION_TIME_UNIT) - .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) - .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) - .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) - .build(); - - be = Space.builder() - .id(beSpaceId) - .name(BE_NAME) - .color(BE_COLOR) - .map(luther) - .area(SPACE_DRAWING) - .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting, beSetting2))) - .build(); - - fe = Space.builder() - .id(feSpaceId) - .name(FE_NAME) - .color(FE_COLOR) - .map(luther) - .area(SPACE_DRAWING) - .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) - .build(); - } - - @Test - @DisplayName("특정 맵 특정 공간의 예약자들을 위한 (flat) 특정 일자의 예약 조건 (setting) 요약 메세지를 조회한다") - void find_flat() { - // given - String api = "/api/maps/" + lutherId + "/spaces/" + beSpaceId + "/settings/summary"; - - // when - ExtractableResponse response = findFlat(api); - SettingsSummaryResponse actualResponse = response.as(SettingsSummaryResponse.class); - - // then - assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); - } - - @Test - @DisplayName("특정 맵 특정 공간의 관리자들을 위한 (stack) 특정 일자의 예약 조건 (setting) 요약 메세지를 조회한다") - void find_stack() { - // given - String api = "/api/maps/" + lutherId + "/spaces/" + beSpaceId + "/settings/summary"; - - // when - ExtractableResponse response = findStack(api); - - // then - assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); - } - - @Test - @DisplayName("특정 맵 특정 공간의 예약자들을 위한 (flat) 전체 예약 조건 (setting) 요약 메세지를 조회한다") - void find_flat_all() { - // given - String api = "/api/maps/" + lutherId + "/spaces/" + beSpaceId + "/settings/summary"; - - // when - ExtractableResponse response = findFlatAll(api); - - // then - assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); - } - - @Test - @DisplayName("특정 맵 특정 공간의 관리자들을 위한 (stack) 전체 예약 조건 (setting) 요약 메세지를 조회한다") - void find_stack_all() { - // given - String api = "/api/maps/" + lutherId + "/spaces/" + beSpaceId + "/settings/summary"; - - // when - ExtractableResponse response = findStackAll(api); - - // then - assertThat(response.statusCode()).isEqualTo(HttpStatus.OK.value()); - } - - static ExtractableResponse findFlat(final String api) { - return RestAssured - .given(getRequestSpecification()).log().all() - .accept("application/json") - .param("selectedDateTime", BE_AM_TEN_ELEVEN_START_TIME_KST.toLocalDate() + "T12:00:00+09:00") - .filter(document("setting/get_flat", getRequestPreprocessor(), getResponsePreprocessor())) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .when().get(api) - .then().log().all().extract(); - } - - static ExtractableResponse findStack(final String api) { - return RestAssured - .given(getRequestSpecification()).log().all() - .accept("application/json") - .param("selectedDateTime", BE_AM_TEN_ELEVEN_START_TIME_KST.toLocalDate() + "T12:00:00+09:00") - .param("settingViewType", "STACK") - .filter(document("setting/get_stack", getRequestPreprocessor(), getResponsePreprocessor())) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .when().get(api) - .then().log().all().extract(); - } - - static ExtractableResponse findFlatAll(final String api) { - return RestAssured - .given(getRequestSpecification()).log().all() - .accept("application/json") - .filter(document("setting/get_flat_all", getRequestPreprocessor(), getResponsePreprocessor())) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .when().get(api) - .then().log().all().extract(); - } - - static ExtractableResponse findStackAll(final String api) { - return RestAssured - .given(getRequestSpecification()).log().all() - .accept("application/json") - .param("settingViewType", "STACK") - .filter(document("setting/get_stack_all", getRequestPreprocessor(), getResponsePreprocessor())) - .contentType(MediaType.APPLICATION_JSON_VALUE) - .when().get(api) - .then().log().all().extract(); - } -} diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/domain/PresetTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/domain/PresetTest.java index 61ade78ee..1a962cc38 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/domain/PresetTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/domain/PresetTest.java @@ -15,7 +15,6 @@ class PresetTest { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); @Test diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/domain/SettingTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/domain/SettingTest.java index f0b30faf6..14831c6f5 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/domain/SettingTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/domain/SettingTest.java @@ -7,19 +7,13 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.EnumSource; -import org.junit.jupiter.params.provider.MethodSource; import java.time.DayOfWeek; import java.time.LocalTime; -import java.util.Collections; -import java.util.List; -import java.util.stream.Stream; import static com.woowacourse.zzimkkong.Constants.*; -import static com.woowacourse.zzimkkong.domain.Setting.FLAT_PRIORITY_ORDER; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; @@ -36,7 +30,6 @@ void name() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build()); } @@ -80,7 +73,6 @@ void timeUnitMismatch_ok(int startMinute, int endMinute, int timeUnit) { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build()); } @@ -125,7 +117,6 @@ void supports_dayOfWeek_settingExists(DayOfWeek dayOfWeek) { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek("monday, wednesday") - .priorityOrder(0) .build(); assertThat(setting.supports(reservationTimeSlot, dayOfWeek)).isTrue(); @@ -142,106 +133,8 @@ void supports_dayOfWeek_settingDoesNotExist(DayOfWeek dayOfWeek) { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek("monday, wednesday") - .priorityOrder(0) .build(); assertThat(setting.supports(reservationTimeSlot, dayOfWeek)).isFalse(); } - - @ParameterizedTest - @DisplayName("인자로 주어진 settings 의 조건들에 배타적인 (겹치지 않는) 새로운 setting slot 리스트를 생성한다") - @MethodSource("provideSettings") - void extractExclusiveSettingSlots(List settings, List expected) { - Setting setting = Setting.builder() - .settingTimeSlot(TimeSlot.of( - LocalTime.of(10, 0), - LocalTime.of(11, 0))) - .reservationTimeUnit(TimeUnit.from(10)) - .reservationMinimumTimeUnit(TimeUnit.from(10)) - .reservationMaximumTimeUnit(TimeUnit.from(30)) - .enabledDayOfWeek("monday,tuesday,wednesday,thursday,friday,saturday,sunday") - .priorityOrder(0) - .build(); - - List actual = setting.extractExclusiveSettingSlots(settings); - assertThat(actual).usingRecursiveComparison() - .ignoringCollectionOrder() - .ignoringExpectedNullFields() - .isEqualTo(expected); - } - - private static Stream provideSettings() { - return Stream.of( - Arguments.of( - List.of( - Setting.builder() - .settingTimeSlot(TimeSlot.of( - LocalTime.of(9, 30), - LocalTime.of(10, 30))) - .reservationTimeUnit(TimeUnit.from(10)) - .reservationMinimumTimeUnit(TimeUnit.from(10)) - .reservationMaximumTimeUnit(TimeUnit.from(30)) - .enabledDayOfWeek("monday,tuesday,wednesday,thursday,friday,saturday,sunday") - .priorityOrder(FLAT_PRIORITY_ORDER) - .build(), - Setting.builder() - .settingTimeSlot(TimeSlot.of( - LocalTime.of(10, 30), - LocalTime.of(11, 0))) - .reservationTimeUnit(TimeUnit.from(10)) - .reservationMinimumTimeUnit(TimeUnit.from(10)) - .reservationMaximumTimeUnit(TimeUnit.from(30)) - .enabledDayOfWeek("monday,tuesday,wednesday,thursday,friday,saturday,sunday") - .priorityOrder(FLAT_PRIORITY_ORDER) - .build() - ), - Collections.emptyList()), - Arguments.of( - List.of( - Setting.builder() - .settingTimeSlot(TimeSlot.of( - LocalTime.of(9, 30), - LocalTime.of(10, 30))) - .reservationTimeUnit(TimeUnit.from(10)) - .reservationMinimumTimeUnit(TimeUnit.from(10)) - .reservationMaximumTimeUnit(TimeUnit.from(30)) - .enabledDayOfWeek("monday,tuesday,wednesday") - .priorityOrder(FLAT_PRIORITY_ORDER) - .build(), - Setting.builder() - .settingTimeSlot(TimeSlot.of( - LocalTime.of(10, 30), - LocalTime.of(11, 0))) - .reservationTimeUnit(TimeUnit.from(10)) - .reservationMinimumTimeUnit(TimeUnit.from(10)) - .reservationMaximumTimeUnit(TimeUnit.from(30)) - .enabledDayOfWeek("thursday,friday,saturday,sunday") - .priorityOrder(FLAT_PRIORITY_ORDER) - .build() - ), - List.of( - Setting.builder() - .settingTimeSlot(TimeSlot.of( - LocalTime.of(10, 30), - LocalTime.of(11, 0))) - .reservationTimeUnit(TimeUnit.from(10)) - .reservationMinimumTimeUnit(TimeUnit.from(10)) - .reservationMaximumTimeUnit(TimeUnit.from(30)) - .enabledDayOfWeek("monday,tuesday,wednesday") - .priorityOrder(FLAT_PRIORITY_ORDER) - .build(), - Setting.builder() - .settingTimeSlot(TimeSlot.of( - LocalTime.of(10, 0), - LocalTime.of(10, 30))) - .reservationTimeUnit(TimeUnit.from(10)) - .reservationMinimumTimeUnit(TimeUnit.from(10)) - .reservationMaximumTimeUnit(TimeUnit.from(30)) - .enabledDayOfWeek("thursday,friday,saturday,sunday") - .priorityOrder(FLAT_PRIORITY_ORDER) - .build() - )) - ); - } } - diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/domain/SettingsTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/domain/SettingsTest.java index 12781f78c..cd3f5b155 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/domain/SettingsTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/domain/SettingsTest.java @@ -11,12 +11,9 @@ import java.time.LocalTime; import java.util.Collections; import java.util.List; -import java.util.Locale; import java.util.stream.Stream; import static com.woowacourse.zzimkkong.Constants.*; -import static com.woowacourse.zzimkkong.domain.Setting.FLAT_PRIORITY_ORDER; -import static com.woowacourse.zzimkkong.domain.Setting.FLAT_SETTING_ID; import static org.assertj.core.api.Assertions.assertThat; class SettingsTest { @@ -29,36 +26,33 @@ class SettingsTest { void setUp() { setting1 = Setting.builder() .settingTimeSlot(TimeSlot.of( - LocalTime.of(10, 0), - LocalTime.of(13, 0))) + LocalTime.of(10,0), + LocalTime.of(13,0))) .reservationTimeUnit(BE_RESERVATION_TIME_UNIT) .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); setting2 = Setting.builder() .settingTimeSlot(TimeSlot.of( - LocalTime.of(14, 0), - LocalTime.of(16, 0))) + LocalTime.of(14,0), + LocalTime.of(16,0))) .reservationTimeUnit(BE_RESERVATION_TIME_UNIT) .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(1) .build(); setting3 = Setting.builder() .settingTimeSlot(TimeSlot.of( - LocalTime.of(16, 0), - LocalTime.of(20, 0))) + LocalTime.of(16,0), + LocalTime.of(20,0))) .reservationTimeUnit(BE_RESERVATION_TIME_UNIT) .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(2) .build(); - settings = Settings.toPrioritizedSettings(List.of(setting1, setting2, setting3)); + settings = new Settings(List.of(setting1, setting2, setting3)); } @ParameterizedTest @@ -73,9 +67,7 @@ void getSettingsByTimeSlotAndDayOfWeek(TimeSlot reservationTimeSlot, Settings ex @DisplayName("예약 가능한 시간대에 속한 예약이면 false, 아니면 true") @MethodSource("provideArgumentsForCannotAcceptDueToAvailableTime") void cannotAcceptDueToAvailableTime(TimeSlot reservationTimeSlot, boolean expectedResult) { - boolean result = this.settings.cannotAcceptDueToAvailableTime( - reservationTimeSlot, - DayOfWeek.MONDAY); + boolean result = this.settings.cannotAcceptDueToAvailableTime(reservationTimeSlot); assertThat(result).isEqualTo(expectedResult); } @@ -88,135 +80,61 @@ void getUnavailableTimeSlots() { TimeSlot.of(LocalTime.of(20, 0), TimeSlot.MAX_TIME) ); - assertThat(settings.getUnavailableTimeSlots(DayOfWeek.MONDAY)).usingRecursiveComparison().isEqualTo(expectedResult); - } - - @Test - @DisplayName("겹쳐진 예약 조건들을 '동등한 우선순위를 가진 겹치지 않은 상태 (= flat 한 상태)' 로 변환한다") - void flatten() { - Settings settings = Settings.toPrioritizedSettings(List.of( - Setting.builder() - .settingTimeSlot(TimeSlot.of( - LocalTime.of(11, 0), - LocalTime.of(12, 0))) - .reservationTimeUnit(TimeUnit.from(10)) - .reservationMinimumTimeUnit(TimeUnit.from(10)) - .reservationMaximumTimeUnit(TimeUnit.from(30)) - .enabledDayOfWeek("monday,tuesday,wednesday") - .priorityOrder(0) - .build(), - Setting.builder() - .settingTimeSlot(TimeSlot.of( - LocalTime.of(10, 0), - LocalTime.of(13, 0))) - .reservationTimeUnit(TimeUnit.from(10)) - .reservationMinimumTimeUnit(TimeUnit.from(10)) - .reservationMaximumTimeUnit(TimeUnit.from(30)) - .enabledDayOfWeek("monday,tuesday,wednesday,thursday,friday,saturday,sunday") - .priorityOrder(1) - .build() - )); - - settings.flatten(); - - List expected = List.of( - Setting.builder() - .settingTimeSlot(TimeSlot.of( - LocalTime.of(10, 0), - LocalTime.of(11, 0))) - .reservationTimeUnit(TimeUnit.from(10)) - .reservationMinimumTimeUnit(TimeUnit.from(10)) - .reservationMaximumTimeUnit(TimeUnit.from(30)) - .enabledDayOfWeek("monday,tuesday,wednesday,thursday,friday,saturday,sunday") - .priorityOrder(FLAT_PRIORITY_ORDER) - .build(), - Setting.builder() - .settingTimeSlot(TimeSlot.of( - LocalTime.of(11, 0), - LocalTime.of(12, 0))) - .reservationTimeUnit(TimeUnit.from(10)) - .reservationMinimumTimeUnit(TimeUnit.from(10)) - .reservationMaximumTimeUnit(TimeUnit.from(30)) - .enabledDayOfWeek("monday,tuesday,wednesday") - .priorityOrder(FLAT_PRIORITY_ORDER) - .build(), - Setting.builder() - .settingTimeSlot(TimeSlot.of( - LocalTime.of(11, 0), - LocalTime.of(12, 0))) - .reservationTimeUnit(TimeUnit.from(10)) - .reservationMinimumTimeUnit(TimeUnit.from(10)) - .reservationMaximumTimeUnit(TimeUnit.from(30)) - .enabledDayOfWeek("thursday,friday,saturday,sunday") - .priorityOrder(FLAT_PRIORITY_ORDER) - .build(), - Setting.builder() - .settingTimeSlot(TimeSlot.of( - LocalTime.of(12, 0), - LocalTime.of(13, 0))) - .reservationTimeUnit(TimeUnit.from(10)) - .reservationMinimumTimeUnit(TimeUnit.from(10)) - .reservationMaximumTimeUnit(TimeUnit.from(30)) - .enabledDayOfWeek("monday,tuesday,wednesday,thursday,friday,saturday,sunday") - .priorityOrder(FLAT_PRIORITY_ORDER) - .build() - ); - - assertThat(settings.getSettings()).usingRecursiveComparison() - .ignoringCollectionOrder() - .ignoringExpectedNullFields() - .isEqualTo(expected); + assertThat(settings.getUnavailableTimeSlots()).usingRecursiveComparison().isEqualTo(expectedResult); } private static Stream provideArgumentsForGetSettingsByTimeSlotAndDayOfWeek() { return Stream.of( Arguments.of( TimeSlot.of(LocalTime.of(8, 0), LocalTime.of(10, 0)), - Settings.toFlattenedSettings(Collections.emptyList())), + new Settings(Collections.emptyList())), Arguments.of( TimeSlot.of(LocalTime.of(8, 0), LocalTime.of(11, 0)), - Settings.toFlattenedSettings(List.of( + new Settings(List.of( Setting.builder() - .id(FLAT_SETTING_ID) .settingTimeSlot(TimeSlot.of( LocalTime.of(10, 0), LocalTime.of(13, 0))) .reservationTimeUnit(BE_RESERVATION_TIME_UNIT) .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) - .enabledDayOfWeek(EnabledDayOfWeek.FRIDAY.name().toLowerCase(Locale.ROOT)) - .priorityOrder(FLAT_PRIORITY_ORDER) + .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) .build()))), Arguments.of( TimeSlot.of(LocalTime.of(13, 0), LocalTime.of(14, 0)), - Settings.toFlattenedSettings(Collections.emptyList())), + new Settings(Collections.emptyList())), Arguments.of( TimeSlot.of(LocalTime.of(13, 30), LocalTime.of(15, 0)), - Settings.toFlattenedSettings(List.of( + new Settings(List.of( Setting.builder() - .id(FLAT_SETTING_ID) .settingTimeSlot(TimeSlot.of( LocalTime.of(14, 0), LocalTime.of(16, 0))) .reservationTimeUnit(BE_RESERVATION_TIME_UNIT) .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) - .enabledDayOfWeek(EnabledDayOfWeek.FRIDAY.name().toLowerCase(Locale.ROOT)) - .priorityOrder(FLAT_PRIORITY_ORDER) + .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) .build()))), Arguments.of( TimeSlot.of(LocalTime.of(15, 0), LocalTime.of(23, 0)), - Settings.toFlattenedSettings(List.of( + new Settings(List.of( Setting.builder() - .id(FLAT_SETTING_ID) .settingTimeSlot(TimeSlot.of( LocalTime.of(14, 0), + LocalTime.of(16, 0))) + .reservationTimeUnit(BE_RESERVATION_TIME_UNIT) + .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) + .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) + .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) + .build(), + Setting.builder() + .settingTimeSlot(TimeSlot.of( + LocalTime.of(16, 0), LocalTime.of(20, 0))) .reservationTimeUnit(BE_RESERVATION_TIME_UNIT) .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) - .enabledDayOfWeek(EnabledDayOfWeek.FRIDAY.name().toLowerCase(Locale.ROOT)) - .priorityOrder(FLAT_PRIORITY_ORDER) + .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) .build())))); } diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/domain/SpaceTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/domain/SpaceTest.java index 301d1c1df..707b6ff06 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/domain/SpaceTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/domain/SpaceTest.java @@ -24,7 +24,6 @@ class SpaceTest { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); private static final Setting setting2 = Setting.builder() .settingTimeSlot(TimeSlot.of( @@ -34,7 +33,6 @@ class SpaceTest { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(1) .build(); @Test @@ -56,9 +54,8 @@ void update() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); - Settings settings = Settings.toPrioritizedSettings(Arrays.asList(setting)); + Settings settings = new Settings(Arrays.asList(setting)); Space space = Space.builder() .name("와우") .color("색깔입니다") @@ -76,9 +73,8 @@ void update() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); - Settings updateSettings = Settings.toPrioritizedSettings(Arrays.asList(setting)); + Settings updateSettings = new Settings(Arrays.asList(setting)); Space updateSpace = Space.builder() .name("우와") .color("색깔") @@ -114,9 +110,8 @@ void isUnableToReserve() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); - Settings settings = Settings.toPrioritizedSettings(Arrays.asList(reservationEnableSetting)); + Settings settings = new Settings(Arrays.asList(reservationEnableSetting)); Space reservationEnableSpace = Space.builder() .spaceSettings(settings) .reservationEnable(true) @@ -136,9 +131,8 @@ void isUnableToReserveFail() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); - Settings settings = Settings.toPrioritizedSettings(Arrays.asList(reservationUnableSetting)); + Settings settings = new Settings(Arrays.asList(reservationUnableSetting)); Space reservationUnableSpace = Space.builder() .spaceSettings(settings) .reservationEnable(false) @@ -154,7 +148,7 @@ void isNotBetweenAvailableTime(TimeSlot reservationTimeSlot, DayOfWeek dayofWeek // setting1: 10 ~ 14 // setting2: 15 ~ 18 Space space = Space.builder() - .spaceSettings(Settings.toPrioritizedSettings(Arrays.asList(setting1, setting2))) + .spaceSettings(new Settings(Arrays.asList(setting1, setting2))) .build(); Settings relevantSettings = space.getRelevantSettings(reservationTimeSlot, dayofWeek); @@ -174,13 +168,13 @@ private static Stream provideReservationInfo() { LocalTime.of(10, 0), LocalTime.of(12, 0)), DayOfWeek.MONDAY, - Settings.toFlattenedSettings(List.of(setting1)).getMergedSettings(EnabledDayOfWeek.MONDAY)), + new Settings(List.of(setting1))), Arguments.of( TimeSlot.of( LocalTime.of(12, 0), LocalTime.of(15, 0)), DayOfWeek.MONDAY, - Settings.toFlattenedSettings(List.of(setting1)).getMergedSettings(EnabledDayOfWeek.MONDAY)), + new Settings(List.of(setting1))), Arguments.of( TimeSlot.of( LocalTime.of(14, 0), @@ -192,6 +186,6 @@ private static Stream provideReservationInfo() { LocalTime.of(15, 0), LocalTime.of(19, 0)), DayOfWeek.MONDAY, - Settings.toFlattenedSettings(List.of(setting2)).getMergedSettings(EnabledDayOfWeek.MONDAY))); + new Settings(List.of(setting2)))); } } diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/domain/TimeSlotTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/domain/TimeSlotTest.java index bea805188..560725b21 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/domain/TimeSlotTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/domain/TimeSlotTest.java @@ -9,8 +9,6 @@ import org.junit.jupiter.params.provider.MethodSource; import java.time.LocalTime; -import java.util.Collections; -import java.util.List; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; @@ -79,25 +77,6 @@ void isNotWithin( assertThat(thisTimeSlot.isNotWithin(thatTimeSlot)).isEqualTo(expectedResult); } - @ParameterizedTest - @DisplayName("두 TimeSlot 이 주어질 떄, 겹치는 부분을 반환한다") - @MethodSource("provideOverlappingTimeSlot") - void extractOverlappingTimeSlot( - final TimeSlot thisTimeSlot, - final TimeSlot thatTimeSlot, - final TimeSlot expectedResult) { - assertThat(thisTimeSlot.extractOverlappingTimeSlot(thatTimeSlot)).isEqualTo(expectedResult); - } - - @ParameterizedTest - @DisplayName("두 TimeSlot 이 주어질 때, 메서드를 호출하는 TimeSlot 이 인자로 들어가는 TimeSlot 에 배타적인 (겹치지 않는) 부분을 반환한다") - @MethodSource("provideExclusiveTimeSlots") - void extractExclusiveTimeSlots(final TimeSlot thisTimeSlot, - final TimeSlot thatTimeSlot, - final List expectedResult) { - assertThat(thisTimeSlot.extractExclusiveTimeSlots(thatTimeSlot)).isEqualTo(expectedResult); - } - private static Stream provideStartAndEndTime_endTimeEqualOrShorterThanStartTime() { return Stream.of( Arguments.of(LocalTime.of(10, 0), LocalTime.of(9, 0)), @@ -170,61 +149,4 @@ private static Stream provideTimeSlotArguments_isNotWithin() { false) ); } - - private static Stream provideOverlappingTimeSlot() { - return Stream.of( - Arguments.of( - TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 5)), - TimeSlot.of(LocalTime.of(10, 5), LocalTime.of(10, 10)), - null), - Arguments.of( - TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 30)), - TimeSlot.of(LocalTime.of(10, 20), LocalTime.of(10, 40)), - TimeSlot.of(LocalTime.of(10, 20), LocalTime.of(10, 30))), - Arguments.of( - TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 30)), - TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(11, 0)), - TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 30))), - Arguments.of( - TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 0)), - TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 30)), - TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 0))), - Arguments.of( - TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 0)), - TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(11, 30)), - TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 0))) - ); - } - - private static Stream provideExclusiveTimeSlots() { - return Stream.of( - Arguments.of( - TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 5)), - TimeSlot.of(LocalTime.of(10, 5), LocalTime.of(10, 10)), - List.of(TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 5)))), - Arguments.of( - TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 30)), - TimeSlot.of(LocalTime.of(10, 20), LocalTime.of(10, 40)), - List.of(TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 20)))), - Arguments.of( - TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 30)), - TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(11, 0)), - Collections.emptyList()), - Arguments.of( - TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 0)), - TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 30)), - Collections.emptyList()), - Arguments.of( - TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 0)), - TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(11, 30)), - Collections.emptyList()), - Arguments.of( - TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(11, 30)), - TimeSlot.of(LocalTime.of(10, 30), LocalTime.of(11, 0)), - List.of( - TimeSlot.of(LocalTime.of(10, 0), LocalTime.of(10, 30)), - TimeSlot.of(LocalTime.of(11, 0), LocalTime.of(11, 30)) - )) - ); - } } \ No newline at end of file diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/domain/TimeUnitTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/domain/TimeUnitTest.java index 5fbac2d41..6ef96ed30 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/domain/TimeUnitTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/domain/TimeUnitTest.java @@ -4,14 +4,9 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.CsvSource; -import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; -import java.time.LocalTime; -import java.util.stream.Stream; - import static com.woowacourse.zzimkkong.domain.TimeUnit.MINIMUM_TIME_UNIT; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -65,82 +60,4 @@ void isShorterThan(final int minutes1, final int minutes2, final boolean expecte boolean actualResult = thisTimeUnit.isShorterThan(thatTimeUnit); assertThat(actualResult).isEqualTo(expectedResult); } - - @ParameterizedTest - @DisplayName("timeSlot duration 에 맞는 예약 시간 단위를 반환한다. divisible by minimum possible time unit (i.e. 5)") - @MethodSource("provideTimeSlots1") - void getAdjustedIntervalTimeUnit(TimeUnit initialTimeUnit, TimeSlot timeSlot, TimeUnit expected) { - TimeUnit actual = initialTimeUnit.getAdjustedIntervalTimeUnit(timeSlot); - assertThat(actual).isEqualTo(expected); - } - - @ParameterizedTest - @DisplayName("timeSlot duration 에 맞는 예약 (최소, 최대) 가능 시간을 반환한다. divisible by interval time unit & shorter than duration length") - @MethodSource("provideTimeSlots2") - void getAdjustedTimeUnit(TimeUnit initialTimeUnit, TimeUnit intervalTimeUnit, TimeSlot timeSlot, TimeUnit expected) { - TimeUnit actual = initialTimeUnit.getAdjustedTimeUnit(timeSlot, intervalTimeUnit); - assertThat(actual).isEqualTo(expected); - } - - private static Stream provideTimeSlots1() { - return Stream.of( - Arguments.of( - TimeUnit.from(60), - TimeSlot.of( - LocalTime.of(10, 0), - LocalTime.of(11, 30)), - TimeUnit.from(30) - ), - Arguments.of( - TimeUnit.from(60), - TimeSlot.of( - LocalTime.of(10, 0), - LocalTime.of(11, 0)), - TimeUnit.from(60) - ), - Arguments.of( - TimeUnit.from(60), - TimeSlot.of( - LocalTime.of(10, 0), - LocalTime.of(10, 20)), - TimeUnit.from(10) - ), - Arguments.of( - TimeUnit.from(60), - TimeSlot.of( - LocalTime.of(10, 0), - LocalTime.of(10, 30)), - TimeUnit.from(30) - ) - ); - } - - private static Stream provideTimeSlots2() { - return Stream.of( - Arguments.of( - TimeUnit.from(60), - TimeUnit.from(10), - TimeSlot.of( - LocalTime.of(10, 0), - LocalTime.of(11, 30)), - TimeUnit.from(60) - ), - Arguments.of( - TimeUnit.from(60), - TimeUnit.from(30), - TimeSlot.of( - LocalTime.of(10, 0), - LocalTime.of(10, 30)), - TimeUnit.from(30) - ), - Arguments.of( - TimeUnit.from(10), - TimeUnit.from(5), - TimeSlot.of( - LocalTime.of(10, 0), - LocalTime.of(10, 5)), - TimeUnit.from(5) - ) - ); - } -} +} \ No newline at end of file diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/dto/PresetCreateRequestTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/dto/PresetCreateRequestTest.java index 95e3972d3..460ebdfc7 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/dto/PresetCreateRequestTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/dto/PresetCreateRequestTest.java @@ -19,8 +19,7 @@ class PresetCreateRequestTest extends RequestTest { BE_RESERVATION_TIME_UNIT.getMinutes(), BE_RESERVATION_MINIMUM_TIME_UNIT.getMinutes(), BE_RESERVATION_MAXIMUM_TIME_UNIT.getMinutes(), - EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK), - 0 + EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK) ); @ParameterizedTest diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/dto/RequestTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/dto/RequestTest.java index 5df20077d..efb5381e6 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/dto/RequestTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/dto/RequestTest.java @@ -20,8 +20,7 @@ class RequestTest { BE_RESERVATION_TIME_UNIT.getMinutes(), BE_RESERVATION_MINIMUM_TIME_UNIT.getMinutes(), BE_RESERVATION_MAXIMUM_TIME_UNIT.getMinutes(), - EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK), - 0 + EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK) ); @BeforeAll diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/dto/SettingRequestTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/dto/SettingRequestTest.java index 1791d3ffa..430383cae 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/dto/SettingRequestTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/dto/SettingRequestTest.java @@ -23,8 +23,7 @@ void invalidTimeUnit(int timeUnit) { timeUnit, 60, 120, - EnabledDayOfWeekDto.from("Monday, Tuesday"), - 0 + EnabledDayOfWeekDto.from("Monday, Tuesday") ); assertThat(getConstraintViolations(settingRequest).stream() @@ -43,8 +42,7 @@ void validTimeUnit(Integer timeUnit) { timeUnit, 60, 120, - EnabledDayOfWeekDto.from("Monday, Tuesday"), - 0 + EnabledDayOfWeekDto.from("Monday, Tuesday") ); assertThat(getConstraintViolations(settingRequest).stream() diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/repository/MapRepositoryTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/repository/MapRepositoryTest.java index e66c17beb..e9e8ddb5d 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/repository/MapRepositoryTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/repository/MapRepositoryTest.java @@ -104,7 +104,6 @@ void findByIdFetchJoinSpace() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); Space be = Space.builder() @@ -112,7 +111,7 @@ void findByIdFetchJoinSpace() { .color(BE_COLOR) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) + .spaceSettings(new Settings(List.of(beSetting))) .map(luther) .build(); @@ -124,7 +123,6 @@ void findByIdFetchJoinSpace() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); Space fe = Space.builder() @@ -133,7 +131,7 @@ void findByIdFetchJoinSpace() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) + .spaceSettings(new Settings(List.of(feSetting))) .build(); spaces.save(be); diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/repository/ReservationRepositoryImplTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/repository/ReservationRepositoryImplTest.java index 032f64851..d2b48d7da 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/repository/ReservationRepositoryImplTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/repository/ReservationRepositoryImplTest.java @@ -38,7 +38,6 @@ void existsReservationsByMember(boolean isReservationExists) { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); Space be = Space.builder() @@ -46,7 +45,7 @@ void existsReservationsByMember(boolean isReservationExists) { .color(BE_COLOR) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) + .spaceSettings(new Settings(List.of(beSetting))) .map(luther) .build(); diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/repository/ReservationRepositoryTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/repository/ReservationRepositoryTest.java index 3eaf14862..655cbf72e 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/repository/ReservationRepositoryTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/repository/ReservationRepositoryTest.java @@ -52,7 +52,6 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); be = Space.builder() @@ -61,7 +60,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) + .spaceSettings(new Settings(List.of(beSetting))) .build(); Setting feSetting = Setting.builder() @@ -72,7 +71,6 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); fe = Space.builder() @@ -81,7 +79,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) + .spaceSettings(new Settings(List.of(feSetting))) .build(); members.save(pobi); diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/repository/SpaceRepositoryTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/repository/SpaceRepositoryTest.java index 42eb67441..4beff107d 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/repository/SpaceRepositoryTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/repository/SpaceRepositoryTest.java @@ -38,7 +38,6 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); be = Space.builder() @@ -46,7 +45,7 @@ void setUp() { .color(BE_COLOR) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) + .spaceSettings(new Settings(List.of(beSetting))) .map(luther) .build(); @@ -58,7 +57,6 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); fe = Space.builder() @@ -67,7 +65,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) + .spaceSettings(new Settings(List.of(feSetting))) .build(); members.save(pobi); diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/service/AdminServiceTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/service/AdminServiceTest.java index 3d5867269..c1d23e4a0 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/service/AdminServiceTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/service/AdminServiceTest.java @@ -123,7 +123,6 @@ void findSpaces() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); Space be = Space.builder() @@ -132,7 +131,7 @@ void findSpaces() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) + .spaceSettings(new Settings(List.of(beSetting))) .build(); PageRequest pageRequest = PageRequest.of(0, 20, Sort.unsorted()); @@ -165,7 +164,6 @@ void findReservations() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); Space be = Space.builder() @@ -174,7 +172,7 @@ void findReservations() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) + .spaceSettings(new Settings(List.of(beSetting))) .build(); Reservation beAmZeroOne = Reservation.builder() diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/service/GuestReservationServiceTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/service/GuestReservationServiceTest.java index 9de5dd739..8c049963d 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/service/GuestReservationServiceTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/service/GuestReservationServiceTest.java @@ -79,7 +79,6 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); be = Space.builder() @@ -88,7 +87,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) + .spaceSettings(new Settings(List.of(beSetting))) .build(); Setting feSetting = Setting.builder() @@ -99,7 +98,6 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); fe = Space.builder() @@ -109,7 +107,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) + .spaceSettings(new Settings(List.of(feSetting))) .build(); beAmZeroOne = Reservation.builder() @@ -345,7 +343,6 @@ void saveReservationUnable() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); Space closedSpace = Space.builder() @@ -355,7 +352,7 @@ void saveReservationUnable() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(false) - .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) + .spaceSettings(new Settings(List.of(setting))) .build(); given(maps.findByIdFetch(anyLong())) @@ -385,7 +382,6 @@ void saveIllegalDayOfWeek() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek(THE_DAY_AFTER_TOMORROW.plusDays(1L).getDayOfWeek().name()) - .priorityOrder(0) .build(); Space invalidDayOfWeekSpace = Space.builder() @@ -395,7 +391,7 @@ void saveIllegalDayOfWeek() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(true) - .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) + .spaceSettings(new Settings(List.of(setting))) .build(); given(maps.findByIdFetch(anyLong())) @@ -501,7 +497,6 @@ void saveUpdateReservationMultipleSettings(int startHour, int endHour) { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(60)) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(1) .build()); given(maps.findByIdFetch(anyLong())) .willReturn(Optional.of(luther)); @@ -1168,7 +1163,6 @@ void updateReservationUnable() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); Space closedSpace = Space.builder() @@ -1178,7 +1172,7 @@ void updateReservationUnable() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(false) - .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) + .spaceSettings(new Settings(List.of(setting))) .build(); given(maps.findByIdFetch(anyLong())) @@ -1213,7 +1207,6 @@ void updateIllegalDayOfWeek() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek(THE_DAY_AFTER_TOMORROW.plusDays(1L).getDayOfWeek().name()) - .priorityOrder(0) .build(); Space invalidDayOfWeekSpace = Space.builder() @@ -1223,7 +1216,7 @@ void updateIllegalDayOfWeek() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(true) - .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) + .spaceSettings(new Settings(List.of(setting))) .build(); given(maps.findByIdFetch(anyLong())) diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/service/ManagerReservationServiceTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/service/ManagerReservationServiceTest.java index 65d20031b..432abf567 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/service/ManagerReservationServiceTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/service/ManagerReservationServiceTest.java @@ -95,7 +95,6 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); be = Space.builder() @@ -104,7 +103,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) + .spaceSettings(new Settings(List.of(beSetting))) .build(); Setting feSetting = Setting.builder() @@ -115,7 +114,6 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); fe = Space.builder() @@ -125,7 +123,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) + .spaceSettings(new Settings(List.of(feSetting))) .build(); beAmZeroOne = Reservation.builder() @@ -410,7 +408,6 @@ void saveReservationUnable() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); Space closedSpace = Space.builder() @@ -420,7 +417,7 @@ void saveReservationUnable() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(false) - .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) + .spaceSettings(new Settings(List.of(setting))) .build(); given(maps.findByIdFetch(anyLong())) @@ -452,7 +449,6 @@ void saveIllegalDayOfWeek() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek(THE_DAY_AFTER_TOMORROW.plusDays(1L).getDayOfWeek().name()) - .priorityOrder(0) .build(); Space invalidDayOfWeekSpace = Space.builder() @@ -462,7 +458,7 @@ void saveIllegalDayOfWeek() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(true) - .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) + .spaceSettings(new Settings(List.of(setting))) .build(); given(maps.findByIdFetch(anyLong())) @@ -572,7 +568,6 @@ void saveUpdateReservationMultipleSettings(int startHour, int endHour) { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(60)) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(1) .build()); given(maps.findByIdFetch(anyLong())) .willReturn(Optional.of(luther)); @@ -1366,7 +1361,6 @@ void updateReservationUnable() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); Space closedSpace = Space.builder() @@ -1376,7 +1370,7 @@ void updateReservationUnable() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(false) - .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) + .spaceSettings(new Settings(List.of(setting))) .build(); @@ -1413,7 +1407,6 @@ void updateIllegalDayOfWeek() { .reservationMinimumTimeUnit(TimeUnit.from(10)) .reservationMaximumTimeUnit(TimeUnit.from(120)) .enabledDayOfWeek(THE_DAY_AFTER_TOMORROW.plusDays(1L).getDayOfWeek().name()) - .priorityOrder(0) .build(); Space invalidDayOfWeekSpace = Space.builder() @@ -1423,7 +1416,7 @@ void updateIllegalDayOfWeek() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(true) - .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) + .spaceSettings(new Settings(List.of(setting))) .build(); diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/service/MapServiceTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/service/MapServiceTest.java index feb7abf7b..bc4987e3c 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/service/MapServiceTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/service/MapServiceTest.java @@ -62,7 +62,6 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); Space be = Space.builder() @@ -71,7 +70,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) + .spaceSettings(new Settings(List.of(beSetting))) .build(); Setting feSetting = Setting.builder() @@ -82,7 +81,6 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); Space fe = Space.builder() @@ -92,7 +90,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) + .spaceSettings(new Settings(List.of(feSetting))) .build(); } diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/service/PresetServiceTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/service/PresetServiceTest.java index effd8ecee..a77320142 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/service/PresetServiceTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/service/PresetServiceTest.java @@ -39,8 +39,7 @@ class PresetServiceTest extends ServiceTest { BE_RESERVATION_TIME_UNIT.getMinutes(), BE_RESERVATION_MINIMUM_TIME_UNIT.getMinutes(), BE_RESERVATION_MAXIMUM_TIME_UNIT.getMinutes(), - EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK), - 0 + EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK) ); private final Setting setting = Setting.builder() @@ -51,7 +50,6 @@ class PresetServiceTest extends ServiceTest { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); private Member pobi; diff --git a/backend/src/test/java/com/woowacourse/zzimkkong/service/SpaceServiceTest.java b/backend/src/test/java/com/woowacourse/zzimkkong/service/SpaceServiceTest.java index 987e41e21..ba5cfe405 100644 --- a/backend/src/test/java/com/woowacourse/zzimkkong/service/SpaceServiceTest.java +++ b/backend/src/test/java/com/woowacourse/zzimkkong/service/SpaceServiceTest.java @@ -38,8 +38,7 @@ class SpaceServiceTest extends ServiceTest { BE_RESERVATION_TIME_UNIT.getMinutes(), BE_RESERVATION_MINIMUM_TIME_UNIT.getMinutes(), BE_RESERVATION_MAXIMUM_TIME_UNIT.getMinutes(), - EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK), - 0 + EnabledDayOfWeekDto.from(BE_ENABLED_DAY_OF_WEEK) ); private final SpaceCreateUpdateRequest spaceCreateUpdateRequest = new SpaceCreateUpdateRequest( @@ -101,7 +100,6 @@ void setUp() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); be = Space.builder() @@ -110,7 +108,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(beSetting))) + .spaceSettings(new Settings(List.of(beSetting))) .build(); Setting feSetting = Setting.builder() @@ -121,7 +119,6 @@ void setUp() { .reservationMinimumTimeUnit(FE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(FE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(FE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); fe = Space.builder() @@ -131,7 +128,7 @@ void setUp() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(FE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(feSetting))) + .spaceSettings(new Settings(List.of(feSetting))) .build(); lutherId = luther.getId(); @@ -152,7 +149,6 @@ void save() { .reservationMinimumTimeUnit(BE_RESERVATION_MINIMUM_TIME_UNIT) .reservationMaximumTimeUnit(BE_RESERVATION_MAXIMUM_TIME_UNIT) .enabledDayOfWeek(BE_ENABLED_DAY_OF_WEEK) - .priorityOrder(0) .build(); Space newSpace = Space.builder() @@ -161,7 +157,7 @@ void save() { .map(luther) .area(SPACE_DRAWING) .reservationEnable(BE_RESERVATION_ENABLE) - .spaceSettings(Settings.toPrioritizedSettings(List.of(setting))) + .spaceSettings(new Settings(List.of(setting))) .build(); given(maps.findById(anyLong())) From 75652b61497aa7d93fde17e62a2fab716b1ba9ca Mon Sep 17 00:00:00 2001 From: Jungseok Sung Date: Mon, 1 Apr 2024 18:00:57 +0900 Subject: [PATCH 5/7] =?UTF-8?q?fix:=20Connection=20Prematurely=20Closed=20?= =?UTF-8?q?issue=20=EB=8C=80=EC=9D=91=20=EC=9E=91=EC=97=85=20(#987)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit slack 서버의 네트워크 관련 구성, 설정등을 알 수 없음. 따라서, Reactor Netty Docs(https://projectreactor.io/docs/netty/1.0.21/reference/index.html\#faq.connection-closed) 의 내용을 토대로 추정하여 대응한다. --- .../zzimkkong/service/SlackService.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/backend/src/main/java/com/woowacourse/zzimkkong/service/SlackService.java b/backend/src/main/java/com/woowacourse/zzimkkong/service/SlackService.java index 8f3d23c52..5fe5e410c 100644 --- a/backend/src/main/java/com/woowacourse/zzimkkong/service/SlackService.java +++ b/backend/src/main/java/com/woowacourse/zzimkkong/service/SlackService.java @@ -4,10 +4,14 @@ import com.woowacourse.zzimkkong.dto.slack.SlackResponse; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.MediaType; +import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.reactive.function.client.WebClient; +import reactor.netty.http.client.HttpClient; +import reactor.netty.resources.ConnectionProvider; +import java.time.Duration; import java.util.Objects; @Service @@ -19,7 +23,14 @@ public class SlackService { public SlackService(@Value("${service.url}") final String titleLink, final WebClient webClient) { this.titleLink = titleLink; - slackWebClient = webClient; + ConnectionProvider provider = ConnectionProvider.builder("slack-pool") + .maxConnections(10) + .maxIdleTime(Duration.ofSeconds(2L)) + .maxLifeTime(Duration.ofSeconds(2L)) + .lifo() + .build(); + HttpClient httpClient = HttpClient.create(provider); + slackWebClient = webClient.mutate().clientConnector(new ReactorClientHttpConnector(httpClient)).build(); } public void sendCreateMessage(SlackResponse slackResponse) { @@ -39,10 +50,8 @@ public void sendDeleteMessage(SlackResponse slackResponse) { private void send(final Attachments attachments, final String slackUrl) { if (!Objects.isNull(slackUrl)) { - slackWebClient.mutate() - .baseUrl(slackUrl) - .build() - .post() + slackWebClient.post() + .uri(slackUrl) .contentType(MediaType.APPLICATION_JSON) .bodyValue(attachments.toString()) .retrieve() From 1668e9068fd4dd459a2eb295c328ad14afcd81f9 Mon Sep 17 00:00:00 2001 From: 2yunseong <56749516+2yunseong@users.noreply.github.com> Date: Tue, 2 Apr 2024 10:19:21 +0900 Subject: [PATCH 6/7] =?UTF-8?q?feat:=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=A7=84=EC=9E=85=EC=A0=90=20=EB=A7=8C?= =?UTF-8?q?=EB=93=A4=EA=B8=B0=20(#968)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 홈페이지에서 마이페이지 진입점 추가 * feat: 주소에 따라 예약자 관련 페이지일 경우 예약자 마이페이지로 분기 --- frontend/src/components/Header/Header.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/Header/Header.tsx b/frontend/src/components/Header/Header.tsx index a6419825d..54bfc05be 100644 --- a/frontend/src/components/Header/Header.tsx +++ b/frontend/src/components/Header/Header.tsx @@ -57,9 +57,16 @@ const Header = ({ onClickLogin }: HeaderProps): JSX.Element => { {accessToken ? ( - - 로그아웃 - + <> + + 마이 페이지 + + + 로그아웃 + + ) : ( <> From 20e8560e252d9f012e1a4314522ac99341e5cfae Mon Sep 17 00:00:00 2001 From: Jungseok Sung Date: Tue, 2 Apr 2024 21:22:43 +0900 Subject: [PATCH 7/7] chore: to v2.1.2 (#990) --- frontend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/package.json b/frontend/package.json index f5da540e3..6282bb7af 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "zzimkkong-frontend", - "version": "2.1.1", + "version": "2.1.2", "main": "src/index.tsx", "license": "MIT", "homepage": "https://github.com/woowacourse-teams/2021-zzimkkong",