From 034ee6e982644b3a3abf53ee57359e6a05c00b97 Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Mon, 30 Oct 2023 16:22:08 +0900 Subject: [PATCH 01/27] =?UTF-8?q?feat:=20Room,=20Participant,=20Routine,?= =?UTF-8?q?=20Certification=20=EC=97=94=ED=8B=B0=ED=8B=B0=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/domain/entity/Certification.java | 52 ++++++++++ .../moabam/api/domain/entity/Participant.java | 70 ++++++++++++++ .../com/moabam/api/domain/entity/Room.java | 95 +++++++++++++++++++ .../com/moabam/api/domain/entity/Routine.java | 46 +++++++++ .../api/domain/entity/enums/RoomType.java | 6 ++ .../repository/CertificationRepository.java | 9 ++ .../repository/ParticipantRepository.java | 9 ++ .../api/domain/repository/RoomRepository.java | 9 ++ .../domain/repository/RoutineRepository.java | 9 ++ 9 files changed, 305 insertions(+) create mode 100644 src/main/java/com/moabam/api/domain/entity/Certification.java create mode 100644 src/main/java/com/moabam/api/domain/entity/Participant.java create mode 100644 src/main/java/com/moabam/api/domain/entity/Room.java create mode 100644 src/main/java/com/moabam/api/domain/entity/Routine.java create mode 100644 src/main/java/com/moabam/api/domain/entity/enums/RoomType.java create mode 100644 src/main/java/com/moabam/api/domain/repository/CertificationRepository.java create mode 100644 src/main/java/com/moabam/api/domain/repository/ParticipantRepository.java create mode 100644 src/main/java/com/moabam/api/domain/repository/RoomRepository.java create mode 100644 src/main/java/com/moabam/api/domain/repository/RoutineRepository.java diff --git a/src/main/java/com/moabam/api/domain/entity/Certification.java b/src/main/java/com/moabam/api/domain/entity/Certification.java new file mode 100644 index 00000000..567402a6 --- /dev/null +++ b/src/main/java/com/moabam/api/domain/entity/Certification.java @@ -0,0 +1,52 @@ +package com.moabam.api.domain.entity; + +import static java.util.Objects.*; + +import com.moabam.global.common.entity.BaseTimeEntity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Table(name = "certifications") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Certification extends BaseTimeEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "routine_id", nullable = false) + private Routine routine; + + @Column(name = "member_id", nullable = false, updatable = false) + private Long memberId; + + @Column(name = "image", nullable = false) + private String image; + + @Builder + private Certification(Routine routine, Long memberId, String image) { + this.routine = requireNonNull(routine); + this.memberId = requireNonNull(memberId); + this.image = requireNonNull(image); + } + + public void changeImage(String image) { + this.image = image; + } +} diff --git a/src/main/java/com/moabam/api/domain/entity/Participant.java b/src/main/java/com/moabam/api/domain/entity/Participant.java new file mode 100644 index 00000000..0273f296 --- /dev/null +++ b/src/main/java/com/moabam/api/domain/entity/Participant.java @@ -0,0 +1,70 @@ +package com.moabam.api.domain.entity; + +import static java.util.Objects.*; + +import java.time.LocalDateTime; + +import org.hibernate.annotations.SQLDelete; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Table(name = "participants") +@SQLDelete(sql = "UPDATE participants SET deleted_at = CURRENT_TIMESTAMP where id = ?") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Participant { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "room_id", updatable = false) + private Room room; + + @Column(name = "member_id", updatable = false) + private Long memberId; + + @Column(name = "is_manager") + private boolean isManager; + + @Column(name = "certify_count") + private int certifyCount; + + @Column(name = "deleted_at") + private LocalDateTime deletedAt; + + @Builder + private Participant(Room room, Long memberId) { + this.room = requireNonNull(room); + this.memberId = requireNonNull(memberId); + this.isManager = false; + this.certifyCount = 0; + } + + public void disableManager() { + this.isManager = false; + } + + public void enableManager() { + this.isManager = true; + } + + public void updateCertifyCount() { + this.certifyCount += 1; + } +} diff --git a/src/main/java/com/moabam/api/domain/entity/Room.java b/src/main/java/com/moabam/api/domain/entity/Room.java new file mode 100644 index 00000000..dfc09862 --- /dev/null +++ b/src/main/java/com/moabam/api/domain/entity/Room.java @@ -0,0 +1,95 @@ +package com.moabam.api.domain.entity; + +import static java.util.Objects.*; + +import org.hibernate.annotations.ColumnDefault; + +import com.moabam.api.domain.entity.enums.RoomType; +import com.moabam.global.common.entity.BaseTimeEntity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Table(name = "rooms") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Room extends BaseTimeEntity { + + // TODO: 방 레벨별 이미지 + private final String ROOM_LEVEL_0_IMAGE = ""; + private final String ROOM_LEVEL_10_IMAGE = ""; + private final String ROOM_LEVEL_20_IMAGE = ""; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + // TODO: 한글 10자도 맞나? + @Column(name = "title", nullable = false, length = 30) + private String title; + + @Column(name = "password", length = 8) + private String password; + + @Column(name = "level", nullable = false) + private int level; + + @Enumerated(value = EnumType.STRING) + @Column(name = "type") + private RoomType roomType; + + @Column(name = "certify_time", nullable = false) + private int certifyTime; + + @Column(name = "current_user_count", nullable = false) + private int currentUserCount; + + @Column(name = "max_user_count", nullable = false) + private int maxUserCount; + + // TODO: 한글 길이 고려 + @Column(name = "announcement", length = 255) + private String announcement; + + @ColumnDefault(ROOM_LEVEL_0_IMAGE) + @Column(name = "room_image", length = 500) + private String roomImage; + + @Builder + private Room(String title, String password, RoomType roomType, int certifyTime, int maxUserCount, + String announcement) { + this.title = requireNonNull(title); + this.password = password; + this.level = 0; + this.roomType = requireNonNull(roomType); + this.certifyTime = certifyTime; + this.currentUserCount = 1; + this.maxUserCount = maxUserCount; + this.announcement = announcement; + this.roomImage = ROOM_LEVEL_0_IMAGE; + } + + public void levelUp() { + this.level += 1; + } + + public void changeAnnouncement(String announcement) { + this.announcement = announcement; + } + + public void upgradeRoomImage(String roomImage) { + this.roomImage = roomImage; + } +} diff --git a/src/main/java/com/moabam/api/domain/entity/Routine.java b/src/main/java/com/moabam/api/domain/entity/Routine.java new file mode 100644 index 00000000..b7d90e51 --- /dev/null +++ b/src/main/java/com/moabam/api/domain/entity/Routine.java @@ -0,0 +1,46 @@ +package com.moabam.api.domain.entity; + +import com.moabam.global.common.entity.BaseTimeEntity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Table(name = "routines") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Routine extends BaseTimeEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "room_id", nullable = false, updatable = false) + private Room room; + + @Column(name = "content", nullable = false, length = 60) + private String content; + + @Builder + private Routine(Room room, String content) { + this.room = room; + this.content = content; + } + + public void changeContent(String content) { + this.content = content; + } +} diff --git a/src/main/java/com/moabam/api/domain/entity/enums/RoomType.java b/src/main/java/com/moabam/api/domain/entity/enums/RoomType.java new file mode 100644 index 00000000..b18ce1be --- /dev/null +++ b/src/main/java/com/moabam/api/domain/entity/enums/RoomType.java @@ -0,0 +1,6 @@ +package com.moabam.api.domain.entity.enums; + +public enum RoomType { + + MORNING, NIGHT +} diff --git a/src/main/java/com/moabam/api/domain/repository/CertificationRepository.java b/src/main/java/com/moabam/api/domain/repository/CertificationRepository.java new file mode 100644 index 00000000..4d794056 --- /dev/null +++ b/src/main/java/com/moabam/api/domain/repository/CertificationRepository.java @@ -0,0 +1,9 @@ +package com.moabam.api.domain.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.moabam.api.domain.entity.Certification; + +public interface CertificationRepository extends JpaRepository { + +} diff --git a/src/main/java/com/moabam/api/domain/repository/ParticipantRepository.java b/src/main/java/com/moabam/api/domain/repository/ParticipantRepository.java new file mode 100644 index 00000000..3f0a7bfc --- /dev/null +++ b/src/main/java/com/moabam/api/domain/repository/ParticipantRepository.java @@ -0,0 +1,9 @@ +package com.moabam.api.domain.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.moabam.api.domain.entity.Participant; + +public interface ParticipantRepository extends JpaRepository { + +} diff --git a/src/main/java/com/moabam/api/domain/repository/RoomRepository.java b/src/main/java/com/moabam/api/domain/repository/RoomRepository.java new file mode 100644 index 00000000..96c8d99f --- /dev/null +++ b/src/main/java/com/moabam/api/domain/repository/RoomRepository.java @@ -0,0 +1,9 @@ +package com.moabam.api.domain.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.moabam.api.domain.entity.Room; + +public interface RoomRepository extends JpaRepository { + +} diff --git a/src/main/java/com/moabam/api/domain/repository/RoutineRepository.java b/src/main/java/com/moabam/api/domain/repository/RoutineRepository.java new file mode 100644 index 00000000..099e82da --- /dev/null +++ b/src/main/java/com/moabam/api/domain/repository/RoutineRepository.java @@ -0,0 +1,9 @@ +package com.moabam.api.domain.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.moabam.api.domain.entity.Routine; + +public interface RoutineRepository extends JpaRepository { + +} From bb3add133cab8e3ae5d19d764b47bf2dadb8a1ec Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Mon, 30 Oct 2023 18:31:29 +0900 Subject: [PATCH 02/27] =?UTF-8?q?feat:=20Room=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=EC=9D=B8=EC=A6=9D=20=EC=8B=9C=EA=B0=84=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/moabam/api/domain/entity/Room.java | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/moabam/api/domain/entity/Room.java b/src/main/java/com/moabam/api/domain/entity/Room.java index dfc09862..649885e5 100644 --- a/src/main/java/com/moabam/api/domain/entity/Room.java +++ b/src/main/java/com/moabam/api/domain/entity/Room.java @@ -1,11 +1,14 @@ package com.moabam.api.domain.entity; +import static com.moabam.api.domain.entity.enums.RoomType.*; +import static com.moabam.global.error.model.ErrorMessage.*; import static java.util.Objects.*; import org.hibernate.annotations.ColumnDefault; import com.moabam.api.domain.entity.enums.RoomType; import com.moabam.global.common.entity.BaseTimeEntity; +import com.moabam.global.error.exception.BadRequestException; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -26,10 +29,15 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Room extends BaseTimeEntity { - // TODO: 방 레벨별 이미지 - private final String ROOM_LEVEL_0_IMAGE = ""; - private final String ROOM_LEVEL_10_IMAGE = ""; - private final String ROOM_LEVEL_20_IMAGE = ""; + private static final String ROOM_LEVEL_0_IMAGE = ""; + private static final String ROOM_LEVEL_10_IMAGE = ""; + private static final String ROOM_LEVEL_20_IMAGE = ""; + + private static final int MORNING_START_TIME = 4; + private static final int MORNING_END_TIME = 10; + private static final int NIGHT_START_TIME = 20; + private static final int NIGHT_END_TIME = 2; + private static final int CLOCK_ZERO = 0; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -74,7 +82,7 @@ private Room(String title, String password, RoomType roomType, int certifyTime, this.password = password; this.level = 0; this.roomType = requireNonNull(roomType); - this.certifyTime = certifyTime; + this.certifyTime = validateCertifyTime(roomType, certifyTime); this.currentUserCount = 1; this.maxUserCount = maxUserCount; this.announcement = announcement; @@ -92,4 +100,21 @@ public void changeAnnouncement(String announcement) { public void upgradeRoomImage(String roomImage) { this.roomImage = roomImage; } + + public void changeCertifyTime(int certifyTime) { + this.certifyTime = validateCertifyTime(this.roomType, certifyTime); + } + + private int validateCertifyTime(RoomType roomType, int certifyTime) { + if (roomType.equals(MORNING) && (certifyTime < MORNING_START_TIME || certifyTime > MORNING_END_TIME)) { + throw new BadRequestException(INVALID_REQUEST_FIELD); + } + + if (roomType.equals(NIGHT) + && ((certifyTime < NIGHT_START_TIME && certifyTime > NIGHT_END_TIME) || certifyTime < CLOCK_ZERO)) { + throw new BadRequestException(INVALID_REQUEST_FIELD); + } + + return certifyTime; + } } From ece167849fc58dd4e40f8c186e6c6eefd6ae6743 Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Mon, 30 Oct 2023 18:33:21 +0900 Subject: [PATCH 03/27] =?UTF-8?q?test:=20Room=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moabam/api/domain/entity/RoomTest.java | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/test/java/com/moabam/api/domain/entity/RoomTest.java diff --git a/src/test/java/com/moabam/api/domain/entity/RoomTest.java b/src/test/java/com/moabam/api/domain/entity/RoomTest.java new file mode 100644 index 00000000..666261c1 --- /dev/null +++ b/src/test/java/com/moabam/api/domain/entity/RoomTest.java @@ -0,0 +1,88 @@ +package com.moabam.api.domain.entity; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import com.moabam.api.domain.entity.enums.RoomType; +import com.moabam.global.error.exception.BadRequestException; +import com.moabam.global.error.model.ErrorMessage; + +class RoomTest { + + @DisplayName("비밀번호 없이 방 생성 성공") + @Test + void create_room_without_password_success() { + // given, when + Room room = Room.builder() + .title("앵윤이의 방") + .roomType(RoomType.MORNING) + .certifyTime(10) + .maxUserCount(9) + .announcement("HI Dev") + .build(); + + // then + assertThat(room.getPassword()).isNull(); + } + + @DisplayName("비밀번호 설정 후 방 생성 성공") + @Test + void create_room_with_password_success() { + // given, when + Room room = Room.builder() + .title("앵윤이의 방") + .password("12345") + .roomType(RoomType.MORNING) + .certifyTime(10) + .maxUserCount(9) + .announcement("HI Dev") + .build(); + + // then + assertThat(room.getPassword()).isEqualTo("12345"); + } + + @DisplayName("아침 방 설정 시, 저녁 시간이 들어오는 예외 발생") + @ParameterizedTest + @CsvSource({ + "13", "19", "3", "11", "0" + }) + void morning_time_validate_exception(int certifyTime) { + Room room = Room.builder() + .title("모아밤 짱") + .password("1234") + .roomType(RoomType.MORNING) + .certifyTime(9) + .maxUserCount(5) + .announcement("HELLO") + .build(); + + // given, when, then + assertThatThrownBy(() -> room.changeCertifyTime(certifyTime)) + .isInstanceOf(BadRequestException.class) + .hasMessage(ErrorMessage.INVALID_REQUEST_FIELD.getMessage()); + } + + @DisplayName("저녁 방 설정 시, 아침 시간이 들어오는 경우 예외 발생") + @ParameterizedTest + @CsvSource({ + "3", "5", "-1", "15", "8", "19" + }) + void night_time_validate_exception(int certifyTime) { + Room room = Room.builder() + .title("모아밤 짱") + .roomType(RoomType.NIGHT) + .certifyTime(21) + .maxUserCount(5) + .build(); + + // given, when, then + assertThatThrownBy(() -> room.changeCertifyTime(certifyTime)) + .isInstanceOf(BadRequestException.class) + .hasMessage(ErrorMessage.INVALID_REQUEST_FIELD.getMessage()); + } +} From b067abbcafa8bcbd67d877be08da0108c19c7ba8 Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Tue, 31 Oct 2023 15:10:58 +0900 Subject: [PATCH 04/27] =?UTF-8?q?refactor:=20Room=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=97=94=ED=8B=B0=ED=8B=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/moabam/api/domain/entity/Certification.java | 4 ++-- .../com/moabam/api/domain/entity/Participant.java | 6 +++--- src/main/java/com/moabam/api/domain/entity/Room.java | 12 +++++------- .../java/com/moabam/api/domain/entity/Routine.java | 8 +++++--- .../java/com/moabam/api/domain/entity/RoomTest.java | 3 --- 5 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/moabam/api/domain/entity/Certification.java b/src/main/java/com/moabam/api/domain/entity/Certification.java index 567402a6..fbb7031b 100644 --- a/src/main/java/com/moabam/api/domain/entity/Certification.java +++ b/src/main/java/com/moabam/api/domain/entity/Certification.java @@ -20,7 +20,7 @@ @Entity @Getter -@Table(name = "certifications") +@Table(name = "certification") @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Certification extends BaseTimeEntity { @@ -30,7 +30,7 @@ public class Certification extends BaseTimeEntity { private Long id; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "routine_id", nullable = false) + @JoinColumn(name = "routine_id", nullable = false, updatable = false) private Routine routine; @Column(name = "member_id", nullable = false, updatable = false) diff --git a/src/main/java/com/moabam/api/domain/entity/Participant.java b/src/main/java/com/moabam/api/domain/entity/Participant.java index 0273f296..b3e08ebb 100644 --- a/src/main/java/com/moabam/api/domain/entity/Participant.java +++ b/src/main/java/com/moabam/api/domain/entity/Participant.java @@ -22,7 +22,7 @@ @Entity @Getter -@Table(name = "participants") +@Table(name = "participant") @SQLDelete(sql = "UPDATE participants SET deleted_at = CURRENT_TIMESTAMP where id = ?") @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Participant { @@ -33,10 +33,10 @@ public class Participant { private Long id; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "room_id", updatable = false) + @JoinColumn(name = "room_id", updatable = false, nullable = false) private Room room; - @Column(name = "member_id", updatable = false) + @Column(name = "member_id", updatable = false, nullable = false) private Long memberId; @Column(name = "is_manager") diff --git a/src/main/java/com/moabam/api/domain/entity/Room.java b/src/main/java/com/moabam/api/domain/entity/Room.java index 649885e5..5148c464 100644 --- a/src/main/java/com/moabam/api/domain/entity/Room.java +++ b/src/main/java/com/moabam/api/domain/entity/Room.java @@ -25,13 +25,13 @@ @Entity @Getter -@Table(name = "rooms") +@Table(name = "room") @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Room extends BaseTimeEntity { - private static final String ROOM_LEVEL_0_IMAGE = ""; - private static final String ROOM_LEVEL_10_IMAGE = ""; - private static final String ROOM_LEVEL_20_IMAGE = ""; + private static final String ROOM_LEVEL_0_IMAGE = "'temptemp'"; + private static final String ROOM_LEVEL_10_IMAGE = "'temp'"; + private static final String ROOM_LEVEL_20_IMAGE = "'tempp'"; private static final int MORNING_START_TIME = 4; private static final int MORNING_END_TIME = 10; @@ -76,8 +76,7 @@ public class Room extends BaseTimeEntity { private String roomImage; @Builder - private Room(String title, String password, RoomType roomType, int certifyTime, int maxUserCount, - String announcement) { + private Room(String title, String password, RoomType roomType, int certifyTime, int maxUserCount) { this.title = requireNonNull(title); this.password = password; this.level = 0; @@ -85,7 +84,6 @@ private Room(String title, String password, RoomType roomType, int certifyTime, this.certifyTime = validateCertifyTime(roomType, certifyTime); this.currentUserCount = 1; this.maxUserCount = maxUserCount; - this.announcement = announcement; this.roomImage = ROOM_LEVEL_0_IMAGE; } diff --git a/src/main/java/com/moabam/api/domain/entity/Routine.java b/src/main/java/com/moabam/api/domain/entity/Routine.java index b7d90e51..8e86e604 100644 --- a/src/main/java/com/moabam/api/domain/entity/Routine.java +++ b/src/main/java/com/moabam/api/domain/entity/Routine.java @@ -1,5 +1,7 @@ package com.moabam.api.domain.entity; +import static java.util.Objects.*; + import com.moabam.global.common.entity.BaseTimeEntity; import jakarta.persistence.Column; @@ -18,7 +20,7 @@ @Entity @Getter -@Table(name = "routines") +@Table(name = "routine") @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Routine extends BaseTimeEntity { @@ -36,8 +38,8 @@ public class Routine extends BaseTimeEntity { @Builder private Routine(Room room, String content) { - this.room = room; - this.content = content; + this.room = requireNonNull(room); + this.content = requireNonNull(content); } public void changeContent(String content) { diff --git a/src/test/java/com/moabam/api/domain/entity/RoomTest.java b/src/test/java/com/moabam/api/domain/entity/RoomTest.java index 666261c1..b9df5be3 100644 --- a/src/test/java/com/moabam/api/domain/entity/RoomTest.java +++ b/src/test/java/com/moabam/api/domain/entity/RoomTest.java @@ -22,7 +22,6 @@ void create_room_without_password_success() { .roomType(RoomType.MORNING) .certifyTime(10) .maxUserCount(9) - .announcement("HI Dev") .build(); // then @@ -39,7 +38,6 @@ void create_room_with_password_success() { .roomType(RoomType.MORNING) .certifyTime(10) .maxUserCount(9) - .announcement("HI Dev") .build(); // then @@ -58,7 +56,6 @@ void morning_time_validate_exception(int certifyTime) { .roomType(RoomType.MORNING) .certifyTime(9) .maxUserCount(5) - .announcement("HELLO") .build(); // given, when, then From 00558f61457c564d3973ef9bf48d0c15601f6682 Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Tue, 31 Oct 2023 15:12:34 +0900 Subject: [PATCH 05/27] =?UTF-8?q?feat:=20=EB=B0=A9=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moabam/api/application/RoomService.java | 42 +++++++++++++++++++ .../com/moabam/api/dto/CreateRoomRequest.java | 23 ++++++++++ .../java/com/moabam/api/dto/RoomMapper.java | 32 ++++++++++++++ .../api/presentation/RoomController.java | 28 +++++++++++++ 4 files changed, 125 insertions(+) create mode 100644 src/main/java/com/moabam/api/application/RoomService.java create mode 100644 src/main/java/com/moabam/api/dto/CreateRoomRequest.java create mode 100644 src/main/java/com/moabam/api/dto/RoomMapper.java create mode 100644 src/main/java/com/moabam/api/presentation/RoomController.java diff --git a/src/main/java/com/moabam/api/application/RoomService.java b/src/main/java/com/moabam/api/application/RoomService.java new file mode 100644 index 00000000..a855f1c9 --- /dev/null +++ b/src/main/java/com/moabam/api/application/RoomService.java @@ -0,0 +1,42 @@ +package com.moabam.api.application; + +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.moabam.api.domain.entity.Participant; +import com.moabam.api.domain.entity.Room; +import com.moabam.api.domain.entity.Routine; +import com.moabam.api.domain.repository.ParticipantRepository; +import com.moabam.api.domain.repository.RoomRepository; +import com.moabam.api.domain.repository.RoutineRepository; +import com.moabam.api.dto.CreateRoomRequest; +import com.moabam.api.dto.RoomMapper; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class RoomService { + + private final RoomRepository roomRepository; + private final RoutineRepository routineRepository; + private final ParticipantRepository participantRepository; + + @Transactional + public void createRoom(Long memberId, CreateRoomRequest createRoomRequest) { + Room room = RoomMapper.toRoomEntity(createRoomRequest); + List routines = RoomMapper.toRoutineEntity(room, createRoomRequest.routines()); + Participant participant = Participant.builder() + .room(room) + .memberId(memberId) + .build(); + participant.enableManager(); + + roomRepository.save(room); + routineRepository.saveAll(routines); + participantRepository.save(participant); + } +} diff --git a/src/main/java/com/moabam/api/dto/CreateRoomRequest.java b/src/main/java/com/moabam/api/dto/CreateRoomRequest.java new file mode 100644 index 00000000..2f49a98a --- /dev/null +++ b/src/main/java/com/moabam/api/dto/CreateRoomRequest.java @@ -0,0 +1,23 @@ +package com.moabam.api.dto; + +import java.util.List; + +import org.hibernate.validator.constraints.Range; + +import com.moabam.api.domain.entity.enums.RoomType; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; + +public record CreateRoomRequest( + @NotBlank String title, + @Pattern(regexp = "^(|[0-9]{4,8})$") String password, + @NotNull @Size(min = 0, max = 4) List routines, + @NotNull RoomType roomType, + @Range(min = 0, max = 23) int certifyTime, + @Range(min = 0, max = 10) int maxUserCount +) { + +} diff --git a/src/main/java/com/moabam/api/dto/RoomMapper.java b/src/main/java/com/moabam/api/dto/RoomMapper.java new file mode 100644 index 00000000..9ac332c2 --- /dev/null +++ b/src/main/java/com/moabam/api/dto/RoomMapper.java @@ -0,0 +1,32 @@ +package com.moabam.api.dto; + +import java.util.List; + +import com.moabam.api.domain.entity.Room; +import com.moabam.api.domain.entity.Routine; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public abstract class RoomMapper { + + public static Room toRoomEntity(CreateRoomRequest createRoomRequest) { + return Room.builder() + .title(createRoomRequest.title()) + .password(createRoomRequest.password()) + .roomType(createRoomRequest.roomType()) + .certifyTime(createRoomRequest.certifyTime()) + .maxUserCount(createRoomRequest.maxUserCount()) + .build(); + } + + public static List toRoutineEntity(Room room, List routinesRequest) { + return routinesRequest.stream() + .map(routine -> Routine.builder() + .room(room) + .content(routine) + .build()) + .toList(); + } +} diff --git a/src/main/java/com/moabam/api/presentation/RoomController.java b/src/main/java/com/moabam/api/presentation/RoomController.java new file mode 100644 index 00000000..9f01944e --- /dev/null +++ b/src/main/java/com/moabam/api/presentation/RoomController.java @@ -0,0 +1,28 @@ +package com.moabam.api.presentation; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +import com.moabam.api.application.RoomService; +import com.moabam.api.dto.CreateRoomRequest; + +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/rooms") +public class RoomController { + + private final RoomService roomService; + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public void createRoom(@Valid @RequestBody CreateRoomRequest createRoomRequest) { + roomService.createRoom(1L, createRoomRequest); + } +} From 20cc332d605c88c9b8a2152a6c2047d963fd925e Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Tue, 31 Oct 2023 15:47:43 +0900 Subject: [PATCH 06/27] =?UTF-8?q?chore:=20DynamicQuery=20Jacoco=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index 1fc75afe..8a948e73 100644 --- a/build.gradle +++ b/build.gradle @@ -73,17 +73,18 @@ jacocoTestReport { afterEvaluate { classDirectories.setFrom( - files(classDirectories.files.collect { - fileTree(dir: it, excludes: [ - "**/*Application*", - "**/*Config*", - "**/*Request*", - "**/*Response*", - "**/*Exception*", - "**/*Mapper*", - "**/*ErrorMessage*", - ] + Qdomains) - }) + files(classDirectories.files.collect { + fileTree(dir: it, excludes: [ + "**/*Application*", + "**/*Config*", + "**/*Request*", + "**/*Response*", + "**/*Exception*", + "**/*Mapper*", + "**/*ErrorMessage*", + "**/*DynamicQuery*", + ] + Qdomains) + }) ) } } @@ -112,8 +113,8 @@ sonar { property "sonar.host.url", "https://sonarcloud.io" property 'sonar.coverage.jacoco.xmlReportPaths', 'build/reports/jacoco/test/jacocoTestReport.xml' property 'sonar.coverage.exclusions', '**/test/**, **/Q*.java, **/*Doc*.java, **/resources/** ' + - ',**/*Application*.java , **/*Config*.java, **/*Request*.java, **/*Response*.java ,**/*Exception*.java ' + - ',**/*ErrorMessage*.java, **/*Mapper*.java' + ',**/*Application*.java , **/*Config*.java, **/*Request*.java, **/*Response*.java ,**/*Exception*.java ' + + ',**/*ErrorMessage*.java, **/*Mapper*.java' property 'sonar.java.checkstyle.reportPaths', 'build/reports/checkstyle/main.xml' } } From 25d004460bf32e3f45ac31a3fd6ea7e6f096fc61 Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Tue, 31 Oct 2023 15:48:09 +0900 Subject: [PATCH 07/27] =?UTF-8?q?test:=20=EB=B0=A9=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/moabam/api/dto/CreateRoomRequest.java | 2 +- .../api/application/RoomServiceTest.java | 83 +++++++ .../api/presentation/RoomControllerTest.java | 219 ++++++++++++++++++ 3 files changed, 303 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/moabam/api/application/RoomServiceTest.java create mode 100644 src/test/java/com/moabam/api/presentation/RoomControllerTest.java diff --git a/src/main/java/com/moabam/api/dto/CreateRoomRequest.java b/src/main/java/com/moabam/api/dto/CreateRoomRequest.java index 2f49a98a..516564ea 100644 --- a/src/main/java/com/moabam/api/dto/CreateRoomRequest.java +++ b/src/main/java/com/moabam/api/dto/CreateRoomRequest.java @@ -14,7 +14,7 @@ public record CreateRoomRequest( @NotBlank String title, @Pattern(regexp = "^(|[0-9]{4,8})$") String password, - @NotNull @Size(min = 0, max = 4) List routines, + @NotNull @Size(min = 1, max = 4) List routines, @NotNull RoomType roomType, @Range(min = 0, max = 23) int certifyTime, @Range(min = 0, max = 10) int maxUserCount diff --git a/src/test/java/com/moabam/api/application/RoomServiceTest.java b/src/test/java/com/moabam/api/application/RoomServiceTest.java new file mode 100644 index 00000000..400d5cbb --- /dev/null +++ b/src/test/java/com/moabam/api/application/RoomServiceTest.java @@ -0,0 +1,83 @@ +package com.moabam.api.application; + +import static com.moabam.api.domain.entity.enums.RoomType.*; +import static org.mockito.BDDMockito.*; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentMatchers; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.moabam.api.domain.entity.Participant; +import com.moabam.api.domain.entity.Room; +import com.moabam.api.domain.entity.Routine; +import com.moabam.api.domain.repository.CertificationRepository; +import com.moabam.api.domain.repository.ParticipantRepository; +import com.moabam.api.domain.repository.RoomRepository; +import com.moabam.api.domain.repository.RoutineRepository; +import com.moabam.api.dto.CreateRoomRequest; + +@ExtendWith(MockitoExtension.class) +class RoomServiceTest { + + @InjectMocks + private RoomService roomService; + + @Mock + private RoomRepository roomRepository; + + @Mock + private RoutineRepository routineRepository; + + @Mock + private CertificationRepository certificationRepository; + + @Mock + private ParticipantRepository participantRepository; + + @DisplayName("비밀번호 없는 방 생성 성공") + @Test + void create_room_no_password_success() { + // given + List routines = new ArrayList<>(); + routines.add("물 마시기"); + routines.add("코테 풀기"); + + CreateRoomRequest createRoomRequest = new CreateRoomRequest( + "재윤과 앵맹이의 방임", null, routines, MORNING, 10, 4); + + // when + roomService.createRoom(1L, createRoomRequest); + + // then + verify(roomRepository).save(any(Room.class)); + verify(routineRepository).saveAll(ArgumentMatchers.anyList()); + verify(participantRepository).save(any(Participant.class)); + } + + @DisplayName("비밀번호 있는 방 생성 성공") + @Test + void create_room_with_password_success() { + // given + List routines = new ArrayList<>(); + routines.add("물 마시기"); + routines.add("코테 풀기"); + + CreateRoomRequest createRoomRequest = new CreateRoomRequest( + "재윤과 앵맹이의 방임", "1234", routines, MORNING, 10, 4); + + // when + roomService.createRoom(1L, createRoomRequest); + + // then + verify(roomRepository).save(any(Room.class)); + verify(routineRepository).saveAll(ArgumentMatchers.anyList()); + verify(participantRepository).save(any(Participant.class)); + } +} diff --git a/src/test/java/com/moabam/api/presentation/RoomControllerTest.java b/src/test/java/com/moabam/api/presentation/RoomControllerTest.java new file mode 100644 index 00000000..164b192a --- /dev/null +++ b/src/test/java/com/moabam/api/presentation/RoomControllerTest.java @@ -0,0 +1,219 @@ +package com.moabam.api.presentation; + +import static com.moabam.api.domain.entity.enums.RoomType.*; +import static org.assertj.core.api.Assertions.*; +import static org.springframework.http.MediaType.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.moabam.api.domain.repository.ParticipantRepository; +import com.moabam.api.domain.repository.RoomRepository; +import com.moabam.api.domain.repository.RoutineRepository; +import com.moabam.api.dto.CreateRoomRequest; + +@Transactional +@SpringBootTest +@AutoConfigureMockMvc +@ActiveProfiles("test") +class RoomControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private RoomRepository roomRepository; + + @Autowired + private RoutineRepository routineRepository; + + @Autowired + private ParticipantRepository participantRepository; + + @DisplayName("비밀번호 없는 방 생성 성공") + @Test + void create_room_no_password_success() throws Exception { + // given + List routines = new ArrayList<>(); + routines.add("물 마시기"); + routines.add("코테 풀기"); + + CreateRoomRequest createRoomRequest = new CreateRoomRequest( + "재윤과 앵맹이의 방임", null, routines, MORNING, 10, 4); + + String json = objectMapper.writeValueAsString(createRoomRequest); + + // expected + mockMvc.perform(post("/rooms") + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isCreated()) + .andDo(print()); + + assertThat(roomRepository.findAll()).hasSize(1); + assertThat(roomRepository.findAll().get(0).getTitle()).isEqualTo("재윤과 앵맹이의 방임"); + assertThat(roomRepository.findAll().get(0).getPassword()).isNull(); + } + + @DisplayName("비밀번호 있는 방 생성 성공") + @ParameterizedTest + @CsvSource({ + "1234", "12345678", "98765" + }) + void create_room_with_password_success(String password) throws Exception { + // given + List routines = new ArrayList<>(); + routines.add("물 마시기"); + routines.add("코테 풀기"); + + CreateRoomRequest createRoomRequest = new CreateRoomRequest( + "비번 있는 재윤과 앵맹이의 방임", password, routines, MORNING, 10, 4); + + String json = objectMapper.writeValueAsString(createRoomRequest); + + // expected + mockMvc.perform(post("/rooms") + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isCreated()) + .andDo(print()); + + assertThat(roomRepository.findAll()).hasSize(1); + assertThat(roomRepository.findAll().get(0).getTitle()).isEqualTo("비번 있는 재윤과 앵맹이의 방임"); + assertThat(roomRepository.findAll().get(0).getPassword()).isEqualTo(password); + } + + @DisplayName("올바르지 않은 비밀번호 방 생성시 예외 발생") + @ParameterizedTest + @CsvSource({ + "1", "12", "123", "123456789", "abc" + }) + void create_room_with_wrong_password_fail(String password) throws Exception { + // given + List routines = new ArrayList<>(); + routines.add("물 마시기"); + routines.add("코테 풀기"); + + CreateRoomRequest createRoomRequest = new CreateRoomRequest( + "비번 있는 재윤과 앵맹이의 방임", password, routines, MORNING, 10, 4); + + String json = objectMapper.writeValueAsString(createRoomRequest); + + // expected + mockMvc.perform(post("/rooms") + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isBadRequest()) + .andDo(print()); + } + + @DisplayName("Routine 갯수를 초과한 방 생성시 예외 발생") + @Test + void create_room_with_too_many_routine_fail() throws Exception { + // given + List routines = new ArrayList<>(); + routines.add("물 마시기"); + routines.add("코테 풀기"); + routines.add("밥 먹기"); + routines.add("코드 리뷰 달기"); + routines.add("책 읽기"); + routines.add("산책 하기"); + + CreateRoomRequest createRoomRequest = new CreateRoomRequest( + "비번 없는 재윤과 앵맹이의 방임", null, routines, MORNING, 10, 4); + + String json = objectMapper.writeValueAsString(createRoomRequest); + + // expected + mockMvc.perform(post("/rooms") + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isBadRequest()) + .andDo(print()); + } + + @DisplayName("Routine 없는 방 생성시 예외 발생") + @Test + void create_room_with_no_routine_fail() throws Exception { + // given + List routines = new ArrayList<>(); + + CreateRoomRequest createRoomRequest = new CreateRoomRequest( + "비번 없는 재윤과 앵맹이의 방임", null, routines, MORNING, 10, 4); + + String json = objectMapper.writeValueAsString(createRoomRequest); + + // expected + mockMvc.perform(post("/rooms") + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isBadRequest()) + .andDo(print()); + } + + @DisplayName("올바르지 못한 시간으로 아침 방 생성") + @ParameterizedTest + @CsvSource({ + "1", "3", "11", "12", "20" + }) + void create_morning_room_wrong_certify_time_fail(int certifyTime) throws Exception { + // given + List routines = new ArrayList<>(); + routines.add("물 마시기"); + routines.add("코테 풀기"); + + CreateRoomRequest createRoomRequest = new CreateRoomRequest( + "비번 없는 재윤과 앵맹이의 방임", null, routines, MORNING, certifyTime, 4); + + String json = objectMapper.writeValueAsString(createRoomRequest); + + // expected + mockMvc.perform(post("/rooms") + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isBadRequest()) + .andDo(print()); + } + + @DisplayName("올바르지 못한 시간으로 저녁 방 생성") + @ParameterizedTest + @CsvSource({ + "19", "3", "6", "9" + }) + void create_night_room_wrong_certify_time_fail(int certifyTime) throws Exception { + // given + List routines = new ArrayList<>(); + routines.add("물 마시기"); + routines.add("코테 풀기"); + + CreateRoomRequest createRoomRequest = new CreateRoomRequest( + "비번 없는 재윤과 앵맹이의 방임", null, routines, NIGHT, certifyTime, 4); + + String json = objectMapper.writeValueAsString(createRoomRequest); + + // expected + mockMvc.perform(post("/rooms") + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isBadRequest()) + .andDo(print()); + } +} From 2dd7c1aef59b2bb5218979f5ab9de9b451e77be7 Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Tue, 31 Oct 2023 17:18:35 +0900 Subject: [PATCH 08/27] =?UTF-8?q?feat:=20=EB=B0=A9=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moabam/api/application/RoomService.java | 22 +++++++++++++++++++ .../com/moabam/api/domain/entity/Room.java | 16 ++++++++++++++ .../repository/ParticipantRepository.java | 3 +++ .../com/moabam/api/dto/ModifyRoomRequest.java | 15 +++++++++++++ .../api/presentation/RoomController.java | 10 +++++++++ .../global/error/model/ErrorMessage.java | 6 ++++- 6 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/moabam/api/dto/ModifyRoomRequest.java diff --git a/src/main/java/com/moabam/api/application/RoomService.java b/src/main/java/com/moabam/api/application/RoomService.java index a855f1c9..94168e55 100644 --- a/src/main/java/com/moabam/api/application/RoomService.java +++ b/src/main/java/com/moabam/api/application/RoomService.java @@ -1,5 +1,7 @@ package com.moabam.api.application; +import static com.moabam.global.error.model.ErrorMessage.*; + import java.util.List; import org.springframework.stereotype.Service; @@ -12,7 +14,10 @@ import com.moabam.api.domain.repository.RoomRepository; import com.moabam.api.domain.repository.RoutineRepository; import com.moabam.api.dto.CreateRoomRequest; +import com.moabam.api.dto.ModifyRoomRequest; import com.moabam.api.dto.RoomMapper; +import com.moabam.global.error.exception.ForbiddenException; +import com.moabam.global.error.exception.NotFoundException; import lombok.RequiredArgsConstructor; @@ -39,4 +44,21 @@ public void createRoom(Long memberId, CreateRoomRequest createRoomRequest) { routineRepository.saveAll(routines); participantRepository.save(participant); } + + @Transactional + public void modifyRoom(Long memberId, Long roomId, ModifyRoomRequest modifyRoomRequest) { + // TODO: 추후에 별도 메서드로 뺄듯 + Participant participant = participantRepository.findParticipantByRoomIdAndMemberId(roomId, memberId) + .orElseThrow(() -> new NotFoundException(PARTICIPANT_NOT_FOUND)); + + if (!participant.isManager()) { + throw new ForbiddenException(ROOM_MODIFY_UNAUTHORIZED_REQUEST); + } + + Room room = roomRepository.findById(roomId).orElseThrow(() -> new NotFoundException(ROOM_NOT_FOUND)); + room.changeTitle(modifyRoomRequest.title()); + room.changePassword(modifyRoomRequest.password()); + room.changeCertifyTime(modifyRoomRequest.certifyTime()); + room.changeMaxCount(modifyRoomRequest.maxUserCount()); + } } diff --git a/src/main/java/com/moabam/api/domain/entity/Room.java b/src/main/java/com/moabam/api/domain/entity/Room.java index 5148c464..5e150acf 100644 --- a/src/main/java/com/moabam/api/domain/entity/Room.java +++ b/src/main/java/com/moabam/api/domain/entity/Room.java @@ -95,6 +95,22 @@ public void changeAnnouncement(String announcement) { this.announcement = announcement; } + public void changeTitle(String title) { + this.title = title; + } + + public void changePassword(String password) { + this.password = password; + } + + public void changeMaxCount(int maxUserCount) { + if (maxUserCount < this.currentUserCount) { + throw new BadRequestException(ROOM_MAX_USER_COUNT_MODIFY_FAIL); + } + + this.maxUserCount = maxUserCount; + } + public void upgradeRoomImage(String roomImage) { this.roomImage = roomImage; } diff --git a/src/main/java/com/moabam/api/domain/repository/ParticipantRepository.java b/src/main/java/com/moabam/api/domain/repository/ParticipantRepository.java index 3f0a7bfc..be814a44 100644 --- a/src/main/java/com/moabam/api/domain/repository/ParticipantRepository.java +++ b/src/main/java/com/moabam/api/domain/repository/ParticipantRepository.java @@ -1,9 +1,12 @@ package com.moabam.api.domain.repository; +import java.util.Optional; + import org.springframework.data.jpa.repository.JpaRepository; import com.moabam.api.domain.entity.Participant; public interface ParticipantRepository extends JpaRepository { + Optional findParticipantByRoomIdAndMemberId(Long roomId, Long MemberId); } diff --git a/src/main/java/com/moabam/api/dto/ModifyRoomRequest.java b/src/main/java/com/moabam/api/dto/ModifyRoomRequest.java new file mode 100644 index 00000000..4e24341a --- /dev/null +++ b/src/main/java/com/moabam/api/dto/ModifyRoomRequest.java @@ -0,0 +1,15 @@ +package com.moabam.api.dto; + +import org.hibernate.validator.constraints.Range; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; + +public record ModifyRoomRequest( + @NotBlank String title, + @Pattern(regexp = "^(|[0-9]{4,8})$") String password, + @Range(min = 0, max = 23) int certifyTime, + @Range(min = 0, max = 10) int maxUserCount +) { + +} diff --git a/src/main/java/com/moabam/api/presentation/RoomController.java b/src/main/java/com/moabam/api/presentation/RoomController.java index 9f01944e..c0edc651 100644 --- a/src/main/java/com/moabam/api/presentation/RoomController.java +++ b/src/main/java/com/moabam/api/presentation/RoomController.java @@ -1,7 +1,9 @@ package com.moabam.api.presentation; import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseStatus; @@ -9,6 +11,7 @@ import com.moabam.api.application.RoomService; import com.moabam.api.dto.CreateRoomRequest; +import com.moabam.api.dto.ModifyRoomRequest; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -25,4 +28,11 @@ public class RoomController { public void createRoom(@Valid @RequestBody CreateRoomRequest createRoomRequest) { roomService.createRoom(1L, createRoomRequest); } + + @PutMapping("/{roomId}") + @ResponseStatus(HttpStatus.OK) + public void modifyRoom(@Valid @RequestBody ModifyRoomRequest modifyRoomRequest, + @PathVariable("roomId") Long roomId) { + roomService.modifyRoom(1L, roomId, modifyRoomRequest); + } } diff --git a/src/main/java/com/moabam/global/error/model/ErrorMessage.java b/src/main/java/com/moabam/global/error/model/ErrorMessage.java index 662874f6..dd05b455 100644 --- a/src/main/java/com/moabam/global/error/model/ErrorMessage.java +++ b/src/main/java/com/moabam/global/error/model/ErrorMessage.java @@ -7,7 +7,11 @@ @RequiredArgsConstructor public enum ErrorMessage { - INVALID_REQUEST_FIELD("올바른 요청 정보가 아닙니다."); + INVALID_REQUEST_FIELD("올바른 요청 정보가 아닙니다."), + ROOM_NOT_FOUND("존재하지 않는 방 입니다."), + ROOM_MAX_USER_COUNT_MODIFY_FAIL("잘못된 최대 인원수 설정입니다."), + ROOM_MODIFY_UNAUTHORIZED_REQUEST("방장이 아닌 사용자는 방을 수정할 수 없습니다."), + PARTICIPANT_NOT_FOUND("방에 대한 참여자의 정보가 없습니다."); private final String message; } From 7b8ff993f70725f5f87db400c7056c161437f42d Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Tue, 31 Oct 2023 17:18:56 +0900 Subject: [PATCH 09/27] =?UTF-8?q?test:=20=EB=B0=A9=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=ED=86=B5=ED=95=A9=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/presentation/RoomControllerTest.java | 70 ++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/moabam/api/presentation/RoomControllerTest.java b/src/test/java/com/moabam/api/presentation/RoomControllerTest.java index 164b192a..55668783 100644 --- a/src/test/java/com/moabam/api/presentation/RoomControllerTest.java +++ b/src/test/java/com/moabam/api/presentation/RoomControllerTest.java @@ -22,10 +22,13 @@ import org.springframework.transaction.annotation.Transactional; import com.fasterxml.jackson.databind.ObjectMapper; +import com.moabam.api.domain.entity.Participant; +import com.moabam.api.domain.entity.Room; import com.moabam.api.domain.repository.ParticipantRepository; import com.moabam.api.domain.repository.RoomRepository; import com.moabam.api.domain.repository.RoutineRepository; import com.moabam.api.dto.CreateRoomRequest; +import com.moabam.api.dto.ModifyRoomRequest; @Transactional @SpringBootTest @@ -193,7 +196,7 @@ void create_morning_room_wrong_certify_time_fail(int certifyTime) throws Excepti .andDo(print()); } - @DisplayName("올바르지 못한 시간으로 저녁 방 생성") + @DisplayName("올바르지 못한 시간으로 저녁 방 생성시 에외 발생") @ParameterizedTest @CsvSource({ "19", "3", "6", "9" @@ -216,4 +219,69 @@ void create_night_room_wrong_certify_time_fail(int certifyTime) throws Exception .andExpect(status().isBadRequest()) .andDo(print()); } + + @DisplayName("방 수정 성공 - 방장일 경우") + @Test + void modify_room_success() throws Exception { + // given + Room room = Room.builder() + .title("처음 제목") + .password("1234") + .roomType(MORNING) + .certifyTime(9) + .maxUserCount(5) + .build(); + + Participant participant = Participant.builder() + .room(room) + .memberId(1L) + .build(); + participant.enableManager(); + + Room savedRoom = roomRepository.save(room); + participantRepository.save(participant); + + ModifyRoomRequest modifyRoomRequest = new ModifyRoomRequest("수정할 방임!", "1234", 10, 7); + + String json = objectMapper.writeValueAsString(modifyRoomRequest); + + // expected + mockMvc.perform(put("/rooms/" + savedRoom.getId()) + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isOk()) + .andDo(print()); + } + + @DisplayName("방 수정 실패 - 방장 아닐 경우") + @Test + void unauthorized_modify_room_fail() throws Exception { + // given + Room room = Room.builder() + .title("처음 제목") + .password("1234") + .roomType(MORNING) + .certifyTime(9) + .maxUserCount(5) + .build(); + + Participant participant = Participant.builder() + .room(room) + .memberId(1L) + .build(); + + Room savedRoom = roomRepository.save(room); + participantRepository.save(participant); + + ModifyRoomRequest modifyRoomRequest = new ModifyRoomRequest("수정할 방임!", "1234", 10, 7); + + String json = objectMapper.writeValueAsString(modifyRoomRequest); + + // expected + mockMvc.perform(put("/rooms/" + savedRoom.getId()) + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isNotFound()) + .andDo(print()); + } } From 051d56e195a253131568ffe055d7676085529fc2 Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Tue, 31 Oct 2023 22:20:07 +0900 Subject: [PATCH 10/27] =?UTF-8?q?refactor:=20Member=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=20=ED=8C=8C=EC=9D=BC=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/moabam/api/application/AuthenticationService.java | 2 +- src/main/java/com/moabam/api/domain/{ => entity}/Member.java | 3 ++- .../java/com/moabam/api/domain/{ => entity/enums}/Role.java | 2 +- src/main/java/com/moabam/api/{mapper => dto}/OAuthMapper.java | 2 +- .../com/moabam/api/application/AuthenticationServiceTest.java | 2 +- src/test/java/com/moabam/api/domain/MemberTest.java | 2 ++ 6 files changed, 8 insertions(+), 5 deletions(-) rename src/main/java/com/moabam/api/domain/{ => entity}/Member.java (96%) rename src/main/java/com/moabam/api/domain/{ => entity/enums}/Role.java (50%) rename src/main/java/com/moabam/api/{mapper => dto}/OAuthMapper.java (94%) diff --git a/src/main/java/com/moabam/api/application/AuthenticationService.java b/src/main/java/com/moabam/api/application/AuthenticationService.java index bd383e95..7c407afc 100644 --- a/src/main/java/com/moabam/api/application/AuthenticationService.java +++ b/src/main/java/com/moabam/api/application/AuthenticationService.java @@ -9,7 +9,7 @@ import org.springframework.web.util.UriComponentsBuilder; import com.moabam.api.dto.AuthorizationCodeRequest; -import com.moabam.api.mapper.OAuthMapper; +import com.moabam.api.dto.OAuthMapper; import com.moabam.global.common.util.GlobalConstant; import com.moabam.global.config.OAuthConfig; import com.moabam.global.error.exception.BadRequestException; diff --git a/src/main/java/com/moabam/api/domain/Member.java b/src/main/java/com/moabam/api/domain/entity/Member.java similarity index 96% rename from src/main/java/com/moabam/api/domain/Member.java rename to src/main/java/com/moabam/api/domain/entity/Member.java index c2e3701e..a0a9e749 100644 --- a/src/main/java/com/moabam/api/domain/Member.java +++ b/src/main/java/com/moabam/api/domain/entity/Member.java @@ -1,4 +1,4 @@ -package com.moabam.api.domain; +package com.moabam.api.domain.entity; import static java.util.Objects.*; @@ -8,6 +8,7 @@ import org.hibernate.annotations.SQLDelete; import org.hibernate.annotations.Where; +import com.moabam.api.domain.entity.enums.Role; import com.moabam.global.common.entity.BaseTimeEntity; import com.moabam.global.common.util.BaseImageUrl; diff --git a/src/main/java/com/moabam/api/domain/Role.java b/src/main/java/com/moabam/api/domain/entity/enums/Role.java similarity index 50% rename from src/main/java/com/moabam/api/domain/Role.java rename to src/main/java/com/moabam/api/domain/entity/enums/Role.java index 65cb1a49..b90adc44 100644 --- a/src/main/java/com/moabam/api/domain/Role.java +++ b/src/main/java/com/moabam/api/domain/entity/enums/Role.java @@ -1,4 +1,4 @@ -package com.moabam.api.domain; +package com.moabam.api.domain.entity.enums; public enum Role { diff --git a/src/main/java/com/moabam/api/mapper/OAuthMapper.java b/src/main/java/com/moabam/api/dto/OAuthMapper.java similarity index 94% rename from src/main/java/com/moabam/api/mapper/OAuthMapper.java rename to src/main/java/com/moabam/api/dto/OAuthMapper.java index 7d16b8ef..dac14930 100644 --- a/src/main/java/com/moabam/api/mapper/OAuthMapper.java +++ b/src/main/java/com/moabam/api/dto/OAuthMapper.java @@ -1,4 +1,4 @@ -package com.moabam.api.mapper; +package com.moabam.api.dto; import com.moabam.api.dto.AuthorizationCodeRequest; import com.moabam.global.config.OAuthConfig; diff --git a/src/test/java/com/moabam/api/application/AuthenticationServiceTest.java b/src/test/java/com/moabam/api/application/AuthenticationServiceTest.java index cfebb663..20fea0af 100644 --- a/src/test/java/com/moabam/api/application/AuthenticationServiceTest.java +++ b/src/test/java/com/moabam/api/application/AuthenticationServiceTest.java @@ -21,7 +21,7 @@ import org.springframework.test.util.ReflectionTestUtils; import com.moabam.api.dto.AuthorizationCodeRequest; -import com.moabam.api.mapper.OAuthMapper; +import com.moabam.api.dto.OAuthMapper; import com.moabam.global.common.util.GlobalConstant; import com.moabam.global.config.OAuthConfig; import com.moabam.global.error.exception.BadRequestException; diff --git a/src/test/java/com/moabam/api/domain/MemberTest.java b/src/test/java/com/moabam/api/domain/MemberTest.java index b08dde3f..02cfc8d7 100644 --- a/src/test/java/com/moabam/api/domain/MemberTest.java +++ b/src/test/java/com/moabam/api/domain/MemberTest.java @@ -6,6 +6,8 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import com.moabam.api.domain.entity.Member; +import com.moabam.api.domain.entity.enums.Role; import com.moabam.global.common.util.BaseImageUrl; class MemberTest { From a35ce88a4d670f1ca821741b7304f753d1ae07d1 Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Tue, 31 Oct 2023 22:28:33 +0900 Subject: [PATCH 11/27] =?UTF-8?q?refactor:=20checkStyle=EC=97=90=20?= =?UTF-8?q?=EB=A7=9E=EC=B6=B0=EC=84=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/moabam/api/domain/repository/ParticipantRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/moabam/api/domain/repository/ParticipantRepository.java b/src/main/java/com/moabam/api/domain/repository/ParticipantRepository.java index be814a44..54a84383 100644 --- a/src/main/java/com/moabam/api/domain/repository/ParticipantRepository.java +++ b/src/main/java/com/moabam/api/domain/repository/ParticipantRepository.java @@ -8,5 +8,5 @@ public interface ParticipantRepository extends JpaRepository { - Optional findParticipantByRoomIdAndMemberId(Long roomId, Long MemberId); + Optional findParticipantByRoomIdAndMemberId(Long roomId, Long memberId); } From c299ac321ce28a7ac6ed5ee4c4c524e8b8bb3056 Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Tue, 31 Oct 2023 23:11:41 +0900 Subject: [PATCH 12/27] =?UTF-8?q?test:=20=EC=B6=94=EA=B0=80=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + .../api/domain/entity/CertificationTest.java | 41 +++++++++++++++++++ .../api/domain/{ => entity}/MemberTest.java | 3 +- .../moabam/api/domain/entity/RoomTest.java | 7 ++++ 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/moabam/api/domain/entity/CertificationTest.java rename src/test/java/com/moabam/api/domain/{ => entity}/MemberTest.java (96%) diff --git a/build.gradle b/build.gradle index bf593fb3..0943c572 100644 --- a/build.gradle +++ b/build.gradle @@ -86,6 +86,7 @@ jacocoTestReport { "**/*Mapper*", "**/*ErrorMessage*", "**/*DynamicQuery*", + "**/*BaseTimeEntity*", ] + Qdomains) }) ) diff --git a/src/test/java/com/moabam/api/domain/entity/CertificationTest.java b/src/test/java/com/moabam/api/domain/entity/CertificationTest.java new file mode 100644 index 00000000..1e14bf29 --- /dev/null +++ b/src/test/java/com/moabam/api/domain/entity/CertificationTest.java @@ -0,0 +1,41 @@ +package com.moabam.api.domain.entity; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import com.moabam.api.domain.entity.enums.RoomType; + +class CertificationTest { + + String content = "물 마시기"; + String image = "https://s3.testtest"; + + @DisplayName("Certification 생성 성공") + @Test + void create_certification_success() { + Room room = Room.builder() + .title("앵윤이의 방") + .roomType(RoomType.MORNING) + .certifyTime(10) + .maxUserCount(9) + .build(); + + Routine routine = Routine.builder() + .room(room) + .content(content) + .build(); + + assertThatNoException().isThrownBy(() -> { + Certification certification = Certification.builder() + .routine(routine) + .memberId(1L) + .image(image).build(); + + assertThat(certification.getImage()).isEqualTo(image); + assertThat(certification.getMemberId()).isEqualTo(1L); + assertThat(certification.getRoutine()).isEqualTo(routine); + }); + } +} diff --git a/src/test/java/com/moabam/api/domain/MemberTest.java b/src/test/java/com/moabam/api/domain/entity/MemberTest.java similarity index 96% rename from src/test/java/com/moabam/api/domain/MemberTest.java rename to src/test/java/com/moabam/api/domain/entity/MemberTest.java index 02cfc8d7..dbc695fc 100644 --- a/src/test/java/com/moabam/api/domain/MemberTest.java +++ b/src/test/java/com/moabam/api/domain/entity/MemberTest.java @@ -1,4 +1,4 @@ -package com.moabam.api.domain; +package com.moabam.api.domain.entity; import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*; @@ -6,7 +6,6 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import com.moabam.api.domain.entity.Member; import com.moabam.api.domain.entity.enums.Role; import com.moabam.global.common.util.BaseImageUrl; diff --git a/src/test/java/com/moabam/api/domain/entity/RoomTest.java b/src/test/java/com/moabam/api/domain/entity/RoomTest.java index b9df5be3..d4516b62 100644 --- a/src/test/java/com/moabam/api/domain/entity/RoomTest.java +++ b/src/test/java/com/moabam/api/domain/entity/RoomTest.java @@ -26,6 +26,13 @@ void create_room_without_password_success() { // then assertThat(room.getPassword()).isNull(); + assertThat(room.getRoomImage()).isEqualTo("'temptemp'"); + assertThat(room.getRoomType()).isEqualTo(RoomType.MORNING); + assertThat(room.getCertifyTime()).isEqualTo(10); + assertThat(room.getMaxUserCount()).isEqualTo(9); + assertThat(room.getLevel()).isZero(); + assertThat(room.getCurrentUserCount()).isEqualTo(1); + assertThat(room.getAnnouncement()).isNull(); } @DisplayName("비밀번호 설정 후 방 생성 성공") From 334cd6f9036e1308ee7cfe8187047ac64b999152 Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Wed, 1 Nov 2023 00:45:38 +0900 Subject: [PATCH 13/27] =?UTF-8?q?chore:=20Apache=20Commons=20Lang=20?= =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle b/build.gradle index 0943c572..b51cafe6 100644 --- a/build.gradle +++ b/build.gradle @@ -55,6 +55,10 @@ dependencies { // Configuration Binding annotationProcessor "org.springframework.boot:spring-boot-configuration-processor" + + // Apache Commons Lang 3 + implementation 'org.apache.commons:commons-lang3:3.13.0' + } tasks.named('test') { From c0be2c9d3d54a0671ec70cce2254c7ea6361a46c Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Wed, 1 Nov 2023 00:46:11 +0900 Subject: [PATCH 14/27] =?UTF-8?q?feat:=20=EB=B0=A9=20=EC=B0=B8=EC=97=AC=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moabam/api/application/RoomService.java | 26 +++++++++++++++++++ .../com/moabam/api/domain/entity/Room.java | 12 +++++++++ .../com/moabam/api/dto/EnterRoomRequest.java | 9 +++++++ .../api/presentation/RoomController.java | 7 +++++ .../global/error/model/ErrorMessage.java | 4 ++- 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/moabam/api/dto/EnterRoomRequest.java diff --git a/src/main/java/com/moabam/api/application/RoomService.java b/src/main/java/com/moabam/api/application/RoomService.java index 94168e55..87091431 100644 --- a/src/main/java/com/moabam/api/application/RoomService.java +++ b/src/main/java/com/moabam/api/application/RoomService.java @@ -4,6 +4,7 @@ import java.util.List; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -14,8 +15,10 @@ import com.moabam.api.domain.repository.RoomRepository; import com.moabam.api.domain.repository.RoutineRepository; import com.moabam.api.dto.CreateRoomRequest; +import com.moabam.api.dto.EnterRoomRequest; import com.moabam.api.dto.ModifyRoomRequest; import com.moabam.api.dto.RoomMapper; +import com.moabam.global.error.exception.BadRequestException; import com.moabam.global.error.exception.ForbiddenException; import com.moabam.global.error.exception.NotFoundException; @@ -61,4 +64,27 @@ public void modifyRoom(Long memberId, Long roomId, ModifyRoomRequest modifyRoomR room.changeCertifyTime(modifyRoomRequest.certifyTime()); room.changeMaxCount(modifyRoomRequest.maxUserCount()); } + + @Transactional + public void enterRoom(Long memberId, Long roomId, EnterRoomRequest enterRoomRequest) { + // TODO: 해당 사용자의 방 입장 횟수 확인, 증가, (비동기 처리? -> 일단 엔티티 로직에서 임시방편) 기능 넣기 + String requestPassword = enterRoomRequest.password(); + Room room = roomRepository.findById(roomId).orElseThrow(() -> new NotFoundException(ROOM_NOT_FOUND)); + + if (!StringUtils.isEmpty(requestPassword) && !room.getPassword().equals(requestPassword)) { + throw new BadRequestException(WRONG_ROOM_PASSWORD); + } + + if (room.getCurrentUserCount() == room.getMaxUserCount()) { + throw new BadRequestException(ROOM_MAX_USER_REACHED); + } + + room.increaseCurrentUserCount(); + Participant participant = Participant.builder() + .room(room) + .memberId(memberId) + .build(); + + participantRepository.save(participant); + } } diff --git a/src/main/java/com/moabam/api/domain/entity/Room.java b/src/main/java/com/moabam/api/domain/entity/Room.java index 5e150acf..c0b36bb9 100644 --- a/src/main/java/com/moabam/api/domain/entity/Room.java +++ b/src/main/java/com/moabam/api/domain/entity/Room.java @@ -111,6 +111,18 @@ public void changeMaxCount(int maxUserCount) { this.maxUserCount = maxUserCount; } + public void increaseCurrentUserCount() { + this.currentUserCount += 1; + + if (this.currentUserCount > this.maxUserCount) { + throw new BadRequestException(ROOM_MAX_USER_REACHED); + } + } + + public void decreaseCurrentUserCount() { + this.currentUserCount -= 1; + } + public void upgradeRoomImage(String roomImage) { this.roomImage = roomImage; } diff --git a/src/main/java/com/moabam/api/dto/EnterRoomRequest.java b/src/main/java/com/moabam/api/dto/EnterRoomRequest.java new file mode 100644 index 00000000..25da6d06 --- /dev/null +++ b/src/main/java/com/moabam/api/dto/EnterRoomRequest.java @@ -0,0 +1,9 @@ +package com.moabam.api.dto; + +import jakarta.validation.constraints.Pattern; + +public record EnterRoomRequest( + @Pattern(regexp = "^(|[0-9]{4,8})$") String password +) { + +} diff --git a/src/main/java/com/moabam/api/presentation/RoomController.java b/src/main/java/com/moabam/api/presentation/RoomController.java index c0edc651..42e355c9 100644 --- a/src/main/java/com/moabam/api/presentation/RoomController.java +++ b/src/main/java/com/moabam/api/presentation/RoomController.java @@ -11,6 +11,7 @@ import com.moabam.api.application.RoomService; import com.moabam.api.dto.CreateRoomRequest; +import com.moabam.api.dto.EnterRoomRequest; import com.moabam.api.dto.ModifyRoomRequest; import jakarta.validation.Valid; @@ -35,4 +36,10 @@ public void modifyRoom(@Valid @RequestBody ModifyRoomRequest modifyRoomRequest, @PathVariable("roomId") Long roomId) { roomService.modifyRoom(1L, roomId, modifyRoomRequest); } + + @PostMapping("/{roomId}") + @ResponseStatus(HttpStatus.OK) + public void enterRoom(@Valid @RequestBody EnterRoomRequest enterRoomRequest, @PathVariable("roomId") Long roomId) { + roomService.enterRoom(1L, roomId, enterRoomRequest); + } } diff --git a/src/main/java/com/moabam/global/error/model/ErrorMessage.java b/src/main/java/com/moabam/global/error/model/ErrorMessage.java index 82942270..4efdbc63 100644 --- a/src/main/java/com/moabam/global/error/model/ErrorMessage.java +++ b/src/main/java/com/moabam/global/error/model/ErrorMessage.java @@ -13,7 +13,9 @@ public enum ErrorMessage { ROOM_MODIFY_UNAUTHORIZED_REQUEST("방장이 아닌 사용자는 방을 수정할 수 없습니다."), PARTICIPANT_NOT_FOUND("방에 대한 참여자의 정보가 없습니다."), LOGIN_FAILED("로그인에 실패했습니다."), - REQUEST_FAILD("네트우크 접근 실패입니다."); + REQUEST_FAILD("네트우크 접근 실패입니다."), + WRONG_ROOM_PASSWORD("방의 비밀번호가 일치하지 않습니다."), + ROOM_MAX_USER_REACHED("방의 인원수가 찼습니다."); private final String message; } From ebb51320f0d8ef20ba317863972d7651562d3b14 Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Wed, 1 Nov 2023 00:46:26 +0900 Subject: [PATCH 15/27] =?UTF-8?q?test:=20=EB=B0=A9=20=EC=B0=B8=EC=97=AC=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/presentation/RoomControllerTest.java | 142 ++++++++++++++++-- 1 file changed, 133 insertions(+), 9 deletions(-) diff --git a/src/test/java/com/moabam/api/presentation/RoomControllerTest.java b/src/test/java/com/moabam/api/presentation/RoomControllerTest.java index 55668783..2ad22e17 100644 --- a/src/test/java/com/moabam/api/presentation/RoomControllerTest.java +++ b/src/test/java/com/moabam/api/presentation/RoomControllerTest.java @@ -28,6 +28,7 @@ import com.moabam.api.domain.repository.RoomRepository; import com.moabam.api.domain.repository.RoutineRepository; import com.moabam.api.dto.CreateRoomRequest; +import com.moabam.api.dto.EnterRoomRequest; import com.moabam.api.dto.ModifyRoomRequest; @Transactional @@ -61,7 +62,6 @@ void create_room_no_password_success() throws Exception { CreateRoomRequest createRoomRequest = new CreateRoomRequest( "재윤과 앵맹이의 방임", null, routines, MORNING, 10, 4); - String json = objectMapper.writeValueAsString(createRoomRequest); // expected @@ -89,7 +89,6 @@ void create_room_with_password_success(String password) throws Exception { CreateRoomRequest createRoomRequest = new CreateRoomRequest( "비번 있는 재윤과 앵맹이의 방임", password, routines, MORNING, 10, 4); - String json = objectMapper.writeValueAsString(createRoomRequest); // expected @@ -117,7 +116,6 @@ void create_room_with_wrong_password_fail(String password) throws Exception { CreateRoomRequest createRoomRequest = new CreateRoomRequest( "비번 있는 재윤과 앵맹이의 방임", password, routines, MORNING, 10, 4); - String json = objectMapper.writeValueAsString(createRoomRequest); // expected @@ -142,7 +140,6 @@ void create_room_with_too_many_routine_fail() throws Exception { CreateRoomRequest createRoomRequest = new CreateRoomRequest( "비번 없는 재윤과 앵맹이의 방임", null, routines, MORNING, 10, 4); - String json = objectMapper.writeValueAsString(createRoomRequest); // expected @@ -161,7 +158,6 @@ void create_room_with_no_routine_fail() throws Exception { CreateRoomRequest createRoomRequest = new CreateRoomRequest( "비번 없는 재윤과 앵맹이의 방임", null, routines, MORNING, 10, 4); - String json = objectMapper.writeValueAsString(createRoomRequest); // expected @@ -185,7 +181,6 @@ void create_morning_room_wrong_certify_time_fail(int certifyTime) throws Excepti CreateRoomRequest createRoomRequest = new CreateRoomRequest( "비번 없는 재윤과 앵맹이의 방임", null, routines, MORNING, certifyTime, 4); - String json = objectMapper.writeValueAsString(createRoomRequest); // expected @@ -209,7 +204,6 @@ void create_night_room_wrong_certify_time_fail(int certifyTime) throws Exception CreateRoomRequest createRoomRequest = new CreateRoomRequest( "비번 없는 재윤과 앵맹이의 방임", null, routines, NIGHT, certifyTime, 4); - String json = objectMapper.writeValueAsString(createRoomRequest); // expected @@ -242,7 +236,6 @@ void modify_room_success() throws Exception { participantRepository.save(participant); ModifyRoomRequest modifyRoomRequest = new ModifyRoomRequest("수정할 방임!", "1234", 10, 7); - String json = objectMapper.writeValueAsString(modifyRoomRequest); // expected @@ -274,7 +267,6 @@ void unauthorized_modify_room_fail() throws Exception { participantRepository.save(participant); ModifyRoomRequest modifyRoomRequest = new ModifyRoomRequest("수정할 방임!", "1234", 10, 7); - String json = objectMapper.writeValueAsString(modifyRoomRequest); // expected @@ -284,4 +276,136 @@ void unauthorized_modify_room_fail() throws Exception { .andExpect(status().isNotFound()) .andDo(print()); } + + @DisplayName("비밀번호 있는 방 참여 성공") + @Test + void enter_room_with_password_success() throws Exception { + // given + Room room = Room.builder() + .title("처음 제목") + .password("7777") + .roomType(MORNING) + .certifyTime(9) + .maxUserCount(5) + .build(); + + Room savedRoom = roomRepository.save(room); + + EnterRoomRequest enterRoomRequest = new EnterRoomRequest("7777"); + String json = objectMapper.writeValueAsString(enterRoomRequest); + + // expected + mockMvc.perform(post("/rooms/" + savedRoom.getId()) + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isOk()) + .andDo(print()); + } + + @DisplayName("비밀번호 없는 방 참여 성공") + @Test + void enter_room_with_no_password_success() throws Exception { + // given + Room room = Room.builder() + .title("처음 제목") + .roomType(MORNING) + .certifyTime(9) + .maxUserCount(5) + .build(); + + Room savedRoom = roomRepository.save(room); + + EnterRoomRequest enterRoomRequest = new EnterRoomRequest(null); + String json = objectMapper.writeValueAsString(enterRoomRequest); + + // expected + mockMvc.perform(post("/rooms/" + savedRoom.getId()) + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isOk()) + .andDo(print()); + } + + @DisplayName("방 참여 후 인원수 증가 테스트") + @Test + void enter_and_increase_room_user_count() throws Exception { + // given + Room room = Room.builder() + .title("방 제목") + .password("1234") + .roomType(MORNING) + .certifyTime(9) + .maxUserCount(5) + .build(); + + Room savedRoom = roomRepository.save(room); + + EnterRoomRequest enterRoomRequest = new EnterRoomRequest("1234"); + String json = objectMapper.writeValueAsString(enterRoomRequest); + + // when + mockMvc.perform(post("/rooms/" + savedRoom.getId()) + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isOk()); + + Room findRoom = roomRepository.findById(savedRoom.getId()).orElseThrow(); + + // then + assertThat(findRoom.getCurrentUserCount()).isEqualTo(2); + } + + @DisplayName("비밀번호 불일치 방 참여시 예외 발생") + @Test + void enter_room_wrong_password_fail() throws Exception { + // given + Room room = Room.builder() + .title("처음 제목") + .password("7777") + .roomType(MORNING) + .certifyTime(9) + .maxUserCount(5) + .build(); + + Room savedRoom = roomRepository.save(room); + + EnterRoomRequest enterRoomRequest = new EnterRoomRequest("1234"); + String json = objectMapper.writeValueAsString(enterRoomRequest); + + // expected + mockMvc.perform(post("/rooms/" + savedRoom.getId()) + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isBadRequest()) + .andDo(print()); + } + + @DisplayName("인원수가 모두 찬 방 참여시 예외 발생") + @Test + void enter_max_user_room_fail() throws Exception { + // given + Room room = Room.builder() + .title("처음 제목") + .password("7777") + .roomType(MORNING) + .certifyTime(9) + .maxUserCount(5) + .build(); + + for (int i = 0; i < 4; i++) { + room.increaseCurrentUserCount(); + } + + Room savedRoom = roomRepository.save(room); + + EnterRoomRequest enterRoomRequest = new EnterRoomRequest("7777"); + String json = objectMapper.writeValueAsString(enterRoomRequest); + + // expected + mockMvc.perform(post("/rooms/" + savedRoom.getId()) + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isBadRequest()) + .andDo(print()); + } } From 3b71611c73dd5df3a5cb2ba7c5e0c5f0fad712ff Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Thu, 2 Nov 2023 17:16:54 +0900 Subject: [PATCH 16/27] =?UTF-8?q?feat:=20=EB=B0=A9=20=EB=82=98=EA=B0=80?= =?UTF-8?q?=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moabam/api/application/MemberService.java | 27 ++++++++ .../moabam/api/application/RoomService.java | 68 +++++++++++++++---- .../moabam/api/domain/entity/Participant.java | 10 ++- .../com/moabam/api/domain/entity/Room.java | 2 - .../ParticipantSearchRepository.java | 2 +- .../api/presentation/RoomController.java | 7 ++ .../global/error/model/ErrorMessage.java | 6 +- 7 files changed, 101 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/moabam/api/application/MemberService.java b/src/main/java/com/moabam/api/application/MemberService.java index 112fcd7e..797871cf 100644 --- a/src/main/java/com/moabam/api/application/MemberService.java +++ b/src/main/java/com/moabam/api/application/MemberService.java @@ -1,11 +1,13 @@ package com.moabam.api.application; +import static com.moabam.api.domain.entity.enums.RoomType.*; import static com.moabam.global.error.model.ErrorMessage.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.moabam.api.domain.entity.Member; +import com.moabam.api.domain.entity.enums.RoomType; import com.moabam.api.domain.repository.MemberRepository; import com.moabam.global.error.exception.NotFoundException; @@ -22,4 +24,29 @@ public Member getById(Long memberId) { return memberRepository.findById(memberId) .orElseThrow(() -> new NotFoundException(MEMBER_NOT_FOUND)); } + + public boolean isEnterRoomAvailable(Long memberId, RoomType roomType) { + Member member = getById(memberId); + + if (roomType.equals(MORNING) && member.getCurrentMorningCount() >= 3) { + return false; + } + + if (roomType.equals(NIGHT) && member.getCurrentNightCount() >= 3) { + return false; + } + + return true; + } + + @Transactional + public void increaseRoomCount(Long memberId, RoomType roomType) { + Member member = getById(memberId); + + if (roomType.equals(MORNING)) { + member.enterMorningRoom(); + } + + member.enterNightRoom(); + } } diff --git a/src/main/java/com/moabam/api/application/RoomService.java b/src/main/java/com/moabam/api/application/RoomService.java index 1981f8e8..56737ea5 100644 --- a/src/main/java/com/moabam/api/application/RoomService.java +++ b/src/main/java/com/moabam/api/application/RoomService.java @@ -34,6 +34,7 @@ public class RoomService { private final RoutineRepository routineRepository; private final ParticipantRepository participantRepository; private final ParticipantSearchRepository participantSearchRepository; + private final MemberService memberService; @Transactional public void createRoom(Long memberId, CreateRoomRequest createRoomRequest) { @@ -43,6 +44,7 @@ public void createRoom(Long memberId, CreateRoomRequest createRoomRequest) { .room(room) .memberId(memberId) .build(); + participant.enableManager(); roomRepository.save(room); routineRepository.saveAll(routines); @@ -51,15 +53,13 @@ public void createRoom(Long memberId, CreateRoomRequest createRoomRequest) { @Transactional public void modifyRoom(Long memberId, Long roomId, ModifyRoomRequest modifyRoomRequest) { - // TODO: 추후에 별도 메서드로 뺄듯 - Participant participant = participantSearchRepository.findParticipant(roomId, memberId) - .orElseThrow(() -> new NotFoundException(PARTICIPANT_NOT_FOUND)); + Participant participant = getParticipant(memberId, roomId); if (!participant.isManager()) { throw new ForbiddenException(ROOM_MODIFY_UNAUTHORIZED_REQUEST); } - Room room = roomRepository.findById(roomId).orElseThrow(() -> new NotFoundException(ROOM_NOT_FOUND)); + Room room = getRoom(roomId); room.changeTitle(modifyRoomRequest.title()); room.changePassword(modifyRoomRequest.password()); room.changeCertifyTime(modifyRoomRequest.certifyTime()); @@ -68,9 +68,55 @@ public void modifyRoom(Long memberId, Long roomId, ModifyRoomRequest modifyRoomR @Transactional public void enterRoom(Long memberId, Long roomId, EnterRoomRequest enterRoomRequest) { - // TODO: 해당 사용자의 방 입장 횟수 확인, 증가, (비동기 처리? -> 일단 엔티티 로직에서 임시방편) 기능 넣기 - String requestPassword = enterRoomRequest.password(); - Room room = roomRepository.findById(roomId).orElseThrow(() -> new NotFoundException(ROOM_NOT_FOUND)); + Room room = getRoom(roomId); + validateRoomEnter(memberId, enterRoomRequest.password(), room); + + room.increaseCurrentUserCount(); + memberService.increaseRoomCount(memberId, room.getRoomType()); + + Participant participant = Participant.builder() + .room(room) + .memberId(memberId) + .build(); + participantRepository.save(participant); + } + + @Transactional + public void exitRoom(Long memberId, Long roomId) { + Participant participant = getParticipant(memberId, roomId); + Room room = participant.getRoom(); + + if (participant.isManager() && room.getCurrentUserCount() != 1) { + throw new BadRequestException(ROOM_EXIT_MANAGER_FAIL); + } + + // TODO: 사용자의 방 입장 횟수 감소 기능 넣기 + participant.removeRoom(); + participantRepository.flush(); + participantRepository.delete(participant); + + if (!participant.isManager()) { + room.decreaseCurrentUserCount(); + return; + } + + roomRepository.flush(); + roomRepository.delete(room); + } + + private Participant getParticipant(Long memberId, Long roomId) { + return participantSearchRepository.findParticipant(memberId, roomId) + .orElseThrow(() -> new NotFoundException(PARTICIPANT_NOT_FOUND)); + } + + private Room getRoom(Long roomId) { + return roomRepository.findById(roomId).orElseThrow(() -> new NotFoundException(ROOM_NOT_FOUND)); + } + + private void validateRoomEnter(Long memberId, String requestPassword, Room room) { + if (!memberService.isEnterRoomAvailable(memberId, room.getRoomType())) { + throw new BadRequestException(MEMBER_ROOM_EXCEED); + } if (!StringUtils.isEmpty(requestPassword) && !room.getPassword().equals(requestPassword)) { throw new BadRequestException(WRONG_ROOM_PASSWORD); @@ -79,13 +125,5 @@ public void enterRoom(Long memberId, Long roomId, EnterRoomRequest enterRoomRequ if (room.getCurrentUserCount() == room.getMaxUserCount()) { throw new BadRequestException(ROOM_MAX_USER_REACHED); } - - room.increaseCurrentUserCount(); - Participant participant = Participant.builder() - .room(room) - .memberId(memberId) - .build(); - - participantRepository.save(participant); } } diff --git a/src/main/java/com/moabam/api/domain/entity/Participant.java b/src/main/java/com/moabam/api/domain/entity/Participant.java index 733585cd..7c4442a8 100644 --- a/src/main/java/com/moabam/api/domain/entity/Participant.java +++ b/src/main/java/com/moabam/api/domain/entity/Participant.java @@ -33,7 +33,7 @@ public class Participant { private Long id; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "room_id", updatable = false, nullable = false) + @JoinColumn(name = "room_id", updatable = false) private Room room; @Column(name = "member_id", updatable = false, nullable = false) @@ -48,6 +48,9 @@ public class Participant { @Column(name = "deleted_at") private LocalDateTime deletedAt; + @Column(name = "deleted_room_title", length = 30) + private String deletedRoomTitle; + @Builder private Participant(Long id, Room room, Long memberId) { this.id = id; @@ -68,4 +71,9 @@ public void enableManager() { public void updateCertifyCount() { this.certifyCount += 1; } + + public void removeRoom() { + this.deletedRoomTitle = this.room.getTitle(); + this.room = null; + } } diff --git a/src/main/java/com/moabam/api/domain/entity/Room.java b/src/main/java/com/moabam/api/domain/entity/Room.java index 6ea1fe9b..acdd2896 100644 --- a/src/main/java/com/moabam/api/domain/entity/Room.java +++ b/src/main/java/com/moabam/api/domain/entity/Room.java @@ -43,7 +43,6 @@ public class Room extends BaseTimeEntity { @Column(name = "id") private Long id; - // TODO: 한글 10자도 맞나? @Column(name = "title", nullable = false, length = 30) private String title; @@ -66,7 +65,6 @@ public class Room extends BaseTimeEntity { @Column(name = "max_user_count", nullable = false) private int maxUserCount; - // TODO: 한글 길이 고려 @Column(name = "announcement", length = 255) private String announcement; diff --git a/src/main/java/com/moabam/api/domain/repository/ParticipantSearchRepository.java b/src/main/java/com/moabam/api/domain/repository/ParticipantSearchRepository.java index e80e81b9..9e3a01b3 100644 --- a/src/main/java/com/moabam/api/domain/repository/ParticipantSearchRepository.java +++ b/src/main/java/com/moabam/api/domain/repository/ParticipantSearchRepository.java @@ -18,7 +18,7 @@ public class ParticipantSearchRepository { private final JPAQueryFactory jpaQueryFactory; - public Optional findParticipant(Long roomId, Long memberId) { + public Optional findParticipant(Long memberId, Long roomId) { return Optional.ofNullable( jpaQueryFactory.selectFrom(participant) .where( diff --git a/src/main/java/com/moabam/api/presentation/RoomController.java b/src/main/java/com/moabam/api/presentation/RoomController.java index 42e355c9..077f94f1 100644 --- a/src/main/java/com/moabam/api/presentation/RoomController.java +++ b/src/main/java/com/moabam/api/presentation/RoomController.java @@ -1,6 +1,7 @@ package com.moabam.api.presentation; import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; @@ -42,4 +43,10 @@ public void modifyRoom(@Valid @RequestBody ModifyRoomRequest modifyRoomRequest, public void enterRoom(@Valid @RequestBody EnterRoomRequest enterRoomRequest, @PathVariable("roomId") Long roomId) { roomService.enterRoom(1L, roomId, enterRoomRequest); } + + @DeleteMapping("/{roomId}") + @ResponseStatus(HttpStatus.OK) + public void exitRoom(@PathVariable("roomId") Long roomId) { + roomService.exitRoom(1L, roomId); + } } diff --git a/src/main/java/com/moabam/global/error/model/ErrorMessage.java b/src/main/java/com/moabam/global/error/model/ErrorMessage.java index 8fce6601..877e9a09 100644 --- a/src/main/java/com/moabam/global/error/model/ErrorMessage.java +++ b/src/main/java/com/moabam/global/error/model/ErrorMessage.java @@ -12,14 +12,16 @@ public enum ErrorMessage { ROOM_NOT_FOUND("존재하지 않는 방 입니다."), ROOM_MAX_USER_COUNT_MODIFY_FAIL("잘못된 최대 인원수 설정입니다."), ROOM_MODIFY_UNAUTHORIZED_REQUEST("방장이 아닌 사용자는 방을 수정할 수 없습니다."), + ROOM_EXIT_MANAGER_FAIL("인원수가 2명 이상일때는 방장을 위임해야합니다."), PARTICIPANT_NOT_FOUND("방에 대한 참여자의 정보가 없습니다."), + WRONG_ROOM_PASSWORD("방의 비밀번호가 일치하지 않습니다."), + ROOM_MAX_USER_REACHED("방의 인원수가 찼습니다."), LOGIN_FAILED("로그인에 실패했습니다."), REQUEST_FAILED("네트워크 접근 실패입니다."), GRANT_FAILED("인가 코드 실패"), MEMBER_NOT_FOUND("존재하지 않는 회원입니다."), - WRONG_ROOM_PASSWORD("방의 비밀번호가 일치하지 않습니다."), - ROOM_MAX_USER_REACHED("방의 인원수가 찼습니다."), + MEMBER_ROOM_EXCEED("참여할 수 있는 방의 갯수가 모두 찼습니다."), INVALID_BUG_COUNT("벌레 개수는 0 이상이어야 합니다."), INVALID_PRICE("가격은 0 이상이어야 합니다."), From 4df95414b5c7366e3e01597871d87d034c9ffc7d Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Thu, 2 Nov 2023 17:17:11 +0900 Subject: [PATCH 17/27] =?UTF-8?q?chore:=20test=20yml=20JPA=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/resources/application-test.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test/resources/application-test.yml b/src/test/resources/application-test.yml index 94864159..0fae9b02 100644 --- a/src/test/resources/application-test.yml +++ b/src/test/resources/application-test.yml @@ -1,3 +1,13 @@ +logging: + level: + org.hibernate.SQL: debug + +spring: + jpa: + properties: + hibernate: + format_sql: true + oauth2: client: provider: test From f3cc0361f417c8387eb36793dc281947a3b16dde Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Thu, 2 Nov 2023 20:29:45 +0900 Subject: [PATCH 18/27] =?UTF-8?q?test:=20=EB=B0=A9=20=EC=B0=B8=EC=97=AC,?= =?UTF-8?q?=20=EB=82=98=EA=B0=80=EA=B8=B0=20=EC=9D=BC=EB=B6=80=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moabam/api/application/MemberService.java | 1 + .../moabam/api/application/RoomService.java | 2 +- .../com/moabam/api/domain/entity/Member.java | 2 +- .../api/presentation/RoomControllerTest.java | 287 +++++++++++++++--- 4 files changed, 255 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/moabam/api/application/MemberService.java b/src/main/java/com/moabam/api/application/MemberService.java index 797871cf..90b0033a 100644 --- a/src/main/java/com/moabam/api/application/MemberService.java +++ b/src/main/java/com/moabam/api/application/MemberService.java @@ -45,6 +45,7 @@ public void increaseRoomCount(Long memberId, RoomType roomType) { if (roomType.equals(MORNING)) { member.enterMorningRoom(); + return; } member.enterNightRoom(); diff --git a/src/main/java/com/moabam/api/application/RoomService.java b/src/main/java/com/moabam/api/application/RoomService.java index 56737ea5..b346e2f7 100644 --- a/src/main/java/com/moabam/api/application/RoomService.java +++ b/src/main/java/com/moabam/api/application/RoomService.java @@ -73,7 +73,7 @@ public void enterRoom(Long memberId, Long roomId, EnterRoomRequest enterRoomRequ room.increaseCurrentUserCount(); memberService.increaseRoomCount(memberId, room.getRoomType()); - + Participant participant = Participant.builder() .room(room) .memberId(memberId) diff --git a/src/main/java/com/moabam/api/domain/entity/Member.java b/src/main/java/com/moabam/api/domain/entity/Member.java index 1d51cb4d..1ba2db2b 100644 --- a/src/main/java/com/moabam/api/domain/entity/Member.java +++ b/src/main/java/com/moabam/api/domain/entity/Member.java @@ -30,7 +30,7 @@ @Getter @Table(name = "member") @SQLDelete(sql = "UPDATE member SET deleted_at = CURRENT_TIMESTAMP where id = ?") -@Where(clause = "deleted_at IS NOT NULL") +@Where(clause = "deleted_at IS NULL") @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Member extends BaseTimeEntity { diff --git a/src/test/java/com/moabam/api/presentation/RoomControllerTest.java b/src/test/java/com/moabam/api/presentation/RoomControllerTest.java index 2ad22e17..0cc97b00 100644 --- a/src/test/java/com/moabam/api/presentation/RoomControllerTest.java +++ b/src/test/java/com/moabam/api/presentation/RoomControllerTest.java @@ -10,31 +10,36 @@ import java.util.ArrayList; import java.util.List; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; import org.springframework.transaction.annotation.Transactional; import com.fasterxml.jackson.databind.ObjectMapper; +import com.moabam.api.domain.entity.Member; import com.moabam.api.domain.entity.Participant; import com.moabam.api.domain.entity.Room; +import com.moabam.api.domain.repository.MemberRepository; import com.moabam.api.domain.repository.ParticipantRepository; import com.moabam.api.domain.repository.RoomRepository; import com.moabam.api.domain.repository.RoutineRepository; import com.moabam.api.dto.CreateRoomRequest; import com.moabam.api.dto.EnterRoomRequest; import com.moabam.api.dto.ModifyRoomRequest; +import com.moabam.fixture.BugFixture; +import com.moabam.fixture.MemberFixture; @Transactional @SpringBootTest @AutoConfigureMockMvc -@ActiveProfiles("test") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) class RoomControllerTest { @Autowired @@ -52,6 +57,17 @@ class RoomControllerTest { @Autowired private ParticipantRepository participantRepository; + @Autowired + private MemberRepository memberRepository; + + Member member; + + @BeforeAll + void setUp() { + member = MemberFixture.member(); + memberRepository.save(member); + } + @DisplayName("비밀번호 없는 방 생성 성공") @Test void create_room_no_password_success() throws Exception { @@ -59,7 +75,6 @@ void create_room_no_password_success() throws Exception { List routines = new ArrayList<>(); routines.add("물 마시기"); routines.add("코테 풀기"); - CreateRoomRequest createRoomRequest = new CreateRoomRequest( "재윤과 앵맹이의 방임", null, routines, MORNING, 10, 4); String json = objectMapper.writeValueAsString(createRoomRequest); @@ -86,7 +101,6 @@ void create_room_with_password_success(String password) throws Exception { List routines = new ArrayList<>(); routines.add("물 마시기"); routines.add("코테 풀기"); - CreateRoomRequest createRoomRequest = new CreateRoomRequest( "비번 있는 재윤과 앵맹이의 방임", password, routines, MORNING, 10, 4); String json = objectMapper.writeValueAsString(createRoomRequest); @@ -97,7 +111,6 @@ void create_room_with_password_success(String password) throws Exception { .content(json)) .andExpect(status().isCreated()) .andDo(print()); - assertThat(roomRepository.findAll()).hasSize(1); assertThat(roomRepository.findAll().get(0).getTitle()).isEqualTo("비번 있는 재윤과 앵맹이의 방임"); assertThat(roomRepository.findAll().get(0).getPassword()).isEqualTo(password); @@ -113,7 +126,6 @@ void create_room_with_wrong_password_fail(String password) throws Exception { List routines = new ArrayList<>(); routines.add("물 마시기"); routines.add("코테 풀기"); - CreateRoomRequest createRoomRequest = new CreateRoomRequest( "비번 있는 재윤과 앵맹이의 방임", password, routines, MORNING, 10, 4); String json = objectMapper.writeValueAsString(createRoomRequest); @@ -137,7 +149,6 @@ void create_room_with_too_many_routine_fail() throws Exception { routines.add("코드 리뷰 달기"); routines.add("책 읽기"); routines.add("산책 하기"); - CreateRoomRequest createRoomRequest = new CreateRoomRequest( "비번 없는 재윤과 앵맹이의 방임", null, routines, MORNING, 10, 4); String json = objectMapper.writeValueAsString(createRoomRequest); @@ -155,7 +166,6 @@ void create_room_with_too_many_routine_fail() throws Exception { void create_room_with_no_routine_fail() throws Exception { // given List routines = new ArrayList<>(); - CreateRoomRequest createRoomRequest = new CreateRoomRequest( "비번 없는 재윤과 앵맹이의 방임", null, routines, MORNING, 10, 4); String json = objectMapper.writeValueAsString(createRoomRequest); @@ -178,7 +188,6 @@ void create_morning_room_wrong_certify_time_fail(int certifyTime) throws Excepti List routines = new ArrayList<>(); routines.add("물 마시기"); routines.add("코테 풀기"); - CreateRoomRequest createRoomRequest = new CreateRoomRequest( "비번 없는 재윤과 앵맹이의 방임", null, routines, MORNING, certifyTime, 4); String json = objectMapper.writeValueAsString(createRoomRequest); @@ -201,7 +210,6 @@ void create_night_room_wrong_certify_time_fail(int certifyTime) throws Exception List routines = new ArrayList<>(); routines.add("물 마시기"); routines.add("코테 풀기"); - CreateRoomRequest createRoomRequest = new CreateRoomRequest( "비번 없는 재윤과 앵맹이의 방임", null, routines, NIGHT, certifyTime, 4); String json = objectMapper.writeValueAsString(createRoomRequest); @@ -225,21 +233,18 @@ void modify_room_success() throws Exception { .certifyTime(9) .maxUserCount(5) .build(); - Participant participant = Participant.builder() .room(room) .memberId(1L) .build(); participant.enableManager(); - - Room savedRoom = roomRepository.save(room); + roomRepository.save(room); participantRepository.save(participant); - ModifyRoomRequest modifyRoomRequest = new ModifyRoomRequest("수정할 방임!", "1234", 10, 7); String json = objectMapper.writeValueAsString(modifyRoomRequest); // expected - mockMvc.perform(put("/rooms/" + savedRoom.getId()) + mockMvc.perform(put("/rooms/" + room.getId()) .contentType(APPLICATION_JSON) .content(json)) .andExpect(status().isOk()) @@ -257,23 +262,22 @@ void unauthorized_modify_room_fail() throws Exception { .certifyTime(9) .maxUserCount(5) .build(); - Participant participant = Participant.builder() .room(room) .memberId(1L) .build(); - - Room savedRoom = roomRepository.save(room); + roomRepository.save(room); participantRepository.save(participant); - ModifyRoomRequest modifyRoomRequest = new ModifyRoomRequest("수정할 방임!", "1234", 10, 7); String json = objectMapper.writeValueAsString(modifyRoomRequest); + String message = "{\"message\":\"방장이 아닌 사용자는 방을 수정할 수 없습니다.\"}"; // expected - mockMvc.perform(put("/rooms/" + savedRoom.getId()) + mockMvc.perform(put("/rooms/" + room.getId()) .contentType(APPLICATION_JSON) .content(json)) .andExpect(status().isNotFound()) + .andExpect(content().json(message)) .andDo(print()); } @@ -289,13 +293,12 @@ void enter_room_with_password_success() throws Exception { .maxUserCount(5) .build(); - Room savedRoom = roomRepository.save(room); - + roomRepository.save(room); EnterRoomRequest enterRoomRequest = new EnterRoomRequest("7777"); String json = objectMapper.writeValueAsString(enterRoomRequest); // expected - mockMvc.perform(post("/rooms/" + savedRoom.getId()) + mockMvc.perform(post("/rooms/" + room.getId()) .contentType(APPLICATION_JSON) .content(json)) .andExpect(status().isOk()) @@ -313,13 +316,12 @@ void enter_room_with_no_password_success() throws Exception { .maxUserCount(5) .build(); - Room savedRoom = roomRepository.save(room); - + roomRepository.save(room); EnterRoomRequest enterRoomRequest = new EnterRoomRequest(null); String json = objectMapper.writeValueAsString(enterRoomRequest); // expected - mockMvc.perform(post("/rooms/" + savedRoom.getId()) + mockMvc.perform(post("/rooms/" + room.getId()) .contentType(APPLICATION_JSON) .content(json)) .andExpect(status().isOk()) @@ -338,23 +340,136 @@ void enter_and_increase_room_user_count() throws Exception { .maxUserCount(5) .build(); - Room savedRoom = roomRepository.save(room); - + roomRepository.save(room); EnterRoomRequest enterRoomRequest = new EnterRoomRequest("1234"); String json = objectMapper.writeValueAsString(enterRoomRequest); // when - mockMvc.perform(post("/rooms/" + savedRoom.getId()) + mockMvc.perform(post("/rooms/" + room.getId()) .contentType(APPLICATION_JSON) .content(json)) .andExpect(status().isOk()); - Room findRoom = roomRepository.findById(savedRoom.getId()).orElseThrow(); + Room findRoom = roomRepository.findById(room.getId()).orElseThrow(); // then assertThat(findRoom.getCurrentUserCount()).isEqualTo(2); } + @DisplayName("아침 방 참여 후 사용자의 방 입장 횟수 증가 테스트") + @Test + void enter_and_increase_morning_room_count() throws Exception { + // given + Room room = Room.builder() + .title("방 제목") + .password("1234") + .roomType(MORNING) + .certifyTime(9) + .maxUserCount(5) + .build(); + + roomRepository.save(room); + EnterRoomRequest enterRoomRequest = new EnterRoomRequest("1234"); + String json = objectMapper.writeValueAsString(enterRoomRequest); + + // when + mockMvc.perform(post("/rooms/" + room.getId()) + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isOk()); + + Member getMember = memberRepository.findById(1L).orElseThrow(); + + // then + assertThat(getMember.getCurrentMorningCount()).isEqualTo(1); + assertThat(getMember.getCurrentNightCount()).isZero(); + } + + @DisplayName("저녁 방 참여 후 사용자의 방 입장 횟수 증가 테스트") + @Test + void enter_and_increase_night_room_count() throws Exception { + // given + Room room = Room.builder() + .title("방 제목") + .password("1234") + .roomType(NIGHT) + .certifyTime(21) + .maxUserCount(5) + .build(); + + roomRepository.save(room); + EnterRoomRequest enterRoomRequest = new EnterRoomRequest("1234"); + String json = objectMapper.writeValueAsString(enterRoomRequest); + + // when + mockMvc.perform(post("/rooms/" + room.getId()) + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isOk()); + + Member getMember = memberRepository.findById(1L).orElseThrow(); + + // then + assertThat(getMember.getCurrentNightCount()).isEqualTo(1); + assertThat(getMember.getCurrentMorningCount()).isZero(); + } + + @DisplayName("사용자의 아침 방 입장 횟수 3일시 예외 처리") + @Test + void enter_and_morning_room_over_three_fail() throws Exception { + // given + Room room = Room.builder() + .title("방 제목") + .password("1234") + .roomType(MORNING) + .certifyTime(9) + .maxUserCount(5) + .build(); + + for (int i = 0; i < 3; i++) { + member.enterMorningRoom(); + } + + memberRepository.save(member); + roomRepository.save(room); + EnterRoomRequest enterRoomRequest = new EnterRoomRequest("1234"); + String json = objectMapper.writeValueAsString(enterRoomRequest); + + // when + mockMvc.perform(post("/rooms/" + room.getId()) + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isBadRequest()); + } + + @DisplayName("사용자의 저녁 방 입장 횟수 3일시 예외 처리") + @Test + void enter_and_night_room_over_three_fail() throws Exception { + // given + Room room = Room.builder() + .title("방 제목") + .password("1234") + .roomType(NIGHT) + .certifyTime(22) + .maxUserCount(5) + .build(); + + for (int i = 0; i < 3; i++) { + member.enterNightRoom(); + } + + memberRepository.save(member); + roomRepository.save(room); + EnterRoomRequest enterRoomRequest = new EnterRoomRequest("1234"); + String json = objectMapper.writeValueAsString(enterRoomRequest); + + // when + mockMvc.perform(post("/rooms/" + room.getId()) + .contentType(APPLICATION_JSON) + .content(json)) + .andExpect(status().isBadRequest()); + } + @DisplayName("비밀번호 불일치 방 참여시 예외 발생") @Test void enter_room_wrong_password_fail() throws Exception { @@ -367,16 +482,26 @@ void enter_room_wrong_password_fail() throws Exception { .maxUserCount(5) .build(); - Room savedRoom = roomRepository.save(room); + Member member = Member.builder() + .id(1L) + .socialId("test123") + .nickname("nick") + .profileImage("testtests") + .bug(BugFixture.bug()) + .build(); + memberRepository.save(member); + roomRepository.save(room); EnterRoomRequest enterRoomRequest = new EnterRoomRequest("1234"); String json = objectMapper.writeValueAsString(enterRoomRequest); + String message = "{\"message\":\"방의 비밀번호가 일치하지 않습니다.\"}"; // expected - mockMvc.perform(post("/rooms/" + savedRoom.getId()) + mockMvc.perform(post("/rooms/" + room.getId()) .contentType(APPLICATION_JSON) .content(json)) .andExpect(status().isBadRequest()) + .andExpect(content().json(message)) .andDo(print()); } @@ -396,16 +521,108 @@ void enter_max_user_room_fail() throws Exception { room.increaseCurrentUserCount(); } - Room savedRoom = roomRepository.save(room); - + roomRepository.save(room); EnterRoomRequest enterRoomRequest = new EnterRoomRequest("7777"); String json = objectMapper.writeValueAsString(enterRoomRequest); + String message = "{\"message\":\"방의 인원수가 찼습니다.\"}"; // expected - mockMvc.perform(post("/rooms/" + savedRoom.getId()) + mockMvc.perform(post("/rooms/" + room.getId()) .contentType(APPLICATION_JSON) .content(json)) .andExpect(status().isBadRequest()) + .andExpect(content().json(message)) + .andDo(print()); + } + + @DisplayName("일반 사용자의 방 나가기 성공") + @Test + void no_manager_exit_room_success() throws Exception { + // given + Room room = Room.builder() + .title("5명이 있는 방~") + .roomType(NIGHT) + .certifyTime(21) + .maxUserCount(8) + .build(); + Participant participant = Participant.builder() + .room(room) + .memberId(1L) + .build(); + + for (int i = 0; i < 4; i++) { + room.increaseCurrentUserCount(); + } + + roomRepository.save(room); + participantRepository.save(participant); + + // expected + mockMvc.perform(delete("/rooms/" + room.getId())) + .andExpect(status().isOk()) + .andDo(print()); + participantRepository.flush(); + Participant deletedParticipant = participantRepository.findById(participant.getId()).orElseThrow(); + assertThat(room.getCurrentUserCount()).isEqualTo(4); + assertThat(deletedParticipant.getDeletedAt()).isNotNull(); + assertThat(deletedParticipant.getDeletedRoomTitle()).isEqualTo("5명이 있는 방~"); + } + + @DisplayName("방장의 방 나가기 - 방 삭제 성공") + @Test + void manager_delete_room_success() throws Exception { + // given + Room room = Room.builder() + .title("1명이 있는 방~") + .roomType(NIGHT) + .certifyTime(21) + .maxUserCount(8) + .build(); + Participant participant = Participant.builder() + .room(room) + .memberId(1L) + .build(); + participant.enableManager(); + roomRepository.save(room); + participantRepository.save(participant); + + // expected + mockMvc.perform(delete("/rooms/" + room.getId())) + .andExpect(status().isOk()) + .andDo(print()); + Participant deletedParticipant = participantRepository.findById(participant.getId()).orElseThrow(); + assertThat(roomRepository.findById(room.getId())).isEmpty(); + assertThat(deletedParticipant.getDeletedAt()).isNotNull(); + } + + @DisplayName("방장이 위임하지 않고 방 나가기 실패") + @Test + void manager_exit_room_fail() throws Exception { + // given + Room room = Room.builder() + .title("7명이 있는 방~") + .roomType(NIGHT) + .certifyTime(21) + .maxUserCount(10) + .build(); + Participant participant = Participant.builder() + .room(room) + .memberId(1L) + .build(); + participant.enableManager(); + + for (int i = 0; i < 6; i++) { + room.increaseCurrentUserCount(); + } + + roomRepository.save(room); + participantRepository.save(participant); + String message = "{\"message\":\"인원수가 2명 이상일때는 방장을 위임해야합니다.\"}"; + + // expected + mockMvc.perform(delete("/rooms/" + room.getId())) + .andExpect(status().isBadRequest()) + .andExpect(content().json(message)) .andDo(print()); } } From 07536483c07255168dfe581bd38fd3010cee9a4b Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Thu, 2 Nov 2023 20:51:41 +0900 Subject: [PATCH 19/27] =?UTF-8?q?feat:=20=EB=B0=A9=20=EB=82=98=EA=B0=80?= =?UTF-8?q?=EA=B8=B0=20=EA=B5=AC=ED=98=84=20=EB=A7=88=EB=AC=B4=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/moabam/api/application/MemberService.java | 12 ++++++++++++ .../java/com/moabam/api/application/RoomService.java | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/moabam/api/application/MemberService.java b/src/main/java/com/moabam/api/application/MemberService.java index 90b0033a..eb093517 100644 --- a/src/main/java/com/moabam/api/application/MemberService.java +++ b/src/main/java/com/moabam/api/application/MemberService.java @@ -50,4 +50,16 @@ public void increaseRoomCount(Long memberId, RoomType roomType) { member.enterNightRoom(); } + + @Transactional + public void decreaseRoomCount(Long memberId, RoomType roomType) { + Member member = getById(memberId); + + if (roomType.equals(MORNING)) { + member.exitMorningRoom(); + return; + } + + member.exitNightRoom(); + } } diff --git a/src/main/java/com/moabam/api/application/RoomService.java b/src/main/java/com/moabam/api/application/RoomService.java index b346e2f7..cab3c32e 100644 --- a/src/main/java/com/moabam/api/application/RoomService.java +++ b/src/main/java/com/moabam/api/application/RoomService.java @@ -90,7 +90,7 @@ public void exitRoom(Long memberId, Long roomId) { throw new BadRequestException(ROOM_EXIT_MANAGER_FAIL); } - // TODO: 사용자의 방 입장 횟수 감소 기능 넣기 + memberService.decreaseRoomCount(memberId, room.getRoomType()); participant.removeRoom(); participantRepository.flush(); participantRepository.delete(participant); From 0db0a20f3610e1b9f511cb4e51f6210d1efd17b9 Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Thu, 2 Nov 2023 20:52:06 +0900 Subject: [PATCH 20/27] =?UTF-8?q?fix:=20Morning=20->=20Night=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/moabam/api/domain/entity/Member.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/moabam/api/domain/entity/Member.java b/src/main/java/com/moabam/api/domain/entity/Member.java index 1ba2db2b..a5c535c3 100644 --- a/src/main/java/com/moabam/api/domain/entity/Member.java +++ b/src/main/java/com/moabam/api/domain/entity/Member.java @@ -103,7 +103,7 @@ public void exitMorningRoom() { } public void exitNightRoom() { - if (currentMorningCount > 0) { + if (currentNightCount > 0) { currentNightCount--; } } From d25695317d8056b4472eda2881b4a4b53cb314ec Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Thu, 2 Nov 2023 20:52:29 +0900 Subject: [PATCH 21/27] =?UTF-8?q?test:=20=EB=B0=A9=20=EB=82=98=EA=B0=80?= =?UTF-8?q?=EA=B8=B0=20=EC=B6=94=EA=B0=80=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/presentation/RoomControllerTest.java | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/test/java/com/moabam/api/presentation/RoomControllerTest.java b/src/test/java/com/moabam/api/presentation/RoomControllerTest.java index 0cc97b00..614f0631 100644 --- a/src/test/java/com/moabam/api/presentation/RoomControllerTest.java +++ b/src/test/java/com/moabam/api/presentation/RoomControllerTest.java @@ -10,6 +10,7 @@ import java.util.ArrayList; import java.util.List; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -68,6 +69,17 @@ void setUp() { memberRepository.save(member); } + @AfterEach + void cleanUp() { + while (member.getCurrentMorningCount() > 0) { + member.exitMorningRoom(); + } + + while (member.getCurrentNightCount() > 0) { + member.exitNightRoom(); + } + } + @DisplayName("비밀번호 없는 방 생성 성공") @Test void create_room_no_password_success() throws Exception { @@ -561,6 +573,7 @@ void no_manager_exit_room_success() throws Exception { mockMvc.perform(delete("/rooms/" + room.getId())) .andExpect(status().isOk()) .andDo(print()); + participantRepository.flush(); Participant deletedParticipant = participantRepository.findById(participant.getId()).orElseThrow(); assertThat(room.getCurrentUserCount()).isEqualTo(4); @@ -625,4 +638,74 @@ void manager_exit_room_fail() throws Exception { .andExpect(content().json(message)) .andDo(print()); } + + @DisplayName("아침 방 나가기 이후 사용자의 방 입장 횟수 감소 테스트") + @Test + void exit_and_decrease_morning_room_count() throws Exception { + // given + Room room = Room.builder() + .title("방 제목") + .password("1234") + .roomType(MORNING) + .certifyTime(9) + .maxUserCount(5) + .build(); + + Participant participant = Participant.builder() + .room(room) + .memberId(1L) + .build(); + + for (int i = 0; i < 3; i++) { + member.enterMorningRoom(); + } + + memberRepository.save(member); + roomRepository.save(room); + participantRepository.save(participant); + + // when + mockMvc.perform(delete("/rooms/" + room.getId())) + .andExpect(status().isOk()); + + Member getMember = memberRepository.findById(1L).orElseThrow(); + + // then + assertThat(getMember.getCurrentMorningCount()).isEqualTo(2); + } + + @DisplayName("저녁 방 나가기 이후 사용자의 방 입장 횟수 감소 테스트") + @Test + void exit_and_decrease_night_room_count() throws Exception { + // given + Room room = Room.builder() + .title("방 제목") + .password("1234") + .roomType(NIGHT) + .certifyTime(23) + .maxUserCount(5) + .build(); + + Participant participant = Participant.builder() + .room(room) + .memberId(1L) + .build(); + + for (int i = 0; i < 3; i++) { + member.enterNightRoom(); + } + + memberRepository.save(member); + roomRepository.save(room); + participantRepository.save(participant); + + // when + mockMvc.perform(delete("/rooms/" + room.getId())) + .andExpect(status().isOk()); + + Member getMember = memberRepository.findById(1L).orElseThrow(); + + // then + assertThat(getMember.getCurrentNightCount()).isEqualTo(2); + } } From 7ce8cccfa3af0f80a916b3303142e71c890d8f53 Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Fri, 3 Nov 2023 14:13:06 +0900 Subject: [PATCH 22/27] =?UTF-8?q?test:=20=EB=B0=A9=20=EB=82=98=EA=B0=80?= =?UTF-8?q?=EA=B8=B0=20=EC=B6=94=EA=B0=80=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/presentation/RoomControllerTest.java | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/test/java/com/moabam/api/presentation/RoomControllerTest.java b/src/test/java/com/moabam/api/presentation/RoomControllerTest.java index 0cc97b00..614f0631 100644 --- a/src/test/java/com/moabam/api/presentation/RoomControllerTest.java +++ b/src/test/java/com/moabam/api/presentation/RoomControllerTest.java @@ -10,6 +10,7 @@ import java.util.ArrayList; import java.util.List; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -68,6 +69,17 @@ void setUp() { memberRepository.save(member); } + @AfterEach + void cleanUp() { + while (member.getCurrentMorningCount() > 0) { + member.exitMorningRoom(); + } + + while (member.getCurrentNightCount() > 0) { + member.exitNightRoom(); + } + } + @DisplayName("비밀번호 없는 방 생성 성공") @Test void create_room_no_password_success() throws Exception { @@ -561,6 +573,7 @@ void no_manager_exit_room_success() throws Exception { mockMvc.perform(delete("/rooms/" + room.getId())) .andExpect(status().isOk()) .andDo(print()); + participantRepository.flush(); Participant deletedParticipant = participantRepository.findById(participant.getId()).orElseThrow(); assertThat(room.getCurrentUserCount()).isEqualTo(4); @@ -625,4 +638,74 @@ void manager_exit_room_fail() throws Exception { .andExpect(content().json(message)) .andDo(print()); } + + @DisplayName("아침 방 나가기 이후 사용자의 방 입장 횟수 감소 테스트") + @Test + void exit_and_decrease_morning_room_count() throws Exception { + // given + Room room = Room.builder() + .title("방 제목") + .password("1234") + .roomType(MORNING) + .certifyTime(9) + .maxUserCount(5) + .build(); + + Participant participant = Participant.builder() + .room(room) + .memberId(1L) + .build(); + + for (int i = 0; i < 3; i++) { + member.enterMorningRoom(); + } + + memberRepository.save(member); + roomRepository.save(room); + participantRepository.save(participant); + + // when + mockMvc.perform(delete("/rooms/" + room.getId())) + .andExpect(status().isOk()); + + Member getMember = memberRepository.findById(1L).orElseThrow(); + + // then + assertThat(getMember.getCurrentMorningCount()).isEqualTo(2); + } + + @DisplayName("저녁 방 나가기 이후 사용자의 방 입장 횟수 감소 테스트") + @Test + void exit_and_decrease_night_room_count() throws Exception { + // given + Room room = Room.builder() + .title("방 제목") + .password("1234") + .roomType(NIGHT) + .certifyTime(23) + .maxUserCount(5) + .build(); + + Participant participant = Participant.builder() + .room(room) + .memberId(1L) + .build(); + + for (int i = 0; i < 3; i++) { + member.enterNightRoom(); + } + + memberRepository.save(member); + roomRepository.save(room); + participantRepository.save(participant); + + // when + mockMvc.perform(delete("/rooms/" + room.getId())) + .andExpect(status().isOk()); + + Member getMember = memberRepository.findById(1L).orElseThrow(); + + // then + assertThat(getMember.getCurrentNightCount()).isEqualTo(2); + } } From b40b60163fb4c304f99e7001a144a8aa2e517a5a Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Fri, 3 Nov 2023 15:02:14 +0900 Subject: [PATCH 23/27] =?UTF-8?q?feat:=20=EB=B0=A9=20ID=EB=A1=9C=20?= =?UTF-8?q?=EC=A1=B4=EC=9E=AC=20=ED=99=95=EC=9D=B8=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/moabam/api/application/RoomService.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/moabam/api/application/RoomService.java b/src/main/java/com/moabam/api/application/RoomService.java index cab3c32e..69e21a75 100644 --- a/src/main/java/com/moabam/api/application/RoomService.java +++ b/src/main/java/com/moabam/api/application/RoomService.java @@ -104,6 +104,12 @@ public void exitRoom(Long memberId, Long roomId) { roomRepository.delete(room); } + public void validateRoomById(Long roomId) { + if (!roomRepository.existsById(roomId)) { + throw new NotFoundException(ROOM_NOT_FOUND); + } + } + private Participant getParticipant(Long memberId, Long roomId) { return participantSearchRepository.findParticipant(memberId, roomId) .orElseThrow(() -> new NotFoundException(PARTICIPANT_NOT_FOUND)); From 3c280c9a3e3a5cf53751cc77781dfc844ffcf36c Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Fri, 3 Nov 2023 16:03:11 +0900 Subject: [PATCH 24/27] =?UTF-8?q?refactor:=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/moabam/global/error/model/ErrorMessage.java | 4 ++-- .../java/com/moabam/api/presentation/RoomControllerTest.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/moabam/global/error/model/ErrorMessage.java b/src/main/java/com/moabam/global/error/model/ErrorMessage.java index 877e9a09..ee69ccb7 100644 --- a/src/main/java/com/moabam/global/error/model/ErrorMessage.java +++ b/src/main/java/com/moabam/global/error/model/ErrorMessage.java @@ -12,7 +12,7 @@ public enum ErrorMessage { ROOM_NOT_FOUND("존재하지 않는 방 입니다."), ROOM_MAX_USER_COUNT_MODIFY_FAIL("잘못된 최대 인원수 설정입니다."), ROOM_MODIFY_UNAUTHORIZED_REQUEST("방장이 아닌 사용자는 방을 수정할 수 없습니다."), - ROOM_EXIT_MANAGER_FAIL("인원수가 2명 이상일때는 방장을 위임해야합니다."), + ROOM_EXIT_MANAGER_FAIL("인원수가 2명 이상일 때는 방장을 위임해야 합니다."), PARTICIPANT_NOT_FOUND("방에 대한 참여자의 정보가 없습니다."), WRONG_ROOM_PASSWORD("방의 비밀번호가 일치하지 않습니다."), ROOM_MAX_USER_REACHED("방의 인원수가 찼습니다."), @@ -21,7 +21,7 @@ public enum ErrorMessage { REQUEST_FAILED("네트워크 접근 실패입니다."), GRANT_FAILED("인가 코드 실패"), MEMBER_NOT_FOUND("존재하지 않는 회원입니다."), - MEMBER_ROOM_EXCEED("참여할 수 있는 방의 갯수가 모두 찼습니다."), + MEMBER_ROOM_EXCEED("참여할 수 있는 방의 개수가 모두 찼습니다."), INVALID_BUG_COUNT("벌레 개수는 0 이상이어야 합니다."), INVALID_PRICE("가격은 0 이상이어야 합니다."), diff --git a/src/test/java/com/moabam/api/presentation/RoomControllerTest.java b/src/test/java/com/moabam/api/presentation/RoomControllerTest.java index 614f0631..36bce475 100644 --- a/src/test/java/com/moabam/api/presentation/RoomControllerTest.java +++ b/src/test/java/com/moabam/api/presentation/RoomControllerTest.java @@ -630,7 +630,7 @@ void manager_exit_room_fail() throws Exception { roomRepository.save(room); participantRepository.save(participant); - String message = "{\"message\":\"인원수가 2명 이상일때는 방장을 위임해야합니다.\"}"; + String message = "{\"message\":\"인원수가 2명 이상일 때는 방장을 위임해야 합니다.\"}"; // expected mockMvc.perform(delete("/rooms/" + room.getId())) From 28288e9e2acb6eea0dfe2e2ed42b7fa4f135d6bf Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Fri, 3 Nov 2023 16:16:28 +0900 Subject: [PATCH 25/27] =?UTF-8?q?fix:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=8B=A4=ED=96=89=20=EB=B6=88=EA=B0=80=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/presentation/BugControllerTest.java | 2 -- .../presentation/MemberControllerTest.java | 19 +++++-------------- .../presentation/ProductControllerTest.java | 2 -- .../{application-test.yml => application.yml} | 15 ++++++--------- 4 files changed, 11 insertions(+), 27 deletions(-) rename src/test/resources/{application-test.yml => application.yml} (96%) diff --git a/src/test/java/com/moabam/api/presentation/BugControllerTest.java b/src/test/java/com/moabam/api/presentation/BugControllerTest.java index 28881031..4bfedb04 100644 --- a/src/test/java/com/moabam/api/presentation/BugControllerTest.java +++ b/src/test/java/com/moabam/api/presentation/BugControllerTest.java @@ -13,7 +13,6 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; import com.fasterxml.jackson.databind.ObjectMapper; @@ -24,7 +23,6 @@ @SpringBootTest @AutoConfigureMockMvc -@ActiveProfiles("test") class BugControllerTest { @Autowired diff --git a/src/test/java/com/moabam/api/presentation/MemberControllerTest.java b/src/test/java/com/moabam/api/presentation/MemberControllerTest.java index 39742fae..11f5de43 100644 --- a/src/test/java/com/moabam/api/presentation/MemberControllerTest.java +++ b/src/test/java/com/moabam/api/presentation/MemberControllerTest.java @@ -1,18 +1,11 @@ package com.moabam.api.presentation; -import static com.moabam.global.common.util.OAuthParameterNames.CLIENT_ID; -import static com.moabam.global.common.util.OAuthParameterNames.CLIENT_SECRET; -import static com.moabam.global.common.util.OAuthParameterNames.CODE; -import static com.moabam.global.common.util.OAuthParameterNames.GRANT_TYPE; -import static com.moabam.global.common.util.OAuthParameterNames.REDIRECT_URI; -import static com.moabam.global.common.util.OAuthParameterNames.RESPONSE_TYPE; -import static com.moabam.global.common.util.OAuthParameterNames.SCOPE; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static com.moabam.global.common.util.OAuthParameterNames.*; +import static org.springframework.test.web.client.match.MockRestRequestMatchers.*; +import static org.springframework.test.web.client.response.MockRestResponseCreators.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -23,7 +16,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.test.context.ActiveProfiles; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.test.web.client.match.MockRestRequestMatchers; @@ -44,7 +36,6 @@ @SpringBootTest @AutoConfigureMockMvc -@ActiveProfiles("test") class MemberControllerTest { @Autowired diff --git a/src/test/java/com/moabam/api/presentation/ProductControllerTest.java b/src/test/java/com/moabam/api/presentation/ProductControllerTest.java index 338ed65b..f18b3236 100644 --- a/src/test/java/com/moabam/api/presentation/ProductControllerTest.java +++ b/src/test/java/com/moabam/api/presentation/ProductControllerTest.java @@ -15,7 +15,6 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; import com.fasterxml.jackson.databind.ObjectMapper; @@ -27,7 +26,6 @@ @SpringBootTest @AutoConfigureMockMvc -@ActiveProfiles("test") class ProductControllerTest { @Autowired diff --git a/src/test/resources/application-test.yml b/src/test/resources/application.yml similarity index 96% rename from src/test/resources/application-test.yml rename to src/test/resources/application.yml index 5f6f4016..a116451d 100644 --- a/src/test/resources/application-test.yml +++ b/src/test/resources/application.yml @@ -8,6 +8,12 @@ spring: hibernate: format_sql: true + # Redis + data: + redis: + host: 127.0.0.1 + port: 6379 + oauth2: client: provider: test @@ -22,12 +28,3 @@ oauth2: authorization_uri: https://authorization.com/test/test redirect_uri: http://redirect:8080/test token_uri: https://token.com/test/test - -# Spring -spring: - - # Redis - data: - redis: - host: 127.0.0.1 - port: 6379 From a27c9eba9a5b364c352c0dbc50901482db54b315 Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Fri, 3 Nov 2023 16:28:55 +0900 Subject: [PATCH 26/27] =?UTF-8?q?fix:=20CI=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/moabam/api/presentation/MemberControllerTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/com/moabam/api/presentation/MemberControllerTest.java b/src/test/java/com/moabam/api/presentation/MemberControllerTest.java index 11f5de43..114d5ba8 100644 --- a/src/test/java/com/moabam/api/presentation/MemberControllerTest.java +++ b/src/test/java/com/moabam/api/presentation/MemberControllerTest.java @@ -4,7 +4,6 @@ import static org.springframework.test.web.client.match.MockRestRequestMatchers.*; import static org.springframework.test.web.client.response.MockRestResponseCreators.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import org.junit.jupiter.api.BeforeAll; From 92c512d57e578cd0937c7734e2cf07ca22dcb289 Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Fri, 3 Nov 2023 16:37:06 +0900 Subject: [PATCH 27/27] =?UTF-8?q?refactor:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moabam/api/application/MemberService.java | 40 ----------------- .../moabam/api/application/RoomService.java | 45 +++++++++++++++++-- 2 files changed, 42 insertions(+), 43 deletions(-) diff --git a/src/main/java/com/moabam/api/application/MemberService.java b/src/main/java/com/moabam/api/application/MemberService.java index eb093517..112fcd7e 100644 --- a/src/main/java/com/moabam/api/application/MemberService.java +++ b/src/main/java/com/moabam/api/application/MemberService.java @@ -1,13 +1,11 @@ package com.moabam.api.application; -import static com.moabam.api.domain.entity.enums.RoomType.*; import static com.moabam.global.error.model.ErrorMessage.*; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.moabam.api.domain.entity.Member; -import com.moabam.api.domain.entity.enums.RoomType; import com.moabam.api.domain.repository.MemberRepository; import com.moabam.global.error.exception.NotFoundException; @@ -24,42 +22,4 @@ public Member getById(Long memberId) { return memberRepository.findById(memberId) .orElseThrow(() -> new NotFoundException(MEMBER_NOT_FOUND)); } - - public boolean isEnterRoomAvailable(Long memberId, RoomType roomType) { - Member member = getById(memberId); - - if (roomType.equals(MORNING) && member.getCurrentMorningCount() >= 3) { - return false; - } - - if (roomType.equals(NIGHT) && member.getCurrentNightCount() >= 3) { - return false; - } - - return true; - } - - @Transactional - public void increaseRoomCount(Long memberId, RoomType roomType) { - Member member = getById(memberId); - - if (roomType.equals(MORNING)) { - member.enterMorningRoom(); - return; - } - - member.enterNightRoom(); - } - - @Transactional - public void decreaseRoomCount(Long memberId, RoomType roomType) { - Member member = getById(memberId); - - if (roomType.equals(MORNING)) { - member.exitMorningRoom(); - return; - } - - member.exitNightRoom(); - } } diff --git a/src/main/java/com/moabam/api/application/RoomService.java b/src/main/java/com/moabam/api/application/RoomService.java index 69e21a75..5480ef16 100644 --- a/src/main/java/com/moabam/api/application/RoomService.java +++ b/src/main/java/com/moabam/api/application/RoomService.java @@ -1,5 +1,6 @@ package com.moabam.api.application; +import static com.moabam.api.domain.entity.enums.RoomType.*; import static com.moabam.global.error.model.ErrorMessage.*; import java.util.List; @@ -8,9 +9,11 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.moabam.api.domain.entity.Member; import com.moabam.api.domain.entity.Participant; import com.moabam.api.domain.entity.Room; import com.moabam.api.domain.entity.Routine; +import com.moabam.api.domain.entity.enums.RoomType; import com.moabam.api.domain.repository.ParticipantRepository; import com.moabam.api.domain.repository.ParticipantSearchRepository; import com.moabam.api.domain.repository.RoomRepository; @@ -72,7 +75,7 @@ public void enterRoom(Long memberId, Long roomId, EnterRoomRequest enterRoomRequ validateRoomEnter(memberId, enterRoomRequest.password(), room); room.increaseCurrentUserCount(); - memberService.increaseRoomCount(memberId, room.getRoomType()); + increaseRoomCount(memberId, room.getRoomType()); Participant participant = Participant.builder() .room(room) @@ -90,7 +93,7 @@ public void exitRoom(Long memberId, Long roomId) { throw new BadRequestException(ROOM_EXIT_MANAGER_FAIL); } - memberService.decreaseRoomCount(memberId, room.getRoomType()); + decreaseRoomCount(memberId, room.getRoomType()); participant.removeRoom(); participantRepository.flush(); participantRepository.delete(participant); @@ -120,7 +123,7 @@ private Room getRoom(Long roomId) { } private void validateRoomEnter(Long memberId, String requestPassword, Room room) { - if (!memberService.isEnterRoomAvailable(memberId, room.getRoomType())) { + if (!isEnterRoomAvailable(memberId, room.getRoomType())) { throw new BadRequestException(MEMBER_ROOM_EXCEED); } @@ -132,4 +135,40 @@ private void validateRoomEnter(Long memberId, String requestPassword, Room room) throw new BadRequestException(ROOM_MAX_USER_REACHED); } } + + private boolean isEnterRoomAvailable(Long memberId, RoomType roomType) { + Member member = memberService.getById(memberId); + + if (roomType.equals(MORNING) && member.getCurrentMorningCount() >= 3) { + return false; + } + + if (roomType.equals(NIGHT) && member.getCurrentNightCount() >= 3) { + return false; + } + + return true; + } + + private void increaseRoomCount(Long memberId, RoomType roomType) { + Member member = memberService.getById(memberId); + + if (roomType.equals(MORNING)) { + member.enterMorningRoom(); + return; + } + + member.enterNightRoom(); + } + + private void decreaseRoomCount(Long memberId, RoomType roomType) { + Member member = memberService.getById(memberId); + + if (roomType.equals(MORNING)) { + member.exitMorningRoom(); + return; + } + + member.exitNightRoom(); + } }