Skip to content

Commit fea0b5d

Browse files
leebs0521m-a-king
authored andcommitted
feat: recruit board 생성 기능 수정 (#23)
* feat(recruit-board): RecruitBoard 엔티티 수정 - 필드 추가 및 수정 - 메서드 추가 * feat(recruit-board): RecruitBoardCreateRequestDto 수정 - 필드 추가 및 수정 * test(recruit-board): 변경에 따른 테스트 수정 및 테스트 케이스 추가 * refactor(recruit-board): 테스트가 모호한 부분 수정
1 parent 6beb14d commit fea0b5d

File tree

4 files changed

+101
-31
lines changed

4 files changed

+101
-31
lines changed

src/main/java/com/somemore/recruitboard/domain/RecruitBoard.java

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import jakarta.persistence.Id;
1414
import jakarta.persistence.Lob;
1515
import jakarta.persistence.Table;
16+
import java.time.Duration;
1617
import java.time.LocalDateTime;
1718
import java.time.LocalTime;
1819
import java.util.UUID;
@@ -56,33 +57,51 @@ public class RecruitBoard extends BaseEntity {
5657
@Column(name = "recruit_status", nullable = false, length = 20)
5758
private RecruitStatus recruitStatus = RECRUITING;
5859

59-
@Column(name = "volunteer_date", nullable = false)
60-
private LocalDateTime volunteerDate;
60+
@Column(name = "volunteer_start_date_time", nullable = false)
61+
private LocalDateTime volunteerStartDateTime;
62+
63+
@Column(name = "volunteer_end_date_time", nullable = false)
64+
private LocalDateTime volunteerEndDateTime;
6165

6266
@Enumerated(value = STRING)
6367
@Column(name = "volunteer_type", nullable = false, length = 30)
6468
private VolunteerType volunteerType;
6569

66-
@Column(name = "volunteer_hours", nullable = false)
67-
private LocalTime volunteerHours;
68-
6970
@Column(name = "admitted", nullable = false)
7071
private Boolean admitted;
7172

7273
@Builder
7374
public RecruitBoard(UUID centerId, Long locationId, String title, String content, String region,
74-
Integer recruitmentCount, String imgUrl, LocalDateTime volunteerDate,
75-
VolunteerType volunteerType, LocalTime volunteerHours, Boolean admitted) {
75+
Integer recruitmentCount, String imgUrl, LocalDateTime volunteerStartDateTime,
76+
LocalDateTime volunteerEndDateTime, VolunteerType volunteerType, Boolean admitted) {
77+
78+
validateVolunteerDateTime(volunteerStartDateTime, volunteerEndDateTime);
79+
7680
this.centerId = centerId;
7781
this.locationId = locationId;
7882
this.title = title;
7983
this.content = content;
8084
this.region = region;
8185
this.recruitmentCount = recruitmentCount;
8286
this.imgUrl = imgUrl;
83-
this.volunteerDate = volunteerDate;
87+
this.volunteerStartDateTime = volunteerStartDateTime;
88+
this.volunteerEndDateTime = volunteerEndDateTime;
8489
this.volunteerType = volunteerType;
85-
this.volunteerHours = volunteerHours;
8690
this.admitted = admitted;
8791
}
92+
93+
public LocalTime calculateVolunteerTime() {
94+
Duration duration = Duration.between(volunteerStartDateTime, volunteerEndDateTime);
95+
96+
long hours = duration.toHours();
97+
long minutes = duration.toMinutes() % 60;
98+
99+
return LocalTime.of((int) hours, (int) minutes);
100+
}
101+
102+
private void validateVolunteerDateTime(LocalDateTime startDateTime, LocalDateTime endDateTime) {
103+
if (endDateTime.isEqual(startDateTime) || endDateTime.isBefore(startDateTime)) {
104+
throw new IllegalArgumentException("종료 시간은 시작 시간보다 이후여야 합니다.");
105+
}
106+
}
88107
}

src/main/java/com/somemore/recruitboard/dto/request/RecruitBoardCreateRequestDto.java

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88
import io.swagger.v3.oas.annotations.media.Schema;
99
import jakarta.validation.constraints.NotBlank;
1010
import jakarta.validation.constraints.NotNull;
11-
import jakarta.validation.constraints.Positive;
1211
import java.time.LocalDateTime;
13-
import java.time.LocalTime;
1412
import java.util.UUID;
1513
import lombok.Builder;
1614

@@ -29,24 +27,22 @@ public record RecruitBoardCreateRequestDto(
2927
@Schema(description = "예상 모집 인원", example = "4")
3028
@NotNull(message = "예상 모집 인원은 필수 값입니다.")
3129
Integer recruitmentCount,
32-
@Schema(description = "봉사 일시", example = "2024-11-20T10:00:00")
33-
@NotNull(message = "봉사 일시는 필수 값입니다.")
34-
LocalDateTime volunteerDate,
30+
@Schema(description = "봉사 시작 일시", example = "2024-11-20T10:00:00")
31+
@NotNull(message = "봉사 시작 일시는 필수 값입니다.")
32+
LocalDateTime volunteerStartDateTime,
33+
@Schema(description = "봉사 종료 일시", example = "2024-11-20T12:00:00")
34+
@NotNull(message = "봉사 종료 일시는 필수 값입니다.")
35+
LocalDateTime volunteerEndDateTime,
3536
@Schema(description = "봉사 활동 유형", example = "ENVIRONMENTAL_PROTECTION")
3637
@NotNull(message = "봉사 활동 유형은 필수 값입니다.")
3738
VolunteerType volunteerType,
38-
@Schema(description = "봉사 시간(시)", example = "1")
39-
@Positive(message = "봉사 시간(시)은 1이상 이어야 합니다.")
40-
Integer volunteerHours,
41-
@Schema(description = "봉사 시간(분)", example = "30")
42-
@Positive(message = "봉사 시간(분)은 1이상 이어야 합니다.")
43-
Integer volunteerMinutes,
4439
@Schema(description = "봉사 시간 인정 여부", example = "true")
4540
@NotNull(message = "시간 인정 여부는 필수 값입니다.")
4641
Boolean admitted,
4742
@NotNull(message = "위치 정보는 필수 값입니다.")
4843
LocationCreateRequestDto location
49-
){
44+
) {
45+
5046
public RecruitBoard toEntity(UUID centerId, Long locationId, String imgUrl) {
5147
return RecruitBoard.builder()
5248
.centerId(centerId)
@@ -56,9 +52,9 @@ public RecruitBoard toEntity(UUID centerId, Long locationId, String imgUrl) {
5652
.region(region)
5753
.recruitmentCount(recruitmentCount)
5854
.imgUrl(imgUrl)
59-
.volunteerDate(volunteerDate)
55+
.volunteerStartDateTime(volunteerStartDateTime)
56+
.volunteerEndDateTime(volunteerEndDateTime)
6057
.volunteerType(volunteerType)
61-
.volunteerHours(LocalTime.of(volunteerHours, volunteerMinutes))
6258
.admitted(admitted)
6359
.build();
6460
}

src/test/java/com/somemore/recruitboard/domain/RecruitBoardTest.java

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,21 @@
33
import static com.somemore.recruitboard.domain.RecruitStatus.RECRUITING;
44
import static com.somemore.recruitboard.domain.VolunteerType.OTHER;
55
import static org.assertj.core.api.Assertions.assertThat;
6+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
67

78
import java.time.LocalDateTime;
89
import java.time.LocalTime;
910
import java.util.UUID;
1011
import org.junit.jupiter.api.DisplayName;
1112
import org.junit.jupiter.api.Test;
13+
import org.junit.jupiter.params.ParameterizedTest;
14+
import org.junit.jupiter.params.provider.ValueSource;
1215

1316
class RecruitBoardTest {
1417

1518
@DisplayName("봉사 모집글 생성시 모집상태는 모집중이다")
1619
@Test
17-
void CreateRecruitBoardWithDefaultStatus() {
20+
void createRecruitBoardWithDefaultStatus() {
1821
// given
1922
RecruitBoard board = RecruitBoard.builder()
2023
.centerId(UUID.randomUUID())
@@ -24,9 +27,9 @@ void CreateRecruitBoardWithDefaultStatus() {
2427
.region("경기")
2528
.recruitmentCount(10)
2629
.imgUrl("https://image.domain.com/links")
27-
.volunteerDate(LocalDateTime.now())
30+
.volunteerStartDateTime(LocalDateTime.now())
31+
.volunteerEndDateTime(LocalDateTime.now().plusHours(1))
2832
.volunteerType(OTHER)
29-
.volunteerHours(LocalTime.of(7, 30))
3033
.admitted(true)
3134
.build();
3235

@@ -36,4 +39,59 @@ void CreateRecruitBoardWithDefaultStatus() {
3639
// then
3740
assertThat(recruitStatus).isEqualTo(RECRUITING);
3841
}
42+
43+
@DisplayName("봉사 종료 시간이 시작 시간과 같거나 빠르면, 봉사 모집글 생성 시 에러가 발생한다")
44+
@ParameterizedTest
45+
@ValueSource(longs = {0, -1})
46+
void createRecruitBoardWithInValidVolunteerTime(long secondsOffset) {
47+
// given
48+
LocalDateTime now = LocalDateTime.now();
49+
LocalDateTime endDateTime = now.plusSeconds(secondsOffset);
50+
51+
// when & then
52+
assertThatThrownBy(
53+
() -> RecruitBoard.builder()
54+
.centerId(UUID.randomUUID())
55+
.locationId(1L)
56+
.title("봉사모집제목")
57+
.content("봉사모집내용")
58+
.region("경기")
59+
.recruitmentCount(10)
60+
.imgUrl("https://image.domain.com/links")
61+
.volunteerStartDateTime(now)
62+
.volunteerEndDateTime(endDateTime)
63+
.volunteerType(VolunteerType.OTHER)
64+
.admitted(true)
65+
.build()
66+
).isInstanceOf(IllegalArgumentException.class);
67+
}
68+
69+
@DisplayName("봉사 시간을 계산할 수 있다")
70+
@Test
71+
void testCalculateVolunteerTime() {
72+
// given
73+
int hours = 3;
74+
LocalDateTime startDateTime = LocalDateTime.now();
75+
LocalDateTime endDateTime = startDateTime.plusHours(hours);
76+
77+
RecruitBoard board = RecruitBoard.builder()
78+
.centerId(UUID.randomUUID())
79+
.locationId(1L)
80+
.title("봉사모집제목")
81+
.content("봉사모집내용")
82+
.region("경기")
83+
.recruitmentCount(10)
84+
.imgUrl("https://image.domain.com/links")
85+
.volunteerStartDateTime(startDateTime)
86+
.volunteerEndDateTime(endDateTime)
87+
.volunteerType(OTHER)
88+
.admitted(true)
89+
.build();
90+
91+
// when
92+
LocalTime volunteerTime = board.calculateVolunteerTime();
93+
94+
// then
95+
assertThat(volunteerTime).isEqualTo(LocalTime.of(hours, 0));
96+
}
3997
}

src/test/java/com/somemore/recruitboard/service/command/CreateRecruitBoardServiceTest.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import com.somemore.recruitboard.repository.RecruitBoardRepository;
1212
import java.math.BigDecimal;
1313
import java.time.LocalDateTime;
14-
import java.time.LocalTime;
1514
import java.util.Optional;
1615
import java.util.UUID;
1716
import org.junit.jupiter.api.AfterEach;
@@ -51,10 +50,9 @@ void createRecruitBoardWithDto() {
5150
.content("봉사 하실분을 모집합니다. <br>")
5251
.region("지역")
5352
.recruitmentCount(10)
54-
.volunteerDate(LocalDateTime.now())
53+
.volunteerStartDateTime(LocalDateTime.now())
54+
.volunteerEndDateTime(LocalDateTime.now().plusHours(2))
5555
.volunteerType(VolunteerType.OTHER)
56-
.volunteerHours(1)
57-
.volunteerMinutes(30)
5856
.admitted(true)
5957
.location(locationDto)
6058
.build();
@@ -72,7 +70,6 @@ void createRecruitBoardWithDto() {
7270
assertThat(recruitBoard.get().getId()).isEqualTo(saveId);
7371
assertThat(recruitBoard.get().getCenterId()).isEqualTo(centerId);
7472
assertThat(recruitBoard.get().getImgUrl()).isEqualTo(imgUrl);
75-
assertThat(recruitBoard.get().getVolunteerHours()).isEqualTo(LocalTime.of(1, 30));
7673
}
7774

7875
}

0 commit comments

Comments
 (0)