diff --git a/README.md b/README.md index e086f61d9..56eea48ad 100644 --- a/README.md +++ b/README.md @@ -34,5 +34,13 @@ - [x] 이미지 타입은 gif, jpg, jpeg, png, svg만 허용한다. - [x] 이미지의 width 는 300픽셀, height는 200픽셀 이상이어야 하며, width : height 은 3:2 여야 한다. +## Step4 + +### 기능 목록 +- [x] 강의는 하나 이상 강의 이미지를 가질 수 있다. +- [x] 강의가 진행 중인 상태에서도 수강신청이 가능하다. + - 강의 진행 상태(준비중, 진행중, 종료)와 모집 상태(비모집중, 모집중)로 상태 분리 필요. +- [x] 강사는 수강신청한 사람 중, 선발된 인원에 대해서만 수강 승인이 가능해야 한다. +- [x] 강사는 수강신청한 사람 중, 선발되지 않은 사람은 수강 취소할 수 있다. ## 온라인 코드 리뷰 과정 * [텍스트와 이미지로 살펴보는 온라인 코드 리뷰 과정](https://github.com/next-step/nextstep-docs/tree/master/codereview) \ No newline at end of file diff --git a/src/main/java/nextstep/courses/domain/FreeSession.java b/src/main/java/nextstep/courses/domain/FreeSession.java index 9a395593e..b842e8760 100644 --- a/src/main/java/nextstep/courses/domain/FreeSession.java +++ b/src/main/java/nextstep/courses/domain/FreeSession.java @@ -3,15 +3,20 @@ import nextstep.payments.domain.Payment; import nextstep.users.domain.NsUser; +import java.util.List; import java.util.Set; public class FreeSession extends Session { - public FreeSession(Long id, SessionImage sessionImage, SessionStatus sessionStatus, SessionDate sessionDate) { - super(id, sessionImage, sessionStatus, sessionDate); + public FreeSession(Long id, List sessionImage, RecruitStatus recruitStatus, SessionDate sessionDate) { + super(id, sessionImage, recruitStatus, sessionDate); } - public FreeSession(Long id, SessionImage sessionImage, SessionStatus sessionStatus, SessionDate sessionDate, Set students) { - super(id, sessionImage, sessionStatus, sessionDate, students); + public FreeSession(Long id, List sessionImage, RecruitStatus recruitStatus, SessionDate sessionDate, Set students) { + super(id, sessionImage, recruitStatus, sessionDate, students); + } + + public FreeSession(Long id, List sessionImage, RecruitStatus recruitStatus, SessionProgressStatus sessionProgressStatus, SessionDate sessionDate, Set students, Set approveStudents) { + super(id, sessionImage, recruitStatus, sessionProgressStatus, sessionDate, students, approveStudents); } diff --git a/src/main/java/nextstep/courses/domain/FreeSessionRepository.java b/src/main/java/nextstep/courses/domain/FreeSessionRepository.java new file mode 100644 index 000000000..66c2c652e --- /dev/null +++ b/src/main/java/nextstep/courses/domain/FreeSessionRepository.java @@ -0,0 +1,11 @@ +package nextstep.courses.domain; + +import java.util.Optional; + +public interface FreeSessionRepository { + Sessions findByCourseId(Long courseId); + + Optional findBySessionId(Long sessionId); + + void saveSession(FreeSession session, Long courseId); +} diff --git a/src/main/java/nextstep/courses/domain/PaySession.java b/src/main/java/nextstep/courses/domain/PaySession.java index 3c3442f2b..69db7e6fb 100644 --- a/src/main/java/nextstep/courses/domain/PaySession.java +++ b/src/main/java/nextstep/courses/domain/PaySession.java @@ -5,6 +5,7 @@ import nextstep.payments.domain.Payment; import nextstep.users.domain.NsUser; +import java.util.List; import java.util.Set; public class PaySession extends Session { @@ -12,16 +13,24 @@ public class PaySession extends Session { private final int maximumStudents; private final long amount; - public PaySession(Long id, SessionImage sessionImage, SessionStatus sessionStatus, SessionDate sessionDate, int maximumStudents, long amount) { - super(id, sessionImage, sessionStatus, sessionDate); + public PaySession(Long id, List sessionImage, RecruitStatus recruitStatus, SessionDate sessionDate, int maximumStudents, long amount) { + super(id, sessionImage, recruitStatus, sessionDate); assertValidMaximumStudents(maximumStudents); assertValidAmount(amount); this.amount = amount; this.maximumStudents = maximumStudents; } - public PaySession(Long id, SessionImage sessionImage, SessionStatus sessionStatus, SessionDate sessionDate, Set students, int maximumStudents, long amount) { - super(id, sessionImage, sessionStatus, sessionDate, students); + public PaySession(Long id, List sessionImage, RecruitStatus recruitStatus, SessionDate sessionDate, Set students, int maximumStudents, long amount) { + super(id, sessionImage, recruitStatus, sessionDate, students); + assertValidMaximumStudents(maximumStudents); + assertValidAmount(amount); + this.amount = amount; + this.maximumStudents = maximumStudents; + } + + public PaySession(Long id, List sessionImage, RecruitStatus recruitStatus, SessionProgressStatus sessionProgressStatus, SessionDate sessionDate, Set students, Set approveStudents, int maximumStudents, long amount) { + super(id, sessionImage, recruitStatus, sessionProgressStatus, sessionDate, students, approveStudents); assertValidMaximumStudents(maximumStudents); assertValidAmount(amount); this.amount = amount; diff --git a/src/main/java/nextstep/courses/domain/PaySessionRepository.java b/src/main/java/nextstep/courses/domain/PaySessionRepository.java new file mode 100644 index 000000000..b263bec41 --- /dev/null +++ b/src/main/java/nextstep/courses/domain/PaySessionRepository.java @@ -0,0 +1,11 @@ +package nextstep.courses.domain; + +import java.util.Optional; + +public interface PaySessionRepository { + Sessions findByCourseId(Long courseId); + + Optional findBySessionId(Long sessionId); + + void saveSession(PaySession session, Long courseId); +} diff --git a/src/main/java/nextstep/courses/domain/RecruitStatus.java b/src/main/java/nextstep/courses/domain/RecruitStatus.java new file mode 100644 index 000000000..aaedaf4f9 --- /dev/null +++ b/src/main/java/nextstep/courses/domain/RecruitStatus.java @@ -0,0 +1,17 @@ +package nextstep.courses.domain; + +public enum RecruitStatus { + + RECRUIT, + NOT_RECRUIT; + + public static RecruitStatus findByName(String name) { + return RecruitStatus.valueOf(name.toUpperCase()); + } + + public boolean isRecruit() { + return this.equals(RECRUIT); + } + + +} diff --git a/src/main/java/nextstep/courses/domain/Session.java b/src/main/java/nextstep/courses/domain/Session.java index c832e8a64..535a70958 100644 --- a/src/main/java/nextstep/courses/domain/Session.java +++ b/src/main/java/nextstep/courses/domain/Session.java @@ -4,29 +4,40 @@ import nextstep.payments.domain.Payment; import nextstep.users.domain.NsUser; -import java.time.LocalDate; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; +import java.util.*; public abstract class Session { private final Long id; - private final SessionImage sessionImage; - private SessionStatus sessionStatus; + private final List sessionImage; + private RecruitStatus recruitStatus; + private SessionProgressStatus sessionProgressStatus; private final Set students; + private final Set approveStudents; private final SessionDate sessionDate; - public Session(Long id, SessionImage sessionImage, SessionStatus sessionStatus, SessionDate sessionDate) { - this(id, sessionImage,sessionStatus, sessionDate, new HashSet<>()); + + public Session(Long id, List sessionImage, RecruitStatus recruitStatus, SessionDate sessionDate) { + this(id, sessionImage, recruitStatus, sessionDate, new HashSet<>()); + } + + public Session(Long id, List sessionImage, RecruitStatus recruitStatus, SessionProgressStatus sessionProgressStatus, SessionDate sessionDate) { + this(id, sessionImage, recruitStatus, sessionProgressStatus, sessionDate, new HashSet<>(), new HashSet<>()); + } + + public Session(Long id, List sessionImage, RecruitStatus recruitStatus, SessionDate sessionDate, Set students) { + this(id, sessionImage, recruitStatus, SessionProgressStatus.PREPARE, sessionDate, students, new HashSet<>()); } - public Session(Long id, SessionImage sessionImage, SessionStatus sessionStatus, SessionDate sessionDate, Set students) { + public Session(Long id, List sessionImage, RecruitStatus recruitStatus, SessionProgressStatus sessionProgressStatus, SessionDate sessionDate, Set students, Set approveStudents) { this.id = id; this.sessionImage = sessionImage; - this.sessionStatus = sessionStatus; + this.recruitStatus = recruitStatus; + this.sessionProgressStatus = sessionProgressStatus; this.sessionDate = sessionDate; this.students = students; + this.approveStudents = approveStudents; + } public final void enrollmentUser(NsUser user, Payment payment) { @@ -37,6 +48,14 @@ public final void enrollmentUser(NsUser user, Payment payment) { students.add(user); } + public final void removeNotApproveUser() { + students.removeIf(student -> !approveStudents.contains(student)); + } + + public final void addApproveStudent(NsUser nsUser) { + approveStudents.add(nsUser); + } + private void assertNotDuplicateStudents(NsUser user) { if (students.contains(user)) { throw new NotRecruitException(); @@ -44,7 +63,7 @@ private void assertNotDuplicateStudents(NsUser user) { } private void assertRecruit() { - if (!sessionStatus.isRecruit()) { + if (!recruitStatus.isRecruit()) { throw new NotRecruitException(); } } @@ -53,22 +72,34 @@ public Set getStudents() { return new HashSet<>(students); } + public Set getApproveStudents() { + return new HashSet<>(approveStudents); + } + public Long getId() { return id; } - public SessionImage getSessionImage() { + public List getSessionImage() { return sessionImage; } - public SessionStatus getSessionStatus() { - return sessionStatus; + public RecruitStatus getRecruitStatus() { + return recruitStatus; + } + + public SessionProgressStatus getSessionProgressStatus() { + return sessionProgressStatus; } public SessionDate getSessionDate() { return sessionDate; } + public void changeProgressStatus(SessionProgressStatus sessionProgressStatus) { + this.sessionProgressStatus = sessionProgressStatus; + } + abstract protected void assertSatisfiedCondition(NsUser user, Payment payment); diff --git a/src/main/java/nextstep/courses/domain/SessionProgressStatus.java b/src/main/java/nextstep/courses/domain/SessionProgressStatus.java new file mode 100644 index 000000000..8ba713603 --- /dev/null +++ b/src/main/java/nextstep/courses/domain/SessionProgressStatus.java @@ -0,0 +1,11 @@ +package nextstep.courses.domain; + +public enum SessionProgressStatus { + PREPARE, + RUN, + END; + + public static SessionProgressStatus findByName(String name) { + return SessionProgressStatus.valueOf(name.toUpperCase()); + } +} diff --git a/src/main/java/nextstep/courses/domain/SessionRepository.java b/src/main/java/nextstep/courses/domain/SessionRepository.java deleted file mode 100644 index 0411c9a5c..000000000 --- a/src/main/java/nextstep/courses/domain/SessionRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package nextstep.courses.domain; - -import java.util.Optional; - -public interface SessionRepository { - Sessions findByCourseId(Long courseId); - Optional findBySessionId(Long sessionId, Class type); - void saveSession(Session session, Long courseId); -} diff --git a/src/main/java/nextstep/courses/domain/SessionStatus.java b/src/main/java/nextstep/courses/domain/SessionStatus.java deleted file mode 100644 index 6355a3220..000000000 --- a/src/main/java/nextstep/courses/domain/SessionStatus.java +++ /dev/null @@ -1,19 +0,0 @@ -package nextstep.courses.domain; - -import java.util.Optional; - -public enum SessionStatus { - PREPARE, - RECRUIT, - END; - - public static SessionStatus findByName(String name) { - return SessionStatus.valueOf(name.toUpperCase()); - } - - public boolean isRecruit() { - return this.equals(RECRUIT); - } - - -} diff --git a/src/main/java/nextstep/courses/domain/Sessions.java b/src/main/java/nextstep/courses/domain/Sessions.java index 6fa628f32..698471e2a 100644 --- a/src/main/java/nextstep/courses/domain/Sessions.java +++ b/src/main/java/nextstep/courses/domain/Sessions.java @@ -15,6 +15,13 @@ public Sessions() { this.sessions = new HashSet<>(); } + public static Sessions concatSessions(Sessions sessions1, Sessions sessions2) { + Set concatResult = new HashSet<>(sessions1.sessions); + concatResult.addAll(new HashSet<>(sessions2.sessions)); + + return new Sessions(concatResult); + } + public void addSession(Session session) { String errorMessage = "이미 등록된 강의입니다."; diff --git a/src/main/java/nextstep/courses/infrastructure/JdbcCourseRepository.java b/src/main/java/nextstep/courses/infrastructure/JdbcCourseRepository.java index 64e4f694f..862322b3e 100644 --- a/src/main/java/nextstep/courses/infrastructure/JdbcCourseRepository.java +++ b/src/main/java/nextstep/courses/infrastructure/JdbcCourseRepository.java @@ -16,11 +16,13 @@ public class JdbcCourseRepository implements CourseRepository { private JdbcOperations jdbcTemplate; - private final SessionRepository sessionRepository; + private final FreeSessionRepository freeSessionRepository; + private final PaySessionRepository paySessionRepository; - public JdbcCourseRepository(JdbcOperations jdbcTemplate, SessionRepository sessionRepository) { + public JdbcCourseRepository(JdbcOperations jdbcTemplate, FreeSessionRepository freeSessionRepository, PaySessionRepository paySessionRepository) { this.jdbcTemplate = jdbcTemplate; - this.sessionRepository = sessionRepository; + this.freeSessionRepository = freeSessionRepository; + this.paySessionRepository = paySessionRepository; } @Override @@ -38,8 +40,15 @@ public int save(Course course) { return ps; }, keyHolder); - course.getSessions().getSessions().forEach(session -> - sessionRepository.saveSession(session, (long) keyHolder.getKey()) + course.getSessions().getSessions().forEach(session -> { + if (session instanceof PaySession) { + paySessionRepository.saveSession((PaySession) session, (long) keyHolder.getKey()); + } + + if (session instanceof FreeSession) { + freeSessionRepository.saveSession((FreeSession) session, (long) keyHolder.getKey()); + } + } ); return result; @@ -48,7 +57,7 @@ public int save(Course course) { @Override public Course findById(Long id) { String sql = "select id, title, creator_id, created_at, updated_at from course where id = ?"; - Sessions sessions = sessionRepository.findByCourseId(id); + Sessions sessions = Sessions.concatSessions(freeSessionRepository.findByCourseId(id), paySessionRepository.findByCourseId(id)); RowMapper rowMapper = (rs, rowNum) -> new Course( rs.getLong(1), diff --git a/src/main/java/nextstep/courses/infrastructure/JdbcFreeSessionRepository.java b/src/main/java/nextstep/courses/infrastructure/JdbcFreeSessionRepository.java new file mode 100644 index 000000000..816a22a00 --- /dev/null +++ b/src/main/java/nextstep/courses/infrastructure/JdbcFreeSessionRepository.java @@ -0,0 +1,168 @@ +package nextstep.courses.infrastructure; + +import nextstep.courses.domain.*; +import nextstep.users.domain.NsUser; +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; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +@Repository("sessionRepository") +public class JdbcFreeSessionRepository implements FreeSessionRepository { + private final JdbcOperations jdbcTemplate; + + private final String sessionImageTableName = "free_session_image"; + private final String studentsTableName = "free_session_students"; + private final String approveStudentsTableName = "free_session_approve_students"; + private final String sessionTableName = "free_session"; + + public JdbcFreeSessionRepository(JdbcOperations jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + @Override + public Sessions findByCourseId(Long courseId) { + String freeSessionSql = "select id from " + sessionTableName + " where course_id = ?"; + + List freeSessionIds = jdbcTemplate.query(freeSessionSql, ((rs, rowNum) -> rs.getLong(1)), courseId); + + Set sessions = freeSessionIds.stream() + .map(this::findBySessionId) + .filter(Optional::isPresent) + .map(Optional::get).collect(Collectors.toSet()); + + + return new Sessions(sessions); + } + + @Override + public Optional findBySessionId(Long sessionId) { + String paySessionSql = "select id, recruit_status, progress_status, start_date, end_date from " + sessionTableName + " where id = ?"; + + + List sessionImage = findSessionImageBySessionId(sessionId); + Set students = findSessionStudentsBySessionId(sessionId); + Set approveStudents = findSessionApproveStudentsBySessionId(sessionId); + + RowMapper sessionMapper = (rs, rowNum) -> + new FreeSession(rs.getLong(1), + sessionImage, + RecruitStatus.findByName(rs.getString(2)), + SessionProgressStatus.findByName(rs.getString(3)), + new SessionDate(toLocalDate(rs.getTimestamp(4)), toLocalDate(rs.getTimestamp(5))), + students, + approveStudents + ); + + return Optional.ofNullable(jdbcTemplate.queryForObject(paySessionSql, sessionMapper, sessionId)); + + } + + @Override + public void saveSession(FreeSession session, Long courseId) { + String sql = "insert into " + sessionTableName + " (id, progress_status, recruit_status, start_date, end_date, course_id) values (?, ?, ?, ?, ?, ?)"; + + jdbcTemplate.update(sql, + session.getId(), + session.getSessionProgressStatus().name(), + session.getRecruitStatus().name(), + session.getSessionDate().getStartDate(), + session.getSessionDate().getEndDate(), + courseId); + + insertStudents(session); + insertSessionImage(session); + insertApproveStudents(session); + } + + private List findSessionImageBySessionId(Long sessionId) { + String sessionImageSql = "select id, image_path, width, height, image_size from " + sessionImageTableName + " where session_id = ?"; + + RowMapper sessionImageMapper = (rs, rowNum) -> + new SessionImage(rs.getLong(1), rs.getString(2), rs.getInt(3), rs.getInt(4), rs.getInt(5)); + + + return jdbcTemplate.query(sessionImageSql, sessionImageMapper, sessionId); + } + + private Set findSessionStudentsBySessionId(Long sessionId) { + String studentsSql = "select ns_user.id, ns_user.user_id, ns_user.password, ns_user.name, ns_user.email, ns_user.created_at, ns_user.updated_at " + + "from " + studentsTableName + " join ns_user on " + studentsTableName + ".student_id = ns_user.id " + + "where " + studentsTableName + ".session_id = ?"; + + RowMapper studentsMapper = (rs, rowNum) -> + new NsUser( + rs.getLong(1), + rs.getString(2), + rs.getString(3), + rs.getString(4), + rs.getString(5), + toLocalDateTime(rs.getTimestamp(6)), + toLocalDateTime(rs.getTimestamp(7))); + + return new HashSet<>(jdbcTemplate.query(studentsSql, studentsMapper, sessionId)); + } + + + private Set findSessionApproveStudentsBySessionId(Long sessionId) { + String studentsSql = "select ns_user.id, ns_user.user_id, ns_user.password, ns_user.name, ns_user.email, ns_user.created_at, ns_user.updated_at " + + "from " + approveStudentsTableName + " join ns_user on " + approveStudentsTableName + ".student_id = ns_user.id " + + "where " + approveStudentsTableName + ".session_id = ?"; + + RowMapper studentsMapper = (rs, rowNum) -> + new NsUser( + rs.getLong(1), + rs.getString(2), + rs.getString(3), + rs.getString(4), + rs.getString(5), + toLocalDateTime(rs.getTimestamp(6)), + toLocalDateTime(rs.getTimestamp(7))); + + return new HashSet<>(jdbcTemplate.query(studentsSql, studentsMapper, sessionId)); + } + + private void insertStudents(Session session) { + String sql = "insert into " + studentsTableName + " (session_id, student_id) values (?, ?)"; + + session.getStudents().forEach(student -> + jdbcTemplate.update(sql, session.getId(), student.getId())); + } + + private void insertApproveStudents(Session session) { + String sql = "insert into " + approveStudentsTableName + " (session_id, student_id) values (?, ?)"; + + session.getApproveStudents().forEach(student -> + jdbcTemplate.update(sql, session.getId(), student.getId())); + } + + private void insertSessionImage(Session session) { + String sql = "insert into " + sessionImageTableName + " (id, image_path, width, height, image_size, session_id) values (?, ?, ?, ?, ?, ?)"; + List sessionImages = session.getSessionImage(); + + sessionImages.forEach(sessionImage -> { + SessionImageSize sessionImageSize = sessionImage.getSessionImageSize(); + jdbcTemplate.update(sql, sessionImage.getId(), sessionImage.getPath(), sessionImageSize.getWidth(), sessionImageSize.getHeight(), sessionImageSize.getSize(), session.getId()); + }); + + } + + private LocalDateTime toLocalDateTime(Timestamp timestamp) { + if (timestamp == null) { + return null; + } + return timestamp.toLocalDateTime(); + } + + private LocalDate toLocalDate(Timestamp timestamp) { + if (timestamp == null) { + return null; + } + return timestamp.toLocalDateTime().toLocalDate(); + } +} diff --git a/src/main/java/nextstep/courses/infrastructure/JdbcPaySessionRepository.java b/src/main/java/nextstep/courses/infrastructure/JdbcPaySessionRepository.java new file mode 100644 index 000000000..f2469bba8 --- /dev/null +++ b/src/main/java/nextstep/courses/infrastructure/JdbcPaySessionRepository.java @@ -0,0 +1,175 @@ +package nextstep.courses.infrastructure; + +import nextstep.courses.domain.*; +import nextstep.users.domain.NsUser; +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; +import java.time.LocalDateTime; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +@Repository("sessionRepository") +public class JdbcPaySessionRepository implements PaySessionRepository { + private final JdbcOperations jdbcTemplate; + + private final String sessionImageTableName = "pay_session_image"; + private final String studentsTableName = "pay_session_students"; + private final String approveStudentsTableName = "pay_session_approve_students"; + private final String sessionTableName = "pay_session"; + + public JdbcPaySessionRepository(JdbcOperations jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + @Override + public Sessions findByCourseId(Long courseId) { + String paySessionSql = "select id from pay_session where course_id = ?"; + + List paySessionIds = jdbcTemplate.query(paySessionSql, ((rs, rowNum) -> rs.getLong(1)), courseId); + + Set sessions = paySessionIds.stream() + .map(this::findBySessionId) + .filter(Optional::isPresent) + .map(Optional::get).collect(Collectors.toSet()); + + + return new Sessions(sessions); + } + + @Override + public Optional findBySessionId(Long sessionId) { + String paySessionSql = "select id, recruit_status, progress_status, amount, maximum_students, start_date, end_date from " + sessionTableName + " where id = ?"; + + + List sessionImage = findSessionImageBySessionId(sessionId); + Set students = findSessionStudentsBySessionId(sessionId); + Set approveStudents = findSessionApproveStudentsBySessionId(sessionId); + + RowMapper sessionMapper = (rs, rowNum) -> + new PaySession(rs.getLong(1), + sessionImage, + RecruitStatus.findByName(rs.getString(2)), + SessionProgressStatus.findByName(rs.getString(3)), + new SessionDate(toLocalDate(rs.getTimestamp(6)), toLocalDate(rs.getTimestamp(7))), + students, + approveStudents, + rs.getInt(5), + rs.getInt(4) + ); + + return Optional.ofNullable(jdbcTemplate.queryForObject(paySessionSql, sessionMapper, sessionId)); + + } + + @Override + public void saveSession(PaySession session, Long courseId) { + String sql = "insert into " + sessionTableName + " (id, progress_status, recruit_status, amount, maximum_students, start_date, end_date, course_id) values (?, ?, ?, ?, ?, ?, ?, ?)"; + + jdbcTemplate.update(sql, + session.getId(), + session.getSessionProgressStatus().name(), + session.getRecruitStatus().name(), + session.getAmount(), + session.getMaximumStudents(), + session.getSessionDate().getStartDate(), + session.getSessionDate().getEndDate(), + courseId); + + insertStudents(session); + insertSessionImage(session); + insertApproveStudents(session); + } + + private List findSessionImageBySessionId(Long sessionId) { + String sessionImageSql = "select id, image_path, width, height, image_size from " + sessionImageTableName + " where session_id = ?"; + + RowMapper sessionImageMapper = (rs, rowNum) -> + new SessionImage(rs.getLong(1), rs.getString(2), rs.getInt(3), rs.getInt(4), rs.getInt(5)); + + + return jdbcTemplate.query(sessionImageSql, sessionImageMapper, sessionId); + } + + private Set findSessionStudentsBySessionId(Long sessionId) { + String studentsSql = "select ns_user.id, ns_user.user_id, ns_user.password, ns_user.name, ns_user.email, ns_user.created_at, ns_user.updated_at " + + "from " + studentsTableName + " join ns_user on " + studentsTableName + ".student_id = ns_user.id " + + "where " + studentsTableName + ".session_id = ?"; + + RowMapper studentsMapper = (rs, rowNum) -> + new NsUser( + rs.getLong(1), + rs.getString(2), + rs.getString(3), + rs.getString(4), + rs.getString(5), + toLocalDateTime(rs.getTimestamp(6)), + toLocalDateTime(rs.getTimestamp(7))); + + return new HashSet<>(jdbcTemplate.query(studentsSql, studentsMapper, sessionId)); + } + + + private Set findSessionApproveStudentsBySessionId(Long sessionId) { + String studentsSql = "select ns_user.id, ns_user.user_id, ns_user.password, ns_user.name, ns_user.email, ns_user.created_at, ns_user.updated_at " + + "from " + approveStudentsTableName + " join ns_user on " + approveStudentsTableName + ".student_id = ns_user.id " + + "where " + approveStudentsTableName + ".session_id = ?"; + + RowMapper studentsMapper = (rs, rowNum) -> + new NsUser( + rs.getLong(1), + rs.getString(2), + rs.getString(3), + rs.getString(4), + rs.getString(5), + toLocalDateTime(rs.getTimestamp(6)), + toLocalDateTime(rs.getTimestamp(7))); + + return new HashSet<>(jdbcTemplate.query(studentsSql, studentsMapper, sessionId)); + } + + private void insertStudents(Session session) { + String sql = "insert into " + studentsTableName + " (session_id, student_id) values (?, ?)"; + + session.getStudents().forEach(student -> + jdbcTemplate.update(sql, session.getId(), student.getId())); + } + + private void insertApproveStudents(Session session) { + String sql = "insert into " + approveStudentsTableName + " (session_id, student_id) values (?, ?)"; + + session.getApproveStudents().forEach(student -> + jdbcTemplate.update(sql, session.getId(), student.getId())); + } + + private void insertSessionImage(Session session) { + String sql = "insert into " + sessionImageTableName + " (id, image_path, width, height, image_size, session_id) values (?, ?, ?, ?, ?, ?)"; + List sessionImages = session.getSessionImage(); + + sessionImages.forEach(sessionImage -> { + SessionImageSize sessionImageSize = sessionImage.getSessionImageSize(); + jdbcTemplate.update(sql, sessionImage.getId(), sessionImage.getPath(), sessionImageSize.getWidth(), sessionImageSize.getHeight(), sessionImageSize.getSize(), session.getId()); + }); + + } + + private LocalDateTime toLocalDateTime(Timestamp timestamp) { + if (timestamp == null) { + return null; + } + return timestamp.toLocalDateTime(); + } + + private LocalDate toLocalDate(Timestamp timestamp) { + if (timestamp == null) { + return null; + } + return timestamp.toLocalDateTime().toLocalDate(); + } +} diff --git a/src/main/java/nextstep/courses/infrastructure/JdbcSessionRepository.java b/src/main/java/nextstep/courses/infrastructure/JdbcSessionRepository.java deleted file mode 100644 index 01f21d16a..000000000 --- a/src/main/java/nextstep/courses/infrastructure/JdbcSessionRepository.java +++ /dev/null @@ -1,204 +0,0 @@ -package nextstep.courses.infrastructure; - -import nextstep.courses.domain.*; -import nextstep.users.domain.NsUser; -import nextstep.users.domain.UserRepository; -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; -import java.time.LocalDateTime; -import java.util.*; -import java.util.stream.Collectors; - -@Repository("sessionRepository") -public class JdbcSessionRepository implements SessionRepository { - private final JdbcOperations jdbcTemplate; - - public JdbcSessionRepository(JdbcOperations jdbcTemplate) { - this.jdbcTemplate = jdbcTemplate; - } - - @Override - public Sessions findByCourseId(Long courseId) { - String paySessionSql = "select id from pay_session where course_id = ?"; - String freeSessionSql = "select id from free_session where course_id = ?"; - Set sessions = new HashSet<>(); - - List paySessionIds = jdbcTemplate.query(paySessionSql, ((rs, rowNum) -> rs.getLong(1)), courseId); - List freeSessionIds = jdbcTemplate.query(freeSessionSql, ((rs, rowNum) -> rs.getLong(1)), courseId); - - sessions.addAll(paySessionIds.stream() - .map(id -> findBySessionId(id, PaySession.class)) - .filter(Optional::isPresent) - .map(Optional::get).collect(Collectors.toSet())); - - sessions.addAll(freeSessionIds.stream() - .map(id -> findBySessionId(id, FreeSession.class)) - .filter(Optional::isPresent) - .map(Optional::get).collect(Collectors.toSet())); - - - return new Sessions(sessions); - } - - @Override - public Optional findBySessionId(Long sessionId, Class type) { - if (type.isAssignableFrom(PaySession.class)) { - return findPaySessionById(sessionId); - } - if (type.isAssignableFrom(FreeSession.class)) { - return findFreeSessionById(sessionId); - } - - throw new NoSuchElementException(); - } - - private Optional findFreeSessionById(Long sessionId) { - String paySessionSql = "select id, session_status, start_date, end_date from free_session where id = ?"; - String sessionImageTableName = "free_session_image"; - String studentsTableName = "free_session_students"; - - SessionImage sessionImage = findSessionImageBySessionId(sessionId, sessionImageTableName); - Set students = findSessionStudentsBySessionId(sessionId, studentsTableName); - - RowMapper sessionMapper = (rs, rowNum) -> - new FreeSession(rs.getLong(1), - sessionImage, - SessionStatus.findByName(rs.getString(2)), - new SessionDate(toLocalDate(rs.getTimestamp(3)), toLocalDate(rs.getTimestamp(4))), - students - ); - - return Optional.ofNullable(jdbcTemplate.queryForObject(paySessionSql, sessionMapper, sessionId)); - } - - private Optional findPaySessionById(Long sessionId) { - String paySessionSql = "select id, session_status, amount, maximum_students, start_date, end_date from pay_session where id = ?"; - String sessionImageTableName = "pay_session_image"; - String studentsTableName = "pay_session_students"; - - SessionImage sessionImage = findSessionImageBySessionId(sessionId, sessionImageTableName); - Set students = findSessionStudentsBySessionId(sessionId, studentsTableName); - - RowMapper sessionMapper = (rs, rowNum) -> - new PaySession(rs.getLong(1), - sessionImage, - SessionStatus.findByName(rs.getString(2)), - new SessionDate(toLocalDate(rs.getTimestamp(5)), toLocalDate(rs.getTimestamp(6))), - students, - rs.getInt(4), - rs.getInt(3) - ); - - return Optional.ofNullable(jdbcTemplate.queryForObject(paySessionSql, sessionMapper, sessionId)); - } - - @Override - public void saveSession(Session session, Long courseId) { - if (session instanceof PaySession) { - savePaySession((PaySession) session, courseId); - return; - } - - if (session instanceof FreeSession) { - saveFreeSession((FreeSession) session, courseId); - return; - } - - throw new NoSuchElementException(); - } - - private void savePaySession(PaySession paySession, Long courseId) { - String sql = "insert into pay_session (id, session_status, amount, maximum_students, start_date, end_date, course_id) values (?, ?, ?, ?, ?, ?, ?)"; - String studentsTableName = "pay_session_students"; - String sessionImageTableName = "pay_session_image"; - - jdbcTemplate.update(sql, - paySession.getId(), - paySession.getSessionStatus().name(), - paySession.getAmount(), - paySession.getMaximumStudents(), - paySession.getSessionDate().getStartDate(), - paySession.getSessionDate().getEndDate(), - courseId); - - insertStudents(paySession, studentsTableName); - insertSessionImage(paySession, sessionImageTableName); - } - - private void saveFreeSession(FreeSession freeSession, Long courseId) { - String sql = "insert into free_session (id, session_status, start_date, end_date, course_id) values (?, ?, ?, ?, ?)"; - String studentsTableName = "free_session_students"; - String sessionImageTableName = "free_session_image"; - - jdbcTemplate.update(sql, - freeSession.getId(), - freeSession.getSessionStatus().name(), - freeSession.getSessionDate().getStartDate(), - freeSession.getSessionDate().getEndDate(), - courseId); - - insertStudents(freeSession, studentsTableName); - insertSessionImage(freeSession, sessionImageTableName); - } - - private SessionImage findSessionImageBySessionId(Long sessionId, String tableName) { - String sessionImageSql = "select id, image_path, width, height, image_size from " + tableName + " where session_id = ?"; - - RowMapper sessionImageMapper = (rs, rowNum) -> - new SessionImage(rs.getLong(1), rs.getString(2), rs.getInt(3), rs.getInt(4), rs.getInt(5)); - - - return jdbcTemplate.queryForObject(sessionImageSql, sessionImageMapper, sessionId); - } - - private Set findSessionStudentsBySessionId(Long sessionId, String tableName) { - String studentsSql = "select ns_user.id, ns_user.user_id, ns_user.password, ns_user.name, ns_user.email, ns_user.created_at, ns_user.updated_at " + - "from " + tableName + " join ns_user on " + tableName + ".student_id = ns_user.id " + - "where " + tableName +".session_id = ?"; - - RowMapper studentsMapper = (rs, rowNum) -> - new NsUser( - rs.getLong(1), - rs.getString(2), - rs.getString(3), - rs.getString(4), - rs.getString(5), - toLocalDateTime(rs.getTimestamp(6)), - toLocalDateTime(rs.getTimestamp(7))); - - return new HashSet<>(jdbcTemplate.query(studentsSql, studentsMapper, sessionId)); - } - - private void insertStudents(Session session, String tableName) { - String sql = "insert into " + tableName + " (session_id, student_id) values (?, ?)"; - - session.getStudents().forEach(student -> - jdbcTemplate.update(sql, session.getId(), student.getId())); - } - - private void insertSessionImage(Session session, String tableName) { - String sql = "insert into " + tableName + " (id, image_path, width, height, image_size, session_id) values (?, ?, ?, ?, ?, ?)"; - SessionImage sessionImage = session.getSessionImage(); - SessionImageSize sessionImageSize = sessionImage.getSessionImageSize(); - - jdbcTemplate.update(sql, sessionImage.getId(), sessionImage.getPath(), sessionImageSize.getWidth(), sessionImageSize.getHeight(), sessionImageSize.getSize(), session.getId()); - } - - private LocalDateTime toLocalDateTime(Timestamp timestamp) { - if (timestamp == null) { - return null; - } - return timestamp.toLocalDateTime(); - } - - private LocalDate toLocalDate(Timestamp timestamp) { - if (timestamp == null) { - return null; - } - return timestamp.toLocalDateTime().toLocalDate(); - } -} diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index f27c2a0cb..e9fdee026 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -108,3 +108,26 @@ create table delete_history ( deleted_by_id bigint, primary key (id) ); + + +alter table pay_session rename column session_status to recruit_status; +alter table free_session rename column session_status to recruit_status; + +alter table pay_session add column progress_status varchar(20) default 'PREPARE'; +alter table free_session add column progress_status varchar(20) default 'PREPARE'; + +create table pay_session_approve_students ( + session_id bigint, + student_id bigint, + foreign key (session_id) REFERENCES pay_session (id), + foreign key (student_id) REFERENCES ns_user (id), + primary key (session_id, student_id) +); + +create table free_session_approve_students ( + session_id bigint, + student_id bigint, + foreign key (session_id) REFERENCES free_session (id), + foreign key (student_id) REFERENCES ns_user (id), + primary key (session_id, student_id) +); \ No newline at end of file diff --git a/src/test/java/nextstep/courses/domain/CourseTest.java b/src/test/java/nextstep/courses/domain/CourseTest.java index 6348bed5e..b715c651f 100644 --- a/src/test/java/nextstep/courses/domain/CourseTest.java +++ b/src/test/java/nextstep/courses/domain/CourseTest.java @@ -16,10 +16,10 @@ public class CourseTest { void testCourse() { Course course = new Course("test", 1L); course.addSession(TestSessionFactory.recruitStatusSession(sessionId)); - course.addSession(TestSessionFactory.recruitStatusSession2(sessionId)); + course.addSession(TestSessionFactory.recruitStatusOtherSession(sessionId)); Sessions sessions = course.getSessions(); - assertThat(sessions.getSessions()).hasSize(2).contains(TestSessionFactory.recruitStatusSession(sessionId), TestSessionFactory.recruitStatusSession2(sessionId)); + assertThat(sessions.getSessions()).hasSize(2).contains(TestSessionFactory.recruitStatusSession(sessionId), TestSessionFactory.recruitStatusOtherSession(sessionId)); } @Test diff --git a/src/test/java/nextstep/courses/domain/FreeSessionTest.java b/src/test/java/nextstep/courses/domain/FreeSessionTest.java index 7efcf1c33..a464c0813 100644 --- a/src/test/java/nextstep/courses/domain/FreeSessionTest.java +++ b/src/test/java/nextstep/courses/domain/FreeSessionTest.java @@ -6,18 +6,20 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import java.util.List; + import static org.assertj.core.api.Assertions.assertThat; public class FreeSessionTest { - public static FreeSession F1 = new FreeSession(1L, SessionImageTest.S1, SessionStatus.RECRUIT, SessionDateTest.of()); + public static FreeSession F1 = new FreeSession(1L, List.of(SessionImageTest.S1), RecruitStatus.RECRUIT, SessionDateTest.of()); private final NsUser student = NsUserTest.JAVAJIGI; private final Long sessionId = 1L; @Test @DisplayName("무료 강의 수강신청 되는 지 테스트") void testEnrollment() { - FreeSession freeSession = new FreeSession(sessionId, SessionImageTest.S1, SessionStatus.RECRUIT, SessionDateTest.of()); + FreeSession freeSession = new FreeSession(sessionId, List.of(SessionImageTest.S1), RecruitStatus.RECRUIT, SessionDateTest.of()); freeSession.enrollmentUser(student, new Payment()); assertThat(freeSession.getStudents()).hasSize(1).containsExactly(student); diff --git a/src/test/java/nextstep/courses/domain/PaySessionTest.java b/src/test/java/nextstep/courses/domain/PaySessionTest.java index 36dfb3616..2fdf0c789 100644 --- a/src/test/java/nextstep/courses/domain/PaySessionTest.java +++ b/src/test/java/nextstep/courses/domain/PaySessionTest.java @@ -5,18 +5,16 @@ import nextstep.payments.domain.Payment; import nextstep.users.domain.NsUser; import nextstep.users.domain.NsUserTest; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; + +import java.util.List; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; public class PaySessionTest { - public static PaySession P1 = new PaySession(1L, SessionImageTest.S1, SessionStatus.RECRUIT, SessionDateTest.of(), 5, 1000); + public static PaySession P1 = new PaySession(1L, List.of(SessionImageTest.S1), RecruitStatus.RECRUIT, SessionDateTest.of(), 5, 1000); private final int maximumStudents = 5; private final long amount = 1000; private final Long sessionId = 1L; @@ -28,7 +26,7 @@ public class PaySessionTest { @Test @DisplayName("유료 강의 수강신청 되는 지 테스트") void testEnrollment() { - PaySession paySession = new PaySession(sessionId, SessionImageTest.S1, SessionStatus.RECRUIT, SessionDateTest.of(), maximumStudents, amount); + PaySession paySession = new PaySession(sessionId, List.of(SessionImageTest.S1), RecruitStatus.RECRUIT, SessionDateTest.of(), maximumStudents, amount); paySession.enrollmentUser(student, payment); assertThat(paySession.getStudents()).hasSize(1).containsExactly(student); @@ -39,7 +37,7 @@ void testEnrollment() { @Test @DisplayName("수강신청 인원을 넘을 경우 에러 발생") void testOverMaximumStudents() { - PaySession paySession = new PaySession(sessionId, SessionImageTest.S1, SessionStatus.RECRUIT, SessionDateTest.of(), 1, amount); + PaySession paySession = new PaySession(sessionId, List.of(SessionImageTest.S1), RecruitStatus.RECRUIT, SessionDateTest.of(), 1, amount); paySession.enrollmentUser(student, payment); assertThatThrownBy(() -> paySession.enrollmentUser(NsUserTest.SANJIGI, payment)).isInstanceOf(NotRecruitException.class); @@ -48,7 +46,7 @@ void testOverMaximumStudents() { @Test @DisplayName("결제 금액이 모자란 경우 에러 발생") void testLackPoint() { - PaySession paySession = new PaySession(sessionId, SessionImageTest.S1, SessionStatus.RECRUIT, SessionDateTest.of(), 1, amount + 1); + PaySession paySession = new PaySession(sessionId, List.of(SessionImageTest.S1), RecruitStatus.RECRUIT, SessionDateTest.of(), 1, amount + 1); Payment payment = new Payment("1", sessionId, student.getId(), amount -1); assertThatThrownBy(() -> paySession.enrollmentUser(student, payment)).isInstanceOf(LackPointException.class); diff --git a/src/test/java/nextstep/courses/domain/SessionImageTest.java b/src/test/java/nextstep/courses/domain/SessionImageTest.java index df2abb76b..b6abe4dfa 100644 --- a/src/test/java/nextstep/courses/domain/SessionImageTest.java +++ b/src/test/java/nextstep/courses/domain/SessionImageTest.java @@ -13,6 +13,8 @@ public class SessionImageTest { private static final int VALID_SIZE = 1024 * 1024; private static final String VALID_PATH = "image.png"; public static final SessionImage S1 = new SessionImage(VALID_ID, VALID_PATH, VALID_WIDTH, VALID_HEIGHT, VALID_SIZE); + public static final SessionImage S2 = new SessionImage(VALID_ID+1, VALID_PATH, VALID_WIDTH, VALID_HEIGHT, VALID_SIZE); + @Test @DisplayName("강의 이미지 생성 테스트") diff --git a/src/test/java/nextstep/courses/domain/SessionTest.java b/src/test/java/nextstep/courses/domain/SessionTest.java index 9c50bc5b4..b197da9f9 100644 --- a/src/test/java/nextstep/courses/domain/SessionTest.java +++ b/src/test/java/nextstep/courses/domain/SessionTest.java @@ -10,18 +10,22 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; public class SessionTest { private final Long sessionId = 1L; private final NsUser student = NsUserTest.JAVAJIGI; + private final NsUser notApproveStudent = NsUserTest.SANJIGI; @ParameterizedTest @EnumSource(mode = EnumSource.Mode.EXCLUDE, names = {"RECRUIT"}) @DisplayName("모집 중이 아닌 강의에 수강신청 하는 경우 에러 발생") - void testInvalidEnrollmentUser(SessionStatus sessionStatus) { - Session testSession = TestSessionFactory.makeSession(sessionId, sessionStatus); + void testInvalidEnrollmentUser(RecruitStatus recruitStatus) { + Session testSession = TestSessionFactory.makeSession(sessionId, recruitStatus); assertThatThrownBy(() -> testSession.enrollmentUser(student, new Payment())).isInstanceOf(NotRecruitException.class); } @@ -35,4 +39,41 @@ void testDuplicateEnrollment() { assertThatThrownBy(() -> testSession.enrollmentUser(student, new Payment())).isInstanceOf(NotRecruitException.class); } + + @Test + @DisplayName("1장 이상의 이미지가 들어갈 수 있는지 테스트") + void testManyImage() { + List sessionImages = List.of(SessionImageTest.S1, SessionImageTest.S2); + Session testSession = TestSessionFactory.recruitSession(sessionId, sessionImages); + + assertThat(testSession.getSessionImage()).hasSize(2) + .containsExactlyInAnyOrderElementsOf(sessionImages); + } + + @Test + @DisplayName("진행 중인 강의 수강신청") + void testEnrollmentWhenSessionRun() { + Session testSession = TestSessionFactory.recruitStatusSession(sessionId); + testSession.changeProgressStatus(SessionProgressStatus.RUN); + testSession.enrollmentUser(student, new Payment()); + + assertThat(testSession.getStudents()).hasSize(1); + } + + @Test + @DisplayName("승인되지 않은 학생 삭제 수강 취소") + void testEnrollmentNotApproveStudent() { + Session testSession = TestSessionFactory.recruitStatusSession(sessionId); + + testSession.addApproveStudent(student); + + testSession.enrollmentUser(student, new Payment()); + testSession.enrollmentUser(notApproveStudent, new Payment()); + assertThat(testSession.getStudents()).hasSize(2); + + testSession.removeNotApproveUser(); + assertThat(testSession.getStudents()).hasSize(1) + .containsExactlyInAnyOrder(student); + + } } diff --git a/src/test/java/nextstep/courses/domain/utils/TestDuplicateSession.java b/src/test/java/nextstep/courses/domain/utils/TestDuplicateSession.java index c26977685..a754f4763 100644 --- a/src/test/java/nextstep/courses/domain/utils/TestDuplicateSession.java +++ b/src/test/java/nextstep/courses/domain/utils/TestDuplicateSession.java @@ -3,13 +3,15 @@ import nextstep.courses.domain.Session; import nextstep.courses.domain.SessionDate; import nextstep.courses.domain.SessionImage; -import nextstep.courses.domain.SessionStatus; +import nextstep.courses.domain.RecruitStatus; import nextstep.payments.domain.Payment; import nextstep.users.domain.NsUser; +import java.util.List; + public class TestDuplicateSession extends Session { - public TestDuplicateSession(Long id, SessionImage sessionImage, SessionStatus sessionStatus, SessionDate sessionDate) { - super(id, sessionImage, sessionStatus, sessionDate); + public TestDuplicateSession(Long id, SessionImage sessionImage, RecruitStatus recruitStatus, SessionDate sessionDate) { + super(id, List.of(sessionImage), recruitStatus, sessionDate); } @Override diff --git a/src/test/java/nextstep/courses/domain/utils/TestSession.java b/src/test/java/nextstep/courses/domain/utils/TestSession.java index ded792399..c33b45b7c 100644 --- a/src/test/java/nextstep/courses/domain/utils/TestSession.java +++ b/src/test/java/nextstep/courses/domain/utils/TestSession.java @@ -3,13 +3,19 @@ import nextstep.courses.domain.Session; import nextstep.courses.domain.SessionDate; import nextstep.courses.domain.SessionImage; -import nextstep.courses.domain.SessionStatus; +import nextstep.courses.domain.RecruitStatus; import nextstep.payments.domain.Payment; import nextstep.users.domain.NsUser; +import java.util.List; + public class TestSession extends Session { - public TestSession(Long id, SessionImage sessionImage, SessionStatus sessionStatus, SessionDate sessionDate) { - super(id, sessionImage, sessionStatus, sessionDate); + public TestSession(Long id, SessionImage sessionImage, RecruitStatus recruitStatus, SessionDate sessionDate) { + super(id, List.of(sessionImage), recruitStatus, sessionDate); + } + + public TestSession(Long id, List sessionImage, RecruitStatus recruitStatus, SessionDate sessionDate) { + super(id, sessionImage, recruitStatus, sessionDate); } @Override diff --git a/src/test/java/nextstep/courses/domain/utils/TestSessionFactory.java b/src/test/java/nextstep/courses/domain/utils/TestSessionFactory.java index 27ea2b230..432194525 100644 --- a/src/test/java/nextstep/courses/domain/utils/TestSessionFactory.java +++ b/src/test/java/nextstep/courses/domain/utils/TestSessionFactory.java @@ -1,21 +1,24 @@ package nextstep.courses.domain.utils; -import nextstep.courses.domain.Session; -import nextstep.courses.domain.SessionDateTest; -import nextstep.courses.domain.SessionImageTest; -import nextstep.courses.domain.SessionStatus; +import nextstep.courses.domain.*; + +import java.util.List; public class TestSessionFactory { static public Session recruitStatusSession(Long id) { - return new TestSession(id, SessionImageTest.S1, SessionStatus.RECRUIT, SessionDateTest.of()); + return new TestSession(id, SessionImageTest.S1, RecruitStatus.RECRUIT, SessionDateTest.of()); + } + + static public Session makeSession(Long id, RecruitStatus recruitStatus) { + return new TestSession(id, SessionImageTest.S1, recruitStatus, SessionDateTest.of()); } - static public Session makeSession(Long id, SessionStatus sessionStatus) { - return new TestSession(id, SessionImageTest.S1, sessionStatus, SessionDateTest.of()); + static public Session recruitStatusOtherSession(Long id) { + return new TestDuplicateSession(id, SessionImageTest.S1, RecruitStatus.RECRUIT, SessionDateTest.of()); } - static public Session recruitStatusSession2(Long id) { - return new TestDuplicateSession(id, SessionImageTest.S1, SessionStatus.RECRUIT, SessionDateTest.of()); + static public Session recruitSession(Long id, List sessionImages) { + return new TestSession(id, sessionImages, RecruitStatus.RECRUIT, SessionDateTest.of()); } } diff --git a/src/test/java/nextstep/courses/infrastructure/CourseRepositoryTest.java b/src/test/java/nextstep/courses/infrastructure/CourseRepositoryTest.java index c783f2c0a..d069ec319 100644 --- a/src/test/java/nextstep/courses/infrastructure/CourseRepositoryTest.java +++ b/src/test/java/nextstep/courses/infrastructure/CourseRepositoryTest.java @@ -24,14 +24,16 @@ public class CourseRepositoryTest { private JdbcTemplate jdbcTemplate; private CourseRepository courseRepository; - private SessionRepository sessionRepository; + private FreeSessionRepository freeSessionRepository; + private PaySessionRepository paySessionRepository; private Long courseId = 1L; @BeforeEach void setUp() { - sessionRepository = new JdbcSessionRepository(jdbcTemplate); - courseRepository = new JdbcCourseRepository(jdbcTemplate, sessionRepository); + freeSessionRepository = new JdbcFreeSessionRepository(jdbcTemplate); + paySessionRepository = new JdbcPaySessionRepository(jdbcTemplate); + courseRepository = new JdbcCourseRepository(jdbcTemplate, freeSessionRepository, paySessionRepository); } @Test diff --git a/src/test/java/nextstep/courses/infrastructure/SessionRepositoryTest.java b/src/test/java/nextstep/courses/infrastructure/FreeSessionRepositoryTest.java similarity index 52% rename from src/test/java/nextstep/courses/infrastructure/SessionRepositoryTest.java rename to src/test/java/nextstep/courses/infrastructure/FreeSessionRepositoryTest.java index 0cccc60ef..46e50a058 100644 --- a/src/test/java/nextstep/courses/infrastructure/SessionRepositoryTest.java +++ b/src/test/java/nextstep/courses/infrastructure/FreeSessionRepositoryTest.java @@ -14,6 +14,7 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.transaction.annotation.Transactional; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -21,76 +22,58 @@ @JdbcTest @Transactional -public class SessionRepositoryTest { - private static final Logger LOGGER = LoggerFactory.getLogger(SessionRepositoryTest.class); +public class FreeSessionRepositoryTest { + private static final Logger LOGGER = LoggerFactory.getLogger(FreeSessionRepositoryTest.class); @Autowired private JdbcTemplate jdbcTemplate; - private SessionRepository sessionRepository; - private CourseRepository courseRepository; + private FreeSessionRepository sessionRepository; - private Set students = Set.of(NsUserTest.JAVAJIGI, NsUserTest.SANJIGI); - private SessionImage sessionImage = SessionImageTest.S1; + private final Set students = Set.of(NsUserTest.JAVAJIGI, NsUserTest.SANJIGI); + private final NsUser approveStudent = NsUserTest.JAVAJIGI; + private final List sessionImages = List.of(SessionImageTest.S1); private Long courseId = 3L; @BeforeEach void setUp() { - sessionRepository = new JdbcSessionRepository(jdbcTemplate); - courseRepository = new JdbcCourseRepository(jdbcTemplate, sessionRepository); + sessionRepository = new JdbcFreeSessionRepository(jdbcTemplate); } @Test @DisplayName("무료 강의 db에 넣고 조회 테스트") void testFreeSession() { - FreeSession freeSession = new FreeSession(1L, sessionImage, SessionStatus.RECRUIT, SessionDateTest.of(), students); + FreeSession freeSession = new FreeSession(1L, sessionImages, RecruitStatus.RECRUIT, SessionDateTest.of(), students); + freeSession.addApproveStudent(approveStudent); sessionRepository.saveSession(freeSession, courseId); - Session findSession = sessionRepository.findBySessionId(freeSession.getId(), FreeSession.class).orElse(null); + Session findSession = sessionRepository.findBySessionId(freeSession.getId()).orElse(null); assertThat(findSession.getId()).isEqualTo(1L); - assertThat(findSession.getSessionImage().getId()).isEqualTo(sessionImage.getId()); + assertThat(findSession.getSessionImage().get(0).getId()).isEqualTo(sessionImages.get(0).getId()); + assertThat(findSession.getSessionProgressStatus()).isEqualTo(SessionProgressStatus.PREPARE); assertThat(findSession.getStudents()).hasSize(2) .extracting(NsUser::getUserId) .containsAll(students.stream().map(NsUser::getUserId).collect(Collectors.toUnmodifiableList())); - } - - @Test - @DisplayName("유료 강의 db에 넣고 조회 테스트") - void testPaySession() { - int amount = 1000; - PaySession paySession = new PaySession(1L, sessionImage, SessionStatus.RECRUIT, SessionDateTest.of(), students, 2, amount); - sessionRepository.saveSession(paySession, courseId); - - Session findSession = sessionRepository.findBySessionId(paySession.getId(), PaySession.class).orElse(null); - - assertThat(findSession.getId()).isEqualTo(1L); - - assertThat(findSession.getSessionImage().getId()).isEqualTo(sessionImage.getId()); - - assertThat(findSession.getStudents()).hasSize(2) + assertThat(findSession.getApproveStudents()).hasSize(1) .extracting(NsUser::getUserId) - .containsAll(students.stream().map(NsUser::getUserId).collect(Collectors.toUnmodifiableList())); + .contains(approveStudent.getUserId()); } @Test @DisplayName("모든 세션 조회 테스트") void testSessions() { int amount = 1000; - FreeSession freeSession = new FreeSession(1L, sessionImage, SessionStatus.RECRUIT, SessionDateTest.of(), students); + FreeSession freeSession = new FreeSession(1L, sessionImages, RecruitStatus.RECRUIT, SessionDateTest.of(), students); sessionRepository.saveSession(freeSession, courseId); - - PaySession paySession = new PaySession(1L, sessionImage, SessionStatus.RECRUIT, SessionDateTest.of(), students, 2, amount); - sessionRepository.saveSession(paySession, courseId); - Sessions sessions = sessionRepository.findByCourseId(courseId); - assertThat(sessions.getSessions()).hasSize(2) - .extracting(Session::getId).contains(freeSession.getId(), paySession.getId()); + assertThat(sessions.getSessions()).hasSize(1) + .extracting(Session::getId).contains(freeSession.getId()); } diff --git a/src/test/java/nextstep/courses/infrastructure/PaySessionRepositoryTest.java b/src/test/java/nextstep/courses/infrastructure/PaySessionRepositoryTest.java new file mode 100644 index 000000000..1bff1b155 --- /dev/null +++ b/src/test/java/nextstep/courses/infrastructure/PaySessionRepositoryTest.java @@ -0,0 +1,80 @@ +package nextstep.courses.infrastructure; + + +import nextstep.courses.domain.*; +import nextstep.users.domain.NsUser; +import nextstep.users.domain.NsUserTest; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; + +@JdbcTest +@Transactional +public class PaySessionRepositoryTest { + private static final Logger LOGGER = LoggerFactory.getLogger(PaySessionRepositoryTest.class); + + @Autowired + private JdbcTemplate jdbcTemplate; + + private PaySessionRepository sessionRepository; + private final Set students = Set.of(NsUserTest.JAVAJIGI, NsUserTest.SANJIGI); + private final NsUser approveStudent = NsUserTest.JAVAJIGI; + private final List sessionImages = List.of(SessionImageTest.S1); + + private Long courseId = 3L; + + @BeforeEach + void setUp() { + sessionRepository = new JdbcPaySessionRepository(jdbcTemplate); + } + + + @Test + @DisplayName("유료 강의 db에 넣고 조회 테스트") + void testPaySession() { + int amount = 1000; + PaySession paySession = new PaySession(1L, sessionImages,RecruitStatus.RECRUIT, SessionDateTest.of(), students, 2, amount); + paySession.addApproveStudent(approveStudent); + sessionRepository.saveSession(paySession, courseId); + + Session findSession = sessionRepository.findBySessionId(paySession.getId()).orElse(null); + + assertThat(findSession.getId()).isEqualTo(1L); + + assertThat(findSession.getSessionImage().get(0).getId()).isEqualTo(sessionImages.get(0).getId()); + assertThat(findSession.getSessionProgressStatus()).isEqualTo(SessionProgressStatus.PREPARE); + assertThat(findSession.getStudents()).hasSize(2) + .extracting(NsUser::getUserId) + .containsAll(students.stream().map(NsUser::getUserId).collect(Collectors.toUnmodifiableList())); + + assertThat(findSession.getApproveStudents()).hasSize(1) + .extracting(NsUser::getUserId) + .contains(approveStudent.getUserId()); + } + + @Test + @DisplayName("모든 세션 조회 테스트") + void testSessions() { + int amount = 1000; + PaySession paySession = new PaySession(1L, sessionImages,RecruitStatus.RECRUIT, SessionDateTest.of(), students, 2, amount); + sessionRepository.saveSession(paySession, courseId); + Sessions sessions = sessionRepository.findByCourseId(courseId); + + assertThat(sessions.getSessions()).hasSize(1) + .extracting(Session::getId).contains(paySession.getId()); + } + + +}