Skip to content

Commit

Permalink
FU-346 feat: 날짜별 스케줄의 비즈니스 로직 검증 용 테스트코드 작성
Browse files Browse the repository at this point in the history
  • Loading branch information
rheeri committed Dec 20, 2024
1 parent 5a9d6a1 commit e4b0e6c
Show file tree
Hide file tree
Showing 2 changed files with 195 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.foru.freebe.schedule.entity.ScheduleStatus;

import jakarta.validation.constraints.NotNull;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

Expand All @@ -23,4 +24,12 @@ public class DailyScheduleRequest {

@NotNull(message = "End time must not be null")
private LocalTime endTime;

@Builder
public DailyScheduleRequest(ScheduleStatus scheduleStatus, LocalDate date, LocalTime startTime, LocalTime endTime) {
this.scheduleStatus = scheduleStatus;
this.date = date;
this.startTime = startTime;
this.endTime = endTime;
}
}
186 changes: 186 additions & 0 deletions src/test/java/com/foru/freebe/schedule/DailyScheduleServiceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
package com.foru.freebe.schedule;

import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.BDDMockito.*;

import java.time.Clock;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import com.foru.freebe.errors.errorcode.ScheduleErrorCode;
import com.foru.freebe.errors.exception.RestApiException;
import com.foru.freebe.member.entity.Member;
import com.foru.freebe.member.entity.Role;
import com.foru.freebe.schedule.dto.DailyScheduleAddResponse;
import com.foru.freebe.schedule.dto.DailyScheduleRequest;
import com.foru.freebe.schedule.dto.DailyScheduleResponse;
import com.foru.freebe.schedule.entity.DailySchedule;
import com.foru.freebe.schedule.entity.ScheduleStatus;
import com.foru.freebe.schedule.repository.DailyScheduleRepository;
import com.foru.freebe.schedule.service.DailyScheduleService;

@ExtendWith(MockitoExtension.class)
public class DailyScheduleServiceTest {
@Mock
private DailyScheduleRepository dailyScheduleRepository;

@Mock
private Clock clock;

@InjectMocks
private DailyScheduleService dailyScheduleService;

private Member photographer;
private LocalDateTime now;

@BeforeEach
void setUp() {
Instant fixedInstant = Instant.parse("2024-12-05T10:00:00Z");
ZoneId zoneId = ZoneId.systemDefault();

given(clock.instant()).willReturn(fixedInstant);
given(clock.getZone()).willReturn(zoneId);

now = LocalDateTime.now(clock);
photographer = Member.builder(1L, Role.PHOTOGRAPHER, "tester", "test@email", "010-0000-0000").build();
}

@Nested
@DisplayName("날짜별 스케줄 조회 테스트")
class FindDailySchedule {
@Test
@DisplayName("날짜별 스케줄 조회 시 현시점 이후의 데이터만 불러온다")
void shouldFetchSchedulesAfterCurrentDate() {
// given
List<DailySchedule> dailySchedules = new ArrayList<>();
DailySchedule dailySchedule1 = DailySchedule.builder()
.member(photographer)
.scheduleStatus(ScheduleStatus.OPEN)
.date(now.toLocalDate().plusDays(1))
.startTime(LocalTime.of(10, 0, 0))
.endTime(LocalTime.of(11, 0, 0))
.build();
DailySchedule dailySchedule2 = DailySchedule.builder()
.member(photographer)
.scheduleStatus(ScheduleStatus.OPEN)
.date(now.toLocalDate())
.startTime(now.toLocalTime().minusSeconds(1L))
.endTime(now.toLocalTime())
.build();
dailySchedules.add(dailySchedule1);
dailySchedules.add(dailySchedule2);

given(dailyScheduleRepository.findByMember(photographer)).willReturn(dailySchedules);

// when
List<DailyScheduleResponse> responses = dailyScheduleService.getDailySchedules(photographer);

// then
assertThat(responses).size().isEqualTo(1);
assertThat(responses.get(0).getDate()).isEqualTo(now.toLocalDate().plusDays(1));
}
}

@Nested
@DisplayName("날짜별 스케줄 추가 테스트")
class AddDailySchedule {
@Test
@DisplayName("현시점 이전의 스케줄은 등록할 수 없다")
void shouldNotAllowSchedulesInThePast() {
// given
DailyScheduleRequest request = DailyScheduleRequest.builder()
.scheduleStatus(ScheduleStatus.OPEN)
.date(now.toLocalDate())
.startTime(now.toLocalTime().minusHours(1L))
.endTime(now.toLocalTime().plusHours(1L))
.build();

//when & then
RestApiException exception = assertThrows(RestApiException.class, () -> {
dailyScheduleService.addDailySchedule(photographer, request);
});

assertThat(exception.getErrorCode()).isEqualTo(ScheduleErrorCode.DAILY_SCHEDULE_IN_PAST);
}

@Test
@DisplayName("중복되는 스케줄이 있을 때 예외가 발생한다")
void shouldThrowExceptionWhenSchedulesOverlap() {
// given
DailyScheduleRequest request = DailyScheduleRequest.builder()
.scheduleStatus(ScheduleStatus.OPEN)
.date(now.toLocalDate())
.startTime(now.toLocalTime().plusHours(1))
.endTime(now.toLocalTime().plusHours(2))
.build();

List<DailySchedule> overlappingSchedules = new ArrayList<>();
overlappingSchedules.add(DailySchedule.builder()
.member(photographer)
.scheduleStatus(ScheduleStatus.OPEN)
.date(now.toLocalDate())
.startTime(now.toLocalTime().plusHours(1).plusMinutes(30))
.endTime(now.toLocalTime().plusHours(3))
.build());

given(dailyScheduleRepository.findOverlappingSchedules(photographer, request.getDate(),
request.getStartTime(), request.getEndTime()))
.willReturn(overlappingSchedules);

// when & then
RestApiException exception = assertThrows(RestApiException.class, () -> {
dailyScheduleService.addDailySchedule(photographer, request);
});

assertThat(exception.getErrorCode()).isEqualTo(ScheduleErrorCode.DAILY_SCHEDULE_OVERLAP);
}

@Test
@DisplayName("중복되는 스케줄이 없으면 예외가 발생하지 않는다")
void shouldNotThrowExceptionWhenNoOverlappingSchedules() {
// given
DailyScheduleRequest request = DailyScheduleRequest.builder()
.scheduleStatus(ScheduleStatus.OPEN)
.date(now.toLocalDate())
.startTime(now.toLocalTime().plusHours(1))
.endTime(now.toLocalTime().plusHours(2))
.build();

List<DailySchedule> overlappingSchedules = new ArrayList<>();

given(dailyScheduleRepository.findOverlappingSchedules(photographer, request.getDate(),
request.getStartTime(), request.getEndTime()))
.willReturn(overlappingSchedules);

given(dailyScheduleRepository.save(any(DailySchedule.class))).willReturn(
DailySchedule.builder()
.member(photographer)
.scheduleStatus(ScheduleStatus.OPEN)
.date(now.toLocalDate())
.startTime(now.toLocalTime().plusHours(1))
.endTime(now.toLocalTime().plusHours(2))
.build()
);

// when
DailyScheduleAddResponse response = dailyScheduleService.addDailySchedule(photographer, request);

// then
assertThat(response).isNotNull();
}
}
}

0 comments on commit e4b0e6c

Please sign in to comment.