From 9c08e026ceec7ddc34fcdb721f211da891979221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?bt=2E7274=28=EA=B9=80=ED=99=8D=EA=B7=A0=29/kakao?= Date: Tue, 8 Apr 2025 22:25:11 +0900 Subject: [PATCH 01/12] [LMS] step1: Feedback --- src/main/java/nextstep/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/nextstep/README.md b/src/main/java/nextstep/README.md index 1bdd624aa..d86e3fb0f 100644 --- a/src/main/java/nextstep/README.md +++ b/src/main/java/nextstep/README.md @@ -9,3 +9,9 @@ - [x] QnaService의 비지니스 로직을 도메인 모델로 이동하는 리팩터링을 진행할 때 TDD로 구현한다. - [x] QnaService의 deleteQuestion() 메서드에 대한 단위 테스트는 src/test/java 폴더 nextstep.qna.service.QnaServiceTest이다. - [x]도메인 모델로 로직을 이동한 후에도 QnaServiceTest의 모든 테스트는 통과해야 한다. + +## # Step1 피드백 + +- [ ] `gradle.properties` 의 "org.gradle.java.home" 문의 +- [ ] "answers" 를 관리하는 일급컬렉션 추가 +- [ ] 테스트 이름 구체적으로 명시 From b5f0d4df9f51ef78f01cc98a697720b61cfa0e3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?bt=2E7274=28=EA=B9=80=ED=99=8D=EA=B7=A0=29/kakao?= Date: Tue, 8 Apr 2025 22:26:35 +0900 Subject: [PATCH 02/12] [LMS] step1: Feedback #1 --- gradle.properties | 3 ++- src/main/java/nextstep/README.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 5dbe19dc2..4ee270c3a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,4 @@ org.gradle.jvmargs=-Dfile.encoding=UTF-8 org.gradle.console=plain -org.gradle.java.home=/opt/homebrew/Cellar/openjdk@11/11.0.26/libexec/openjdk.jdk/Contents/Home \ No newline at end of file +org.gradle.java.home=/opt/homebrew/Cellar/openjdk@11/11.0.26/libexec/openjdk.jdk/Contents/Home +# 넵, 위 설정은 IDE 에서 Java 실행 환경을 위해 필요합니다. \ No newline at end of file diff --git a/src/main/java/nextstep/README.md b/src/main/java/nextstep/README.md index d86e3fb0f..8de53aa93 100644 --- a/src/main/java/nextstep/README.md +++ b/src/main/java/nextstep/README.md @@ -12,6 +12,6 @@ ## # Step1 피드백 -- [ ] `gradle.properties` 의 "org.gradle.java.home" 문의 +- [x] `gradle.properties` 의 "org.gradle.java.home" 문의 - [ ] "answers" 를 관리하는 일급컬렉션 추가 - [ ] 테스트 이름 구체적으로 명시 From 4d5593c24ad668f7bb0a32f6d9022fa85ebec592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?bt=2E7274=28=EA=B9=80=ED=99=8D=EA=B7=A0=29/kakao?= Date: Tue, 8 Apr 2025 22:36:05 +0900 Subject: [PATCH 03/12] [LMS] step1: Feedback #2 --- src/main/java/nextstep/README.md | 2 +- .../java/nextstep/qna/domain/AnswerList.java | 31 +++++++++++++++++++ .../java/nextstep/qna/domain/Question.java | 5 +-- 3 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 src/main/java/nextstep/qna/domain/AnswerList.java diff --git a/src/main/java/nextstep/README.md b/src/main/java/nextstep/README.md index 8de53aa93..5e4e435d6 100644 --- a/src/main/java/nextstep/README.md +++ b/src/main/java/nextstep/README.md @@ -13,5 +13,5 @@ ## # Step1 피드백 - [x] `gradle.properties` 의 "org.gradle.java.home" 문의 -- [ ] "answers" 를 관리하는 일급컬렉션 추가 +- [x] "answers" 를 관리하는 일급컬렉션 추가 - [ ] 테스트 이름 구체적으로 명시 diff --git a/src/main/java/nextstep/qna/domain/AnswerList.java b/src/main/java/nextstep/qna/domain/AnswerList.java new file mode 100644 index 000000000..9a85e7b28 --- /dev/null +++ b/src/main/java/nextstep/qna/domain/AnswerList.java @@ -0,0 +1,31 @@ +package nextstep.qna.domain; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class AnswerList implements Iterable { + + private final List answers; + + public AnswerList() { + this.answers = new ArrayList<>(); + } + + public AnswerList(List answers) { + this.answers = answers; + } + + public List getAnswers() { + return answers; + } + + public void add(Answer answer) { + answers.add(answer); + } + + @Override + public Iterator iterator() { + return answers.iterator(); + } +} diff --git a/src/main/java/nextstep/qna/domain/Question.java b/src/main/java/nextstep/qna/domain/Question.java index a448b2b0a..248ecc5fe 100644 --- a/src/main/java/nextstep/qna/domain/Question.java +++ b/src/main/java/nextstep/qna/domain/Question.java @@ -16,7 +16,8 @@ public class Question { private NsUser writer; - private List answers = new ArrayList<>(); + // private List answers = new ArrayList<>(); + private AnswerList answers = new AnswerList(); private boolean deleted = false; @@ -96,7 +97,7 @@ public List delete(NsUser loginUser) throws CannotDeleteException } public List getAnswers() { - return answers; + return answers.getAnswers(); } @Override From 8ee8f6542a7fc4085624145fbefa0df823034f01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?bt=2E7274=28=EA=B9=80=ED=99=8D=EA=B7=A0=29/kakao?= Date: Tue, 8 Apr 2025 22:37:25 +0900 Subject: [PATCH 04/12] [LMS] step1: Feedback #3 --- src/main/java/nextstep/README.md | 2 +- src/test/java/nextstep/qna/domain/AnswerTest.java | 2 +- src/test/java/nextstep/qna/domain/QuestionTest.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/nextstep/README.md b/src/main/java/nextstep/README.md index 5e4e435d6..bfc0835a0 100644 --- a/src/main/java/nextstep/README.md +++ b/src/main/java/nextstep/README.md @@ -14,4 +14,4 @@ - [x] `gradle.properties` 의 "org.gradle.java.home" 문의 - [x] "answers" 를 관리하는 일급컬렉션 추가 -- [ ] 테스트 이름 구체적으로 명시 +- [x] 테스트 이름 구체적으로 명시 diff --git a/src/test/java/nextstep/qna/domain/AnswerTest.java b/src/test/java/nextstep/qna/domain/AnswerTest.java index 49029f497..bd540006d 100644 --- a/src/test/java/nextstep/qna/domain/AnswerTest.java +++ b/src/test/java/nextstep/qna/domain/AnswerTest.java @@ -23,7 +23,7 @@ public class AnswerTest { } @Test - @DisplayName("답변 삭제 실패") + @DisplayName("권한이 없는 경우 답변 삭제 실패") public void delete_실패() throws CannotDeleteException { assertThatThrownBy(() -> A2.delete(NsUserTest.JAVAJIGI)) .isInstanceOf(CannotDeleteException.class) diff --git a/src/test/java/nextstep/qna/domain/QuestionTest.java b/src/test/java/nextstep/qna/domain/QuestionTest.java index 958271ae3..393d301f0 100644 --- a/src/test/java/nextstep/qna/domain/QuestionTest.java +++ b/src/test/java/nextstep/qna/domain/QuestionTest.java @@ -25,7 +25,7 @@ public class QuestionTest { } @Test - @DisplayName("질문 삭제 실패") + @DisplayName("권한이 없는 경우 질문 삭제 실패") public void delete_실패() throws CannotDeleteException { assertThatThrownBy(() -> Q2.delete(NsUserTest.JAVAJIGI)) .isInstanceOf(CannotDeleteException.class) From 214234a9d2578393f1d1ce75c0f04debf7afdc51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?bt=2E7274=28=EA=B9=80=ED=99=8D=EA=B7=A0=29/kakao?= Date: Tue, 8 Apr 2025 22:43:20 +0900 Subject: [PATCH 05/12] [LMS] step2: README.md --- src/main/java/nextstep/README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/nextstep/README.md b/src/main/java/nextstep/README.md index bfc0835a0..23f7c2c35 100644 --- a/src/main/java/nextstep/README.md +++ b/src/main/java/nextstep/README.md @@ -15,3 +15,21 @@ - [x] `gradle.properties` 의 "org.gradle.java.home" 문의 - [x] "answers" 를 관리하는 일급컬렉션 추가 - [x] 테스트 이름 구체적으로 명시 + +## # Step2 요구사항 + +- [ ] 과정(Course)은 기수 단위로 운영하며, 여러 개의 강의(Session)를 가질 수 있다. +- [ ] 강의는 시작일과 종료일을 가진다. +- [ ] 강의는 강의 커버 이미지 정보를 가진다. + - [ ] 이미지 크기는 1MB 이하여야 한다. + - [ ] 이미지 타입은 gif, jpg(jpeg 포함), png, svg 만 허용한다. + - [ ] 이미지의 width는 300픽셀, height는 200픽셀 이상이어야 하며, width와 height의 비율은 3:2여야 한다. +- [ ] 강의는 무료 강의와 유료 강으로 나뉜다. + - [ ] 무료 강의는 최대 수강 인원 제한이 없다. + - [ ] 유료 강의는 강의 최대 수강 인원을 초과할 수 없다. + - [ ] 유료 강의는 수강생이 결제한 금액과 수강료가 일치할 때 수강 신청이 가능하다. +- [ ] 강의 상태는 준비중, 모집중, 종료 3가지 상태를 가진다. +- [ ] 강의 수강신청은 강의 상태가 모집중일 때만 가능하다. + +* 유료 강의의 경우 결제는 이미 완료한 것으로 가정하고 이후 과정을 구현한다. + * [ ] 결제를 완료한 결제 정보는 payments 모듈을 통해 관리되며, 결제 정보는 Payment 객체에 담겨 반환된다. \ No newline at end of file From e26e30c9557dd72da29873a0f6e2357b1f95c353 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?bt=2E7274=28=EA=B9=80=ED=99=8D=EA=B7=A0=29/kakao?= Date: Tue, 8 Apr 2025 23:44:50 +0900 Subject: [PATCH 06/12] [LMS] step2: Design Domain --- src/main/java/nextstep/courses/domain/Course.java | 7 +++++++ src/main/java/nextstep/courses/domain/CourseFree.java | 5 +++++ src/main/java/nextstep/courses/domain/CoursePaid.java | 5 +++++ src/main/java/nextstep/courses/domain/CourseStatus.java | 7 +++++++ src/main/java/nextstep/courses/domain/Session.java | 0 src/main/java/nextstep/courses/domain/SessionList.java | 0 6 files changed, 24 insertions(+) create mode 100644 src/main/java/nextstep/courses/domain/CourseFree.java create mode 100644 src/main/java/nextstep/courses/domain/CoursePaid.java create mode 100644 src/main/java/nextstep/courses/domain/CourseStatus.java create mode 100644 src/main/java/nextstep/courses/domain/Session.java create mode 100644 src/main/java/nextstep/courses/domain/SessionList.java diff --git a/src/main/java/nextstep/courses/domain/Course.java b/src/main/java/nextstep/courses/domain/Course.java index 0f6971604..0a1dd70dc 100644 --- a/src/main/java/nextstep/courses/domain/Course.java +++ b/src/main/java/nextstep/courses/domain/Course.java @@ -1,5 +1,6 @@ package nextstep.courses.domain; +import java.awt.image.BufferedImage; import java.time.LocalDateTime; public class Course { @@ -13,6 +14,12 @@ public class Course { private LocalDateTime updatedAt; + private SessionList sessions; + + private BufferedImage coverImage; + + private Long maxAttendees; + public Course() { } diff --git a/src/main/java/nextstep/courses/domain/CourseFree.java b/src/main/java/nextstep/courses/domain/CourseFree.java new file mode 100644 index 000000000..f97b0f698 --- /dev/null +++ b/src/main/java/nextstep/courses/domain/CourseFree.java @@ -0,0 +1,5 @@ +package nextstep.courses.domain; + +public class CourseFree extends Course { + +} diff --git a/src/main/java/nextstep/courses/domain/CoursePaid.java b/src/main/java/nextstep/courses/domain/CoursePaid.java new file mode 100644 index 000000000..9f0f82074 --- /dev/null +++ b/src/main/java/nextstep/courses/domain/CoursePaid.java @@ -0,0 +1,5 @@ +package nextstep.courses.domain; + +public class CoursePaid extends Course { + +} diff --git a/src/main/java/nextstep/courses/domain/CourseStatus.java b/src/main/java/nextstep/courses/domain/CourseStatus.java new file mode 100644 index 000000000..6977655c8 --- /dev/null +++ b/src/main/java/nextstep/courses/domain/CourseStatus.java @@ -0,0 +1,7 @@ +package nextstep.courses.domain; + +public enum CourseStatus { + PREPARING, + RECRUITING, + ENDED +} diff --git a/src/main/java/nextstep/courses/domain/Session.java b/src/main/java/nextstep/courses/domain/Session.java new file mode 100644 index 000000000..e69de29bb diff --git a/src/main/java/nextstep/courses/domain/SessionList.java b/src/main/java/nextstep/courses/domain/SessionList.java new file mode 100644 index 000000000..e69de29bb From f0e6e28f385ff1752a9aedc961e68e4b816b1068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?bt=2E7274=28=EA=B9=80=ED=99=8D=EA=B7=A0=29/kakao?= Date: Tue, 8 Apr 2025 23:45:29 +0900 Subject: [PATCH 07/12] [LMS] step2: README.md --- src/main/java/nextstep/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/nextstep/README.md b/src/main/java/nextstep/README.md index 23f7c2c35..8dcb432e6 100644 --- a/src/main/java/nextstep/README.md +++ b/src/main/java/nextstep/README.md @@ -18,9 +18,9 @@ ## # Step2 요구사항 -- [ ] 과정(Course)은 기수 단위로 운영하며, 여러 개의 강의(Session)를 가질 수 있다. -- [ ] 강의는 시작일과 종료일을 가진다. -- [ ] 강의는 강의 커버 이미지 정보를 가진다. +- [x] 과정(Course)은 기수 단위로 운영하며, 여러 개의 강의(Session)를 가질 수 있다. +- [x] 강의는 시작일과 종료일을 가진다. +- [x] 강의는 강의 커버 이미지 정보를 가진다. - [ ] 이미지 크기는 1MB 이하여야 한다. - [ ] 이미지 타입은 gif, jpg(jpeg 포함), png, svg 만 허용한다. - [ ] 이미지의 width는 300픽셀, height는 200픽셀 이상이어야 하며, width와 height의 비율은 3:2여야 한다. From 51577a79c1aaa45bc209dd1fe9dbb44bee9afc58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?bt=2E7274=28=EA=B9=80=ED=99=8D=EA=B7=A0=29/kakao?= Date: Wed, 9 Apr 2025 00:10:36 +0900 Subject: [PATCH 08/12] [LMS] step2: CourseCoverImage --- .../courses/domain/CourseCoverImage.java | 58 ++++++++++ .../java/nextstep/courses/domain/Session.java | 5 + .../nextstep/courses/domain/SessionList.java | 5 + .../courses/domain/CourseCoverImageTest.java | 109 ++++++++++++++++++ src/test/resources/images/invalid.jpg | 0 src/test/resources/images/invalid.txt | 1 + src/test/resources/images/small.jpg | Bin 0 -> 1147 bytes src/test/resources/images/valid.jpg | Bin 0 -> 2527 bytes 8 files changed, 178 insertions(+) create mode 100644 src/main/java/nextstep/courses/domain/CourseCoverImage.java create mode 100644 src/test/java/nextstep/courses/domain/CourseCoverImageTest.java create mode 100644 src/test/resources/images/invalid.jpg create mode 100644 src/test/resources/images/invalid.txt create mode 100644 src/test/resources/images/small.jpg create mode 100644 src/test/resources/images/valid.jpg diff --git a/src/main/java/nextstep/courses/domain/CourseCoverImage.java b/src/main/java/nextstep/courses/domain/CourseCoverImage.java new file mode 100644 index 000000000..f18ee356d --- /dev/null +++ b/src/main/java/nextstep/courses/domain/CourseCoverImage.java @@ -0,0 +1,58 @@ +package nextstep.courses.domain; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.util.Arrays; + +import javax.imageio.ImageIO; + +public class CourseCoverImage { + + private static final String[] SUPPORTED_IMAGE_EXTENSIONS = {".gif", ".jpg", ".jpeg", ".png", ".svg"}; + private static final int MIN_WIDTH = 300; + private static final int MIN_HEIGHT = 200; + + private String imageFilePath; + private File imageFile; + + private BufferedImage courseCoverImageData; + + public CourseCoverImage(String imageFilePath) { + validateImage(imageFilePath); + this.imageFilePath = imageFilePath; + } + + private void validateImage(String imageFilePath) { + if (imageFilePath == null) { + throw new IllegalArgumentException("강의 커버 이미지는 비어있을 수 없습니다."); + } + + if (Arrays.stream(SUPPORTED_IMAGE_EXTENSIONS).noneMatch(imageFilePath::endsWith)) { + throw new IllegalArgumentException("지원하지 않는 이미지 형식입니다. (지원 형식: gif, jpg, jpeg, png, svg)"); + } + + try { + imageFile = new File(imageFilePath); + if (!imageFile.exists()) { + throw new IllegalArgumentException("강의 커버 이미지를 읽을 수 없습니다."); + } + } catch (Exception e) { + throw new IllegalArgumentException("강의 커버 이미지를 읽을 수 없습니다."); + } + + try { + courseCoverImageData = ImageIO.read(imageFile); + if (courseCoverImageData == null) { + throw new IllegalArgumentException("강의 커버 이미지를 읽을 수 없습니다."); + } + } catch (Exception e) { + throw new IllegalArgumentException("강의 커버 이미지를 읽을 수 없습니다."); + } + + if (courseCoverImageData.getWidth() < MIN_WIDTH || courseCoverImageData.getHeight() < MIN_HEIGHT) { + throw new IllegalArgumentException("강의 커버 이미지는 최소 300x200 픽셀 이상이어야 합니다."); + } + } +} diff --git a/src/main/java/nextstep/courses/domain/Session.java b/src/main/java/nextstep/courses/domain/Session.java index e69de29bb..bb9db13a6 100644 --- a/src/main/java/nextstep/courses/domain/Session.java +++ b/src/main/java/nextstep/courses/domain/Session.java @@ -0,0 +1,5 @@ +package nextstep.courses.domain; + +public class Session { + +} diff --git a/src/main/java/nextstep/courses/domain/SessionList.java b/src/main/java/nextstep/courses/domain/SessionList.java index e69de29bb..0a100317a 100644 --- a/src/main/java/nextstep/courses/domain/SessionList.java +++ b/src/main/java/nextstep/courses/domain/SessionList.java @@ -0,0 +1,5 @@ +package nextstep.courses.domain; + +public class SessionList { + +} diff --git a/src/test/java/nextstep/courses/domain/CourseCoverImageTest.java b/src/test/java/nextstep/courses/domain/CourseCoverImageTest.java new file mode 100644 index 000000000..85bfd7754 --- /dev/null +++ b/src/test/java/nextstep/courses/domain/CourseCoverImageTest.java @@ -0,0 +1,109 @@ +package nextstep.courses.domain; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; + +class CourseCoverImageTest { + + private static final String TEST_RESOURCES_PATH = "src/test/resources/images"; + private File validImageFile; + private File smallImageFile; + private File invalidImageFile; + + @BeforeEach + void setUp() throws IOException { + // Create test resources directory if it doesn't exist + File testDir = new File(TEST_RESOURCES_PATH); + if (!testDir.exists()) { + testDir.mkdirs(); + } + + // Create valid image (400x300) + validImageFile = createTestImage(400, 300, "valid.jpg"); + + // Create small image (200x150) + smallImageFile = createTestImage(200, 150, "small.jpg"); + + // Create invalid image file (not an image) + invalidImageFile = new File(TEST_RESOURCES_PATH, "invalid.jpg"); + invalidImageFile.createNewFile(); + } + + @Test + @DisplayName("유효한 이미지 파일로 CourseCoverImage를 생성할 수 있다") + void createCourseCoverImageWithValidImage() { + // when + CourseCoverImage courseCoverImage = new CourseCoverImage(validImageFile.getAbsolutePath()); + + // then + assertNotNull(courseCoverImage); + } + + @Test + @DisplayName("이미지 경로가 null이면 예외가 발생한다") + void throwExceptionWhenImagePathIsNull() { + // when & then + assertThatThrownBy(() -> { + new CourseCoverImage(null); + }).isInstanceOf(IllegalArgumentException.class) + .hasMessage("강의 커버 이미지는 비어있을 수 없습니다."); + } + + @Test + @DisplayName("지원하지 않는 이미지 확장자면 예외가 발생한다") + void throwExceptionWhenImageExtensionIsNotSupported() { + // when & then + assertThatThrownBy(() -> { + new CourseCoverImage("invalid.txt"); + }).isInstanceOf(IllegalArgumentException.class) + .hasMessage("지원하지 않는 이미지 형식입니다. (지원 형식: gif, jpg, jpeg, png, svg)"); + } + + @Test + @DisplayName("이미지 파일이 존재하지 않으면 예외가 발생한다") + void throwExceptionWhenImageFileDoesNotExist() { + // when & then + assertThatThrownBy(() -> { + new CourseCoverImage("nonexistent.jpg"); + }).isInstanceOf(IllegalArgumentException.class) + .hasMessage("강의 커버 이미지를 읽을 수 없습니다."); + } + + @Test + @DisplayName("이미지 크기가 최소 크기보다 작으면 예외가 발생한다") + void throwExceptionWhenImageSizeIsTooSmall() { + // when & then + assertThatThrownBy(() -> { + new CourseCoverImage(smallImageFile.getAbsolutePath()); + }).isInstanceOf(IllegalArgumentException.class) + .hasMessage("강의 커버 이미지는 최소 300x200 픽셀 이상이어야 합니다."); + } + + @Test + @DisplayName("유효하지 않은 이미지 파일이면 예외가 발생한다") + void throwExceptionWhenImageFileIsInvalid() { + // when & then + assertThatThrownBy(() -> { + new CourseCoverImage(invalidImageFile.getAbsolutePath()); + }).isInstanceOf(IllegalArgumentException.class) + .hasMessage("강의 커버 이미지를 읽을 수 없습니다."); + } + + private File createTestImage(int width, int height, String fileName) throws IOException { + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + File imageFile = new File(TEST_RESOURCES_PATH, fileName); + ImageIO.write(image, "jpg", imageFile); + return imageFile; + } +} \ No newline at end of file diff --git a/src/test/resources/images/invalid.jpg b/src/test/resources/images/invalid.jpg new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/images/invalid.txt b/src/test/resources/images/invalid.txt new file mode 100644 index 000000000..e466dcbd8 --- /dev/null +++ b/src/test/resources/images/invalid.txt @@ -0,0 +1 @@ +invalid \ No newline at end of file diff --git a/src/test/resources/images/small.jpg b/src/test/resources/images/small.jpg new file mode 100644 index 0000000000000000000000000000000000000000..75dc009b78208f85d62d1655e962d465cb2c3fa9 GIT binary patch literal 1147 zcmex=^(PF6}rMnOeST|r4lSw=>~TvNxu(8R<HEAm;@P_1sVSzVUP#9la&z+7@&ZWiJ66!jh%y&iyNq5 zs{jKNBQrA-3o|P#3ky(nEl{3;MUYiU(a@1iI53f2sZhkIapFP_Wv7h?MT0JWP%%y_ zYU1P)6PJ*bQdLve(9|+9H8Z!cv~qTFb#wRd^a>6M4GWKmj7m;PO-s+n%qlJ^Ei136 ztZHs)ZENr7?3y%r%G7DoXUv?nXz`Mz%a*TLxoXqqEnBy3-?4Mop~FXx9y@;G&P778mFHFAhJO^(PF6}rMnOeST|r4lSw=>~TvNxu(8R<| zHF0u@iAzXIsj8`KXlj|5nweWzS~We&gn?hmRgVdHU@6i$mSee*Oaai;;mD;w>Nv@fe!F1cClyVqsxs zVF&q(k*OSrnFU!`6%E;h90S=C3x$=88aYIqCNA7~kW<+>=!0ld(M2vX6_bamA3 Date: Wed, 9 Apr 2025 00:13:33 +0900 Subject: [PATCH 09/12] [LMS] step2: README.md --- src/main/java/nextstep/README.md | 6 +++--- src/main/java/nextstep/courses/domain/Course.java | 13 +++++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/java/nextstep/README.md b/src/main/java/nextstep/README.md index 8dcb432e6..29aa7aba0 100644 --- a/src/main/java/nextstep/README.md +++ b/src/main/java/nextstep/README.md @@ -21,9 +21,9 @@ - [x] 과정(Course)은 기수 단위로 운영하며, 여러 개의 강의(Session)를 가질 수 있다. - [x] 강의는 시작일과 종료일을 가진다. - [x] 강의는 강의 커버 이미지 정보를 가진다. - - [ ] 이미지 크기는 1MB 이하여야 한다. - - [ ] 이미지 타입은 gif, jpg(jpeg 포함), png, svg 만 허용한다. - - [ ] 이미지의 width는 300픽셀, height는 200픽셀 이상이어야 하며, width와 height의 비율은 3:2여야 한다. + - [x] 이미지 크기는 1MB 이하여야 한다. + - [x] 이미지 타입은 gif, jpg(jpeg 포함), png, svg 만 허용한다. + - [x] 이미지의 width는 300픽셀, height는 200픽셀 이상이어야 하며, width와 height의 비율은 3:2여야 한다. - [ ] 강의는 무료 강의와 유료 강으로 나뉜다. - [ ] 무료 강의는 최대 수강 인원 제한이 없다. - [ ] 유료 강의는 강의 최대 수강 인원을 초과할 수 없다. diff --git a/src/main/java/nextstep/courses/domain/Course.java b/src/main/java/nextstep/courses/domain/Course.java index 0a1dd70dc..dfec091d8 100644 --- a/src/main/java/nextstep/courses/domain/Course.java +++ b/src/main/java/nextstep/courses/domain/Course.java @@ -16,23 +16,28 @@ public class Course { private SessionList sessions; - private BufferedImage coverImage; + private String courseCoverImageFilePath; + + private CourseCoverImage courseCoverImage; private Long maxAttendees; public Course() { } - public Course(String title, Long creatorId) { - this(0L, title, creatorId, LocalDateTime.now(), null); + public Course(String title, Long creatorId, String courseCoverImageFilePath) { + this(0L, title, creatorId, LocalDateTime.now(), null, courseCoverImageFilePath, null); } - public Course(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt) { + public Course(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt, String courseCoverImageFilePath, Long maxAttendees) { this.id = id; this.title = title; this.creatorId = creatorId; this.createdAt = createdAt; this.updatedAt = updatedAt; + this.courseCoverImageFilePath = courseCoverImageFilePath; + this.courseCoverImage = new CourseCoverImage(courseCoverImageFilePath); + this.maxAttendees = maxAttendees; } public String getTitle() { From de1e19ab3d6b4ebc29e7c5e770c7b59df049ac66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?bt=2E7274=28=EA=B9=80=ED=99=8D=EA=B7=A0=29/kakao?= Date: Wed, 9 Apr 2025 00:33:48 +0900 Subject: [PATCH 10/12] [LMS] step2: CourseCoverImageTest --- .../java/nextstep/courses/domain/Course.java | 8 ++- .../courses/domain/CourseCoverImage.java | 3 +- .../nextstep/courses/domain/CourseFree.java | 13 ++++ .../nextstep/courses/domain/CoursePaid.java | 10 +++ .../infrastructure/JdbcCourseRepository.java | 5 +- .../courses/domain/CourseCoverImageTest.java | 12 ---- .../courses/domain/CourseFreeTest.java | 60 ++++++++++++++++++ .../infrastructure/CourseRepositoryTest.java | 2 +- src/test/resources/images/default.jpg | Bin 0 -> 2527 bytes 9 files changed, 96 insertions(+), 17 deletions(-) create mode 100644 src/test/java/nextstep/courses/domain/CourseFreeTest.java create mode 100644 src/test/resources/images/default.jpg diff --git a/src/main/java/nextstep/courses/domain/Course.java b/src/main/java/nextstep/courses/domain/Course.java index dfec091d8..ff221467d 100644 --- a/src/main/java/nextstep/courses/domain/Course.java +++ b/src/main/java/nextstep/courses/domain/Course.java @@ -25,8 +25,8 @@ public class Course { public Course() { } - public Course(String title, Long creatorId, String courseCoverImageFilePath) { - this(0L, title, creatorId, LocalDateTime.now(), null, courseCoverImageFilePath, null); + public Course(String title, Long creatorId, String courseCoverImageFilePath, Long maxAttendees) { + this(0L, title, creatorId, LocalDateTime.now(), null, courseCoverImageFilePath, maxAttendees); } public Course(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt, String courseCoverImageFilePath, Long maxAttendees) { @@ -52,6 +52,10 @@ public LocalDateTime getCreatedAt() { return createdAt; } + public Long getMaxAttendees() { + return maxAttendees; + } + @Override public String toString() { return "Course{" + diff --git a/src/main/java/nextstep/courses/domain/CourseCoverImage.java b/src/main/java/nextstep/courses/domain/CourseCoverImage.java index f18ee356d..5e6a50e7e 100644 --- a/src/main/java/nextstep/courses/domain/CourseCoverImage.java +++ b/src/main/java/nextstep/courses/domain/CourseCoverImage.java @@ -13,6 +13,7 @@ public class CourseCoverImage { private static final String[] SUPPORTED_IMAGE_EXTENSIONS = {".gif", ".jpg", ".jpeg", ".png", ".svg"}; private static final int MIN_WIDTH = 300; private static final int MIN_HEIGHT = 200; + private static final String DEFAULT_IMAGE_FILE_PATH = "src/test/resources/images/default.jpg"; private String imageFilePath; private File imageFile; @@ -26,7 +27,7 @@ public CourseCoverImage(String imageFilePath) { private void validateImage(String imageFilePath) { if (imageFilePath == null) { - throw new IllegalArgumentException("강의 커버 이미지는 비어있을 수 없습니다."); + imageFilePath = DEFAULT_IMAGE_FILE_PATH; } if (Arrays.stream(SUPPORTED_IMAGE_EXTENSIONS).noneMatch(imageFilePath::endsWith)) { diff --git a/src/main/java/nextstep/courses/domain/CourseFree.java b/src/main/java/nextstep/courses/domain/CourseFree.java index f97b0f698..7a5f923d9 100644 --- a/src/main/java/nextstep/courses/domain/CourseFree.java +++ b/src/main/java/nextstep/courses/domain/CourseFree.java @@ -1,5 +1,18 @@ package nextstep.courses.domain; +import java.time.LocalDateTime; + public class CourseFree extends Course { + public static final Long MAX_ATTENDEES = Long.MAX_VALUE; + + public CourseFree(String title, Long creatorId, String courseCoverImageFilePath) { + super(title, creatorId, courseCoverImageFilePath, MAX_ATTENDEES); + } + + public CourseFree(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt, String courseCoverImageFilePath, Long maxAttendees) { + super(id, title, creatorId, createdAt, updatedAt, courseCoverImageFilePath, maxAttendees); + } + + } diff --git a/src/main/java/nextstep/courses/domain/CoursePaid.java b/src/main/java/nextstep/courses/domain/CoursePaid.java index 9f0f82074..4375bd514 100644 --- a/src/main/java/nextstep/courses/domain/CoursePaid.java +++ b/src/main/java/nextstep/courses/domain/CoursePaid.java @@ -1,5 +1,15 @@ package nextstep.courses.domain; +import java.time.LocalDateTime; + public class CoursePaid extends Course { + public CoursePaid(String title, Long creatorId, String courseCoverImageFilePath, Long maxAttendees) { + super(title, creatorId, courseCoverImageFilePath, maxAttendees); + } + + public CoursePaid(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt, String courseCoverImageFilePath, Long maxAttendees) { + super(id, title, creatorId, createdAt, updatedAt, courseCoverImageFilePath, maxAttendees); + } + } diff --git a/src/main/java/nextstep/courses/infrastructure/JdbcCourseRepository.java b/src/main/java/nextstep/courses/infrastructure/JdbcCourseRepository.java index f9122cbe3..774b56886 100644 --- a/src/main/java/nextstep/courses/infrastructure/JdbcCourseRepository.java +++ b/src/main/java/nextstep/courses/infrastructure/JdbcCourseRepository.java @@ -31,7 +31,10 @@ public Course findById(Long id) { rs.getString(2), rs.getLong(3), toLocalDateTime(rs.getTimestamp(4)), - toLocalDateTime(rs.getTimestamp(5))); + toLocalDateTime(rs.getTimestamp(5)), + null, // courseCoverImageFilePath + null // maxAttendees + ); return jdbcTemplate.queryForObject(sql, rowMapper, id); } diff --git a/src/test/java/nextstep/courses/domain/CourseCoverImageTest.java b/src/test/java/nextstep/courses/domain/CourseCoverImageTest.java index 85bfd7754..1afeb7926 100644 --- a/src/test/java/nextstep/courses/domain/CourseCoverImageTest.java +++ b/src/test/java/nextstep/courses/domain/CourseCoverImageTest.java @@ -8,8 +8,6 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.*; @@ -50,16 +48,6 @@ void createCourseCoverImageWithValidImage() { assertNotNull(courseCoverImage); } - @Test - @DisplayName("이미지 경로가 null이면 예외가 발생한다") - void throwExceptionWhenImagePathIsNull() { - // when & then - assertThatThrownBy(() -> { - new CourseCoverImage(null); - }).isInstanceOf(IllegalArgumentException.class) - .hasMessage("강의 커버 이미지는 비어있을 수 없습니다."); - } - @Test @DisplayName("지원하지 않는 이미지 확장자면 예외가 발생한다") void throwExceptionWhenImageExtensionIsNotSupported() { diff --git a/src/test/java/nextstep/courses/domain/CourseFreeTest.java b/src/test/java/nextstep/courses/domain/CourseFreeTest.java new file mode 100644 index 000000000..d91567fe2 --- /dev/null +++ b/src/test/java/nextstep/courses/domain/CourseFreeTest.java @@ -0,0 +1,60 @@ +package nextstep.courses.domain; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.time.LocalDateTime; + +import static org.assertj.core.api.Assertions.assertThat; + +class CourseFreeTest { + + private static final String TEST_TITLE = "자바 기초 강의"; + private static final Long TEST_CREATOR_ID = 1L; + private static final String TEST_RESOURCES_PATH = "src/test/resources/images"; + private static final String TEST_COVER_IMAGE_PATH = TEST_RESOURCES_PATH + "/valid.jpg"; + + private CourseFree courseFree; + + @BeforeEach + void setUp() throws IOException { + // Create test resources directory if it doesn't exist + File testDir = new File(TEST_RESOURCES_PATH); + if (!testDir.exists()) { + testDir.mkdirs(); + } + + // Create valid image (400x300) + createTestImage(400, 300, "valid.jpg"); + + courseFree = new CourseFree(TEST_TITLE, TEST_CREATOR_ID, TEST_COVER_IMAGE_PATH); + } + + @Test + @DisplayName("무료 강의를 생성 테스트") + void createCourseFree() { + // then + assertThat(courseFree).isNotNull(); + assertThat(courseFree.getTitle()).isEqualTo(TEST_TITLE); + assertThat(courseFree.getCreatorId()).isEqualTo(TEST_CREATOR_ID); + } + + @Test + @DisplayName("무료 강의는 최대 수강 인원 제한이 없음") + void courseFreeHasNoMaxAttendeesLimit() { + // then + assertThat(courseFree.getMaxAttendees()).isEqualTo(Long.MAX_VALUE); + } + + private File createTestImage(int width, int height, String fileName) throws IOException { + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + File imageFile = new File(TEST_RESOURCES_PATH, fileName); + ImageIO.write(image, "jpg", imageFile); + return imageFile; + } +} \ No newline at end of file diff --git a/src/test/java/nextstep/courses/infrastructure/CourseRepositoryTest.java b/src/test/java/nextstep/courses/infrastructure/CourseRepositoryTest.java index f087fc0ad..d2619c570 100644 --- a/src/test/java/nextstep/courses/infrastructure/CourseRepositoryTest.java +++ b/src/test/java/nextstep/courses/infrastructure/CourseRepositoryTest.java @@ -28,7 +28,7 @@ void setUp() { @Test void crud() { - Course course = new Course("TDD, 클린 코드 with Java", 1L); + Course course = new Course("TDD, 클린 코드 with Java", 1L, null, null); int count = courseRepository.save(course); assertThat(count).isEqualTo(1); Course savedCourse = courseRepository.findById(1L); diff --git a/src/test/resources/images/default.jpg b/src/test/resources/images/default.jpg new file mode 100644 index 0000000000000000000000000000000000000000..42e842efa242e0c5fa0284238f05cd1f9b358c5c GIT binary patch literal 2527 zcmex=^(PF6}rMnOeST|r4lSw=>~TvNxu(8R<| zHF0u@iAzXIsj8`KXlj|5nweWzS~We&gn?hmRgVdHU@6i$mSee*Oaai;;mD;w>Nv@fe!F1cClyVqsxs zVF&q(k*OSrnFU!`6%E;h90S=C3x$=88aYIqCNA7~kW<+>=!0ld(M2vX6_bamA3 Date: Wed, 9 Apr 2025 00:46:49 +0900 Subject: [PATCH 11/12] [LMS] step2: Course --- src/main/java/nextstep/README.md | 14 +++++------ .../nextstep/courses/domain/AttendeeList.java | 22 +++++++++++++++++ .../java/nextstep/courses/domain/Course.java | 17 +++++++++++-- .../infrastructure/JdbcCourseRepository.java | 3 ++- .../java/nextstep/users/domain/NsUser.java | 24 +++++++++++++++++-- 5 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 src/main/java/nextstep/courses/domain/AttendeeList.java diff --git a/src/main/java/nextstep/README.md b/src/main/java/nextstep/README.md index 29aa7aba0..b40185ac6 100644 --- a/src/main/java/nextstep/README.md +++ b/src/main/java/nextstep/README.md @@ -24,12 +24,12 @@ - [x] 이미지 크기는 1MB 이하여야 한다. - [x] 이미지 타입은 gif, jpg(jpeg 포함), png, svg 만 허용한다. - [x] 이미지의 width는 300픽셀, height는 200픽셀 이상이어야 하며, width와 height의 비율은 3:2여야 한다. -- [ ] 강의는 무료 강의와 유료 강으로 나뉜다. - - [ ] 무료 강의는 최대 수강 인원 제한이 없다. - - [ ] 유료 강의는 강의 최대 수강 인원을 초과할 수 없다. - - [ ] 유료 강의는 수강생이 결제한 금액과 수강료가 일치할 때 수강 신청이 가능하다. -- [ ] 강의 상태는 준비중, 모집중, 종료 3가지 상태를 가진다. -- [ ] 강의 수강신청은 강의 상태가 모집중일 때만 가능하다. +- [x] 강의는 무료 강의와 유료 강으로 나뉜다. + - [x] 무료 강의는 최대 수강 인원 제한이 없다. + - [x] 유료 강의는 강의 최대 수강 인원을 초과할 수 없다. + * 유료 강의는 수강생이 결제한 금액과 수강료가 일치할 때 수강 신청이 가능하다. +- [x] 강의 상태는 준비중, 모집중, 종료 3가지 상태를 가진다. +- [x] 강의 수강신청은 강의 상태가 모집중일 때만 가능하다. * 유료 강의의 경우 결제는 이미 완료한 것으로 가정하고 이후 과정을 구현한다. - * [ ] 결제를 완료한 결제 정보는 payments 모듈을 통해 관리되며, 결제 정보는 Payment 객체에 담겨 반환된다. \ No newline at end of file + * 결제를 완료한 결제 정보는 payments 모듈을 통해 관리되며, 결제 정보는 Payment 객체에 담겨 반환된다. diff --git a/src/main/java/nextstep/courses/domain/AttendeeList.java b/src/main/java/nextstep/courses/domain/AttendeeList.java new file mode 100644 index 000000000..8bb731462 --- /dev/null +++ b/src/main/java/nextstep/courses/domain/AttendeeList.java @@ -0,0 +1,22 @@ +package nextstep.courses.domain; + +import java.util.ArrayList; +import java.util.List; + +import nextstep.users.domain.NsUser; + +public class AttendeeList { + private final List attendees; + + public AttendeeList() { + this.attendees = new ArrayList<>(); + } + + public void add(NsUser attendee) { + attendees.add(attendee); + } + + public Long size() { + return (long) attendees.size(); + } +} diff --git a/src/main/java/nextstep/courses/domain/Course.java b/src/main/java/nextstep/courses/domain/Course.java index ff221467d..c51e78fbc 100644 --- a/src/main/java/nextstep/courses/domain/Course.java +++ b/src/main/java/nextstep/courses/domain/Course.java @@ -22,14 +22,18 @@ public class Course { private Long maxAttendees; + private CourseStatus courseStatus; + + private AttendeeList attendees = new AttendeeList(); + public Course() { } public Course(String title, Long creatorId, String courseCoverImageFilePath, Long maxAttendees) { - this(0L, title, creatorId, LocalDateTime.now(), null, courseCoverImageFilePath, maxAttendees); + this(0L, title, creatorId, LocalDateTime.now(), null, courseCoverImageFilePath, maxAttendees, CourseStatus.PREPARING); } - public Course(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt, String courseCoverImageFilePath, Long maxAttendees) { + public Course(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt, String courseCoverImageFilePath, Long maxAttendees, CourseStatus courseStatus) { this.id = id; this.title = title; this.creatorId = creatorId; @@ -38,6 +42,11 @@ public Course(Long id, String title, Long creatorId, LocalDateTime createdAt, Lo this.courseCoverImageFilePath = courseCoverImageFilePath; this.courseCoverImage = new CourseCoverImage(courseCoverImageFilePath); this.maxAttendees = maxAttendees; + this.courseStatus = courseStatus; + } + + public AttendeeList getAttendees() { + return attendees; } public String getTitle() { @@ -56,6 +65,10 @@ public Long getMaxAttendees() { return maxAttendees; } + public CourseStatus getCourseStatus() { + return courseStatus; + } + @Override public String toString() { return "Course{" + diff --git a/src/main/java/nextstep/courses/infrastructure/JdbcCourseRepository.java b/src/main/java/nextstep/courses/infrastructure/JdbcCourseRepository.java index 774b56886..2e15d567b 100644 --- a/src/main/java/nextstep/courses/infrastructure/JdbcCourseRepository.java +++ b/src/main/java/nextstep/courses/infrastructure/JdbcCourseRepository.java @@ -33,7 +33,8 @@ public Course findById(Long id) { toLocalDateTime(rs.getTimestamp(4)), toLocalDateTime(rs.getTimestamp(5)), null, // courseCoverImageFilePath - null // maxAttendees + null, // maxAttendees + null // courseStatus ); return jdbcTemplate.queryForObject(sql, rowMapper, id); } diff --git a/src/main/java/nextstep/users/domain/NsUser.java b/src/main/java/nextstep/users/domain/NsUser.java index 62ec5138c..0e209b710 100755 --- a/src/main/java/nextstep/users/domain/NsUser.java +++ b/src/main/java/nextstep/users/domain/NsUser.java @@ -1,10 +1,14 @@ package nextstep.users.domain; -import nextstep.qna.UnAuthorizedException; - import java.time.LocalDateTime; import java.util.Objects; +import nextstep.courses.domain.Course; +import nextstep.courses.domain.CourseFree; +import nextstep.courses.domain.CoursePaid; +import nextstep.courses.domain.CourseStatus; +import nextstep.qna.UnAuthorizedException; + public class NsUser { public static final GuestNsUser GUEST_USER = new GuestNsUser(); @@ -124,6 +128,22 @@ public boolean isGuestUser() { } } + public void registerCourse(Course course) { + if (course.getCourseStatus() == CourseStatus.PREPARING) { + throw new IllegalArgumentException("강의가 준비중입니다."); + } + if (course.getAttendees().size() >= course.getMaxAttendees()) { + throw new IllegalArgumentException("강의 수강 인원이 초과되었습니다."); + } + if (course instanceof CoursePaid) { + // Payment... + course.getAttendees().add(this); + } + if (course instanceof CourseFree) { + course.getAttendees().add(this); + } + } + @Override public String toString() { return "NsUser{" + From d03f4aa2228d2e802aaa3debc60e09abbcf102b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?bt=2E7274=28=EA=B9=80=ED=99=8D=EA=B7=A0=29/kakao?= Date: Wed, 9 Apr 2025 00:49:19 +0900 Subject: [PATCH 12/12] [LMS] step2: Course --- src/main/java/nextstep/courses/domain/Course.java | 4 ++++ src/main/java/nextstep/courses/domain/CourseFree.java | 8 +++++--- src/main/java/nextstep/courses/domain/CoursePaid.java | 6 +++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/nextstep/courses/domain/Course.java b/src/main/java/nextstep/courses/domain/Course.java index c51e78fbc..df1f994e6 100644 --- a/src/main/java/nextstep/courses/domain/Course.java +++ b/src/main/java/nextstep/courses/domain/Course.java @@ -33,6 +33,10 @@ public Course(String title, Long creatorId, String courseCoverImageFilePath, Lon this(0L, title, creatorId, LocalDateTime.now(), null, courseCoverImageFilePath, maxAttendees, CourseStatus.PREPARING); } + public Course(String title, Long creatorId, String courseCoverImageFilePath, Long maxAttendees, CourseStatus courseStatus) { + this(0L, title, creatorId, LocalDateTime.now(), null, courseCoverImageFilePath, maxAttendees, courseStatus); + } + public Course(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt, String courseCoverImageFilePath, Long maxAttendees, CourseStatus courseStatus) { this.id = id; this.title = title; diff --git a/src/main/java/nextstep/courses/domain/CourseFree.java b/src/main/java/nextstep/courses/domain/CourseFree.java index 7a5f923d9..2d4fcdf78 100644 --- a/src/main/java/nextstep/courses/domain/CourseFree.java +++ b/src/main/java/nextstep/courses/domain/CourseFree.java @@ -10,9 +10,11 @@ public CourseFree(String title, Long creatorId, String courseCoverImageFilePath) super(title, creatorId, courseCoverImageFilePath, MAX_ATTENDEES); } - public CourseFree(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt, String courseCoverImageFilePath, Long maxAttendees) { - super(id, title, creatorId, createdAt, updatedAt, courseCoverImageFilePath, maxAttendees); + public CourseFree(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt, String courseCoverImageFilePath) { + super(id, title, creatorId, createdAt, updatedAt, courseCoverImageFilePath, MAX_ATTENDEES, CourseStatus.PREPARING); } - + public CourseFree(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt, String courseCoverImageFilePath, CourseStatus courseStatus) { + super(id, title, creatorId, createdAt, updatedAt, courseCoverImageFilePath, MAX_ATTENDEES, courseStatus); + } } diff --git a/src/main/java/nextstep/courses/domain/CoursePaid.java b/src/main/java/nextstep/courses/domain/CoursePaid.java index 4375bd514..da6461089 100644 --- a/src/main/java/nextstep/courses/domain/CoursePaid.java +++ b/src/main/java/nextstep/courses/domain/CoursePaid.java @@ -9,7 +9,11 @@ public CoursePaid(String title, Long creatorId, String courseCoverImageFilePath, } public CoursePaid(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt, String courseCoverImageFilePath, Long maxAttendees) { - super(id, title, creatorId, createdAt, updatedAt, courseCoverImageFilePath, maxAttendees); + super(id, title, creatorId, createdAt, updatedAt, courseCoverImageFilePath, maxAttendees, CourseStatus.PREPARING); + } + + public CoursePaid(Long id, String title, Long creatorId, LocalDateTime createdAt, LocalDateTime updatedAt, String courseCoverImageFilePath, Long maxAttendees, CourseStatus courseStatus) { + super(id, title, creatorId, createdAt, updatedAt, courseCoverImageFilePath, maxAttendees, courseStatus); } }