From 3f6cb972455e2ba819c642a19f50855288e07836 Mon Sep 17 00:00:00 2001 From: ddingmin Date: Thu, 28 Dec 2023 12:38:15 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20=EB=AF=B8=ED=8C=85=20=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=EC=9D=84=20=EA=B5=AC=ED=98=84=ED=95=9C?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../net/teumteum/meeting/domain/Meeting.java | 50 +++++++++++++++++++ .../teumteum/meeting/domain/MeetingArea.java | 24 +++++++++ .../meeting/domain/PromiseDateTime.java | 23 +++++++++ .../net/teumteum/meeting/domain/Topic.java | 10 ++++ .../db/migration/V2__create_meeting.sql | 32 ++++++++++++ 5 files changed, 139 insertions(+) create mode 100644 src/main/java/net/teumteum/meeting/domain/Meeting.java create mode 100644 src/main/java/net/teumteum/meeting/domain/MeetingArea.java create mode 100644 src/main/java/net/teumteum/meeting/domain/PromiseDateTime.java create mode 100644 src/main/java/net/teumteum/meeting/domain/Topic.java create mode 100644 src/main/resources/db/migration/V2__create_meeting.sql diff --git a/src/main/java/net/teumteum/meeting/domain/Meeting.java b/src/main/java/net/teumteum/meeting/domain/Meeting.java new file mode 100644 index 00000000..301a8b96 --- /dev/null +++ b/src/main/java/net/teumteum/meeting/domain/Meeting.java @@ -0,0 +1,50 @@ +package net.teumteum.meeting.domain; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import net.teumteum.core.entity.TimeBaseEntity; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class Meeting extends TimeBaseEntity { + + @Id + @Column(name = "id") + private Long id; + + @Column(name = "title", length = 32) + private String title; + + @Column(name = "host_user_id") + private Long hostUserId; + + @ElementCollection + private List participantUserIds = new ArrayList<>(); + + @Column(name = "topic") + @Enumerated(EnumType.STRING) + private Topic topic; + + @Column(name = "introduction", length = 200) + private String introduction; + + @Embedded + private MeetingArea meetingArea; + + @Column(name = "number_of_recruits") + private int numberOfRecruits; + + @Embedded + private PromiseDateTime promiseDateTime; + + @ElementCollection + private List imageUrls = new ArrayList<>(); + +} diff --git a/src/main/java/net/teumteum/meeting/domain/MeetingArea.java b/src/main/java/net/teumteum/meeting/domain/MeetingArea.java new file mode 100644 index 00000000..a9e5aafb --- /dev/null +++ b/src/main/java/net/teumteum/meeting/domain/MeetingArea.java @@ -0,0 +1,24 @@ +package net.teumteum.meeting.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@NoArgsConstructor +@AllArgsConstructor +public class MeetingArea { + + @Column(name = "city") + private String city; + + @Column(name = "street") + private String street; + + @Column(name = "zip_code") + private String zipCode; + +} diff --git a/src/main/java/net/teumteum/meeting/domain/PromiseDateTime.java b/src/main/java/net/teumteum/meeting/domain/PromiseDateTime.java new file mode 100644 index 00000000..f9514ff7 --- /dev/null +++ b/src/main/java/net/teumteum/meeting/domain/PromiseDateTime.java @@ -0,0 +1,23 @@ +package net.teumteum.meeting.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.time.LocalTime; + +@Getter +@Embeddable +@NoArgsConstructor +@AllArgsConstructor +public class PromiseDateTime { + + @Column(name = "promise_date") + private LocalDate date; + + @Column(name = "promise_time") + private LocalTime time; +} diff --git a/src/main/java/net/teumteum/meeting/domain/Topic.java b/src/main/java/net/teumteum/meeting/domain/Topic.java new file mode 100644 index 00000000..7da1d268 --- /dev/null +++ b/src/main/java/net/teumteum/meeting/domain/Topic.java @@ -0,0 +1,10 @@ +package net.teumteum.meeting.domain; + +public enum Topic { + + 고민_나누기, + 모여서_작업, + 스터디, + 사이드_프로젝트, + +} diff --git a/src/main/resources/db/migration/V2__create_meeting.sql b/src/main/resources/db/migration/V2__create_meeting.sql new file mode 100644 index 00000000..2464dc30 --- /dev/null +++ b/src/main/resources/db/migration/V2__create_meeting.sql @@ -0,0 +1,32 @@ +create table if not exists meeting +( + id bigint not null + primary key, + number_of_recruits int null, + promise_date date null, + promise_time time(6) null, + created_at timestamp(6) not null, + host_user_id bigint null, + updated_at timestamp(6) not null, + title varchar(32) null, + introduction varchar(200) null, + city varchar(255) null, + street varchar(255) null, + zip_code varchar(255) null, + topic enum ('고민_나누기', '모여서_작업', '스터디', '사이드_프로젝트') null + ); + +create table if not exists meeting_image_urls +( + meeting_id bigint not null, + image_urls varchar(255) null, + foreign key (meeting_id) references meeting (id) + ); + +create table if not exists meeting_participant_user_ids +( + meeting_id bigint not null, + participant_user_ids bigint null, + foreign key (meeting_id) references meeting (id) + ); + From 85360b65fd38695817a89c4c31e6be4531982bd8 Mon Sep 17 00:00:00 2001 From: ddingmin Date: Thu, 28 Dec 2023 12:38:35 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20MeetingRepository=EB=A5=BC=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../net/teumteum/meeting/domain/MeetingRepository.java | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/main/java/net/teumteum/meeting/domain/MeetingRepository.java diff --git a/src/main/java/net/teumteum/meeting/domain/MeetingRepository.java b/src/main/java/net/teumteum/meeting/domain/MeetingRepository.java new file mode 100644 index 00000000..d573f995 --- /dev/null +++ b/src/main/java/net/teumteum/meeting/domain/MeetingRepository.java @@ -0,0 +1,8 @@ +package net.teumteum.meeting.domain; + +import org.springframework.data.jpa.repository.JpaRepository; + + +public interface MeetingRepository extends JpaRepository { + +} From 53e81b500217eb404f6bfdf52652cbd0a5fab105 Mon Sep 17 00:00:00 2001 From: ddingmin Date: Thu, 28 Dec 2023 23:48:28 +0900 Subject: [PATCH 3/7] =?UTF-8?q?chore:=20auto=5Fincrement=20id=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=A0=84=EB=9E=B5=EC=9D=84=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../db/migration/V1__create_users.sql | 2 +- .../db/migration/V2__create_meeting.sql | 2 +- src/test/resources/schema.sql | 35 ++++++++++++++++++- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/main/resources/db/migration/V1__create_users.sql b/src/main/resources/db/migration/V1__create_users.sql index cbe3bac1..08626b0e 100644 --- a/src/main/resources/db/migration/V1__create_users.sql +++ b/src/main/resources/db/migration/V1__create_users.sql @@ -1,9 +1,9 @@ create table if not exists users( + id bigint not null auto_increment, certificated boolean, manner_temperature integer, mbti varchar(4), character_id bigint, - id bigint not null, birth varchar(10), name varchar(10), goal varchar(50), diff --git a/src/main/resources/db/migration/V2__create_meeting.sql b/src/main/resources/db/migration/V2__create_meeting.sql index 2464dc30..ddda2cc3 100644 --- a/src/main/resources/db/migration/V2__create_meeting.sql +++ b/src/main/resources/db/migration/V2__create_meeting.sql @@ -1,7 +1,7 @@ create table if not exists meeting ( id bigint not null - primary key, + primary key auto_increment, number_of_recruits int null, promise_date date null, promise_time time(6) null, diff --git a/src/test/resources/schema.sql b/src/test/resources/schema.sql index cbe3bac1..3d90dd9f 100644 --- a/src/test/resources/schema.sql +++ b/src/test/resources/schema.sql @@ -1,9 +1,9 @@ create table if not exists users( + id bigint not null auto_increment, certificated boolean, manner_temperature integer, mbti varchar(4), character_id bigint, - id bigint not null, birth varchar(10), name varchar(10), goal varchar(50), @@ -32,3 +32,36 @@ create table if not exists users_street( street varchar(255), foreign key (users_id) references users(id) ); + +create table if not exists meeting +( + id bigint not null + primary key auto_increment, + number_of_recruits int null, + promise_date date null, + promise_time time(6) null, + created_at timestamp(6) not null, + host_user_id bigint null, + updated_at timestamp(6) not null, + title varchar(32) null, + introduction varchar(200) null, + city varchar(255) null, + street varchar(255) null, + zip_code varchar(255) null, + topic enum ('고민_나누기', '모여서_작업', '스터디', '사이드_프로젝트') null +); + +create table if not exists meeting_image_urls +( + meeting_id bigint not null, + image_urls varchar(255) null, + foreign key (meeting_id) references meeting (id) +); + +create table if not exists meeting_participant_user_ids +( + meeting_id bigint not null, + participant_user_ids bigint null, + foreign key (meeting_id) references meeting (id) +); + From 8656509dcb8064639352b01150c029f8df1a236d Mon Sep 17 00:00:00 2001 From: ddingmin Date: Thu, 28 Dec 2023 23:49:10 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20meeting=EC=9D=98=20Id=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=A0=84=EB=9E=B5=EC=9D=84=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/net/teumteum/meeting/domain/Meeting.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/teumteum/meeting/domain/Meeting.java b/src/main/java/net/teumteum/meeting/domain/Meeting.java index 301a8b96..71ae0252 100644 --- a/src/main/java/net/teumteum/meeting/domain/Meeting.java +++ b/src/main/java/net/teumteum/meeting/domain/Meeting.java @@ -15,7 +15,7 @@ @AllArgsConstructor public class Meeting extends TimeBaseEntity { - @Id + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; From effe33975dd7056eedd6e9a70a38c6dc15bf53bb Mon Sep 17 00:00:00 2001 From: ddingmin Date: Fri, 29 Dec 2023 03:21:14 +0900 Subject: [PATCH 5/7] =?UTF-8?q?feat:=20meeting=EC=9D=98=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EB=A1=9C=EC=A7=81=EB=93=A4=EC=9D=84=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 모임 소개는 10~200자 사이여야 한다. 2. 참여자 수는 2~6명 사이여야 한다. 3. 모임의 제목은 2~32자 사이여야 한다. --- .../net/teumteum/meeting/domain/Meeting.java | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/teumteum/meeting/domain/Meeting.java b/src/main/java/net/teumteum/meeting/domain/Meeting.java index 71ae0252..78fc4582 100644 --- a/src/main/java/net/teumteum/meeting/domain/Meeting.java +++ b/src/main/java/net/teumteum/meeting/domain/Meeting.java @@ -5,6 +5,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import net.teumteum.core.entity.TimeBaseEntity; +import org.springframework.util.Assert; import java.util.ArrayList; import java.util.List; @@ -15,7 +16,8 @@ @AllArgsConstructor public class Meeting extends TimeBaseEntity { - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; @@ -47,4 +49,23 @@ public class Meeting extends TimeBaseEntity { @ElementCollection private List imageUrls = new ArrayList<>(); + @PrePersist + private void assertField() { + assertTitle(); + assertNumberOfRecruits(); + assertIntroduction(); + } + + private void assertIntroduction() { + Assert.isTrue(introduction.length() >= 10 && introduction.length() <= 200, "모임 소개는 10자 ~ 200자 사이가 되어야 합니다. [현재 입력된 모임 소개] : " + introduction); + } + + private void assertNumberOfRecruits() { + Assert.isTrue(numberOfRecruits >= 2 && numberOfRecruits <= 6, "참여자 수는 2명 ~ 6명 사이가 되어야 합니다. [현재 입력된 참여자 수] : " + numberOfRecruits); + } + + private void assertTitle() { + Assert.isTrue(title.length() >= 2 && title.length() <= 32, "모임 제목은 2자 ~ 32자 사이가 되어야 합니다. [현재 입력된 모임 제목] : " + title); + } + } From de343ad85cb73f56cc5298f7dee31f2032e23669 Mon Sep 17 00:00:00 2001 From: ddingmin Date: Fri, 29 Dec 2023 03:21:53 +0900 Subject: [PATCH 6/7] =?UTF-8?q?chore:=20Test=20H2=20DB=EC=9D=98=20?= =?UTF-8?q?=EB=B0=A9=EC=96=B8=EC=9D=84=20=EB=B3=80=EA=B2=BD=ED=95=9C?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 1833301b..db08cf4e 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -2,7 +2,7 @@ spring.datasource.driver-class-name = org.h2.Driver spring.datasource.url = jdbc:h2:mem:test;MODE=MySQL;DATABASE_TO_LOWER=TRUE spring.jpa.hibernated.ddl-auto = validate -spring.jpa.database-platform = org.hibernate.dialect.H2Dialect +spring.jpa.database-platform = org.hibernate.dialect.MySQLDialect spring.datasource.hikari.maximum-pool-size = 4 spring.datasource.hikari.pool-name = H2_TEST_POOL From ec2dcde61df3e0662740104d7a384cfdf84771e3 Mon Sep 17 00:00:00 2001 From: ddingmin Date: Fri, 29 Dec 2023 03:23:54 +0900 Subject: [PATCH 7/7] =?UTF-8?q?test:=20MeetingFixture=EB=A5=BC=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=ED=95=98=EA=B3=A0,=20MeetingRepository=EB=A5=BC=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../meeting/domain/MeetingFixture.java | 70 +++++++++++++++++++ .../meeting/domain/MeetingRepositoryTest.java | 67 ++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 src/test/java/net/teumteum/meeting/domain/MeetingFixture.java create mode 100644 src/test/java/net/teumteum/meeting/domain/MeetingRepositoryTest.java diff --git a/src/test/java/net/teumteum/meeting/domain/MeetingFixture.java b/src/test/java/net/teumteum/meeting/domain/MeetingFixture.java new file mode 100644 index 00000000..8526c225 --- /dev/null +++ b/src/test/java/net/teumteum/meeting/domain/MeetingFixture.java @@ -0,0 +1,70 @@ +package net.teumteum.meeting.domain; + +import lombok.Builder; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.ArrayList; +import java.util.List; + +public class MeetingFixture { + + public static Meeting getMeetingWithId(Long id) { + return newMeetingByBuilder(MeetingBuilder.builder() + .id(id) + .build()); + } + + public static Meeting getDefaultMeeting() { + return newMeetingByBuilder(MeetingBuilder.builder().build()); + } + + public static Meeting newMeetingByBuilder(MeetingBuilder meetingBuilder) { + return new Meeting( + meetingBuilder.id, + meetingBuilder.title, + meetingBuilder.hostUserId, + meetingBuilder.participantUserIds, + meetingBuilder.topic, + meetingBuilder.introduction, + meetingBuilder.meetingArea, + meetingBuilder.numberOfRecruits, + meetingBuilder.promiseDateTime, + meetingBuilder.imageUrls + ); + } + + @Builder + public static class MeetingBuilder { + @Builder.Default + private Long id = 0L; + + @Builder.Default + private String title = "모임 제목"; + + @Builder.Default + private Long hostUserId = 0L; + + @Builder.Default + private List participantUserIds = new ArrayList<>(List.of(0L)); + + @Builder.Default + private Topic topic = Topic.스터디; + + @Builder.Default + private String introduction = "모임에 대한 간단한 설명입니다."; + + @Builder.Default + private MeetingArea meetingArea = new MeetingArea("서울특별시", "강남구", "강남대로 390"); + + @Builder.Default + private int numberOfRecruits = 3; + + @Builder.Default + private PromiseDateTime promiseDateTime = new PromiseDateTime(LocalDate.of(2023, 1, 1), LocalTime.of(12, 0)); + + @Builder.Default + private List imageUrls = new ArrayList<>(List.of("https://www.google.com")); + } + +} diff --git a/src/test/java/net/teumteum/meeting/domain/MeetingRepositoryTest.java b/src/test/java/net/teumteum/meeting/domain/MeetingRepositoryTest.java new file mode 100644 index 00000000..0e3e8096 --- /dev/null +++ b/src/test/java/net/teumteum/meeting/domain/MeetingRepositoryTest.java @@ -0,0 +1,67 @@ +package net.teumteum.meeting.domain; + +import jakarta.persistence.EntityManager; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +import java.util.Optional; + +@DataJpaTest +@DisplayName("MeetingRepository 클래스의") +class MeetingRepositoryTest { + + @Autowired + private MeetingRepository meetingRepository; + + @Autowired + private EntityManager entityManager; + + @Nested + @DisplayName("save 메소드는") + class Save_method { + + @Test + @DisplayName("올바른 MeetingEntity가 들어오면, 모임 저장에 성공한다.") + void Save_success_if_correct_meeting_entered() { + // given + var newMeeting = MeetingFixture.getDefaultMeeting(); + + // when + var result = Assertions.catchException(() -> meetingRepository.saveAndFlush(newMeeting)); + + // then + Assertions.assertThat(result).isNull(); + } + } + + @Nested + @DisplayName("findById 메소드는") + class FindById_method { + + @Test + @DisplayName("저장된 모임의 id로 조회하면, 모임을 반환한다.") + void Find_success_if_exists_meeting_id_input() { + // given + var id = 1L; + var existsMeeting = MeetingFixture.getMeetingWithId(id); + + meetingRepository.saveAndFlush(existsMeeting); + entityManager.clear(); + + // when + var result = meetingRepository.findById(id); + + // then + Assertions.assertThat(result) + .isPresent() + .usingRecursiveComparison() + .ignoringFields("value.createdAt", "value.updatedAt") + .isEqualTo(Optional.of(existsMeeting)); + } + } + +}