Skip to content

Commit 69422dd

Browse files
Merge pull request #211 from prgrms-web-devcourse-final-project/feature/EA3-167-study-detail
[EA3-167] feature: 스터디 생성 예외 추가
2 parents 2cec246 + 73abe3c commit 69422dd

File tree

10 files changed

+95
-49
lines changed

10 files changed

+95
-49
lines changed

src/main/java/grep/neogulcoder/domain/study/Study.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ public class Study extends BaseEntity {
1717
@GeneratedValue(strategy = GenerationType.IDENTITY)
1818
private Long id;
1919

20+
private Long userId;
21+
2022
private Long originStudyId;
2123

2224
private String name;
@@ -49,8 +51,9 @@ protected Study() {
4951
}
5052

5153
@Builder
52-
private Study(Long originStudyId, String name, Category category, int capacity, StudyType studyType, String location,
54+
private Study(Long userId, Long originStudyId, String name, Category category, int capacity, StudyType studyType, String location,
5355
LocalDateTime startDate, LocalDateTime endDate, String introduction, String imageUrl) {
56+
this.userId = userId;
5457
this.originStudyId = originStudyId;
5558
this.name = name;
5659
this.category = category;

src/main/java/grep/neogulcoder/domain/study/StudyMember.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ public StudyMember(Study study, Long userId, StudyMemberRole role) {
3636
this.participated = false;
3737
}
3838

39+
public static StudyMember createLeader(Study study, Long userId) {
40+
return StudyMember.builder()
41+
.study(study)
42+
.userId(userId)
43+
.role(StudyMemberRole.LEADER)
44+
.build();
45+
}
46+
3947
public static StudyMember createMember(Study study, Long userId) {
4048
return StudyMember.builder()
4149
.study(study)

src/main/java/grep/neogulcoder/domain/study/controller/dto/request/StudyCreateRequest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,9 @@ private StudyCreateRequest(String name, Category category, int capacity, StudyTy
6060
this.introduction = introduction;
6161
}
6262

63-
public Study toEntity(String imageUrl) {
63+
public Study toEntity(Long userId, String imageUrl) {
6464
return Study.builder()
65+
.userId(userId)
6566
.name(this.name)
6667
.category(this.category)
6768
.capacity(this.capacity)

src/main/java/grep/neogulcoder/domain/study/exception/code/StudyErrorCode.java

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,19 @@ public enum StudyErrorCode implements ErrorCode {
1111
STUDY_MEMBER_NOT_FOUND("S002", HttpStatus.NOT_FOUND, "스터디 멤버가 아닙니다."),
1212
EXTENDED_STUDY_NOT_FOUND("S003", HttpStatus.NOT_FOUND, "연장된 스터디를 찾을 수 없습니다."),
1313

14-
STUDY_ALREADY_STARTED("S004", HttpStatus.BAD_REQUEST, "이미 시작된 스터디의 시작일은 변경할 수 없습니다."),
15-
STUDY_DELETE_NOT_ALLOWED("S005", HttpStatus.BAD_REQUEST, "스터디 멤버가 1명일 때만 삭제할 수 있습니다."),
16-
STUDY_LOCATION_REQUIRED("S006", HttpStatus.BAD_REQUEST, "스터디 타입이 OFFLINE이나 HYBRID인 스터디는 지역 입력이 필수입니다."),
17-
18-
STUDY_EXTENSION_NOT_AVAILABLE("S007", HttpStatus.BAD_REQUEST, "스터디 연장은 스터디 종료일 7일 전부터 가능합니다."),
19-
END_DATE_BEFORE_ORIGIN_STUDY("S008", HttpStatus.BAD_REQUEST, "연장 스터디 종료일은 기존 스터디 종료일 이후여야 합니다."),
20-
ALREADY_EXTENDED_STUDY("S009", HttpStatus.BAD_REQUEST, "이미 연장된 스터디입니다."),
21-
ALREADY_REGISTERED_PARTICIPATION("S010", HttpStatus.BAD_REQUEST, "연장 스터디 참여는 한 번만 등록할 수 있습니다."),
22-
23-
NOT_STUDY_LEADER("S011", HttpStatus.FORBIDDEN, "스터디장만 접근이 가능합니다."),
24-
LEADER_CANNOT_LEAVE_STUDY("S012", HttpStatus.BAD_REQUEST, "스터디장은 스터디를 탈퇴할 수 없습니다."),
25-
LEADER_CANNOT_DELEGATE_TO_SELF("S013", HttpStatus.BAD_REQUEST, "자기 자신에게는 스터디장 위임이 불가능합니다.");
14+
STUDY_CREATE_LIMIT_EXCEEDED("S004", HttpStatus.BAD_REQUEST, "종료되지 않은 스터디는 최대 10개까지만 생성할 수 있습니다."),
15+
STUDY_ALREADY_STARTED("S005", HttpStatus.BAD_REQUEST, "이미 시작된 스터디의 시작일은 변경할 수 없습니다."),
16+
STUDY_DELETE_NOT_ALLOWED("S006", HttpStatus.BAD_REQUEST, "스터디 멤버가 1명일 때만 삭제할 수 있습니다."),
17+
STUDY_LOCATION_REQUIRED("S007", HttpStatus.BAD_REQUEST, "스터디 타입이 OFFLINE이나 HYBRID인 스터디는 지역 입력이 필수입니다."),
18+
19+
STUDY_EXTENSION_NOT_AVAILABLE("S008", HttpStatus.BAD_REQUEST, "스터디 연장은 스터디 종료일 7일 전부터 가능합니다."),
20+
END_DATE_BEFORE_ORIGIN_STUDY("S009", HttpStatus.BAD_REQUEST, "연장 스터디 종료일은 기존 스터디 종료일 이후여야 합니다."),
21+
ALREADY_EXTENDED_STUDY("S010", HttpStatus.BAD_REQUEST, "이미 연장된 스터디입니다."),
22+
ALREADY_REGISTERED_PARTICIPATION("S011", HttpStatus.BAD_REQUEST, "연장 스터디 참여는 한 번만 등록할 수 있습니다."),
23+
24+
NOT_STUDY_LEADER("S012", HttpStatus.FORBIDDEN, "스터디장만 접근이 가능합니다."),
25+
LEADER_CANNOT_LEAVE_STUDY("S013", HttpStatus.BAD_REQUEST, "스터디장은 스터디를 탈퇴할 수 없습니다."),
26+
LEADER_CANNOT_DELEGATE_TO_SELF("S014", HttpStatus.BAD_REQUEST, "자기 자신에게는 스터디장 위임이 불가능합니다.");
2627

2728
private final String code;
2829
private final HttpStatus status;

src/main/java/grep/neogulcoder/domain/study/repository/StudyRepository.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,6 @@ public interface StudyRepository extends JpaRepository<Study, Long> {
2626

2727
@Query("select s from Study s where s.endDate < :now and s.finished = false and s.activated = true")
2828
List<Study> findStudiesToBeFinished(@Param("now") LocalDateTime now);
29+
30+
int countByUserIdAndActivatedTrueAndFinishedFalse(Long userId);
2931
}

src/main/java/grep/neogulcoder/domain/study/service/StudyService.java

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,7 @@ public StudyItemPagingResponse getMyStudiesPaging(Pageable pageable, Long userId
6868
}
6969

7070
public List<StudyItemResponse> getMyUnfinishedStudies(Long userId) {
71-
List<StudyItemResponse> myUnfinishedStudies = studyQueryRepository.findMyUnfinishedStudies(userId);
72-
return myUnfinishedStudies;
73-
}
74-
75-
public List<StudyItemResponse> getMyStudies(Long userId) {
76-
return studyQueryRepository.findMyStudies(userId);
71+
return studyQueryRepository.findMyUnfinishedStudies(userId);
7772
}
7873

7974
public StudyHeaderResponse getStudyHeader(Long studyId) {
@@ -90,10 +85,7 @@ public StudyResponse getStudy(Long studyId) {
9085
progressDays = Math.max(0, Math.min(progressDays, totalDays));
9186
int totalPostCount = studyPostRepository.countByStudyIdAndActivatedTrue(studyId);
9287

93-
LocalDate now = LocalDate.now();
94-
int currentYear = now.getYear();
95-
int currentMonth = now.getMonthValue();
96-
List<TeamCalendarResponse> teamCalendars = teamCalendarService.findByMonth(studyId, currentYear, currentMonth);
88+
List<TeamCalendarResponse> teamCalendars = getCurrentMonthTeamCalendars(studyId);
9789

9890
List<NoticePostInfo> noticePosts = studyPostQueryRepository.findLatestNoticeInfoBy(studyId);
9991
List<FreePostInfo> freePosts = studyPostQueryRepository.findLatestFreeInfoBy(studyId);
@@ -121,8 +113,7 @@ public StudyInfoResponse getMyStudyContent(Long studyId, Long userId) {
121113
}
122114

123115
public StudyMemberInfoResponse getMyStudyMemberInfo(Long studyId, Long userId) {
124-
StudyMember studyMember = Optional.ofNullable(studyMemberQueryRepository.findByStudyIdAndUserId(studyId, userId))
125-
.orElseThrow(() -> new NotFoundException(STUDY_MEMBER_NOT_FOUND));
116+
StudyMember studyMember = findValidStudyMember(studyId, userId);
126117

127118
User user = userRepository.findById(userId)
128119
.orElseThrow(() -> new NotFoundException(USER_NOT_FOUND));
@@ -132,20 +123,16 @@ public StudyMemberInfoResponse getMyStudyMemberInfo(Long studyId, Long userId) {
132123

133124
@Transactional
134125
public Long createStudy(StudyCreateRequest request, Long userId, MultipartFile image) throws IOException {
126+
validateStudyCreateLimit(userId);
135127
validateLocation(request.getStudyType(), request.getLocation());
136128

137129
String imageUrl = createImageUrl(userId, image);
138130

139-
Study study = studyRepository.save(request.toEntity(imageUrl));
131+
Study study = studyRepository.save(request.toEntity(userId, imageUrl));
140132

141-
StudyMember leader = StudyMember.builder()
142-
.study(study)
143-
.userId(userId)
144-
.role(LEADER)
145-
.build();
133+
StudyMember leader = StudyMember.createLeader(study, userId);
146134
studyMemberRepository.save(leader);
147135

148-
// 3. 그룹 채팅방 생성
149136
GroupChatRoom chatRoom = new GroupChatRoom(study.getId());
150137
groupChatRoomRepository.save(chatRoom);
151138

@@ -200,12 +187,31 @@ private Study findValidStudy(Long studyId) {
200187
.orElseThrow(() -> new NotFoundException(STUDY_NOT_FOUND));
201188
}
202189

190+
private StudyMember findValidStudyMember(Long studyId, Long userId) {
191+
return Optional.ofNullable(studyMemberQueryRepository.findByStudyIdAndUserId(studyId, userId))
192+
.orElseThrow(() -> new NotFoundException(STUDY_MEMBER_NOT_FOUND));
193+
}
194+
195+
private void validateStudyCreateLimit(Long userId) {
196+
int count = studyRepository.countByUserIdAndActivatedTrueAndFinishedFalse(userId);
197+
if (count >= 10) {
198+
throw new BusinessException(STUDY_CREATE_LIMIT_EXCEEDED);
199+
}
200+
}
201+
203202
private static void validateLocation(StudyType studyType, String location) {
204203
if ((studyType == StudyType.OFFLINE || studyType == StudyType.HYBRID) && (location == null || location.isBlank())) {
205204
throw new BusinessException(STUDY_LOCATION_REQUIRED);
206205
}
207206
}
208207

208+
private List<TeamCalendarResponse> getCurrentMonthTeamCalendars(Long studyId) {
209+
LocalDate now = LocalDate.now();
210+
int currentYear = now.getYear();
211+
int currentMonth = now.getMonthValue();
212+
return teamCalendarService.findByMonth(studyId, currentYear, currentMonth);
213+
}
214+
209215
private void validateStudyMember(Long studyId, Long userId) {
210216
boolean exists = studyMemberRepository.existsByStudyIdAndUserIdAndActivatedTrue(studyId, userId);
211217
if (!exists) {
@@ -234,9 +240,8 @@ private void validateStudyDeletable(Long studyId) {
234240
}
235241

236242
private String createImageUrl(Long userId, MultipartFile image) throws IOException {
237-
FileUploadResponse response = null;
238243
if (isImgExists(image)) {
239-
response = fileUploader.upload(image, userId, FileUsageType.STUDY_COVER, userId);
244+
FileUploadResponse response = fileUploader.upload(image, userId, FileUsageType.STUDY_COVER, userId);
240245
return response.getFileUrl();
241246
}
242247
return null;

src/main/java/grep/neogulcoder/domain/studypost/controller/dto/response/FreePostInfo.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import io.swagger.v3.oas.annotations.media.Schema;
66
import lombok.Getter;
77

8-
import java.time.LocalDate;
98
import java.time.LocalDateTime;
109

1110
@Getter
@@ -21,13 +20,13 @@ public class FreePostInfo {
2120
private String title;
2221

2322
@Schema(example = "2025-07-21", description = "생성일")
24-
private LocalDate createdAt;
23+
private LocalDateTime createdAt;
2524

2625
@QueryProjection
2726
public FreePostInfo(long postId, Category category, String title, LocalDateTime createdAt) {
2827
this.postId = postId;
2928
this.category = category.getKorean();
3029
this.title = title;
31-
this.createdAt = createdAt.toLocalDate();
30+
this.createdAt = createdAt;
3231
}
3332
}

src/main/java/grep/neogulcoder/domain/studypost/controller/dto/response/NoticePostInfo.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import io.swagger.v3.oas.annotations.media.Schema;
66
import lombok.Getter;
77

8-
import java.time.LocalDate;
98
import java.time.LocalDateTime;
109

1110
@Getter
@@ -21,13 +20,13 @@ public class NoticePostInfo {
2120
private String title;
2221

2322
@Schema(example = "2025-07-21", description = "생성일")
24-
private LocalDate createdAt;
23+
private LocalDateTime createdAt;
2524

2625
@QueryProjection
2726
public NoticePostInfo(long postId, Category category, String title, LocalDateTime createdAt) {
2827
this.postId = postId;
2928
this.category = category.getKorean();
3029
this.title = title;
31-
this.createdAt = createdAt.toLocalDate();
30+
this.createdAt = createdAt;
3231
}
3332
}

src/main/resources/data.sql

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ INSERT INTO member (activated, email, password, nickname, profile_image_url, rol
77
INSERT INTO member (activated, email, password, nickname, profile_image_url, role, oauth_id, oauth_provider) VALUES (true,'[email protected]', '{bcrypt}$2b$12$TK9zyc6f5qjHE1sSUSULieLOJVDBraWqSz2HRrIKgEKjUES0J2kva', 'test2','https://placekitten.com/812/625', 'ROLE_USER', NULL, NULL);
88
INSERT INTO member (activated, email, password, nickname, profile_image_url, role, oauth_id, oauth_provider) VALUES (true,'[email protected]', '{bcrypt}$2b$12$TK9zyc6f5qjHE1sSUSULieLOJVDBraWqSz2HRrIKgEKjUES0J2kva', 'test3','https://placekitten.com/812/626', 'ROLE_USER', NULL, NULL);
99

10-
INSERT INTO study (origin_study_id, name, category, capacity, current_count, study_type, location, start_date, end_date, introduction, image_url, extended, activated, finished) VALUES (NULL, '자바 스터디', 'IT', 10, 1, 'ONLINE', NULL, '2025-08-01', '2025-12-31', '자바 스터디에 오신 것을 환영합니다.', 'https://example.com/image.jpg', FALSE, TRUE, FALSE);
11-
INSERT INTO study (origin_study_id, name, category, capacity, current_count, study_type, location, start_date, end_date, introduction, image_url, extended, activated, finished) VALUES (NULL, '파이썬 스터디', 'IT', 8, 1, 'OFFLINE', '대구', '2025-09-01', '2026-01-31', '파이썬 기초부터 심화까지 학습합니다.', 'https://example.com/python.jpg', FALSE, TRUE, FALSE);
12-
INSERT INTO study (origin_study_id, name, category, capacity, current_count, study_type, location, start_date, end_date, introduction, image_url, extended, activated, finished) VALUES (NULL, '디자인 스터디', 'DESIGN', 6, 1, 'HYBRID', '서울', '2025-07-15', '2025-10-15', 'UI/UX 디자인 실습 중심 스터디입니다.', 'https://example.com/design.jpg', FALSE, TRUE, FALSE);
13-
INSERT INTO study (origin_study_id, name, category, capacity, current_count, study_type, location, start_date, end_date, introduction, image_url, extended, activated, finished) VALUES (NULL, '7급 공무원 스터디', 'EXAM', 12, 1, 'ONLINE', NULL, '2025-08-10', '2025-12-20', '7급 공무원 대비 스터디입니다.', 'https://example.com/exam.jpg', FALSE, TRUE, FALSE);
14-
INSERT INTO study (origin_study_id, name, category, capacity, current_count, study_type, location, start_date, end_date, introduction, image_url, extended, activated, finished) VALUES (NULL, '토익 스터디', 'LANGUAGE', 9, 1, 'OFFLINE', '광주', '2025-09-05', '2026-02-28', '토익 스터디입니다.', 'https://example.com/datascience.jpg', FALSE, TRUE, FALSE);
15-
INSERT INTO study (origin_study_id, name, category, capacity, current_count, study_type, location, start_date, end_date, introduction, image_url, extended, activated, finished) VALUES (NULL, '최적시간 테스트 스터디', 'IT', 9, 1, 'OFFLINE', '광주', '2025-09-05', '2026-02-28', '테스트 스터디입니다.', 'https://example.com/datascience.jpg', FALSE, TRUE, FALSE);
10+
INSERT INTO study (user_id, origin_study_id, name, category, capacity, current_count, study_type, location, start_date, end_date, introduction, image_url, extended, activated, finished) VALUES (1, NULL, '자바 스터디', 'IT', 10, 1, 'ONLINE', NULL, '2025-08-01', '2025-12-31', '자바 스터디에 오신 것을 환영합니다.', 'https://example.com/image.jpg', FALSE, TRUE, FALSE);
11+
INSERT INTO study (user_id, origin_study_id, name, category, capacity, current_count, study_type, location, start_date, end_date, introduction, image_url, extended, activated, finished) VALUES (1, NULL, '파이썬 스터디', 'IT', 8, 1, 'OFFLINE', '대구', '2025-09-01', '2026-01-31', '파이썬 기초부터 심화까지 학습합니다.', 'https://example.com/python.jpg', FALSE, TRUE, FALSE);
12+
INSERT INTO study (user_id, origin_study_id, name, category, capacity, current_count, study_type, location, start_date, end_date, introduction, image_url, extended, activated, finished) VALUES (1, NULL, '디자인 스터디', 'DESIGN', 6, 1, 'HYBRID', '서울', '2025-07-15', '2025-10-15', 'UI/UX 디자인 실습 중심 스터디입니다.', 'https://example.com/design.jpg', FALSE, TRUE, FALSE);
13+
INSERT INTO study (user_id, origin_study_id, name, category, capacity, current_count, study_type, location, start_date, end_date, introduction, image_url, extended, activated, finished) VALUES (1, NULL, '7급 공무원 스터디', 'EXAM', 12, 1, 'ONLINE', NULL, '2025-08-10', '2025-12-20', '7급 공무원 대비 스터디입니다.', 'https://example.com/exam.jpg', FALSE, TRUE, FALSE);
14+
INSERT INTO study (user_id, origin_study_id, name, category, capacity, current_count, study_type, location, start_date, end_date, introduction, image_url, extended, activated, finished) VALUES (1, NULL, '토익 스터디', 'LANGUAGE', 9, 1, 'OFFLINE', '광주', '2025-09-05', '2026-02-28', '토익 스터디입니다.', 'https://example.com/datascience.jpg', FALSE, TRUE, FALSE);
15+
INSERT INTO study (user_id, origin_study_id, name, category, capacity, current_count, study_type, location, start_date, end_date, introduction, image_url, extended, activated, finished) VALUES (1, NULL, '최적시간 테스트 스터디', 'IT', 9, 1, 'OFFLINE', '광주', '2025-09-05', '2026-02-28', '테스트 스터디입니다.', 'https://example.com/datascience.jpg', FALSE, TRUE, FALSE);
1616

1717
INSERT INTO study_post (study_id, user_id, title, category, content, activated) VALUES (5, 3, '자바 스터디 1주차 공지.', 'NOTICE', '1주차 스터디 내용은 가위바위보 게임 만들기 입니다. 모두 각자 만드시고 설명 하는 시간을 가지겠습니다.', true);
1818
INSERT INTO study_post (study_id, user_id, title, category, content, activated) VALUES (4, 4, '익명 클래스 자료 공유', 'FREE', '동물 이라는 인터페이스가 있을때 구현체는 강아지, 고양이 등이 있습니다. 구현을 하면 여러 구현 클래스가 필요합니다 이를 줄이기 위해 익명클래스를 사용할 수 있습니다.', true);

src/test/java/grep/neogulcoder/domain/study/service/StudyServiceTest.java

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import static grep.neogulcoder.domain.study.enums.StudyMemberRole.LEADER;
3131
import static grep.neogulcoder.domain.study.enums.StudyMemberRole.MEMBER;
3232
import static grep.neogulcoder.domain.study.exception.code.StudyErrorCode.NOT_STUDY_LEADER;
33+
import static grep.neogulcoder.domain.study.exception.code.StudyErrorCode.STUDY_CREATE_LIMIT_EXCEEDED;
3334
import static org.assertj.core.api.Assertions.assertThat;
3435
import static org.assertj.core.api.Assertions.assertThatThrownBy;
3536

@@ -69,7 +70,6 @@ void getStudies() {
6970
Study study = createStudy("스터디", Category.IT, 3, StudyType.OFFLINE, "서울", LocalDateTime.of(2025, 7, 18, 0, 0, 0),
7071
LocalDateTime.of(2025, 7, 28, 0, 0, 0), "스터디입니다.", "http://localhost:8083/image.url");
7172
studyRepository.save(study);
72-
Long studyId = study.getId();
7373

7474
StudyMember studyMember = createStudyMember(study, userId, LEADER);
7575
studyMemberRepository.save(studyMember);
@@ -92,7 +92,7 @@ void createStudy() throws IOException {
9292
.studyType(StudyType.OFFLINE)
9393
.location("서울")
9494
.startDate(LocalDateTime.of(2025, 7, 20, 0, 0, 0))
95-
.endDate(LocalDateTime.of(2025, 7, 28, 0, 0, 0))
95+
.endDate(LocalDateTime.of(2026, 7, 28, 0, 0, 0))
9696
.introduction("스터디입니다.")
9797
.build();
9898
MultipartFile image = null;
@@ -107,6 +107,34 @@ void createStudy() throws IOException {
107107
assertThat(findStudy.getName()).isEqualTo("스터디");
108108
}
109109

110+
@DisplayName("종료되지 않은 스터디를 10개 초과로 생성할 시 예외가 발생합니다.")
111+
@Test
112+
void createStudyFail() throws IOException {
113+
// given
114+
StudyCreateRequest request = StudyCreateRequest.builder()
115+
.name("스터디")
116+
.category(Category.IT)
117+
.capacity(5)
118+
.studyType(StudyType.OFFLINE)
119+
.location("서울")
120+
.startDate(LocalDateTime.of(2025, 7, 20, 0, 0, 0))
121+
.endDate(LocalDateTime.of(2026, 7, 28, 0, 0, 0))
122+
.introduction("스터디입니다.")
123+
.build();
124+
MultipartFile image = null;
125+
126+
for (int i = 0; i < 10; i++) {
127+
studyService.createStudy(request, userId, image);
128+
em.flush();
129+
em.clear();
130+
}
131+
132+
// when then
133+
assertThatThrownBy(() ->
134+
studyService.createStudy(request, userId, image))
135+
.isInstanceOf(BusinessException.class).hasMessage(STUDY_CREATE_LIMIT_EXCEEDED.getMessage());
136+
}
137+
110138
@DisplayName("스터디장이 스터디를 수정합니다.")
111139
@Test
112140
void updateStudy() throws IOException {

0 commit comments

Comments
 (0)