Skip to content

Commit

Permalink
Merge pull request #102 from Cafegory/feature-101
Browse files Browse the repository at this point in the history
[BUILD SUCCESS] Feature 101
  • Loading branch information
donghyun0304 authored May 14, 2024
2 parents 326f419 + d89dea5 commit 8460ab8
Show file tree
Hide file tree
Showing 14 changed files with 389 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static com.example.demo.exception.ExceptionType.*;

import java.time.LocalDate;
import java.time.LocalDateTime;

import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -84,7 +85,8 @@ public ResponseEntity<StudyOnceCreateResponse> create(
@RequestBody @Validated StudyOnceCreateRequest studyOnceCreateRequest,
@RequestHeader("Authorization") String authorization) {
long memberId = cafegoryTokenManager.getIdentityId(authorization);
StudyOnceCreateResponse response = studyOnceService.createStudy(memberId, studyOnceCreateRequest);
StudyOnceCreateResponse response = studyOnceService.createStudy(memberId, studyOnceCreateRequest,
LocalDate.now());
return ResponseEntity.ok(response);
}

Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/example/demo/domain/cafe/BusinessHour.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,8 @@ public boolean existsMatchingDayOfWeek(LocalDateTime now) {
return false;
}
}

public boolean matchesDayOfWeek(DayOfWeek dayOfWeek) {
return day.equals(dayOfWeek.toString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ public boolean checkWithBusinessHours(List<BusinessHour> businessHours, LocalDat
hour -> checkByNowTime(DayOfWeek.valueOf(hour.getDay()), hour.getStartTime(), hour.getEndTime(), now));
}

public boolean checkBetweenHours(LocalTime businessStartTime, LocalTime businessEndTime,
public boolean checkBetweenBusinessHours(LocalTime businessStartTime, LocalTime businessEndTime,
LocalTime chosenStartTime, LocalTime chosenEndTime) {
if ((chosenStartTime.equals(businessStartTime) || chosenStartTime.isBefore(businessStartTime))
&& (chosenEndTime.equals(businessEndTime) || chosenEndTime.isAfter(businessEndTime))) {
if ((businessStartTime.equals(chosenStartTime) || businessStartTime.isBefore(chosenStartTime))
&& (businessEndTime.equals(chosenEndTime) || businessEndTime.isAfter(chosenEndTime))) {
return true;
}
return false;
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/com/example/demo/domain/cafe/Cafe.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.example.demo.domain.cafe;

import static com.example.demo.exception.ExceptionType.*;

import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -17,6 +20,7 @@

import com.example.demo.domain.review.Review;
import com.example.demo.domain.study.StudyOnce;
import com.example.demo.exception.CafegoryException;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
Expand Down Expand Up @@ -87,4 +91,11 @@ public OptionalDouble calcAverageRating() {
.mapToDouble(Review::getRate)
.average();
}

public BusinessHour findBusinessHour(DayOfWeek dayOfWeek) {
return businessHours.stream()
.filter(businessHour -> businessHour.matchesDayOfWeek(dayOfWeek))
.findFirst()
.orElseThrow(() -> new CafegoryException(CAFE_NOT_FOUND_DAY_OF_WEEK));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public enum ExceptionType {
JWT_DESTROYED(UNAUTHORIZED, "JWT 토큰이 잘못되었습니다."),
TOKEN_NOT_FOUND(UNAUTHORIZED, "토큰이 없습니다."),
TOKEN_REFRESH_REJECT(UNAUTHORIZED, "토큰을 재발행할 수 없습니다."),
STUDY_ONCE_CREATE_BETWEEN_CAFE_BUSINESS_HOURS(BAD_REQUEST, "카공 생성시 시작시간과 종료시간은 카페 영업시간내에 포함되어야 합니다."),
STUDY_ONCE_WRONG_START_TIME(BAD_REQUEST, "카공 시작 시간은 현재 시간보다 최소 3시간 이후여야 합니다."),
STUDY_ONCE_SHORT_DURATION(BAD_REQUEST, "카공 시간은 1시간 이상이어야 합니다."),
STUDY_ONCE_LONG_DURATION(BAD_REQUEST, "카공 시간은 5시간 미만이어야 합니다."),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.demo.service.study;

import java.time.LocalDate;
import java.time.LocalDateTime;

import com.example.demo.domain.study.Attendance;
Expand Down Expand Up @@ -31,7 +32,8 @@ UpdateAttendanceResponse updateAttendances(long leaderId, long studyOnceId,

void updateAttendance(long leaderId, long studyOnceId, long memberId, Attendance attendance, LocalDateTime now);

StudyOnceCreateResponse createStudy(long leaderId, StudyOnceCreateRequest studyOnceCreateRequest);
StudyOnceCreateResponse createStudy(long leaderId, StudyOnceCreateRequest studyOnceCreateRequest,
LocalDate nowDate);

Long changeCafe(Long requestMemberId, Long studyOnceId, Long changingCafeId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
import static com.example.demo.exception.ExceptionType.*;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.example.demo.domain.cafe.BusinessHour;
import com.example.demo.domain.cafe.BusinessHourOpenChecker;
import com.example.demo.domain.cafe.Cafe;
import com.example.demo.domain.member.Member;
import com.example.demo.domain.study.Attendance;
Expand Down Expand Up @@ -51,6 +55,7 @@ public class StudyOnceServiceImpl implements StudyOnceService {
private final StudyMemberRepository studyMemberRepository;
private final StudyOnceMapper studyOnceMapper;
private final StudyMemberMapper studyMemberMapper;
private final BusinessHourOpenChecker openChecker = new BusinessHourOpenChecker();

@Override
public void tryJoin(long memberIdThatExpectedToJoin, long studyId) {
Expand Down Expand Up @@ -190,16 +195,24 @@ private StudyOnce findStudyOnceById(long studyOnceId) {
}

@Override
public StudyOnceCreateResponse createStudy(long leaderId, StudyOnceCreateRequest studyOnceCreateRequest) {
Cafe cafe = cafeRepository.findById(studyOnceCreateRequest.getCafeId())
.orElseThrow(() -> new CafegoryException(CAFE_NOT_FOUND));
//ToDo 카페 영업시간 이내인지 확인 하는 작업 추가 필요
LocalDateTime startDateTime = studyOnceCreateRequest.getStartDateTime();
Member leader = getMember(leaderId, startDateTime);
StudyOnce studyOnce = studyOnceMapper.toNewEntity(studyOnceCreateRequest, cafe, leader);
public StudyOnceCreateResponse createStudy(long leaderId, StudyOnceCreateRequest request, LocalDate nowDate) {
Cafe cafe = findCafeById(request.getCafeId());
BusinessHour businessHour = cafe.findBusinessHour(nowDate.getDayOfWeek());
validateBetweenBusinessHour(request.getStartDateTime().toLocalTime(), request.getEndDateTime().toLocalTime(),
businessHour);
Member leader = getMember(leaderId, request.getStartDateTime());
StudyOnce studyOnce = studyOnceMapper.toNewEntity(request, cafe, leader);
StudyOnce saved = studyOnceRepository.save(studyOnce);
boolean canJoin = true;
return studyOnceMapper.toStudyOnceCreateResponse(saved, canJoin);
return studyOnceMapper.toStudyOnceCreateResponse(saved, true);
}

private void validateBetweenBusinessHour(LocalTime studyOnceStartTime, LocalTime studyOnceEndTime,
BusinessHour businessHour) {
boolean isBetweenBusinessHour = openChecker.checkBetweenBusinessHours(businessHour.getStartTime(),
businessHour.getEndTime(), studyOnceStartTime, studyOnceEndTime);
if (!isBetweenBusinessHour) {
throw new CafegoryException(STUDY_ONCE_CREATE_BETWEEN_CAFE_BUSINESS_HOURS);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.example.demo.builder;

import java.time.LocalTime;

import com.example.demo.domain.cafe.BusinessHour;
import com.example.demo.domain.cafe.Cafe;

public class TestBusinessHourBuilder {

private Long id;
private String day;
private LocalTime startTime = LocalTime.MIN;
private LocalTime endTime = LocalTime.MAX;
private Cafe cafe;

public TestBusinessHourBuilder id(Long id) {
this.id = id;
return this;
}

public TestBusinessHourBuilder day(String day) {
this.day = day;
return this;
}

public TestBusinessHourBuilder startTime(LocalTime startTime) {
this.startTime = startTime;
return this;
}

public TestBusinessHourBuilder endTime(LocalTime endTime) {
this.endTime = endTime;
return this;
}

public TestBusinessHourBuilder cafe(Cafe cafe) {
this.cafe = cafe;
return this;
}

public BusinessHour build() {
return BusinessHour.builder()
.id(id)
.day(day)
.startTime(startTime)
.endTime(endTime)
.cafe(cafe)
.build();
}
}
12 changes: 12 additions & 0 deletions src/test/java/com/example/demo/builder/TestCafeBuilder.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.example.demo.builder;

import java.util.ArrayList;
import java.util.List;

import com.example.demo.domain.cafe.Address;
import com.example.demo.domain.cafe.BusinessHour;
import com.example.demo.domain.cafe.Cafe;
import com.example.demo.domain.cafe.MaxAllowableStay;

Expand All @@ -15,6 +19,8 @@ public class TestCafeBuilder {
private boolean isAbleToStudy = true;
private int minBeveragePrice = 3_000;

private List<BusinessHour> businessHours = new ArrayList<>();

public TestCafeBuilder id(Long id) {
this.id = id;
return this;
Expand Down Expand Up @@ -55,6 +61,11 @@ public TestCafeBuilder minBeveragePrice(int minBeveragePrice) {
return this;
}

public TestCafeBuilder businessHours(List<BusinessHour> businessHours) {
this.businessHours = businessHours;
return this;
}

public Cafe build() {
return Cafe.builder()
.id(id)
Expand All @@ -65,6 +76,7 @@ public Cafe build() {
.avgReviewRate(avgReviewRate)
.isAbleToStudy(isAbleToStudy)
.minBeveragePrice(minBeveragePrice)
.businessHours(businessHours)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -285,15 +285,15 @@ void checkDayOfWeekWithBusinessHours() {

@ParameterizedTest
@MethodSource("provideChosenTimeAndExpected")
@DisplayName("선택된 시간사이에 영업시간이 포함한다.")
void when_check_businessHours_between_chosen_hours_then_contains(LocalTime chosenStartTime, LocalTime chosenEndTime,
@DisplayName("영업시간 시간사이에 선택된 시간이 포함한다.")
void when_check_chosen_hours_between_businessHours_then_contains(LocalTime chosenStartTime, LocalTime chosenEndTime,
boolean expected) {
//given
LocalTime businessStartTime = LocalTime.of(9, 0);
LocalTime businessEndTime = LocalTime.of(21, 0);

//when
boolean isBetween = openChecker.checkBetweenHours(businessStartTime, businessEndTime,
boolean isBetween = openChecker.checkBetweenBusinessHours(businessStartTime, businessEndTime,
chosenStartTime, chosenEndTime);
//then
assertThat(isBetween).isEqualTo(expected);
Expand All @@ -304,46 +304,41 @@ private static Stream<Arguments> provideChosenTimeAndExpected() {
// LocalTime chosenStartTime
// LocalTime chosenEndTime,
// boolean expected
Arguments.of(
LocalTime.of(8, 0),
LocalTime.of(22, 0),
true
),
Arguments.of(
LocalTime.of(9, 0),
LocalTime.of(21, 0),
true
),
Arguments.of(
LocalTime.of(8, 59, 59),
LocalTime.of(9, 0, 0, 1),
LocalTime.of(21, 0),
true
),
Arguments.of(
LocalTime.of(8, 59, 59),
LocalTime.of(21, 0, 1),
LocalTime.of(9, 0),
LocalTime.of(20, 59, 59, 999_999_999),
true
),
Arguments.of(
LocalTime.of(0, 0, 0),
LocalTime.of(23, 59, 59, 999_999_999),
LocalTime.of(9, 0, 0, 1),
LocalTime.of(20, 59, 59, 999_999_999),
true
)
);
}

@ParameterizedTest
@MethodSource("provideChosenTimeAndExpected2")
@DisplayName("선택된 시간사이에 영업시간이 포함되지 않는다.")
void when_check_businessHours_between_chosen_hours_then_not_contains(LocalTime chosenStartTime,
@DisplayName("영업시간 사이에 선택된 시간이 포함되지 않는다.")
void when_check_chosen_hours_between_businessHours_then_not_contains(LocalTime chosenStartTime,
LocalTime chosenEndTime,
boolean expected) {
//given
LocalTime businessStartTime = LocalTime.of(9, 0);
LocalTime businessEndTime = LocalTime.of(21, 0);

//when
boolean isBetween = openChecker.checkBetweenHours(businessStartTime, businessEndTime,
boolean isBetween = openChecker.checkBetweenBusinessHours(businessStartTime, businessEndTime,
chosenStartTime, chosenEndTime);
//then
assertThat(isBetween).isEqualTo(expected);
Expand All @@ -355,18 +350,18 @@ private static Stream<Arguments> provideChosenTimeAndExpected2() {
// LocalTime chosenEndTime,
// boolean expected
Arguments.of(
LocalTime.of(9, 0),
LocalTime.of(20, 59, 59),
LocalTime.of(8, 59, 59, 999_999_999),
LocalTime.of(21, 0),
false
),
Arguments.of(
LocalTime.of(9, 0, 1),
LocalTime.of(21, 0),
LocalTime.of(9, 0, 0),
LocalTime.of(21, 0, 0, 1),
false
),
Arguments.of(
LocalTime.of(8, 59, 59),
LocalTime.of(20, 59, 59),
LocalTime.of(8, 59, 59, 999_999_999),
LocalTime.of(21, 0, 0, 1),
false
)
);
Expand All @@ -382,7 +377,7 @@ void when_businessHour_is_0_to_24() {
//when
LocalTime chosenStartTime1 = LocalTime.of(0, 0);
LocalTime chosenEndTime = LocalTime.MAX;
boolean isBetween = openChecker.checkBetweenHours(businessStartTime, businessEndTime,
boolean isBetween = openChecker.checkBetweenBusinessHours(businessStartTime, businessEndTime,
chosenStartTime1, chosenEndTime);
//then
assertThat(isBetween).isTrue();
Expand All @@ -399,7 +394,7 @@ void when_businessHour_is_22_to_2(LocalTime chosenStartTime, LocalTime chosenEnd
LocalTime businessEndTime = LocalTime.of(2, 0);

//when
boolean isBetween = openChecker.checkBetweenHours(businessStartTime, businessEndTime,
boolean isBetween = openChecker.checkBetweenBusinessHours(businessStartTime, businessEndTime,
chosenStartTime, chosenEndTime);
//then
assertThat(isBetween).isEqualTo(expected);
Expand All @@ -416,24 +411,24 @@ private static Stream<Arguments> provideChosenTimeAndExpected3() {
true
),
Arguments.of(
LocalTime.of(21, 0),
LocalTime.of(22, 0, 0, 1),
LocalTime.of(2, 0),
true
),
Arguments.of(
LocalTime.of(22, 0, 1),
LocalTime.of(21, 59, 59, 999_999_999),
LocalTime.of(2, 0),
false
),
Arguments.of(
LocalTime.of(22, 0, 0),
LocalTime.of(1, 59, 59),
LocalTime.of(2, 0, 0, 1),
false
),
Arguments.of(
LocalTime.of(0, 0),
LocalTime.MAX,
true
false
)
);
}
Expand Down
Loading

0 comments on commit 8460ab8

Please sign in to comment.