diff --git a/src/main/java/nextstep/courses/domain/Course.java b/src/main/java/nextstep/courses/domain/Course.java index 0f6971604..997bd0c0d 100644 --- a/src/main/java/nextstep/courses/domain/Course.java +++ b/src/main/java/nextstep/courses/domain/Course.java @@ -1,6 +1,10 @@ package nextstep.courses.domain; +import nextstep.sessions.domain.Session; +import nextstep.sessions.domain.Sessions; + import java.time.LocalDateTime; +import java.util.List; public class Course { private Long id; @@ -9,6 +13,10 @@ public class Course { private Long creatorId; + private int cardinalNumber; + + private Sessions sessions; + private LocalDateTime createdAt; private LocalDateTime updatedAt; @@ -17,7 +25,18 @@ public Course() { } public Course(String title, Long creatorId) { - this(0L, title, creatorId, LocalDateTime.now(), null); + this(0L, title, creatorId, 1, null, LocalDateTime.now(), null); + } + + public Course(Long id, String title, Long creatorId, int cardinalNumber, Sessions sessions, + LocalDateTime createdAt, LocalDateTime updatedAt) { + this.id = id; + this.title = title; + this.creatorId = creatorId; + this.cardinalNumber = cardinalNumber; + this.sessions = sessions; + this.createdAt = createdAt; + this.updatedAt = updatedAt; } public Course(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt) { @@ -40,12 +59,18 @@ public LocalDateTime getCreatedAt() { return createdAt; } + public List getPossibleSessionList() { + return this.sessions.getPossibleSessionList(); + } + @Override public String toString() { return "Course{" + "id=" + id + ", title='" + title + '\'' + ", creatorId=" + creatorId + + ", cardinalNumber=" + cardinalNumber + + ", sessions=" + sessions + ", createdAt=" + createdAt + ", updatedAt=" + updatedAt + '}'; diff --git a/src/main/java/nextstep/courses/domain/CourseRepository.java b/src/main/java/nextstep/courses/domain/CourseRepository.java index 6aaeb638d..bed12af2d 100644 --- a/src/main/java/nextstep/courses/domain/CourseRepository.java +++ b/src/main/java/nextstep/courses/domain/CourseRepository.java @@ -4,4 +4,6 @@ public interface CourseRepository { int save(Course course); Course findById(Long id); + + Course findByCardinalNumber(int order); } diff --git a/src/main/java/nextstep/courses/infrastructure/JdbcCourseRepository.java b/src/main/java/nextstep/courses/infrastructure/JdbcCourseRepository.java index f9122cbe3..38e198026 100644 --- a/src/main/java/nextstep/courses/infrastructure/JdbcCourseRepository.java +++ b/src/main/java/nextstep/courses/infrastructure/JdbcCourseRepository.java @@ -2,6 +2,7 @@ import nextstep.courses.domain.Course; import nextstep.courses.domain.CourseRepository; +import nextstep.sessions.domain.Sessions; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; @@ -35,6 +36,20 @@ public Course findById(Long id) { return jdbcTemplate.queryForObject(sql, rowMapper, id); } + @Override + public Course findByCardinalNumber(int cardinalNumber) { + String sql = "select id, title, creator_id, cardinal_number, sessions, created_at, updated_at from course where cardinal_number = ?"; + RowMapper rowMapper = (rs, rowNum) -> new Course( + rs.getLong(1), + rs.getString(2), + rs.getLong(3), + rs.getInt(4), + (Sessions) rs.getObject(5), + toLocalDateTime(rs.getTimestamp(6)), + toLocalDateTime(rs.getTimestamp(7))); + return jdbcTemplate.queryForObject(sql, rowMapper, cardinalNumber); + } + private LocalDateTime toLocalDateTime(Timestamp timestamp) { if (timestamp == null) { return null; diff --git a/src/main/java/nextstep/courses/service/CourseService.java b/src/main/java/nextstep/courses/service/CourseService.java new file mode 100644 index 000000000..bff2d1dc4 --- /dev/null +++ b/src/main/java/nextstep/courses/service/CourseService.java @@ -0,0 +1,17 @@ +package nextstep.courses.service; + +import nextstep.courses.domain.Course; +import nextstep.courses.infrastructure.JdbcCourseRepository; + +public class CourseService { + + private final JdbcCourseRepository jdbcCourseRepository; + + public CourseService(JdbcCourseRepository jdbcCourseRepository) { + this.jdbcCourseRepository = jdbcCourseRepository; + } + + public Course findByCardinalNumber(int cardinalNumber) { + return jdbcCourseRepository.findByCardinalNumber(cardinalNumber); + } +} diff --git a/src/main/java/nextstep/docs/step2.md b/src/main/java/nextstep/docs/step2.md new file mode 100644 index 000000000..8add2e33d --- /dev/null +++ b/src/main/java/nextstep/docs/step2.md @@ -0,0 +1,17 @@ +### step2 수강 신청(도메인 모델) + +- [x] 과정(Course)은 기수 단위로 운영하고, 여러 개의 강의(Session)를 가진다. +- [X] 강의는 시작일과 종료일을 가진다. +- [X] 강의는 강의 커버 이미지 정보를 가진다. + - [X] 이미지 크기는 1MB 이하 + - [X] 이미지 타입은 gif, jpg, jpeg, png, svg 만 허용 + - [X] 이미지의 width 는 300 픽셀, height 은 200 픽셀 이상이어야 하고 비율은 3:2 +- [X] 강의는 무료 강의와 유료 강의로 나뉜다. + - [X] 무료 강의는 최대 수강 인원 제한 X + - [X] 유료 강의는 강의 최대 수강 인원 초과 X + - [X] 유료 강의는 수강생이 결제한 금액과 수강료가 일치할 때 수강 신청 가능 +- [X] 강의 상태는 준비중, 모집중, 종료 3가지 상태 +- [X] 강의 수강 신청은 강의 상태가 모집중일 때만 가능 +- [X] 유료 강의의 경우 결제는 이미 완료한 것으로 가정, 이후 과정을 구현 +- [X] 결제를 완료한 결제 정보는 payments 모듈을 통해 관리되며, 결제 정보는 Payment 객체에 담겨 반환 +- [X] 도메인 모델 TDD 로 구현 diff --git a/src/main/java/nextstep/enrolment/EnrolmentMain.java b/src/main/java/nextstep/enrolment/EnrolmentMain.java new file mode 100644 index 000000000..776f7f85b --- /dev/null +++ b/src/main/java/nextstep/enrolment/EnrolmentMain.java @@ -0,0 +1,32 @@ +package nextstep.enrolment; + +import nextstep.courses.infrastructure.JdbcCourseRepository; +import nextstep.courses.service.CourseService; +import nextstep.enrolment.controller.EnrolmentController; +import nextstep.enrolment.facade.EnrolmentFacade; +import nextstep.payments.service.PaymentService; +import nextstep.sessions.dto.SessionResponse; +import nextstep.sessions.dto.SessionsResponse; +import nextstep.sessions.infrastructure.JdbcSessionRepository; +import nextstep.sessions.service.SessionService; +import org.springframework.jdbc.core.JdbcTemplate; + +public class EnrolmentMain { + + public static void main(String[] args) { + EnrolmentFacade enrolmentFacade = new EnrolmentFacade( + new CourseService(new JdbcCourseRepository(new JdbcTemplate())), + new SessionService(new JdbcSessionRepository(new JdbcTemplate())), + new PaymentService() + ); + EnrolmentController enrolmentController = new EnrolmentController(enrolmentFacade); + + //수강 신청 전에 현재 오픈된 기수의 과정을 볼 수 있는 로직 + SessionsResponse sessionsResponse = enrolmentController.findPossibleSessionList(17); + //특정 강의에 대한 세부 내용을 확인하는 로직 + SessionResponse sessionInfo = enrolmentController.findSessionInfo(1L); + //수강 신청 + Long nsUserId = 1L; + enrolmentController.enrollCourse(sessionInfo.id(), nsUserId); + } +} diff --git a/src/main/java/nextstep/enrolment/controller/EnrolmentController.java b/src/main/java/nextstep/enrolment/controller/EnrolmentController.java new file mode 100644 index 000000000..6523a16a2 --- /dev/null +++ b/src/main/java/nextstep/enrolment/controller/EnrolmentController.java @@ -0,0 +1,53 @@ +package nextstep.enrolment.controller; + +import nextstep.courses.domain.Course; +import nextstep.enrolment.facade.EnrolmentFacade; +import nextstep.payments.domain.Payment; +import nextstep.sessions.domain.Session; +import nextstep.sessions.dto.SessionResponse; +import nextstep.sessions.dto.SessionsResponse; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class EnrolmentController { + + private final EnrolmentFacade enrolmentFacade; + + public EnrolmentController(EnrolmentFacade enrolmentFacade) { + this.enrolmentFacade = enrolmentFacade; + } + + public SessionsResponse findPossibleSessionList(int cardinalNumber) { + Course course = enrolmentFacade.findCourseByCardinalNumber(cardinalNumber); + return new SessionsResponse(course.getPossibleSessionList().stream() + .map(SessionResponse::of) + .collect(Collectors.toList())); + } + + public SessionResponse findSessionInfo(long sessionId) { + Session session = enrolmentFacade.findSessionById(sessionId); + return SessionResponse.of(session); + } + + public void enrollCourse(Long sessionId, Long nsUserId) { + Session session = enrolmentFacade.findSessionById(sessionId); + if (!session.isRecruitingStatus()) { + throw new IllegalArgumentException("수강 신청이 불가능한 강의 입니다."); + } + + List payments = enrolmentFacade.findPaymentsBySessionId(sessionId); + Payment payment = payments.stream().filter(p -> Objects.equals(p.nsUserId(), nsUserId)) + .findAny() + .orElse(null); + + if (Objects.nonNull(payment) && !session.isPossibleToRegister(payment.amount(), payments.size())) { + //수강 신청 불가 + throw new IllegalArgumentException("수강 신청이 불가능합니다."); + } + + //수강 신청 + + } +} diff --git a/src/main/java/nextstep/enrolment/facade/EnrolmentFacade.java b/src/main/java/nextstep/enrolment/facade/EnrolmentFacade.java new file mode 100644 index 000000000..3d4932125 --- /dev/null +++ b/src/main/java/nextstep/enrolment/facade/EnrolmentFacade.java @@ -0,0 +1,41 @@ +package nextstep.enrolment.facade; + +import nextstep.courses.domain.Course; +import nextstep.courses.service.CourseService; +import nextstep.payments.domain.Payment; +import nextstep.payments.service.PaymentService; +import nextstep.sessions.domain.Session; +import nextstep.sessions.service.SessionService; + +import java.util.List; + +public class EnrolmentFacade { + + private final CourseService courseService; + private final SessionService sessionService; + private final PaymentService paymentService; + + public EnrolmentFacade(CourseService courseService, + SessionService sessionService, + PaymentService paymentService) { + this.courseService = courseService; + this.sessionService = sessionService; + this.paymentService = paymentService; + } + + public Course findCourseByCardinalNumber(int cardinalNumber) { + return courseService.findByCardinalNumber(cardinalNumber); + } + + public Session findSessionById(Long sessionId) { + return sessionService.findById(sessionId); + } + + public List findPaymentsBySessionId(Long sessionId) { + return paymentService.findBySessionId(sessionId); + } + + public Payment findPaymentBySessionIdAndNsUserId(Long sessionId, Long nsUserId) { + return paymentService.findBySessionIdAndNsUserId(sessionId, nsUserId); + } +} diff --git a/src/main/java/nextstep/images/domain/Image.java b/src/main/java/nextstep/images/domain/Image.java new file mode 100644 index 000000000..dff100941 --- /dev/null +++ b/src/main/java/nextstep/images/domain/Image.java @@ -0,0 +1,58 @@ +package nextstep.images.domain; + +import java.util.EnumSet; +import java.util.Objects; + +public class Image { + + private Long id; + + private ImageType imageType; + + private int size; + + private int width; + + private int height; + + public Image(Long id, ImageType imageType, int size, int width, int height) { + checkImageSize(size); + checkImageType(imageType); + checkImageWidthAndHeight(width, height); + this.id = id; + this.imageType = imageType; + this.size = size; + this.width = width; + this.height = height; + } + + private void checkImageSize(int size) { + if (size == 0) { + throw new IllegalArgumentException("강의는 강의 커버 이미지 정보가 필요합니다."); + } + + if (size > 1024 * 1024) { // 1MB + throw new IllegalArgumentException("이미지 크기는 1MB 이하여야 합니다."); + } + } + + private void checkImageType(ImageType imageType) { + if (Objects.isNull(imageType) || !EnumSet.allOf(ImageType.class).contains(imageType)) { + throw new IllegalArgumentException("이미지 타입은 gif, jpg, jpeg, png, svg 만 가능합니다."); + } + } + + private void checkImageWidthAndHeight(int width, int height) { + if (width == 0 || height == 0) { + throw new IllegalArgumentException("강의는 강의 커버 이미지 정보가 필요합니다."); + } + + if (width < 300 || height < 200) { + throw new IllegalArgumentException("이미지 가로는 300 픽셀, 세로는 200 픽셀 이상이어야 합니다."); + } + + if (2 * width != 3 * height) { + throw new IllegalArgumentException("가로와 세로의 비율은 3:2여야 합니다"); + } + } +} diff --git a/src/main/java/nextstep/images/domain/ImageType.java b/src/main/java/nextstep/images/domain/ImageType.java new file mode 100644 index 000000000..bc16e84e9 --- /dev/null +++ b/src/main/java/nextstep/images/domain/ImageType.java @@ -0,0 +1,14 @@ +package nextstep.images.domain; + +public enum ImageType { + + GIF, + JPG, + JPEG, + PNG, + SVG; + + ImageType() { + + } +} diff --git a/src/main/java/nextstep/payments/domain/Payment.java b/src/main/java/nextstep/payments/domain/Payment.java index 57d833f85..d27f0ec1b 100644 --- a/src/main/java/nextstep/payments/domain/Payment.java +++ b/src/main/java/nextstep/payments/domain/Payment.java @@ -26,4 +26,12 @@ public Payment(String id, Long sessionId, Long nsUserId, Long amount) { this.amount = amount; this.createdAt = LocalDateTime.now(); } + + public Long amount() { + return amount; + } + + public Long nsUserId() { + return nsUserId; + } } diff --git a/src/main/java/nextstep/payments/service/PaymentService.java b/src/main/java/nextstep/payments/service/PaymentService.java index 372019abb..599b07b7e 100644 --- a/src/main/java/nextstep/payments/service/PaymentService.java +++ b/src/main/java/nextstep/payments/service/PaymentService.java @@ -2,9 +2,21 @@ import nextstep.payments.domain.Payment; +import java.util.List; + public class PaymentService { public Payment payment(String id) { // PG사 API를 통해 id에 해당하는 결제 정보를 반환 return new Payment(); } + + //sessionId 에 맞는 결제 정보를 가져왔다고 가정 + public List findBySessionId(Long sessionId) { + return List.of(new Payment(), new Payment()); + } + + public Payment findBySessionIdAndNsUserId(Long sessionId, Long nsUserId) { + //sessionId 와 nsUserId 에 맞는 결제 정보를 가져왔다고 가정 + return new Payment(); + } } diff --git a/src/main/java/nextstep/sessions/domain/FreeSessionType.java b/src/main/java/nextstep/sessions/domain/FreeSessionType.java new file mode 100644 index 000000000..6537de767 --- /dev/null +++ b/src/main/java/nextstep/sessions/domain/FreeSessionType.java @@ -0,0 +1,17 @@ +package nextstep.sessions.domain; + +public class FreeSessionType implements SessionType { + + private Long amount; + private int maxCapacity; + + public FreeSessionType() { + this.amount = 0L; + this.maxCapacity = Integer.MAX_VALUE; + } + + @Override + public boolean isPossibleToRegister(Long paidAmount, int enrolledStudents) { + return true; + } +} diff --git a/src/main/java/nextstep/sessions/domain/PaidSessionType.java b/src/main/java/nextstep/sessions/domain/PaidSessionType.java new file mode 100644 index 000000000..823229fe3 --- /dev/null +++ b/src/main/java/nextstep/sessions/domain/PaidSessionType.java @@ -0,0 +1,24 @@ +package nextstep.sessions.domain; + +public class PaidSessionType implements SessionType { + + private Long amount; + private int maxCapacity; + + public PaidSessionType(Long amount, int maxCapacity) { + this.amount = amount; + this.maxCapacity = maxCapacity; + } + + @Override + public boolean isPossibleToRegister(Long paidAmount, int enrolledStudents) { + if (!amount.equals(paidAmount)) { + throw new IllegalArgumentException("수강생이 결제한 금액과 수강료가 일치할 때 수강 신청이 가능합니다."); + } + + if (maxCapacity < enrolledStudents + 1) { + throw new IllegalArgumentException("강의 최대 수강 인원을 초과할 수 없습니다."); + } + return true; + } +} diff --git a/src/main/java/nextstep/sessions/domain/Session.java b/src/main/java/nextstep/sessions/domain/Session.java new file mode 100644 index 000000000..63a2942bc --- /dev/null +++ b/src/main/java/nextstep/sessions/domain/Session.java @@ -0,0 +1,60 @@ +package nextstep.sessions.domain; + +import java.time.LocalDate; + +public class Session { + + private Long id; + + private String name; + + private SessionStatus sessionStatus; + + private SessionType sessionType; + + private LocalDate startDt; + + private LocalDate endDt; + + public Session(Long id, String name, SessionStatus sessionStatus, SessionType sessionType, + LocalDate startDt, LocalDate endDt) { + this.id = id; + this.name = name; + this.sessionStatus = sessionStatus; + this.sessionType = sessionType; + this.startDt = startDt; + this.endDt = endDt; + } + + public boolean isRecruitingStatus() { + return sessionStatus.equals(SessionStatus.RECRUITING); + } + + public Long id() { + return id; + } + + public String name() { + return name; + } + + public SessionStatus sessionStatus() { + return sessionStatus; + } + + public SessionType sessionType() { + return sessionType; + } + + public LocalDate startDt() { + return startDt; + } + + public LocalDate endDt() { + return endDt; + } + + public boolean isPossibleToRegister(Long paidAmount, int enrolledStudents) { + return this.sessionType.isPossibleToRegister(paidAmount, enrolledStudents); + } +} diff --git a/src/main/java/nextstep/sessions/domain/SessionRepository.java b/src/main/java/nextstep/sessions/domain/SessionRepository.java new file mode 100644 index 000000000..59904582a --- /dev/null +++ b/src/main/java/nextstep/sessions/domain/SessionRepository.java @@ -0,0 +1,6 @@ +package nextstep.sessions.domain; + +public interface SessionRepository { + + Session findById(Long id); +} diff --git a/src/main/java/nextstep/sessions/domain/SessionStatus.java b/src/main/java/nextstep/sessions/domain/SessionStatus.java new file mode 100644 index 000000000..eda6244f9 --- /dev/null +++ b/src/main/java/nextstep/sessions/domain/SessionStatus.java @@ -0,0 +1,14 @@ +package nextstep.sessions.domain; + +public enum SessionStatus { + + PREPARING("준비중"), + RECRUITING("모집중"), + TERMINATION("종료"); + + private final String description; + + SessionStatus(String description) { + this.description = description; + } +} diff --git a/src/main/java/nextstep/sessions/domain/SessionType.java b/src/main/java/nextstep/sessions/domain/SessionType.java new file mode 100644 index 000000000..e9d9247d3 --- /dev/null +++ b/src/main/java/nextstep/sessions/domain/SessionType.java @@ -0,0 +1,6 @@ +package nextstep.sessions.domain; + +public interface SessionType { + + boolean isPossibleToRegister(Long paidAmount, int enrolledStudents); +} diff --git a/src/main/java/nextstep/sessions/domain/Sessions.java b/src/main/java/nextstep/sessions/domain/Sessions.java new file mode 100644 index 000000000..a160a32a4 --- /dev/null +++ b/src/main/java/nextstep/sessions/domain/Sessions.java @@ -0,0 +1,19 @@ +package nextstep.sessions.domain; + +import java.util.List; +import java.util.stream.Collectors; + +public class Sessions { + + private List sessionList; + + public Sessions(List sessionList) { + this.sessionList = sessionList; + } + + public List getPossibleSessionList() { + return sessionList.stream() + .filter(session -> session.isRecruitingStatus()) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/nextstep/sessions/dto/SessionResponse.java b/src/main/java/nextstep/sessions/dto/SessionResponse.java new file mode 100644 index 000000000..8cce54596 --- /dev/null +++ b/src/main/java/nextstep/sessions/dto/SessionResponse.java @@ -0,0 +1,41 @@ +package nextstep.sessions.dto; + +import nextstep.sessions.domain.Session; +import nextstep.sessions.domain.SessionStatus; +import nextstep.sessions.domain.SessionType; + +import java.time.LocalDate; + +public class SessionResponse { + + private Long id; + + private String name; + + private SessionStatus sessionStatus; + + private SessionType sessionType; + + private LocalDate startDt; + + private LocalDate endDt; + + public SessionResponse(Long id, String name, SessionStatus sessionStatus, SessionType sessionType, + LocalDate startDt, LocalDate endDt) { + this.id = id; + this.name = name; + this.sessionStatus = sessionStatus; + this.sessionType = sessionType; + this.startDt = startDt; + this.endDt = endDt; + } + + public static SessionResponse of(Session session) { + return new SessionResponse(session.id(), session.name(), session.sessionStatus(), session.sessionType(), + session.startDt(), session.endDt()); + } + + public Long id() { + return id; + } +} diff --git a/src/main/java/nextstep/sessions/dto/SessionsResponse.java b/src/main/java/nextstep/sessions/dto/SessionsResponse.java new file mode 100644 index 000000000..c7c416331 --- /dev/null +++ b/src/main/java/nextstep/sessions/dto/SessionsResponse.java @@ -0,0 +1,12 @@ +package nextstep.sessions.dto; + +import java.util.List; + +public class SessionsResponse { + + private List sessionResponses; + + public SessionsResponse(List sessionResponses) { + this.sessionResponses = sessionResponses; + } +} diff --git a/src/main/java/nextstep/sessions/infrastructure/JdbcSessionRepository.java b/src/main/java/nextstep/sessions/infrastructure/JdbcSessionRepository.java new file mode 100644 index 000000000..dab7b6ed3 --- /dev/null +++ b/src/main/java/nextstep/sessions/infrastructure/JdbcSessionRepository.java @@ -0,0 +1,41 @@ +package nextstep.sessions.infrastructure; + +import nextstep.sessions.domain.Session; +import nextstep.sessions.domain.SessionRepository; +import nextstep.sessions.domain.SessionStatus; +import nextstep.sessions.domain.SessionType; +import org.springframework.jdbc.core.JdbcOperations; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Repository; + +import java.sql.Timestamp; +import java.time.LocalDate; + +@Repository("sessionRepository") +public class JdbcSessionRepository implements SessionRepository { + private JdbcOperations jdbcTemplate; + + public JdbcSessionRepository(JdbcOperations jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + @Override + public Session findById(Long id) { + String sql = "select id, name, session_status, session_type, start_dt, end_dt from session where id = ?"; + RowMapper rowMapper = (rs, rowNum) -> new Session( + rs.getLong(1), + rs.getString(2), + (SessionStatus) rs.getObject(3), + (SessionType) rs.getObject(4), + toLocalDate(rs.getTimestamp(5)), + toLocalDate(rs.getTimestamp(6))); + return jdbcTemplate.queryForObject(sql, rowMapper, id); + } + + private LocalDate toLocalDate(Timestamp timestamp) { + if (timestamp == null) { + return null; + } + return timestamp.toLocalDateTime().toLocalDate(); + } +} diff --git a/src/main/java/nextstep/sessions/service/SessionService.java b/src/main/java/nextstep/sessions/service/SessionService.java new file mode 100644 index 000000000..aa74cec5e --- /dev/null +++ b/src/main/java/nextstep/sessions/service/SessionService.java @@ -0,0 +1,17 @@ +package nextstep.sessions.service; + +import nextstep.sessions.domain.Session; +import nextstep.sessions.infrastructure.JdbcSessionRepository; + +public class SessionService { + + private final JdbcSessionRepository jdbcSessionRepository; + + public SessionService(JdbcSessionRepository jdbcSessionRepository) { + this.jdbcSessionRepository = jdbcSessionRepository; + } + + public Session findById(Long id) { + return jdbcSessionRepository.findById(id); + } +} diff --git a/src/test/java/nextstep/images/domain/ImageTest.java b/src/test/java/nextstep/images/domain/ImageTest.java new file mode 100644 index 000000000..83d2b588d --- /dev/null +++ b/src/test/java/nextstep/images/domain/ImageTest.java @@ -0,0 +1,30 @@ +package nextstep.images.domain; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; + +class ImageTest { + + @ParameterizedTest + @CsvSource(value = {"0", "1048577"}) + void 이미지_사이즈_크기_exception_테스트(int size) { + assertThatIllegalArgumentException() + .isThrownBy(() -> new Image(1L, ImageType.GIF, size, 1, 1)); + } + + @Test + void 이미지_타입_exception_테스트() { + assertThatIllegalArgumentException() + .isThrownBy(() -> new Image(1L, null, 0, 1, 1)); + } + + @ParameterizedTest + @CsvSource(value = {"0, 200", "200, 200", "500, 400"}) + void 이미지_가로_세로_exception_테스트(int width, int height) { + assertThatIllegalArgumentException() + .isThrownBy(() -> new Image(1L, ImageType.GIF, 1024 * 1024 - 1, width, height)); + } +} diff --git a/src/test/java/nextstep/sessions/domain/SessionTest.java b/src/test/java/nextstep/sessions/domain/SessionTest.java new file mode 100644 index 000000000..02e2edfa7 --- /dev/null +++ b/src/test/java/nextstep/sessions/domain/SessionTest.java @@ -0,0 +1,46 @@ +package nextstep.sessions.domain; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.time.LocalDate; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; + +class SessionTest { + + Session freeSession; + Session paidSession; + + @BeforeEach + void setUp() { + freeSession = new Session(1L, "test1", SessionStatus.RECRUITING, new FreeSessionType(), + LocalDate.now().minusDays(1), LocalDate.now().plusDays(30)); + paidSession = new Session(2L, "test2", SessionStatus.PREPARING, new PaidSessionType(50_000L, 30), + LocalDate.now().plusDays(10), LocalDate.now().plusDays(60)); + } + + @Test + void 수강_가능_상태_확인_테스트() { + assertThat(freeSession.isRecruitingStatus()).isTrue(); + assertThat(paidSession.isRecruitingStatus()).isFalse(); + } + + @Test + void 무료_강의_수강_신청_테스트() { + assertThat(freeSession.isPossibleToRegister(0L, 1)).isTrue(); + } + + @Test + void 유료_강의_수강_신청_실패_수강료_불일치_테스트() { + assertThatIllegalArgumentException() + .isThrownBy(() -> paidSession.isPossibleToRegister(50_000L - 1, 10)); + } + + @Test + void 유료_강의_수강_신청_실패_수강_인원_초과_테스트() { + assertThatIllegalArgumentException() + .isThrownBy(() -> paidSession.isPossibleToRegister(40_000L, 30)); + } +} diff --git a/src/test/java/nextstep/sessions/domain/SessionsTest.java b/src/test/java/nextstep/sessions/domain/SessionsTest.java new file mode 100644 index 000000000..3e01d1482 --- /dev/null +++ b/src/test/java/nextstep/sessions/domain/SessionsTest.java @@ -0,0 +1,32 @@ +package nextstep.sessions.domain; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.time.LocalDate; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class SessionsTest { + + Sessions sessions; + + Session sessionA; + Session sessionB; + Session sessionC; + + @BeforeEach + void setUp() { + sessionA = new Session(1L, "test1", SessionStatus.RECRUITING, new FreeSessionType(), LocalDate.now(), LocalDate.now()); + sessionB = new Session(2L, "test2", SessionStatus.TERMINATION, new FreeSessionType(), LocalDate.now(), LocalDate.now()); + sessionC = new Session(3L, "test3", SessionStatus.RECRUITING, new FreeSessionType(), LocalDate.now(), LocalDate.now()); + + sessions = new Sessions(List.of(sessionA, sessionB, sessionC)); + } + + @Test + void 수강_신청_가능한_강의_목록_조회_테스트() { + assertThat(sessions.getPossibleSessionList()).hasSize(2); + } +}