Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 28 additions & 9 deletions src/main/java/com/somemore/recruitboard/domain/RecruitBoard.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import jakarta.persistence.Id;
import jakarta.persistence.Lob;
import jakarta.persistence.Table;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.UUID;
Expand Down Expand Up @@ -56,33 +57,51 @@ public class RecruitBoard extends BaseEntity {
@Column(name = "recruit_status", nullable = false, length = 20)
private RecruitStatus recruitStatus = RECRUITING;

@Column(name = "volunteer_date", nullable = false)
private LocalDateTime volunteerDate;
@Column(name = "volunteer_start_date_time", nullable = false)
private LocalDateTime volunteerStartDateTime;

@Column(name = "volunteer_end_date_time", nullable = false)
private LocalDateTime volunteerEndDateTime;

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

@Column(name = "volunteer_hours", nullable = false)
private LocalTime volunteerHours;

@Column(name = "admitted", nullable = false)
private Boolean admitted;

@Builder
public RecruitBoard(UUID centerId, Long locationId, String title, String content, String region,
Integer recruitmentCount, String imgUrl, LocalDateTime volunteerDate,
VolunteerType volunteerType, LocalTime volunteerHours, Boolean admitted) {
Integer recruitmentCount, String imgUrl, LocalDateTime volunteerStartDateTime,
LocalDateTime volunteerEndDateTime, VolunteerType volunteerType, Boolean admitted) {

validateVolunteerDateTime(volunteerStartDateTime, volunteerEndDateTime);

this.centerId = centerId;
this.locationId = locationId;
this.title = title;
this.content = content;
this.region = region;
this.recruitmentCount = recruitmentCount;
this.imgUrl = imgUrl;
this.volunteerDate = volunteerDate;
this.volunteerStartDateTime = volunteerStartDateTime;
this.volunteerEndDateTime = volunteerEndDateTime;
this.volunteerType = volunteerType;
this.volunteerHours = volunteerHours;
this.admitted = admitted;
}

public LocalTime calculateVolunteerTime() {
Duration duration = Duration.between(volunteerStartDateTime, volunteerEndDateTime);

long hours = duration.toHours();
long minutes = duration.toMinutes() % 60;

return LocalTime.of((int) hours, (int) minutes);
}

private void validateVolunteerDateTime(LocalDateTime startDateTime, LocalDateTime endDateTime) {
if (endDateTime.isEqual(startDateTime) || endDateTime.isBefore(startDateTime)) {
throw new IllegalArgumentException("종료 시간은 시작 시간보다 이후여야 합니다.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.UUID;
import lombok.Builder;

Expand All @@ -29,24 +27,22 @@ public record RecruitBoardCreateRequestDto(
@Schema(description = "예상 모집 인원", example = "4")
@NotNull(message = "예상 모집 인원은 필수 값입니다.")
Integer recruitmentCount,
@Schema(description = "봉사 일시", example = "2024-11-20T10:00:00")
@NotNull(message = "봉사 일시는 필수 값입니다.")
LocalDateTime volunteerDate,
@Schema(description = "봉사 시작 일시", example = "2024-11-20T10:00:00")
@NotNull(message = "봉사 시작 일시는 필수 값입니다.")
LocalDateTime volunteerStartDateTime,
@Schema(description = "봉사 종료 일시", example = "2024-11-20T12:00:00")
@NotNull(message = "봉사 종료 일시는 필수 값입니다.")
LocalDateTime volunteerEndDateTime,
@Schema(description = "봉사 활동 유형", example = "ENVIRONMENTAL_PROTECTION")
@NotNull(message = "봉사 활동 유형은 필수 값입니다.")
VolunteerType volunteerType,
@Schema(description = "봉사 시간(시)", example = "1")
@Positive(message = "봉사 시간(시)은 1이상 이어야 합니다.")
Integer volunteerHours,
@Schema(description = "봉사 시간(분)", example = "30")
@Positive(message = "봉사 시간(분)은 1이상 이어야 합니다.")
Integer volunteerMinutes,
@Schema(description = "봉사 시간 인정 여부", example = "true")
@NotNull(message = "시간 인정 여부는 필수 값입니다.")
Boolean admitted,
@NotNull(message = "위치 정보는 필수 값입니다.")
LocationCreateRequestDto location
){
) {

public RecruitBoard toEntity(UUID centerId, Long locationId, String imgUrl) {
return RecruitBoard.builder()
.centerId(centerId)
Expand All @@ -56,9 +52,9 @@ public RecruitBoard toEntity(UUID centerId, Long locationId, String imgUrl) {
.region(region)
.recruitmentCount(recruitmentCount)
.imgUrl(imgUrl)
.volunteerDate(volunteerDate)
.volunteerStartDateTime(volunteerStartDateTime)
.volunteerEndDateTime(volunteerEndDateTime)
.volunteerType(volunteerType)
.volunteerHours(LocalTime.of(volunteerHours, volunteerMinutes))
.admitted(admitted)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@
import static com.somemore.recruitboard.domain.RecruitStatus.RECRUITING;
import static com.somemore.recruitboard.domain.VolunteerType.OTHER;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.UUID;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

class RecruitBoardTest {

@DisplayName("봉사 모집글 생성시 모집상태는 모집중이다")
@Test
void CreateRecruitBoardWithDefaultStatus() {
void createRecruitBoardWithDefaultStatus() {
// given
RecruitBoard board = RecruitBoard.builder()
.centerId(UUID.randomUUID())
Expand All @@ -24,9 +27,9 @@ void CreateRecruitBoardWithDefaultStatus() {
.region("경기")
.recruitmentCount(10)
.imgUrl("https://image.domain.com/links")
.volunteerDate(LocalDateTime.now())
.volunteerStartDateTime(LocalDateTime.now())
.volunteerEndDateTime(LocalDateTime.now().plusHours(1))
.volunteerType(OTHER)
.volunteerHours(LocalTime.of(7, 30))
.admitted(true)
.build();

Expand All @@ -36,4 +39,59 @@ void CreateRecruitBoardWithDefaultStatus() {
// then
assertThat(recruitStatus).isEqualTo(RECRUITING);
}

@DisplayName("봉사 종료 시간이 시작 시간과 같거나 빠르면, 봉사 모집글 생성 시 에러가 발생한다")
@ParameterizedTest
@ValueSource(longs = {0, -1})
void createRecruitBoardWithInValidVolunteerTime(long secondsOffset) {
// given
LocalDateTime now = LocalDateTime.now();
LocalDateTime endDateTime = now.plusSeconds(secondsOffset);

// when & then
assertThatThrownBy(
() -> RecruitBoard.builder()
.centerId(UUID.randomUUID())
.locationId(1L)
.title("봉사모집제목")
.content("봉사모집내용")
.region("경기")
.recruitmentCount(10)
.imgUrl("https://image.domain.com/links")
.volunteerStartDateTime(now)
.volunteerEndDateTime(endDateTime)
.volunteerType(VolunteerType.OTHER)
.admitted(true)
.build()
).isInstanceOf(IllegalArgumentException.class);
}

@DisplayName("봉사 시간을 계산할 수 있다")
@Test
void testCalculateVolunteerTime() {
// given
int hours = 3;
LocalDateTime startDateTime = LocalDateTime.now();
LocalDateTime endDateTime = startDateTime.plusHours(hours);

RecruitBoard board = RecruitBoard.builder()
.centerId(UUID.randomUUID())
.locationId(1L)
.title("봉사모집제목")
.content("봉사모집내용")
.region("경기")
.recruitmentCount(10)
.imgUrl("https://image.domain.com/links")
.volunteerStartDateTime(startDateTime)
.volunteerEndDateTime(endDateTime)
.volunteerType(OTHER)
.admitted(true)
.build();

// when
LocalTime volunteerTime = board.calculateVolunteerTime();

// then
assertThat(volunteerTime).isEqualTo(LocalTime.of(hours, 0));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import com.somemore.recruitboard.repository.RecruitBoardRepository;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Optional;
import java.util.UUID;
import org.junit.jupiter.api.AfterEach;
Expand Down Expand Up @@ -51,10 +50,9 @@ void createRecruitBoardWithDto() {
.content("봉사 하실분을 모집합니다. <br>")
.region("지역")
.recruitmentCount(10)
.volunteerDate(LocalDateTime.now())
.volunteerStartDateTime(LocalDateTime.now())
.volunteerEndDateTime(LocalDateTime.now().plusHours(2))
.volunteerType(VolunteerType.OTHER)
.volunteerHours(1)
.volunteerMinutes(30)
.admitted(true)
.location(locationDto)
.build();
Expand All @@ -72,7 +70,6 @@ void createRecruitBoardWithDto() {
assertThat(recruitBoard.get().getId()).isEqualTo(saveId);
assertThat(recruitBoard.get().getCenterId()).isEqualTo(centerId);
assertThat(recruitBoard.get().getImgUrl()).isEqualTo(imgUrl);
assertThat(recruitBoard.get().getVolunteerHours()).isEqualTo(LocalTime.of(1, 30));
}

}
Loading