From 2789bb9ca4304d9f91b1954977b7d297b946840e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Fri, 20 Oct 2023 20:11:50 +0900 Subject: [PATCH 001/311] =?UTF-8?q?chore:=20.gitignore=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 --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c2065bc2..55608a8e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ build/ !gradle/wrapper/gradle-wrapper.jar !**/src/main/**/build/ !**/src/test/**/build/ +.env ### STS ### .apt_generated From c6baf5a74b818116793c9ae9d9f9cb41a5546f38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Fri, 20 Oct 2023 20:14:48 +0900 Subject: [PATCH 002/311] =?UTF-8?q?feat:=20BaseEntity=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/entity/AdvancedBaseEntity.java | 23 +++++++++++++++++++ .../server/common/entity/BaseEntity.java | 23 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/entity/AdvancedBaseEntity.java create mode 100644 src/main/java/coffeemeet/server/common/entity/BaseEntity.java diff --git a/src/main/java/coffeemeet/server/common/entity/AdvancedBaseEntity.java b/src/main/java/coffeemeet/server/common/entity/AdvancedBaseEntity.java new file mode 100644 index 00000000..c53a48d9 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/entity/AdvancedBaseEntity.java @@ -0,0 +1,23 @@ +package coffeemeet.server.common.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.MappedSuperclass; +import java.time.LocalDateTime; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +@Getter +@MappedSuperclass +@EntityListeners(AuditingEntityListener.class) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public abstract class AdvancedBaseEntity extends BaseEntity { + + @LastModifiedDate + @Column(columnDefinition = "TIMESTAMP(6)") + private LocalDateTime updatedAt; + +} diff --git a/src/main/java/coffeemeet/server/common/entity/BaseEntity.java b/src/main/java/coffeemeet/server/common/entity/BaseEntity.java new file mode 100644 index 00000000..2be962aa --- /dev/null +++ b/src/main/java/coffeemeet/server/common/entity/BaseEntity.java @@ -0,0 +1,23 @@ +package coffeemeet.server.common.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.MappedSuperclass; +import java.time.LocalDateTime; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +@Getter +@MappedSuperclass +@EntityListeners(AuditingEntityListener.class) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public abstract class BaseEntity { + + @CreatedDate + @Column(columnDefinition = "TIMESTAMP(6)", updatable = false) + private LocalDateTime createdAt; + +} From 2cdc9ffc8719eefbc74cde2fd6923def70ab6862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 21 Oct 2023 11:19:40 +0900 Subject: [PATCH 003/311] =?UTF-8?q?feat:=20UserChattingHistory=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/UserChattingHistory.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/main/java/coffeemeet/server/user_chatting_history/domain/UserChattingHistory.java diff --git a/src/main/java/coffeemeet/server/user_chatting_history/domain/UserChattingHistory.java b/src/main/java/coffeemeet/server/user_chatting_history/domain/UserChattingHistory.java new file mode 100644 index 00000000..c968c9c0 --- /dev/null +++ b/src/main/java/coffeemeet/server/user_chatting_history/domain/UserChattingHistory.java @@ -0,0 +1,38 @@ +package coffeemeet.server.user_chatting_history.domain; + +import coffeemeet.server.chatting_room_history.domain.ChattingRoomHistory; +import coffeemeet.server.common.entity.BaseEntity; +import coffeemeet.server.user.domain.User; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Table(name = "user_chatting_histories") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class UserChattingHistory extends BaseEntity { + + @Id + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "users_id", nullable = false) + private User user; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "chatting_room_history_id", nullable = false) + private ChattingRoomHistory chattingRoomHistory; + + public UserChattingHistory(User user, ChattingRoomHistory chattingRoomHistory) { + this.user = user; + this.chattingRoomHistory = chattingRoomHistory; + } + +} From e58af868c69bcf3fabbb32fa2b4786440f7cd21d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 21 Oct 2023 11:20:08 +0900 Subject: [PATCH 004/311] =?UTF-8?q?feat:=20Inquiry=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/inquiry/domain/Inquiry.java | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/main/java/coffeemeet/server/inquiry/domain/Inquiry.java diff --git a/src/main/java/coffeemeet/server/inquiry/domain/Inquiry.java b/src/main/java/coffeemeet/server/inquiry/domain/Inquiry.java new file mode 100644 index 00000000..37ad009a --- /dev/null +++ b/src/main/java/coffeemeet/server/inquiry/domain/Inquiry.java @@ -0,0 +1,64 @@ +package coffeemeet.server.inquiry.domain; + +import coffeemeet.server.common.entity.BaseEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.util.StringUtils; + +@Entity +@Getter +@Table(name = "inquiries") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Inquiry extends BaseEntity { + + private static final int TITLE_MAX_LENGTH = 20; + private static final int CONTENT_MAX_LENGTH = 200; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private Long inquirerId; + + @Column(nullable = false, length = TITLE_MAX_LENGTH) + private String title; + + @Column(nullable = false, length = CONTENT_MAX_LENGTH) + private String content; + + public Inquiry(Long inquirerId, String title, String content) { + validateInquirer(inquirerId); + validateTitle(title); + validateContent(content); + this.inquirerId = inquirerId; + this.title = title; + this.content = content; + } + + private void validateTitle(String title) { + if (!StringUtils.hasText(title) || title.length() > TITLE_MAX_LENGTH) { + throw new IllegalArgumentException("올바르지 않은 제목입니다."); + } + } + + private void validateContent(String content) { + if (!StringUtils.hasText(content) || content.length() > CONTENT_MAX_LENGTH) { + throw new IllegalArgumentException("올바르지 않은 내용입니다."); + } + } + + private void validateInquirer(Long inquirerId) { + if (inquirerId == null) { + throw new IllegalArgumentException("올바르지 않은 사용자 아이디입니다."); + } + } + +} From 5a9dce1d46cfa44e22c3be6a70dbe77f53099d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 21 Oct 2023 11:20:37 +0900 Subject: [PATCH 005/311] =?UTF-8?q?feat:=20Interest=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/interest/domain/Interest.java | 43 +++++++++++++++++++ .../server/interest/domain/Keyword.java | 8 ++++ 2 files changed, 51 insertions(+) create mode 100644 src/main/java/coffeemeet/server/interest/domain/Interest.java create mode 100644 src/main/java/coffeemeet/server/interest/domain/Keyword.java diff --git a/src/main/java/coffeemeet/server/interest/domain/Interest.java b/src/main/java/coffeemeet/server/interest/domain/Interest.java new file mode 100644 index 00000000..a2091d55 --- /dev/null +++ b/src/main/java/coffeemeet/server/interest/domain/Interest.java @@ -0,0 +1,43 @@ +package coffeemeet.server.interest.domain; + +import coffeemeet.server.common.entity.BaseEntity; +import coffeemeet.server.user.domain.User; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +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.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Table(name = "interests") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Interest extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Enumerated(EnumType.STRING) + @Column(nullable = false) + private Keyword keyword; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; + + public Interest(String keyword, User user) { + this.keyword = Keyword.valueOf(keyword); + this.user = user; + } + +} diff --git a/src/main/java/coffeemeet/server/interest/domain/Keyword.java b/src/main/java/coffeemeet/server/interest/domain/Keyword.java new file mode 100644 index 00000000..717ad9e5 --- /dev/null +++ b/src/main/java/coffeemeet/server/interest/domain/Keyword.java @@ -0,0 +1,8 @@ +package coffeemeet.server.interest.domain; + +public enum Keyword { + COOK, + GAME, + EXERCISE, + +} From ee2b396f6062545443a5e2ff4635663d1d09cd0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 21 Oct 2023 11:22:45 +0900 Subject: [PATCH 006/311] =?UTF-8?q?feat:=20User=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/domain/Certification.java | 41 +++++++++ .../server/user/domain/CompanyEmail.java | 26 ++++++ .../coffeemeet/server/user/domain/Email.java | 26 ++++++ .../server/user/domain/OAuthInfo.java | 31 +++++++ .../server/user/domain/OAuthProvider.java | 6 ++ .../server/user/domain/Profile.java | 89 +++++++++++++++++++ .../server/user/domain/ReportInfo.java | 41 +++++++++ .../coffeemeet/server/user/domain/User.java | 62 +++++++++++++ 8 files changed, 322 insertions(+) create mode 100644 src/main/java/coffeemeet/server/user/domain/Certification.java create mode 100644 src/main/java/coffeemeet/server/user/domain/CompanyEmail.java create mode 100644 src/main/java/coffeemeet/server/user/domain/Email.java create mode 100644 src/main/java/coffeemeet/server/user/domain/OAuthInfo.java create mode 100644 src/main/java/coffeemeet/server/user/domain/OAuthProvider.java create mode 100644 src/main/java/coffeemeet/server/user/domain/Profile.java create mode 100644 src/main/java/coffeemeet/server/user/domain/ReportInfo.java create mode 100644 src/main/java/coffeemeet/server/user/domain/User.java diff --git a/src/main/java/coffeemeet/server/user/domain/Certification.java b/src/main/java/coffeemeet/server/user/domain/Certification.java new file mode 100644 index 00000000..192c8fe5 --- /dev/null +++ b/src/main/java/coffeemeet/server/user/domain/Certification.java @@ -0,0 +1,41 @@ +package coffeemeet.server.user.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Embedded; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.util.StringUtils; + +@Getter +@Embeddable +@NoArgsConstructor +public class Certification { + + @Embedded + @Column(nullable = false) + private CompanyEmail companyEmail; + + @Column(nullable = false) + private String businessCardUrl; + + @Column(nullable = false) + private boolean isCertificated; + + public Certification(CompanyEmail companyEmail, String businessCardUrl) { + validateBusinessCardUrl(businessCardUrl); + this.companyEmail = companyEmail; + this.businessCardUrl = businessCardUrl; + } + + private void validateBusinessCardUrl(String businessCardUrl) { + if (!StringUtils.hasText(businessCardUrl)) { + throw new IllegalArgumentException("올바르지 않은 명함 url입니다."); + } + } + + public void certificate() { + isCertificated = true; + } + +} diff --git a/src/main/java/coffeemeet/server/user/domain/CompanyEmail.java b/src/main/java/coffeemeet/server/user/domain/CompanyEmail.java new file mode 100644 index 00000000..a9522bfe --- /dev/null +++ b/src/main/java/coffeemeet/server/user/domain/CompanyEmail.java @@ -0,0 +1,26 @@ +package coffeemeet.server.user.domain; + +import coffeemeet.server.common.util.Patterns; +import jakarta.persistence.Embeddable; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@NoArgsConstructor +public class CompanyEmail { + + private String companyEmail; + + public CompanyEmail(String companyEmail) { + validateCompanyEmail(companyEmail); + this.companyEmail = companyEmail; + } + + private void validateCompanyEmail(String companyEmail) { + if (!Patterns.EMAIL_PATTERN.matcher(companyEmail).matches()) { + throw new IllegalArgumentException("올바르지 않은 이메일입니다."); + } + } + +} diff --git a/src/main/java/coffeemeet/server/user/domain/Email.java b/src/main/java/coffeemeet/server/user/domain/Email.java new file mode 100644 index 00000000..14cd302e --- /dev/null +++ b/src/main/java/coffeemeet/server/user/domain/Email.java @@ -0,0 +1,26 @@ +package coffeemeet.server.user.domain; + +import coffeemeet.server.common.util.Patterns; +import jakarta.persistence.Embeddable; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@NoArgsConstructor +public class Email { + + private String email; + + public Email(String email) { + validateEmail(email); + this.email = email; + } + + private void validateEmail(String email) { + if (!Patterns.EMAIL_PATTERN.matcher(email).matches()) { + throw new IllegalArgumentException("올바르지 않은 이메일입니다."); + } + } + +} diff --git a/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java b/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java new file mode 100644 index 00000000..1d0d07ea --- /dev/null +++ b/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java @@ -0,0 +1,31 @@ +package coffeemeet.server.user.domain; + +import jakarta.persistence.Embeddable; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.util.StringUtils; + +@Getter +@Embeddable +@NoArgsConstructor +public class OAuthInfo { + + @Enumerated(value = EnumType.STRING) + private OAuthProvider oauthProvider; + + private String oauthProviderId; + + public OAuthInfo(OAuthProvider oauthProvider, String oauthProviderId) { + validateOAuthProviderId(oauthProviderId); + this.oauthProviderId = oauthProviderId; + } + + private void validateOAuthProviderId(String oauthProviderId) { + if (!StringUtils.hasText(oauthProviderId)) { + throw new IllegalArgumentException("올바르지 않은 로그인 아이디입니다."); + } + } + +} diff --git a/src/main/java/coffeemeet/server/user/domain/OAuthProvider.java b/src/main/java/coffeemeet/server/user/domain/OAuthProvider.java new file mode 100644 index 00000000..64a285ec --- /dev/null +++ b/src/main/java/coffeemeet/server/user/domain/OAuthProvider.java @@ -0,0 +1,6 @@ +package coffeemeet.server.user.domain; + +public enum OAuthProvider { + KAKAO, + NAVER, +} diff --git a/src/main/java/coffeemeet/server/user/domain/Profile.java b/src/main/java/coffeemeet/server/user/domain/Profile.java new file mode 100644 index 00000000..685ee9ef --- /dev/null +++ b/src/main/java/coffeemeet/server/user/domain/Profile.java @@ -0,0 +1,89 @@ +package coffeemeet.server.user.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import jakarta.persistence.Embedded; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.util.StringUtils; + +@Getter +@Embeddable +@NoArgsConstructor +public class Profile { + + private static final int NICKNAME_MAX_LENGTH = 20; + + @Column(nullable = false) + private String name; + + @Column(nullable = false, length = NICKNAME_MAX_LENGTH) + private String nickname; + + @Embedded + @Column(nullable = false) + private Email email; + + @Column(nullable = false) + private String profileImageUrl; + + @Column(nullable = false) + private String birth; + + @Column(nullable = false) + private String department; + + @Builder + private Profile( + String name, + String nickname, + Email email, + String profileImageUrl, + String birth, + String department + ) { + validateName(name); + validateNickname(nickname); + validateProfileImage(profileImageUrl); + validateBirth(birth); + validateDepartment(department); + this.name = name; + this.nickname = nickname; + this.email = email; + this.profileImageUrl = profileImageUrl; + this.birth = birth; + this.department = department; + } + + private void validateName(String name) { + if (!StringUtils.hasText(name)) { + throw new IllegalArgumentException("올바르지 않은 이름입니다."); + } + } + + private void validateNickname(String nickname) { + if (!StringUtils.hasText(nickname) || nickname.length() > NICKNAME_MAX_LENGTH) { + throw new IllegalArgumentException("올바르지 않은 닉네임입니다."); + } + } + + private void validateProfileImage(String profileImageUrl) { + if (!StringUtils.hasText(profileImageUrl)) { + throw new IllegalArgumentException("올바르지 않은 프로필 사진 url입니다."); + } + } + + private void validateBirth(String birth) { + if (!StringUtils.hasText(birth)) { + throw new IllegalArgumentException("올바르지 않은 생년월일입니다."); + } + } + + private void validateDepartment(String department) { + if (!StringUtils.hasText(department)) { + throw new IllegalArgumentException("올바르지 않은 부서 이름입니다."); + } + } + +} diff --git a/src/main/java/coffeemeet/server/user/domain/ReportInfo.java b/src/main/java/coffeemeet/server/user/domain/ReportInfo.java new file mode 100644 index 00000000..cee774c8 --- /dev/null +++ b/src/main/java/coffeemeet/server/user/domain/ReportInfo.java @@ -0,0 +1,41 @@ +package coffeemeet.server.user.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import java.time.LocalDateTime; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@NoArgsConstructor +public class ReportInfo { + + private static final int REPORT_COUNT_MIN_LENGTH = 0; + + @Column(nullable = false) + private int reportedCount; + + @Column(nullable = false) + private LocalDateTime sanctionPeriod; + + public ReportInfo(int reportedCount, LocalDateTime sanctionPeriod) { + validateReportedCount(reportedCount); + validateSanctionPeriod(sanctionPeriod); + this.reportedCount = reportedCount; + this.sanctionPeriod = sanctionPeriod; + } + + private void validateReportedCount(int reportedCount) { + if (reportedCount < 0) { + throw new IllegalArgumentException("올바르지 않은 신고횟수입니다."); + } + } + + private void validateSanctionPeriod(LocalDateTime sanctionPeriod) { + if (sanctionPeriod != null) { + throw new IllegalArgumentException("올바르지 않은 제재 기간입니다."); + } + } + +} diff --git a/src/main/java/coffeemeet/server/user/domain/User.java b/src/main/java/coffeemeet/server/user/domain/User.java new file mode 100644 index 00000000..d4140fb3 --- /dev/null +++ b/src/main/java/coffeemeet/server/user/domain/User.java @@ -0,0 +1,62 @@ +package coffeemeet.server.user.domain; + +import coffeemeet.server.chatting_room.domain.ChattingRoom; +import jakarta.persistence.Column; +import jakarta.persistence.Embedded; +import jakarta.persistence.Entity; +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.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.Where; + +@Entity +@Getter +@Table(name = "users") +@Where(clause = "is_deleted = false") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class User { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Embedded + @Column(nullable = false) + private OAuthInfo oAuthInfo; + + @Embedded + @Column(nullable = false) + private Profile profile; + + @ManyToOne + @JoinColumn(name = "chatting_room_id", nullable = false) + private ChattingRoom chattingRoom; + + @Embedded + @Column(nullable = false) + private Certification certification; + + @Embedded + @Column(nullable = false) + private ReportInfo reportInfo; + + @Column(nullable = false) + private boolean isDeleted; + + public User( + OAuthInfo oAuthInfo, + Profile profile, + Certification certification + ) { + this.oAuthInfo = oAuthInfo; + this.profile = profile; + this.certification = certification; + } + +} From c314971d5cc6bec4a09dfb975553200490e70301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 21 Oct 2023 11:22:56 +0900 Subject: [PATCH 007/311] =?UTF-8?q?feat:=20Report=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/report/domain/Report.java | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/main/java/coffeemeet/server/report/domain/Report.java diff --git a/src/main/java/coffeemeet/server/report/domain/Report.java b/src/main/java/coffeemeet/server/report/domain/Report.java new file mode 100644 index 00000000..1e1259f6 --- /dev/null +++ b/src/main/java/coffeemeet/server/report/domain/Report.java @@ -0,0 +1,81 @@ +package coffeemeet.server.report.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +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; +import org.springframework.util.StringUtils; + +@Entity +@Getter +@Table(name = "reports") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Report { + + private static final int TITLE_MAX_LENGTH = 20; + private static final int REASON_MAX_LENGTH = 200; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private Long reporterId; + + @Column(nullable = false) + private Long targetId; + + @Column(nullable = false, length = TITLE_MAX_LENGTH) + private String title; + + @Column(nullable = false, length = REASON_MAX_LENGTH) + private String reason; + + @Builder + private Report( + Long reporterId, + Long targetId, + String title, + String reason + ) { + validateReporter(reporterId); + validateTarget(targetId); + validateTitle(title); + validateReason(reason); + this.reporterId = reporterId; + this.targetId = targetId; + this.title = title; + this.reason = reason; + } + + private void validateReporter(Long reporterId) { + if (reporterId == null) { + throw new IllegalArgumentException("올바르지 않은 사용자(리포터) 아이디입니다."); + } + } + + private void validateTarget(Long targetId) { + if (targetId == null) { + throw new IllegalArgumentException("올바르지 않은 사용자(타켓) 아이디입니다."); + } + } + + private void validateTitle(String title) { + if (!StringUtils.hasText(title) || title.length() > TITLE_MAX_LENGTH) { + throw new IllegalArgumentException("올바르지 않은 제목입니다."); + } + } + + private void validateReason(String reason) { + if (!StringUtils.hasText(reason) || reason.length() > REASON_MAX_LENGTH) { + throw new IllegalArgumentException("올바르지 않은 사유입니다."); + } + } + +} From 75ac0c7c8b6c4c56419e97ca01d4a80e1b84cc6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 21 Oct 2023 11:23:12 +0900 Subject: [PATCH 008/311] =?UTF-8?q?feat:=20ChattingRoom=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chatting_room/domain/ChattingRoom.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/main/java/coffeemeet/server/chatting_room/domain/ChattingRoom.java diff --git a/src/main/java/coffeemeet/server/chatting_room/domain/ChattingRoom.java b/src/main/java/coffeemeet/server/chatting_room/domain/ChattingRoom.java new file mode 100644 index 00000000..64586482 --- /dev/null +++ b/src/main/java/coffeemeet/server/chatting_room/domain/ChattingRoom.java @@ -0,0 +1,23 @@ +package coffeemeet.server.chatting_room.domain; + +import coffeemeet.server.common.entity.BaseEntity; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Table(name = "chatting_rooms") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ChattingRoom extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + +} From 33a5cfb33fad21f3f0a3a18ccd4dd848308402d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 21 Oct 2023 11:23:31 +0900 Subject: [PATCH 009/311] =?UTF-8?q?feat:=20ChattingMessageHistory=20?= =?UTF-8?q?=EC=97=94=ED=8B=B0=ED=8B=B0=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/ChattingMessage.java | 48 +++++++++++++++++++ .../domain/ChattingMessageHistory.java | 47 ++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 src/main/java/coffeemeet/server/chatting_message/domain/ChattingMessage.java create mode 100644 src/main/java/coffeemeet/server/chatting_message_history/domain/ChattingMessageHistory.java diff --git a/src/main/java/coffeemeet/server/chatting_message/domain/ChattingMessage.java b/src/main/java/coffeemeet/server/chatting_message/domain/ChattingMessage.java new file mode 100644 index 00000000..db6ca4f2 --- /dev/null +++ b/src/main/java/coffeemeet/server/chatting_message/domain/ChattingMessage.java @@ -0,0 +1,48 @@ +package coffeemeet.server.chatting_message.domain; + +import coffeemeet.server.chatting_room.domain.ChattingRoom; +import coffeemeet.server.common.entity.BaseEntity; +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.Getter; +import lombok.NoArgsConstructor; +import org.springframework.util.StringUtils; + +@Entity +@Getter +@Table(name = "chatting_messages") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ChattingMessage extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String message; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "chatting_room_id", nullable = false) + private ChattingRoom chattingRoom; + + public ChattingMessage(String message, ChattingRoom chattingRoom) { + validateMessage(message); + this.message = message; + this.chattingRoom = chattingRoom; + } + + private void validateMessage(String message) { + if (!StringUtils.hasText(message)) { + throw new IllegalArgumentException("올바르지 않은 메시지입니다."); + } + } + +} diff --git a/src/main/java/coffeemeet/server/chatting_message_history/domain/ChattingMessageHistory.java b/src/main/java/coffeemeet/server/chatting_message_history/domain/ChattingMessageHistory.java new file mode 100644 index 00000000..7bcf098b --- /dev/null +++ b/src/main/java/coffeemeet/server/chatting_message_history/domain/ChattingMessageHistory.java @@ -0,0 +1,47 @@ +package coffeemeet.server.chatting_message_history.domain; + +import coffeemeet.server.chatting_room_history.domain.ChattingRoomHistory; +import coffeemeet.server.common.entity.BaseEntity; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +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.Getter; +import lombok.NoArgsConstructor; +import org.springframework.util.StringUtils; + +@Entity +@Getter +@Table(name = "chatting_message_histories") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ChattingMessageHistory extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String message; + + @ManyToOne + @JoinColumn(name = "chatting_room_history_id", nullable = false) + private ChattingRoomHistory chattingRoomHistory; + + public ChattingMessageHistory(String message, ChattingRoomHistory chattingRoomHistory) { + validateMessage(message); + this.message = message; + this.chattingRoomHistory = chattingRoomHistory; + } + + private void validateMessage(String message) { + if (!StringUtils.hasText(message)) { + throw new IllegalArgumentException("올바르지 않은 메시지입니다."); + } + } + +} From 9060a7e736468066d4c302a27d6114dfb2591531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 21 Oct 2023 11:24:11 +0900 Subject: [PATCH 010/311] =?UTF-8?q?feat:=20ChattingRoomHistory=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/ChattingRoomHistory.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/main/java/coffeemeet/server/chatting_room_history/domain/ChattingRoomHistory.java diff --git a/src/main/java/coffeemeet/server/chatting_room_history/domain/ChattingRoomHistory.java b/src/main/java/coffeemeet/server/chatting_room_history/domain/ChattingRoomHistory.java new file mode 100644 index 00000000..edadac32 --- /dev/null +++ b/src/main/java/coffeemeet/server/chatting_room_history/domain/ChattingRoomHistory.java @@ -0,0 +1,23 @@ +package coffeemeet.server.chatting_room_history.domain; + +import coffeemeet.server.common.entity.BaseEntity; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Table(name = "chatting_room_histories") +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ChattingRoomHistory extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + +} From a0b2b3c8739c1a9536841a904e9d5a8b2c3b72de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 21 Oct 2023 11:24:19 +0900 Subject: [PATCH 011/311] =?UTF-8?q?feat:=20Admin=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/admin/domain/Admin.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/main/java/coffeemeet/server/admin/domain/Admin.java diff --git a/src/main/java/coffeemeet/server/admin/domain/Admin.java b/src/main/java/coffeemeet/server/admin/domain/Admin.java new file mode 100644 index 00000000..2f122938 --- /dev/null +++ b/src/main/java/coffeemeet/server/admin/domain/Admin.java @@ -0,0 +1,23 @@ +package coffeemeet.server.admin.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Table(name = "admins") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Admin { + + @Id + @Column(nullable = false) + private String id; + + @Column(nullable = false) + private String password; +} From f32bd3dd7042652f2f0f816a969d4425438dab5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 21 Oct 2023 11:25:12 +0900 Subject: [PATCH 012/311] =?UTF-8?q?feat:=20Pattern=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/common/util/Patterns.java | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/util/Patterns.java diff --git a/src/main/java/coffeemeet/server/common/util/Patterns.java b/src/main/java/coffeemeet/server/common/util/Patterns.java new file mode 100644 index 00000000..60da9bc8 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/util/Patterns.java @@ -0,0 +1,9 @@ +package coffeemeet.server.common.util; + +import java.util.regex.Pattern; + +public class Patterns { + + public static final Pattern EMAIL_PATTERN = Pattern.compile( + "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?"); +} From 75807d0004b201e39b7337689efb2f0089ffec9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 21 Oct 2023 11:26:05 +0900 Subject: [PATCH 013/311] =?UTF-8?q?feat:=20JPAConfig=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/coffeemeet/server/config/JPAConfig.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/coffeemeet/server/config/JPAConfig.java diff --git a/src/main/java/coffeemeet/server/config/JPAConfig.java b/src/main/java/coffeemeet/server/config/JPAConfig.java new file mode 100644 index 00000000..448c15bc --- /dev/null +++ b/src/main/java/coffeemeet/server/config/JPAConfig.java @@ -0,0 +1,11 @@ +package coffeemeet.server.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; + +@Configuration +@EnableJpaAuditing +public class JPAConfig { + +} + From 2baeb91d1bb3020c2731cade258813f6401b4919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 21 Oct 2023 18:34:24 +0900 Subject: [PATCH 014/311] =?UTF-8?q?chore:=20yml=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/resources/application.yml diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 00000000..e69de29b From 4ea71595eac2723dfe6d06bd6fd6ef93a26b4e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sun, 22 Oct 2023 21:25:43 +0900 Subject: [PATCH 015/311] =?UTF-8?q?chore:=20yml=20=ED=8C=8C=EC=9D=BC=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/resources/application.properties | 1 - src/main/resources/application.yml | 28 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) delete mode 100644 src/main/resources/application.properties diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index 8b137891..00000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e69de29b..3887879e 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -0,0 +1,28 @@ +spring: + datasource: + url: ${DATASOURCE_URL} + username: ${DATASOURCE_USERNAME} + password: ${DATASOURCE_PASSWORD} + + jpa: + open-in-view: false + show-sql: true + hibernate: + ddl-auto: create + properties: + hibernate: + format_sql: true + + data: + redis: + host: ${REDIS_HOST} + port: ${REDIS_PORT} + password: ${REDIS_PASSWORD} + +logging: + level: + org: + hibernate: + orm: + jdbc: + bind: trace \ No newline at end of file From 1071ad6479fe06b09bd5eb475a4b43140a2998a0 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Sun, 22 Oct 2023 22:22:19 +0900 Subject: [PATCH 016/311] Create ci.yml --- .github/workflows/ci.yml | 54 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..d1f3851d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,54 @@ +name: coffee-meet CI + +on: + pull_request: + branches: + - main + - dev + +jobs: + test: + name: Test + runs-on: ubuntu-latest + + permissions: + checks: write + pull-requests: write + + steps: + - name: 현재 작업중인 Repository 가져온다. + uses: actions/checkout@v3 + + - name: CI 프로세스를 최적화 하기 위해 Gradle 정보를 캐싱한다. + uses: actions/cache@v3 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: JDK 17 설치한다. + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + + - name: Gradle 명령 실행을 위한 권한을 부여한다. + run: chmod +x gradlew + + - name: Gradle test를 수행한다. + run: ./gradlew test + + - name: 테스트 결과를 PR 코멘트 등록한다. + uses: EnricoMi/publish-unit-test-result-action@v2 + if: always() + with: + files: '**/build/test-results/test/TEST-*.xml' + + - name: 테스트 실패 시 해당 코드 라인에 Check 등록한다. + uses: mikepenz/action-junit-report@v3 + if: always() + with: + report_paths: '**/build/test-results/test/TEST-*.xml' From 84857e29ebfa7c5363edd248ae9cf6ab986797b8 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Sun, 22 Oct 2023 23:14:53 +0900 Subject: [PATCH 017/311] chore: update gradle --- build.gradle | 75 +++++++++++++++++++++++++++--- src/test/resources/application.yml | 21 +++++++++ 2 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 src/test/resources/application.yml diff --git a/build.gradle b/build.gradle index 4c23e467..a9e6eb68 100644 --- a/build.gradle +++ b/build.gradle @@ -1,8 +1,17 @@ +import org.hidetake.gradle.swagger.generator.GenerateSwaggerUI + +buildscript { + ext { + restdocsApiSpecVersion = '0.18.3' // restdocsApiSpecVersion 버전 변수 설정 + } +} + plugins { id 'java' id 'org.springframework.boot' version '3.1.4' id 'io.spring.dependency-management' version '1.1.3' - id 'org.asciidoctor.jvm.convert' version '3.3.2' + id 'com.epages.restdocs-api-spec' version "${restdocsApiSpecVersion}" + id 'org.hidetake.swagger.generator' version '2.18.2' } group = 'coffee-meet' @@ -27,24 +36,76 @@ ext { } dependencies { + /* Database */ implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-data-redis' + runtimeOnly 'com.mysql:mysql-connector-j' + runtimeOnly 'com.h2database:h2' + + /* Spring */ implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' + + /* Lombok */ compileOnly 'org.projectlombok:lombok' - runtimeOnly 'com.h2database:h2' - runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' + + /* Test */ testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation group: 'org.instancio', name: 'instancio-junit', version: '3.0.0' + + /* TestContainer */ + testImplementation "org.testcontainers:testcontainers:1.19.0" + testImplementation "org.testcontainers:junit-jupiter:1.19.0" + + /* Docs & UI */ testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' + testImplementation "com.epages:restdocs-api-spec-mockmvc:${restdocsApiSpecVersion}" + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0' + swaggerUI 'org.webjars:swagger-ui:4.11.1' } tasks.named('test') { - outputs.dir snippetsDir useJUnitPlatform() } -tasks.named('asciidoctor') { - inputs.dir snippetsDir - dependsOn test +swaggerSources { + sample { + setInputFile(file("${project.buildDir}/api-spec/openapi3.yaml")) + } +} + +openapi3 { + servers = [ + { url = "http://localhost:8080" }, + { url = "http://13.209.253.204:8080" } + ] + title = "API 문서" + description = "RestDocsWithSwagger Docs" + version = "0.0.1" + format = "yaml" +} + +tasks.withType(GenerateSwaggerUI) { + dependsOn 'openapi3' + doFirst { + def swaggerUIFile = file("${openapi3.outputDirectory}/openapi3.yaml") + + def securitySchemesContent = " securitySchemes:\n" + \ + " APIKey:\n" + \ + " type: apiKey\n" + \ + " name: Authorization\n" + \ + " in: header\n" + \ + "security:\n" + + " - APIKey: [] # Apply the security scheme here" + + swaggerUIFile.append securitySchemesContent + } +} + +bootJar { + dependsOn generateSwaggerUISample + from("${generateSwaggerUISample.outputDir}") { + into 'static/docs' + } } diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml new file mode 100644 index 00000000..12bbdbbb --- /dev/null +++ b/src/test/resources/application.yml @@ -0,0 +1,21 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb;MODE=MYSQL + username: sa + password: + jpa: + show-sql: true + hibernate: + ddl-auto: create + + properties: + hibernate: + format_sql: true + +logging: + level: + org: + hibernate: + orm: + jdbc: + bind: trace From f4b9daa0a9ee792358a5509b2ab7938c67458100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sun, 22 Oct 2023 21:53:56 +0900 Subject: [PATCH 018/311] =?UTF-8?q?refactor:=20=EB=B6=80=EC=84=9C=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=EB=A5=BC=20Certification=EC=9C=BC=EB=A1=9C?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/domain/Certification.java | 13 ++++++++++++- .../coffeemeet/server/user/domain/Profile.java | 14 +------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/Certification.java b/src/main/java/coffeemeet/server/user/domain/Certification.java index 192c8fe5..3c6b2577 100644 --- a/src/main/java/coffeemeet/server/user/domain/Certification.java +++ b/src/main/java/coffeemeet/server/user/domain/Certification.java @@ -22,10 +22,15 @@ public class Certification { @Column(nullable = false) private boolean isCertificated; - public Certification(CompanyEmail companyEmail, String businessCardUrl) { + @Column(nullable = false) + private String department; + + public Certification(CompanyEmail companyEmail, String businessCardUrl, String department) { validateBusinessCardUrl(businessCardUrl); + validateDepartment(department); this.companyEmail = companyEmail; this.businessCardUrl = businessCardUrl; + this.department = department; } private void validateBusinessCardUrl(String businessCardUrl) { @@ -34,6 +39,12 @@ private void validateBusinessCardUrl(String businessCardUrl) { } } + private void validateDepartment(String department) { + if (!StringUtils.hasText(department)) { + throw new IllegalArgumentException("올바르지 않은 부서 이름입니다."); + } + } + public void certificate() { isCertificated = true; } diff --git a/src/main/java/coffeemeet/server/user/domain/Profile.java b/src/main/java/coffeemeet/server/user/domain/Profile.java index 685ee9ef..a4c3b71e 100644 --- a/src/main/java/coffeemeet/server/user/domain/Profile.java +++ b/src/main/java/coffeemeet/server/user/domain/Profile.java @@ -31,29 +31,23 @@ public class Profile { @Column(nullable = false) private String birth; - @Column(nullable = false) - private String department; - @Builder private Profile( String name, String nickname, Email email, String profileImageUrl, - String birth, - String department + String birth ) { validateName(name); validateNickname(nickname); validateProfileImage(profileImageUrl); validateBirth(birth); - validateDepartment(department); this.name = name; this.nickname = nickname; this.email = email; this.profileImageUrl = profileImageUrl; this.birth = birth; - this.department = department; } private void validateName(String name) { @@ -80,10 +74,4 @@ private void validateBirth(String birth) { } } - private void validateDepartment(String department) { - if (!StringUtils.hasText(department)) { - throw new IllegalArgumentException("올바르지 않은 부서 이름입니다."); - } - } - } From bc3422a0cfa8a9444df30a1d1f26008186980d76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sun, 22 Oct 2023 22:49:48 +0900 Subject: [PATCH 019/311] =?UTF-8?q?refactor:=20User=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/coffeemeet/server/user/domain/User.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/User.java b/src/main/java/coffeemeet/server/user/domain/User.java index d4140fb3..e3e18346 100644 --- a/src/main/java/coffeemeet/server/user/domain/User.java +++ b/src/main/java/coffeemeet/server/user/domain/User.java @@ -51,12 +51,10 @@ public class User { public User( OAuthInfo oAuthInfo, - Profile profile, - Certification certification + Profile profile ) { this.oAuthInfo = oAuthInfo; this.profile = profile; - this.certification = certification; } } From 031571b602c875cf9035c75205819691b3c528cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sun, 22 Oct 2023 22:51:08 +0900 Subject: [PATCH 020/311] =?UTF-8?q?refactor:=20User=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=EC=9D=98=20=EC=83=9D=EB=85=84=EC=9B=94=EC=9D=BC=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=ED=83=80=EC=9E=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/user/domain/Birth.java | 41 +++++++++++++++++++ .../server/user/domain/Profile.java | 12 ++---- 2 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 src/main/java/coffeemeet/server/user/domain/Birth.java diff --git a/src/main/java/coffeemeet/server/user/domain/Birth.java b/src/main/java/coffeemeet/server/user/domain/Birth.java new file mode 100644 index 00000000..506fe396 --- /dev/null +++ b/src/main/java/coffeemeet/server/user/domain/Birth.java @@ -0,0 +1,41 @@ +package coffeemeet.server.user.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.util.StringUtils; + +@Getter +@Embeddable +@NoArgsConstructor +public class Birth { + + private static final int BIRTH_LENGTH = 4; + + @Column(nullable = false, length = 4) + String year; + + @Column(nullable = false, length = 4) + String day; + + public Birth(String year, String day) { + validateYear(year); + validateDay(day); + this.year = year; + this.day = day; + } + + private void validateYear(String year) { + if (!StringUtils.hasText(year) || year.length() != BIRTH_LENGTH) { + throw new IllegalArgumentException("올바르지 않은 연도 형식입니다."); + } + } + + private void validateDay(String day) { + if (!StringUtils.hasText(day) || day.length() != BIRTH_LENGTH) { + throw new IllegalArgumentException("올바르지 않은 날짜 형식입니다."); + } + } + +} diff --git a/src/main/java/coffeemeet/server/user/domain/Profile.java b/src/main/java/coffeemeet/server/user/domain/Profile.java index a4c3b71e..10aaa25a 100644 --- a/src/main/java/coffeemeet/server/user/domain/Profile.java +++ b/src/main/java/coffeemeet/server/user/domain/Profile.java @@ -28,8 +28,9 @@ public class Profile { @Column(nullable = false) private String profileImageUrl; + @Embedded @Column(nullable = false) - private String birth; + private Birth birth; @Builder private Profile( @@ -37,12 +38,11 @@ private Profile( String nickname, Email email, String profileImageUrl, - String birth + Birth birth ) { validateName(name); validateNickname(nickname); validateProfileImage(profileImageUrl); - validateBirth(birth); this.name = name; this.nickname = nickname; this.email = email; @@ -68,10 +68,4 @@ private void validateProfileImage(String profileImageUrl) { } } - private void validateBirth(String birth) { - if (!StringUtils.hasText(birth)) { - throw new IllegalArgumentException("올바르지 않은 생년월일입니다."); - } - } - } From 7423d0db15983001af2bdd47fb48e5bb32b5f1b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 00:03:45 +0900 Subject: [PATCH 021/311] =?UTF-8?q?refactor:=20OAuthInfo=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/coffeemeet/server/user/domain/OAuthInfo.java | 1 + src/main/java/coffeemeet/server/user/domain/User.java | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java b/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java index 1d0d07ea..da841c4c 100644 --- a/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java +++ b/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java @@ -19,6 +19,7 @@ public class OAuthInfo { public OAuthInfo(OAuthProvider oauthProvider, String oauthProviderId) { validateOAuthProviderId(oauthProviderId); + this.oauthProvider = oauthProvider; this.oauthProviderId = oauthProviderId; } diff --git a/src/main/java/coffeemeet/server/user/domain/User.java b/src/main/java/coffeemeet/server/user/domain/User.java index e3e18346..b7e9f0f5 100644 --- a/src/main/java/coffeemeet/server/user/domain/User.java +++ b/src/main/java/coffeemeet/server/user/domain/User.java @@ -28,7 +28,7 @@ public class User { @Embedded @Column(nullable = false) - private OAuthInfo oAuthInfo; + private OAuthInfo oauthInfo; @Embedded @Column(nullable = false) @@ -50,10 +50,10 @@ public class User { private boolean isDeleted; public User( - OAuthInfo oAuthInfo, + OAuthInfo oauthInfo, Profile profile ) { - this.oAuthInfo = oAuthInfo; + this.oauthInfo = oauthInfo; this.profile = profile; } From 5004717b16b465f952d734255286877ea4543fef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 00:04:50 +0900 Subject: [PATCH 022/311] =?UTF-8?q?chore:=20build.gradle=20=EB=B0=8F=20yml?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 5 +++++ src/main/resources/application.yml | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/build.gradle b/build.gradle index a9e6eb68..903c2868 100644 --- a/build.gradle +++ b/build.gradle @@ -46,6 +46,11 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' + /* JWT */ + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' + implementation 'io.jsonwebtoken:jjwt-impl:0.11.5' + implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5' + /* Lombok */ compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 3887879e..8304cf69 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -19,6 +19,17 @@ spring: port: ${REDIS_PORT} password: ${REDIS_PASSWORD} +jwt: + secret-key: ${JWT_SECRET_KEY} + access-token-expire-time: ${ACCESS_TOKEN_EXPIRE_TIME} + refresh-token-expire-time: ${REFRESH_TOKEN_EXPIRE_TIME} + +oauth: + kakao: + client-id: ${KAKAO_CLIENT_ID} + redirect-url: ${KAKAO_REDIRECT_URL} + client-secret: ${KAKAO_SECRET} + logging: level: org: From 77a583674ac6576478bdfd9fa7f055fdc11580a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 00:05:27 +0900 Subject: [PATCH 023/311] =?UTF-8?q?refactor:=20Interest=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=9E=90=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/coffeemeet/server/interest/domain/Interest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/interest/domain/Interest.java b/src/main/java/coffeemeet/server/interest/domain/Interest.java index a2091d55..1a4fd237 100644 --- a/src/main/java/coffeemeet/server/interest/domain/Interest.java +++ b/src/main/java/coffeemeet/server/interest/domain/Interest.java @@ -35,8 +35,8 @@ public class Interest extends BaseEntity { @JoinColumn(name = "user_id", nullable = false) private User user; - public Interest(String keyword, User user) { - this.keyword = Keyword.valueOf(keyword); + public Interest(Keyword keyword, User user) { + this.keyword = keyword; this.user = user; } From 01911678849e726a9268e0e746b86419e3ef17c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 00:06:22 +0900 Subject: [PATCH 024/311] =?UTF-8?q?feat:=20InterestRepository,=20UserRepos?= =?UTF-8?q?itory=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interest/repository/InterestRepository.java | 8 ++++++++ .../server/user/repository/UserRepository.java | 12 ++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 src/main/java/coffeemeet/server/interest/repository/InterestRepository.java create mode 100644 src/main/java/coffeemeet/server/user/repository/UserRepository.java diff --git a/src/main/java/coffeemeet/server/interest/repository/InterestRepository.java b/src/main/java/coffeemeet/server/interest/repository/InterestRepository.java new file mode 100644 index 00000000..1440537b --- /dev/null +++ b/src/main/java/coffeemeet/server/interest/repository/InterestRepository.java @@ -0,0 +1,8 @@ +package coffeemeet.server.interest.repository; + +import coffeemeet.server.interest.domain.Interest; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface InterestRepository extends JpaRepository { + +} diff --git a/src/main/java/coffeemeet/server/user/repository/UserRepository.java b/src/main/java/coffeemeet/server/user/repository/UserRepository.java new file mode 100644 index 00000000..c0686339 --- /dev/null +++ b/src/main/java/coffeemeet/server/user/repository/UserRepository.java @@ -0,0 +1,12 @@ +package coffeemeet.server.user.repository; + +import coffeemeet.server.user.domain.OAuthProvider; +import coffeemeet.server.user.domain.User; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { + + boolean existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId(OAuthProvider oauthProvider, + String oauthProviderId); + +} From b2ff9e9190a87fcee39e2e49d8733e65105c2703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 00:06:53 +0900 Subject: [PATCH 025/311] =?UTF-8?q?style:=20JPAConfig=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/{ => common}/config/JPAConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/java/coffeemeet/server/{ => common}/config/JPAConfig.java (82%) diff --git a/src/main/java/coffeemeet/server/config/JPAConfig.java b/src/main/java/coffeemeet/server/common/config/JPAConfig.java similarity index 82% rename from src/main/java/coffeemeet/server/config/JPAConfig.java rename to src/main/java/coffeemeet/server/common/config/JPAConfig.java index 448c15bc..7e14ecc2 100644 --- a/src/main/java/coffeemeet/server/config/JPAConfig.java +++ b/src/main/java/coffeemeet/server/common/config/JPAConfig.java @@ -1,4 +1,4 @@ -package coffeemeet.server.config; +package coffeemeet.server.common.config; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; From 25d05a84ac50435fe7e3d6857e2996e9f896c760 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 00:10:20 +0900 Subject: [PATCH 026/311] =?UTF-8?q?feat:=20AuthController=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 --- .../auth/controller/AuthController.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/main/java/coffeemeet/server/auth/controller/AuthController.java diff --git a/src/main/java/coffeemeet/server/auth/controller/AuthController.java b/src/main/java/coffeemeet/server/auth/controller/AuthController.java new file mode 100644 index 00000000..48877b4f --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/controller/AuthController.java @@ -0,0 +1,40 @@ +package coffeemeet.server.auth.controller; + +import coffeemeet.server.auth.utils.AuthTokens; +import coffeemeet.server.auth.domain.dto.SignupRequest; +import coffeemeet.server.auth.service.AuthService; +import coffeemeet.server.user.domain.OAuthProvider; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +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.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/oauth2/auth") +public class AuthController { + + private final AuthService authService; + + @GetMapping("/{oAuthProvider}") + public ResponseEntity redirectAuthCodeRequestUrl(@PathVariable OAuthProvider oAuthProvider, + HttpServletResponse response) throws IOException { + String redirectUrl = authService.getAuthCodeRequestUrl(oAuthProvider); + response.sendRedirect(redirectUrl); + + return new ResponseEntity<>(HttpStatus.FOUND); + } + + @PostMapping("/sign-up") + public ResponseEntity signup(@RequestBody SignupRequest request) { + return ResponseEntity.ok(authService.signup(request)); + } + +} From 0fbbdb5c3e8d3c820e89938442e135babb837272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 00:10:33 +0900 Subject: [PATCH 027/311] =?UTF-8?q?feat:=20AuthService=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 --- .../server/auth/service/AuthService.java | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/main/java/coffeemeet/server/auth/service/AuthService.java diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java new file mode 100644 index 00000000..b84aa1ff --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -0,0 +1,87 @@ +package coffeemeet.server.auth.service; + +import coffeemeet.server.auth.utils.AuthTokens; +import coffeemeet.server.auth.utils.AuthTokensGenerator; +import coffeemeet.server.auth.domain.authcode.AuthCodeRequestUrlProviderComposite; +import coffeemeet.server.auth.domain.client.OAuthMemberClientComposite; +import coffeemeet.server.auth.domain.dto.OAuthInfoResponse; +import coffeemeet.server.auth.domain.dto.SignupRequest; +import coffeemeet.server.interest.domain.Interest; +import coffeemeet.server.interest.domain.Keyword; +import coffeemeet.server.interest.repository.InterestRepository; +import coffeemeet.server.user.domain.OAuthInfo; +import coffeemeet.server.user.domain.OAuthProvider; +import coffeemeet.server.user.domain.Profile; +import coffeemeet.server.user.domain.User; +import coffeemeet.server.user.repository.UserRepository; +import java.util.ArrayList; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class AuthService { + + private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; + + private final AuthCodeRequestUrlProviderComposite authCodeRequestUrlProviderComposite; + private final OAuthMemberClientComposite oauthMemberClientComposite; + private final UserRepository userRepository; + private final InterestRepository interestRepository; + private final AuthTokensGenerator authTokensGenerator; + + public String getAuthCodeRequestUrl(OAuthProvider oAuthProvider) { + return authCodeRequestUrlProviderComposite.provide(oAuthProvider); + } + + public AuthTokens signup(SignupRequest request) { + OAuthInfoResponse response = oauthMemberClientComposite.fetch(request.oAuthProvider(), + request.authCode()); + checkDuplicateUser(response); + String profileImage = checkProfileImage(response.profileImage()); + + User user = new User( + new OAuthInfo( + response.oAuthProvider(), + response.oAuthProviderId() + ), + Profile.builder() + .name(response.name()) + .nickname(request.nickname()) + .email(response.email()) + .profileImageUrl(profileImage) + .birth(response.birth()) + .build() + ); + + User newUser = userRepository.save(user); + + generateInterests(request, newUser); + + return authTokensGenerator.generate(newUser.getId()); + } + + private void checkDuplicateUser(OAuthInfoResponse response) { + if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( + response.oAuthProvider(), response.oAuthProviderId())) { + throw new IllegalArgumentException(ALREADY_REGISTERED_MESSAGE); + } + } + + private String checkProfileImage(String profileImage) { + if (profileImage == null) { + profileImage = "기본 이미지 URL"; + } + return profileImage; + } + + private void generateInterests(SignupRequest request, User newUser) { + List interests = new ArrayList<>(); + for (Keyword value : request.keywords()) { + interests.add(new Interest(value, newUser)); + } + interestRepository.saveAll(interests); + } + +} From f1d88143509cad5cc2422899c555bd964538be5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 00:11:45 +0900 Subject: [PATCH 028/311] =?UTF-8?q?feat:=20authCode=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=EA=B3=BC=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=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 --- .../authcode/AuthCodeRequestUrlProvider.java | 11 +++ .../AuthCodeRequestUrlProviderComposite.java | 38 ++++++++++ .../auth/domain/client/OAuthMemberClient.java | 12 ++++ .../client/OAuthMemberClientComposite.java | 35 ++++++++++ .../auth/domain/dto/OAuthInfoResponse.java | 34 +++++++++ .../server/auth/domain/dto/SignupRequest.java | 28 ++++++++ .../server/auth/utils/AuthTokens.java | 18 +++++ .../auth/utils/AuthTokensGenerator.java | 53 ++++++++++++++ .../server/auth/utils/JwtTokenProvider.java | 70 +++++++++++++++++++ .../server/user/domain/OAuthProvider.java | 8 +++ 10 files changed, 307 insertions(+) create mode 100644 src/main/java/coffeemeet/server/auth/domain/authcode/AuthCodeRequestUrlProvider.java create mode 100644 src/main/java/coffeemeet/server/auth/domain/authcode/AuthCodeRequestUrlProviderComposite.java create mode 100644 src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClient.java create mode 100644 src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClientComposite.java create mode 100644 src/main/java/coffeemeet/server/auth/domain/dto/OAuthInfoResponse.java create mode 100644 src/main/java/coffeemeet/server/auth/domain/dto/SignupRequest.java create mode 100644 src/main/java/coffeemeet/server/auth/utils/AuthTokens.java create mode 100644 src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java create mode 100644 src/main/java/coffeemeet/server/auth/utils/JwtTokenProvider.java diff --git a/src/main/java/coffeemeet/server/auth/domain/authcode/AuthCodeRequestUrlProvider.java b/src/main/java/coffeemeet/server/auth/domain/authcode/AuthCodeRequestUrlProvider.java new file mode 100644 index 00000000..e7687c4c --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/domain/authcode/AuthCodeRequestUrlProvider.java @@ -0,0 +1,11 @@ +package coffeemeet.server.auth.domain.authcode; + +import coffeemeet.server.user.domain.OAuthProvider; + +public interface AuthCodeRequestUrlProvider { + + OAuthProvider oAuthProvider(); + + String provide(); + +} diff --git a/src/main/java/coffeemeet/server/auth/domain/authcode/AuthCodeRequestUrlProviderComposite.java b/src/main/java/coffeemeet/server/auth/domain/authcode/AuthCodeRequestUrlProviderComposite.java new file mode 100644 index 00000000..f4d36b79 --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/domain/authcode/AuthCodeRequestUrlProviderComposite.java @@ -0,0 +1,38 @@ +package coffeemeet.server.auth.domain.authcode; + +import coffeemeet.server.user.domain.OAuthProvider; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; +import org.springframework.stereotype.Component; + +@Component +public class AuthCodeRequestUrlProviderComposite { + + private static final String INVALID_LOGIN_TYPE_MESSAGE = "로그인 타입(%s)에 일치하는 타입이 없습니다."; + private final Map mapping; + + public AuthCodeRequestUrlProviderComposite(Set providers) { + this.mapping = providers.stream().collect( + Collectors.toUnmodifiableMap( + AuthCodeRequestUrlProvider::oAuthProvider, + Function.identity() + ) + ); + } + + public String provide(OAuthProvider oAuthProvider) { + return getProvider(oAuthProvider).provide(); + } + + private AuthCodeRequestUrlProvider getProvider(OAuthProvider oAuthProvider) { + return Optional.ofNullable(mapping.get(oAuthProvider)) + .orElseThrow(() -> new IllegalArgumentException( + String.format(INVALID_LOGIN_TYPE_MESSAGE, oAuthProvider) + ) + ); + } + +} diff --git a/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClient.java b/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClient.java new file mode 100644 index 00000000..b61cb965 --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClient.java @@ -0,0 +1,12 @@ +package coffeemeet.server.auth.domain.client; + +import coffeemeet.server.auth.domain.dto.OAuthInfoResponse; +import coffeemeet.server.user.domain.OAuthProvider; + +public interface OAuthMemberClient { + + OAuthProvider oAuthProvider(); + + OAuthInfoResponse fetch(String authCode); + +} diff --git a/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClientComposite.java b/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClientComposite.java new file mode 100644 index 00000000..e3489e6d --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClientComposite.java @@ -0,0 +1,35 @@ +package coffeemeet.server.auth.domain.client; + +import coffeemeet.server.auth.domain.dto.OAuthInfoResponse; +import coffeemeet.server.user.domain.OAuthProvider; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; +import org.springframework.stereotype.Component; + +@Component +public class OAuthMemberClientComposite { + + private static final String INVALID_LOGIN_TYPE_MESSAGE = "로그인 타입(%s)에 일치하는 타입이 없습니다."; + private final Map mapping; + + public OAuthMemberClientComposite(Set clients) { + this.mapping = clients.stream().collect( + Collectors.toUnmodifiableMap(OAuthMemberClient::oAuthProvider, Function.identity()) + ); + } + + public OAuthInfoResponse fetch(OAuthProvider oAuthProvider, String authCode) { + return getClient(oAuthProvider).fetch(authCode); + } + + public OAuthMemberClient getClient(OAuthProvider oAuthProvider) { + return Optional.ofNullable(mapping.get(oAuthProvider)) + .orElseThrow(() -> new IllegalArgumentException( + String.format(INVALID_LOGIN_TYPE_MESSAGE, oAuthProvider)) + ); + } + +} diff --git a/src/main/java/coffeemeet/server/auth/domain/dto/OAuthInfoResponse.java b/src/main/java/coffeemeet/server/auth/domain/dto/OAuthInfoResponse.java new file mode 100644 index 00000000..f14ceab0 --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/domain/dto/OAuthInfoResponse.java @@ -0,0 +1,34 @@ +package coffeemeet.server.auth.domain.dto; + +import coffeemeet.server.user.domain.Birth; +import coffeemeet.server.user.domain.Email; +import coffeemeet.server.user.domain.OAuthProvider; + +public record OAuthInfoResponse( + String name, + String profileImage, + Birth birth, + Email email, + OAuthProvider oAuthProvider, + String oAuthProviderId +) { + + public static OAuthInfoResponse of( + String name, + String profileImage, + Birth birth, + Email email, + OAuthProvider oAuthProvider, + String oAuthProviderId + ) { + return new OAuthInfoResponse( + name, + profileImage, + birth, + email, + oAuthProvider, + oAuthProviderId + ); + } + +} diff --git a/src/main/java/coffeemeet/server/auth/domain/dto/SignupRequest.java b/src/main/java/coffeemeet/server/auth/domain/dto/SignupRequest.java new file mode 100644 index 00000000..232f8530 --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/domain/dto/SignupRequest.java @@ -0,0 +1,28 @@ +package coffeemeet.server.auth.domain.dto; + +import coffeemeet.server.interest.domain.Keyword; +import coffeemeet.server.user.domain.OAuthProvider; +import java.util.List; + +public record SignupRequest( + String nickname, + List keywords, + String authCode, + OAuthProvider oAuthProvider +) { + + public static SignupRequest of( + String nickname, + List keywords, + String authCode, + OAuthProvider oAuthProvider + ) { + return new SignupRequest( + nickname, + keywords, + authCode, + oAuthProvider + ); + } + +} diff --git a/src/main/java/coffeemeet/server/auth/utils/AuthTokens.java b/src/main/java/coffeemeet/server/auth/utils/AuthTokens.java new file mode 100644 index 00000000..37e9ca9f --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/utils/AuthTokens.java @@ -0,0 +1,18 @@ +package coffeemeet.server.auth.utils; + +public record AuthTokens( + String accessToken, + String refreshToken +) { + + public static AuthTokens of( + String accessToken, + String refreshToken + ) { + return new AuthTokens( + accessToken, + refreshToken + ); + } + +} diff --git a/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java b/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java new file mode 100644 index 00000000..88f212c5 --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java @@ -0,0 +1,53 @@ +package coffeemeet.server.auth.utils; + +import java.util.Date; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class AuthTokensGenerator { + + private static final String BEARER_TYPE = "Bearer "; + + private final JwtTokenProvider jwtTokenProvider; + private final Long accessTokenExpireTime; + private final Long refreshTokenExpireTime; + + public AuthTokensGenerator(JwtTokenProvider jwtTokenProvider, + @Value("${jwt.access-token-expire-time}") Long accessTokenExpireTime, + @Value("${jwt.refresh-token-expire-time}") Long refreshTokenExpireTime + ) { + this.jwtTokenProvider = jwtTokenProvider; + this.accessTokenExpireTime = accessTokenExpireTime; + this.refreshTokenExpireTime = refreshTokenExpireTime; + } + + public AuthTokens generate(Long userId) { + long now = (new Date()).getTime(); + Date accessTokenExpiredAt = new Date(now + accessTokenExpireTime); + Date refreshTokenExpiredAt = new Date(now + refreshTokenExpireTime); + + String subject = userId.toString(); + String accessToken = jwtTokenProvider.generate(subject, accessTokenExpiredAt); + String refreshToken = jwtTokenProvider.generate(subject, refreshTokenExpiredAt); + + return AuthTokens.of( + BEARER_TYPE + accessToken, + BEARER_TYPE + refreshToken + ); + } + + public AuthTokens refreshJwtToken(Long userId, String refreshToken) { + long now = (new Date()).getTime(); + Date accessTokenExpiredAt = new Date(now + accessTokenExpireTime); + + String subject = userId.toString(); + String accessToken = jwtTokenProvider.generate(subject, accessTokenExpiredAt); + + return AuthTokens.of( + BEARER_TYPE + accessToken, + BEARER_TYPE + refreshToken + ); + } + +} diff --git a/src/main/java/coffeemeet/server/auth/utils/JwtTokenProvider.java b/src/main/java/coffeemeet/server/auth/utils/JwtTokenProvider.java new file mode 100644 index 00000000..516754cd --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/utils/JwtTokenProvider.java @@ -0,0 +1,70 @@ +package coffeemeet.server.auth.utils; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.UnsupportedJwtException; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.security.Keys; +import java.security.Key; +import java.util.Date; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class JwtTokenProvider { + + private static final String EXPIRED_TOKEN_MESSAGE = "토큰이 만료되었습니다."; + private static final String INVALID_FORMAT_TOKEN_MESSAGE = "토큰의 형식이 적절하지 않습니다."; + private static final String INVALID_STRUCTURE_TOKEN_MESSAGE = "토큰이 올바르게 구성되지 않았거나, 적절하지 않게 수정되었습니다."; + private final Key key; + + public JwtTokenProvider(@Value("${jwt.secret-key}") String secretKey) { + byte[] keyBytes = Decoders.BASE64.decode(secretKey); + this.key = Keys.hmacShaKeyFor(keyBytes); + } + + public String generate(String subject, Date expiredAt) { + return Jwts.builder() + .setSubject(subject) + .setExpiration(expiredAt) + .signWith(key, SignatureAlgorithm.HS512) + .compact(); + } + + public Long extractUserId(String token) { + Claims claims = parseClaims(token); + return Long.parseLong(claims.getSubject()); + } + + public boolean isExpiredRefreshToken(String token) { + try { + Jwts.parserBuilder() + .setSigningKey(key) + .build() + .parseClaimsJws(token); + return false; + } catch (Exception e) { + return true; + } + } + + private Claims parseClaims(String accessToken) { + try { + return Jwts.parserBuilder() + .setSigningKey(key) + .build() + .parseClaimsJws(accessToken) + .getBody(); + } catch (ExpiredJwtException e) { + throw new IllegalArgumentException(EXPIRED_TOKEN_MESSAGE); + } catch (UnsupportedJwtException e) { + throw new IllegalArgumentException(INVALID_FORMAT_TOKEN_MESSAGE); + } catch (MalformedJwtException e) { + throw new IllegalArgumentException(INVALID_STRUCTURE_TOKEN_MESSAGE); + } + } + +} diff --git a/src/main/java/coffeemeet/server/user/domain/OAuthProvider.java b/src/main/java/coffeemeet/server/user/domain/OAuthProvider.java index 64a285ec..93496556 100644 --- a/src/main/java/coffeemeet/server/user/domain/OAuthProvider.java +++ b/src/main/java/coffeemeet/server/user/domain/OAuthProvider.java @@ -1,6 +1,14 @@ package coffeemeet.server.user.domain; +import static java.util.Locale.ENGLISH; + public enum OAuthProvider { KAKAO, NAVER, + ; + + public static OAuthProvider from(String type) { + return OAuthProvider.valueOf(type.toUpperCase(ENGLISH)); + } + } From 17d70f2752c0cc0244181bf65b2cbf0d5ffa1d7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 00:13:17 +0900 Subject: [PATCH 029/311] =?UTF-8?q?feat:=20OAuthProvider=20=EC=BB=A8?= =?UTF-8?q?=EB=B2=84=ED=84=B0=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../converter/OAuthProviderConverter.java | 14 +++++++++++++ .../server/common/config/AuthWebConfig.java | 21 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 src/main/java/coffeemeet/server/auth/utils/converter/OAuthProviderConverter.java create mode 100644 src/main/java/coffeemeet/server/common/config/AuthWebConfig.java diff --git a/src/main/java/coffeemeet/server/auth/utils/converter/OAuthProviderConverter.java b/src/main/java/coffeemeet/server/auth/utils/converter/OAuthProviderConverter.java new file mode 100644 index 00000000..c828aad1 --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/utils/converter/OAuthProviderConverter.java @@ -0,0 +1,14 @@ +package coffeemeet.server.auth.utils.converter; + +import coffeemeet.server.user.domain.OAuthProvider; +import jakarta.validation.constraints.NotNull; +import org.springframework.core.convert.converter.Converter; + +public class OAuthProviderConverter implements Converter { + + @Override + public OAuthProvider convert(@NotNull String provider) { + return OAuthProvider.from(provider); + } + +} diff --git a/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java b/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java new file mode 100644 index 00000000..38715672 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java @@ -0,0 +1,21 @@ +package coffeemeet.server.common.config; + +import coffeemeet.server.auth.utils.JwtTokenProvider; +import coffeemeet.server.auth.utils.converter.OAuthProviderConverter; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.format.FormatterRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +@RequiredArgsConstructor +public class AuthWebConfig implements WebMvcConfigurer { + + private final JwtTokenProvider jwtTokenProvider; + + @Override + public void addFormatters(FormatterRegistry registry) { + registry.addConverter(new OAuthProviderConverter()); + } + +} From f225e0c61e3e4831baf97c3c42c82bef86908d0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 00:13:29 +0900 Subject: [PATCH 030/311] =?UTF-8?q?feat:=20AuthConfig=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/common/config/AuthConfig.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/config/AuthConfig.java diff --git a/src/main/java/coffeemeet/server/common/config/AuthConfig.java b/src/main/java/coffeemeet/server/common/config/AuthConfig.java new file mode 100644 index 00000000..77813b06 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/config/AuthConfig.java @@ -0,0 +1,15 @@ +package coffeemeet.server.common.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class AuthConfig { + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } + +} From f35cf6377b51a878314ae75b6f90d556d9cf77bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 00:13:51 +0900 Subject: [PATCH 031/311] =?UTF-8?q?feat:=20Kakao=20=ED=9A=8C=EC=9B=90?= =?UTF-8?q?=EA=B0=80=EC=9E=85=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../KakaoAuthCodeRequestUrlProvider.java | 34 ++++++++++ .../oauth/kakao/client/KakaoApiClient.java | 62 +++++++++++++++++++ .../oauth/kakao/client/KakaoMemberClient.java | 30 +++++++++ .../oauth/kakao/config/KakaoConfig.java | 10 +++ .../oauth/kakao/config/KakaoProperties.java | 16 +++++ .../oauth/kakao/dto/KakaoMemberResponse.java | 45 ++++++++++++++ .../oauth/kakao/dto/KakaoTokens.java | 14 +++++ 7 files changed, 211 insertions(+) create mode 100644 src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/authcode/KakaoAuthCodeRequestUrlProvider.java create mode 100644 src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoApiClient.java create mode 100644 src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoMemberClient.java create mode 100644 src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/config/KakaoConfig.java create mode 100644 src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/config/KakaoProperties.java create mode 100644 src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoMemberResponse.java create mode 100644 src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoTokens.java diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/authcode/KakaoAuthCodeRequestUrlProvider.java b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/authcode/KakaoAuthCodeRequestUrlProvider.java new file mode 100644 index 00000000..4e65a2fc --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/authcode/KakaoAuthCodeRequestUrlProvider.java @@ -0,0 +1,34 @@ +package coffeemeet.server.auth.infrastructure.oauth.kakao.authcode; + +import coffeemeet.server.auth.infrastructure.oauth.kakao.config.KakaoProperties; +import coffeemeet.server.auth.domain.authcode.AuthCodeRequestUrlProvider; +import coffeemeet.server.user.domain.OAuthProvider; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.web.util.UriComponentsBuilder; + +@Component +@RequiredArgsConstructor +public class KakaoAuthCodeRequestUrlProvider implements AuthCodeRequestUrlProvider { + + private static final String AUTHORIZE_URL = "https://kauth.kakao.com/oauth/authorize"; + private static final String RESPONSE_TYPE = "code"; + + private final KakaoProperties kakaoProperties; + + @Override + public OAuthProvider oAuthProvider() { + return OAuthProvider.KAKAO; + } + + @Override + public String provide() { + return UriComponentsBuilder + .fromUriString(AUTHORIZE_URL) + .queryParam("response_type", RESPONSE_TYPE) + .queryParam("client_id", kakaoProperties.getClientId()) + .queryParam("redirect_uri", kakaoProperties.getRedirectUrl()) + .toUriString(); + } + +} diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoApiClient.java b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoApiClient.java new file mode 100644 index 00000000..a1440505 --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoApiClient.java @@ -0,0 +1,62 @@ +package coffeemeet.server.auth.infrastructure.oauth.kakao.client; + +import coffeemeet.server.auth.infrastructure.oauth.kakao.config.KakaoProperties; +import coffeemeet.server.auth.infrastructure.oauth.kakao.dto.KakaoMemberResponse; +import coffeemeet.server.auth.infrastructure.oauth.kakao.dto.KakaoTokens; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +@Component +@RequiredArgsConstructor +public class KakaoApiClient { + + private static final String REQUEST_TOKEN_URL = "https://kauth.kakao.com/oauth/token"; + private static final String REQUEST_INFO_URL = "https://kapi.kakao.com/v2/user/me"; + private static final String GRANT_TYPE = "authorization_code"; + private static final String BEARER_TYPE = "Bearer "; + + private final RestTemplate restTemplate; + private final KakaoProperties kakaoProperties; + + public KakaoTokens fetchToken(String authCode) { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + + MultiValueMap body = new LinkedMultiValueMap<>(); + body.add("grant_type", GRANT_TYPE); + body.add("client_id", kakaoProperties.getClientId()); + body.add("redirect_uri", kakaoProperties.getRedirectUrl()); + body.add("client_secret", kakaoProperties.getClientSecret()); + body.add("code", authCode); + + HttpEntity request = new HttpEntity<>(body, httpHeaders); + + KakaoTokens response = restTemplate.postForObject(REQUEST_TOKEN_URL, request, + KakaoTokens.class); + + assert response != null; + return response; + } + + public KakaoMemberResponse fetchMember(String accessToken) { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + httpHeaders.set("Authorization", BEARER_TYPE + accessToken); + + HttpEntity request = new HttpEntity<>(httpHeaders); + + KakaoMemberResponse response = restTemplate.exchange(REQUEST_INFO_URL, HttpMethod.GET, request, + KakaoMemberResponse.class).getBody(); + + assert response != null; + return response; + } + +} diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoMemberClient.java b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoMemberClient.java new file mode 100644 index 00000000..e5ced4d7 --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoMemberClient.java @@ -0,0 +1,30 @@ +package coffeemeet.server.auth.infrastructure.oauth.kakao.client; + +import coffeemeet.server.auth.infrastructure.oauth.kakao.dto.KakaoMemberResponse; +import coffeemeet.server.auth.infrastructure.oauth.kakao.dto.KakaoTokens; +import coffeemeet.server.auth.domain.client.OAuthMemberClient; +import coffeemeet.server.auth.domain.dto.OAuthInfoResponse; +import coffeemeet.server.user.domain.OAuthProvider; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class KakaoMemberClient implements OAuthMemberClient { + + private final KakaoApiClient kakaoApiClient; + + @Override + public OAuthProvider oAuthProvider() { + return OAuthProvider.KAKAO; + } + + @Override + public OAuthInfoResponse fetch(String authCode) { + KakaoTokens tokenInfo = kakaoApiClient.fetchToken(authCode); + KakaoMemberResponse response = kakaoApiClient.fetchMember(tokenInfo.accessToken()); + + return response.toOAuthInfoResponse(); + } + +} diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/config/KakaoConfig.java b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/config/KakaoConfig.java new file mode 100644 index 00000000..27524a2e --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/config/KakaoConfig.java @@ -0,0 +1,10 @@ +package coffeemeet.server.auth.infrastructure.oauth.kakao.config; + +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableConfigurationProperties(KakaoProperties.class) +public class KakaoConfig { + +} diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/config/KakaoProperties.java b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/config/KakaoProperties.java new file mode 100644 index 00000000..7f148f8b --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/config/KakaoProperties.java @@ -0,0 +1,16 @@ +package coffeemeet.server.auth.infrastructure.oauth.kakao.config; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.context.properties.ConfigurationProperties; + +@Getter +@RequiredArgsConstructor +@ConfigurationProperties(prefix = "oauth.kakao") +public class KakaoProperties { + + private final String clientId; + private final String redirectUrl; + private final String clientSecret; + +} diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoMemberResponse.java b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoMemberResponse.java new file mode 100644 index 00000000..d3ab4ef0 --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoMemberResponse.java @@ -0,0 +1,45 @@ +package coffeemeet.server.auth.infrastructure.oauth.kakao.dto; + +import coffeemeet.server.auth.domain.dto.OAuthInfoResponse; +import coffeemeet.server.user.domain.Birth; +import coffeemeet.server.user.domain.Email; +import coffeemeet.server.user.domain.OAuthProvider; +import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +@JsonNaming(SnakeCaseStrategy.class) +public record KakaoMemberResponse( + Long id, + KakaoAccount kakaoAccount +) { + + public OAuthInfoResponse toOAuthInfoResponse() { + return OAuthInfoResponse.of( + kakaoAccount.profile.name, + kakaoAccount.profile.profileImageUrl, + new Birth(kakaoAccount.birthyear, kakaoAccount.birthday), + new Email(kakaoAccount.email), + OAuthProvider.KAKAO, + String.valueOf(id) + ); + } + + @JsonNaming(SnakeCaseStrategy.class) + private record KakaoAccount( + Profile profile, + String email, + String birthyear, + String birthday + ) { + + } + + @JsonNaming(SnakeCaseStrategy.class) + private record Profile( + String name, + String profileImageUrl + ) { + + } + +} diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoTokens.java b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoTokens.java new file mode 100644 index 00000000..b678eb11 --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoTokens.java @@ -0,0 +1,14 @@ +package coffeemeet.server.auth.infrastructure.oauth.kakao.dto; + +import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; + +@JsonNaming(SnakeCaseStrategy.class) +public record KakaoTokens( + String accessToken, + String tokenType, + String refreshToken, + int expiresIn, + int refreshTokenExpiresIn +) { +} From 7f6a61ec5ce92a9997405f1ee91996a1b2b2a8b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 00:24:26 +0900 Subject: [PATCH 032/311] =?UTF-8?q?chore:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?yml=20=ED=8C=8C=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/resources/application.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index 12bbdbbb..71685eff 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -12,6 +12,17 @@ spring: hibernate: format_sql: true +jwt: + secret-key: yo0ToXEwMlNd32XqxRGKx8hsHWIk6P0u2/xlpny1vFw + access-token-expire-time: 3600000 + refresh-token-expire-time: 1209600000 + +oauth: + kakao: + client-id: 8cb00376d47f416927cadfded0f9dab3 + redirect-url: http://localhost:8080/oauth/redirected/kakao + client-secret: 223lkwe934efj2349ewufwe23owf09p1 + logging: level: org: From e24512780f8cb22c571e9f81a6b82699b8421c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 00:48:02 +0900 Subject: [PATCH 033/311] =?UTF-8?q?refactor:=20OAuthInfoResponse=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infrastructure/oauth/kakao/dto/KakaoMemberResponse.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoMemberResponse.java b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoMemberResponse.java index d3ab4ef0..145c9558 100644 --- a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoMemberResponse.java +++ b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoMemberResponse.java @@ -15,7 +15,7 @@ public record KakaoMemberResponse( public OAuthInfoResponse toOAuthInfoResponse() { return OAuthInfoResponse.of( - kakaoAccount.profile.name, + kakaoAccount.name, kakaoAccount.profile.profileImageUrl, new Birth(kakaoAccount.birthyear, kakaoAccount.birthday), new Email(kakaoAccount.email), @@ -27,6 +27,7 @@ public OAuthInfoResponse toOAuthInfoResponse() { @JsonNaming(SnakeCaseStrategy.class) private record KakaoAccount( Profile profile, + String name, String email, String birthyear, String birthday @@ -36,7 +37,6 @@ private record KakaoAccount( @JsonNaming(SnakeCaseStrategy.class) private record Profile( - String name, String profileImageUrl ) { From 80f708263b9add84e0fc101b3c4774eab1333bbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 00:48:45 +0900 Subject: [PATCH 034/311] =?UTF-8?q?test:=20AuthController=EC=9D=98=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=20=EA=B6=8C=ED=95=9C=20url=20=EB=A6=AC?= =?UTF-8?q?=EB=8B=A4=EC=9D=B4=EB=A0=89=ED=8A=B8=20=EA=B8=B0=EB=8A=A5=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 --- .../common/config/ControllerTestConfig.java | 39 ++++++++++++ .../auth/controller/AuthControllerTest.java | 61 +++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 src/test/java/coffeemeet/server/auth/common/config/ControllerTestConfig.java create mode 100644 src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java diff --git a/src/test/java/coffeemeet/server/auth/common/config/ControllerTestConfig.java b/src/test/java/coffeemeet/server/auth/common/config/ControllerTestConfig.java new file mode 100644 index 00000000..9114931e --- /dev/null +++ b/src/test/java/coffeemeet/server/auth/common/config/ControllerTestConfig.java @@ -0,0 +1,39 @@ +package coffeemeet.server.auth.common.config; + +import coffeemeet.server.auth.utils.JwtTokenProvider; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.restdocs.RestDocumentationContextProvider; +import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.filter.CharacterEncodingFilter; + +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; + +@ExtendWith({RestDocumentationExtension.class}) +public abstract class ControllerTestConfig { + + protected static final String TOKEN = "Bearer aaaaaaaa.bbbbbbb.ccccccc"; + + protected ObjectMapper objectMapper = new ObjectMapper(); + + protected MockMvc mockMvc; + + @MockBean + protected JwtTokenProvider jwtTokenProvider; + + @BeforeEach + void setUp(WebApplicationContext ctx, RestDocumentationContextProvider restDocumentation) { + mockMvc = MockMvcBuilders.webAppContextSetup(ctx) + .apply(documentationConfiguration(restDocumentation)) + .addFilters(new CharacterEncodingFilter("UTF-8", true)) + .alwaysDo(print()) + .build(); + } + +} diff --git a/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java b/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java new file mode 100644 index 00000000..5fef4ba1 --- /dev/null +++ b/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java @@ -0,0 +1,61 @@ +package coffeemeet.server.auth.controller; + +import coffeemeet.server.auth.common.config.ControllerTestConfig; +import coffeemeet.server.auth.service.AuthService; +import coffeemeet.server.user.domain.OAuthProvider; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; + +import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; +import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.resourceDetails; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(AuthController.class) +class AuthControllerTest extends ControllerTestConfig { + + @MockBean + private AuthService authService; + + @DisplayName("사용자가 로그인 버튼을 누르면 해당하는 서비스의 접근 권한 url로 리다이렉트한다.") + @Test + void redirectAuthCodeRequestUrlTest() throws Exception { + String expectedRedirectUrl = "https://example.com"; + + when(authService.getAuthCodeRequestUrl(eq(OAuthProvider.KAKAO))).thenReturn( + expectedRedirectUrl); + + mockMvc.perform(get("/oauth2/auth/{oAuthProvider}", OAuthProvider.KAKAO) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + ) + .andDo(document("auth-redirect", + resourceDetails().tag("Auth").description("접근 권한 url 리다이렉트"), + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + pathParameters( + parameterWithName("oAuthProvider").description("OAuth 로그인 타입") + ), + responseHeaders( + headerWithName("Location").description("리다이렉션 대상 URL") + ) + ) + ) + .andExpect(status().is3xxRedirection()) + .andExpect(redirectedUrl(expectedRedirectUrl)); + } + +} From dbad77679864183c873cbc1dd4e7864e1d9a2c57 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 01:04:24 +0900 Subject: [PATCH 035/311] =?UTF-8?q?:lipstick:=20=EA=B2=BD=EB=A1=9C=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 --- .../coffeemeet/server/ServerApplication.java | 6 ++-- .../auth/controller/AuthController.java | 4 +-- .../auth/domain/client/OAuthMemberClient.java | 2 +- .../client/OAuthMemberClientComposite.java | 2 +- .../{domain => }/dto/OAuthInfoResponse.java | 2 +- .../auth/{domain => }/dto/SignupRequest.java | 2 +- .../KakaoAuthCodeRequestUrlProvider.java | 34 +++++++++---------- .../oauth/kakao/client/KakaoMemberClient.java | 4 +-- .../oauth/kakao/dto/KakaoMemberResponse.java | 2 +- .../oauth/kakao/dto/KakaoTokens.java | 11 +++--- .../server/auth/service/AuthService.java | 8 ++--- .../server/auth/utils/AuthTokens.java | 22 ++++++------ .../server/common/config/AuthConfig.java | 8 ++--- .../user/repository/UserRepository.java | 3 +- .../server/ServerApplicationTests.java | 13 ------- .../auth/controller/AuthControllerTest.java | 21 ++++++------ .../common/config/ControllerTestConfig.java | 8 ++--- 17 files changed, 70 insertions(+), 82 deletions(-) rename src/main/java/coffeemeet/server/auth/{domain => }/dto/OAuthInfoResponse.java (93%) rename src/main/java/coffeemeet/server/auth/{domain => }/dto/SignupRequest.java (92%) delete mode 100644 src/test/java/coffeemeet/server/ServerApplicationTests.java rename src/test/java/coffeemeet/server/{auth => }/common/config/ControllerTestConfig.java (97%) diff --git a/src/main/java/coffeemeet/server/ServerApplication.java b/src/main/java/coffeemeet/server/ServerApplication.java index 792c27a1..ec48a22b 100644 --- a/src/main/java/coffeemeet/server/ServerApplication.java +++ b/src/main/java/coffeemeet/server/ServerApplication.java @@ -6,8 +6,8 @@ @SpringBootApplication public class ServerApplication { - public static void main(String[] args) { - SpringApplication.run(ServerApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } } diff --git a/src/main/java/coffeemeet/server/auth/controller/AuthController.java b/src/main/java/coffeemeet/server/auth/controller/AuthController.java index 48877b4f..7ced79a7 100644 --- a/src/main/java/coffeemeet/server/auth/controller/AuthController.java +++ b/src/main/java/coffeemeet/server/auth/controller/AuthController.java @@ -1,8 +1,8 @@ package coffeemeet.server.auth.controller; -import coffeemeet.server.auth.utils.AuthTokens; -import coffeemeet.server.auth.domain.dto.SignupRequest; +import coffeemeet.server.auth.dto.SignupRequest; import coffeemeet.server.auth.service.AuthService; +import coffeemeet.server.auth.utils.AuthTokens; import coffeemeet.server.user.domain.OAuthProvider; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; diff --git a/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClient.java b/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClient.java index b61cb965..28c018c0 100644 --- a/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClient.java +++ b/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClient.java @@ -1,6 +1,6 @@ package coffeemeet.server.auth.domain.client; -import coffeemeet.server.auth.domain.dto.OAuthInfoResponse; +import coffeemeet.server.auth.dto.OAuthInfoResponse; import coffeemeet.server.user.domain.OAuthProvider; public interface OAuthMemberClient { diff --git a/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClientComposite.java b/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClientComposite.java index e3489e6d..5ad41848 100644 --- a/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClientComposite.java +++ b/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClientComposite.java @@ -1,6 +1,6 @@ package coffeemeet.server.auth.domain.client; -import coffeemeet.server.auth.domain.dto.OAuthInfoResponse; +import coffeemeet.server.auth.dto.OAuthInfoResponse; import coffeemeet.server.user.domain.OAuthProvider; import java.util.Map; import java.util.Optional; diff --git a/src/main/java/coffeemeet/server/auth/domain/dto/OAuthInfoResponse.java b/src/main/java/coffeemeet/server/auth/dto/OAuthInfoResponse.java similarity index 93% rename from src/main/java/coffeemeet/server/auth/domain/dto/OAuthInfoResponse.java rename to src/main/java/coffeemeet/server/auth/dto/OAuthInfoResponse.java index f14ceab0..679bde6e 100644 --- a/src/main/java/coffeemeet/server/auth/domain/dto/OAuthInfoResponse.java +++ b/src/main/java/coffeemeet/server/auth/dto/OAuthInfoResponse.java @@ -1,4 +1,4 @@ -package coffeemeet.server.auth.domain.dto; +package coffeemeet.server.auth.dto; import coffeemeet.server.user.domain.Birth; import coffeemeet.server.user.domain.Email; diff --git a/src/main/java/coffeemeet/server/auth/domain/dto/SignupRequest.java b/src/main/java/coffeemeet/server/auth/dto/SignupRequest.java similarity index 92% rename from src/main/java/coffeemeet/server/auth/domain/dto/SignupRequest.java rename to src/main/java/coffeemeet/server/auth/dto/SignupRequest.java index 232f8530..4cb8c8ee 100644 --- a/src/main/java/coffeemeet/server/auth/domain/dto/SignupRequest.java +++ b/src/main/java/coffeemeet/server/auth/dto/SignupRequest.java @@ -1,4 +1,4 @@ -package coffeemeet.server.auth.domain.dto; +package coffeemeet.server.auth.dto; import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.user.domain.OAuthProvider; diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/authcode/KakaoAuthCodeRequestUrlProvider.java b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/authcode/KakaoAuthCodeRequestUrlProvider.java index 4e65a2fc..29121844 100644 --- a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/authcode/KakaoAuthCodeRequestUrlProvider.java +++ b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/authcode/KakaoAuthCodeRequestUrlProvider.java @@ -1,7 +1,7 @@ package coffeemeet.server.auth.infrastructure.oauth.kakao.authcode; -import coffeemeet.server.auth.infrastructure.oauth.kakao.config.KakaoProperties; import coffeemeet.server.auth.domain.authcode.AuthCodeRequestUrlProvider; +import coffeemeet.server.auth.infrastructure.oauth.kakao.config.KakaoProperties; import coffeemeet.server.user.domain.OAuthProvider; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -11,24 +11,24 @@ @RequiredArgsConstructor public class KakaoAuthCodeRequestUrlProvider implements AuthCodeRequestUrlProvider { - private static final String AUTHORIZE_URL = "https://kauth.kakao.com/oauth/authorize"; - private static final String RESPONSE_TYPE = "code"; + private static final String AUTHORIZE_URL = "https://kauth.kakao.com/oauth/authorize"; + private static final String RESPONSE_TYPE = "code"; - private final KakaoProperties kakaoProperties; + private final KakaoProperties kakaoProperties; - @Override - public OAuthProvider oAuthProvider() { - return OAuthProvider.KAKAO; - } + @Override + public OAuthProvider oAuthProvider() { + return OAuthProvider.KAKAO; + } - @Override - public String provide() { - return UriComponentsBuilder - .fromUriString(AUTHORIZE_URL) - .queryParam("response_type", RESPONSE_TYPE) - .queryParam("client_id", kakaoProperties.getClientId()) - .queryParam("redirect_uri", kakaoProperties.getRedirectUrl()) - .toUriString(); - } + @Override + public String provide() { + return UriComponentsBuilder + .fromUriString(AUTHORIZE_URL) + .queryParam("response_type", RESPONSE_TYPE) + .queryParam("client_id", kakaoProperties.getClientId()) + .queryParam("redirect_uri", kakaoProperties.getRedirectUrl()) + .toUriString(); + } } diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoMemberClient.java b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoMemberClient.java index e5ced4d7..8771e9bc 100644 --- a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoMemberClient.java +++ b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoMemberClient.java @@ -1,9 +1,9 @@ package coffeemeet.server.auth.infrastructure.oauth.kakao.client; +import coffeemeet.server.auth.domain.client.OAuthMemberClient; +import coffeemeet.server.auth.dto.OAuthInfoResponse; import coffeemeet.server.auth.infrastructure.oauth.kakao.dto.KakaoMemberResponse; import coffeemeet.server.auth.infrastructure.oauth.kakao.dto.KakaoTokens; -import coffeemeet.server.auth.domain.client.OAuthMemberClient; -import coffeemeet.server.auth.domain.dto.OAuthInfoResponse; import coffeemeet.server.user.domain.OAuthProvider; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoMemberResponse.java b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoMemberResponse.java index 145c9558..295da79e 100644 --- a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoMemberResponse.java +++ b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoMemberResponse.java @@ -1,6 +1,6 @@ package coffeemeet.server.auth.infrastructure.oauth.kakao.dto; -import coffeemeet.server.auth.domain.dto.OAuthInfoResponse; +import coffeemeet.server.auth.dto.OAuthInfoResponse; import coffeemeet.server.user.domain.Birth; import coffeemeet.server.user.domain.Email; import coffeemeet.server.user.domain.OAuthProvider; diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoTokens.java b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoTokens.java index b678eb11..84404093 100644 --- a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoTokens.java +++ b/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoTokens.java @@ -5,10 +5,11 @@ @JsonNaming(SnakeCaseStrategy.class) public record KakaoTokens( - String accessToken, - String tokenType, - String refreshToken, - int expiresIn, - int refreshTokenExpiresIn + String accessToken, + String tokenType, + String refreshToken, + int expiresIn, + int refreshTokenExpiresIn ) { + } diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index b84aa1ff..cde3a740 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -1,11 +1,11 @@ package coffeemeet.server.auth.service; -import coffeemeet.server.auth.utils.AuthTokens; -import coffeemeet.server.auth.utils.AuthTokensGenerator; import coffeemeet.server.auth.domain.authcode.AuthCodeRequestUrlProviderComposite; import coffeemeet.server.auth.domain.client.OAuthMemberClientComposite; -import coffeemeet.server.auth.domain.dto.OAuthInfoResponse; -import coffeemeet.server.auth.domain.dto.SignupRequest; +import coffeemeet.server.auth.dto.OAuthInfoResponse; +import coffeemeet.server.auth.dto.SignupRequest; +import coffeemeet.server.auth.utils.AuthTokens; +import coffeemeet.server.auth.utils.AuthTokensGenerator; import coffeemeet.server.interest.domain.Interest; import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.interest.repository.InterestRepository; diff --git a/src/main/java/coffeemeet/server/auth/utils/AuthTokens.java b/src/main/java/coffeemeet/server/auth/utils/AuthTokens.java index 37e9ca9f..cdbfaf21 100644 --- a/src/main/java/coffeemeet/server/auth/utils/AuthTokens.java +++ b/src/main/java/coffeemeet/server/auth/utils/AuthTokens.java @@ -1,18 +1,18 @@ package coffeemeet.server.auth.utils; public record AuthTokens( - String accessToken, - String refreshToken + String accessToken, + String refreshToken ) { - public static AuthTokens of( - String accessToken, - String refreshToken - ) { - return new AuthTokens( - accessToken, - refreshToken - ); - } + public static AuthTokens of( + String accessToken, + String refreshToken + ) { + return new AuthTokens( + accessToken, + refreshToken + ); + } } diff --git a/src/main/java/coffeemeet/server/common/config/AuthConfig.java b/src/main/java/coffeemeet/server/common/config/AuthConfig.java index 77813b06..dea6f202 100644 --- a/src/main/java/coffeemeet/server/common/config/AuthConfig.java +++ b/src/main/java/coffeemeet/server/common/config/AuthConfig.java @@ -7,9 +7,9 @@ @Configuration public class AuthConfig { - @Bean - public RestTemplate restTemplate() { - return new RestTemplate(); - } + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } } diff --git a/src/main/java/coffeemeet/server/user/repository/UserRepository.java b/src/main/java/coffeemeet/server/user/repository/UserRepository.java index c0686339..a83cdb69 100644 --- a/src/main/java/coffeemeet/server/user/repository/UserRepository.java +++ b/src/main/java/coffeemeet/server/user/repository/UserRepository.java @@ -6,7 +6,8 @@ public interface UserRepository extends JpaRepository { - boolean existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId(OAuthProvider oauthProvider, + boolean existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( + OAuthProvider oauthProvider, String oauthProviderId); } diff --git a/src/test/java/coffeemeet/server/ServerApplicationTests.java b/src/test/java/coffeemeet/server/ServerApplicationTests.java deleted file mode 100644 index 4a41637f..00000000 --- a/src/test/java/coffeemeet/server/ServerApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -package coffeemeet.server; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class ServerApplicationTests { - - @Test - void contextLoads() { - } - -} diff --git a/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java b/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java index 5fef4ba1..0a539001 100644 --- a/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java +++ b/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java @@ -1,17 +1,7 @@ package coffeemeet.server.auth.controller; -import coffeemeet.server.auth.common.config.ControllerTestConfig; -import coffeemeet.server.auth.service.AuthService; -import coffeemeet.server.user.domain.OAuthProvider; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; - import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.resourceDetails; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; @@ -24,6 +14,15 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import coffeemeet.server.auth.service.AuthService; +import coffeemeet.server.common.config.ControllerTestConfig; +import coffeemeet.server.user.domain.OAuthProvider; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; + @WebMvcTest(AuthController.class) class AuthControllerTest extends ControllerTestConfig { @@ -35,7 +34,7 @@ class AuthControllerTest extends ControllerTestConfig { void redirectAuthCodeRequestUrlTest() throws Exception { String expectedRedirectUrl = "https://example.com"; - when(authService.getAuthCodeRequestUrl(eq(OAuthProvider.KAKAO))).thenReturn( + when(authService.getAuthCodeRequestUrl(OAuthProvider.KAKAO)).thenReturn( expectedRedirectUrl); mockMvc.perform(get("/oauth2/auth/{oAuthProvider}", OAuthProvider.KAKAO) diff --git a/src/test/java/coffeemeet/server/auth/common/config/ControllerTestConfig.java b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java similarity index 97% rename from src/test/java/coffeemeet/server/auth/common/config/ControllerTestConfig.java rename to src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java index 9114931e..f9f30ee2 100644 --- a/src/test/java/coffeemeet/server/auth/common/config/ControllerTestConfig.java +++ b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java @@ -1,4 +1,7 @@ -package coffeemeet.server.auth.common.config; +package coffeemeet.server.common.config; + +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import coffeemeet.server.auth.utils.JwtTokenProvider; import com.fasterxml.jackson.databind.ObjectMapper; @@ -12,9 +15,6 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.filter.CharacterEncodingFilter; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; - @ExtendWith({RestDocumentationExtension.class}) public abstract class ControllerTestConfig { From 7ecbc20890b92ca49da49b2521cb1557ad31b99a Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 10:36:26 +0900 Subject: [PATCH 036/311] =?UTF-8?q?docs:=20s3=20=EC=84=A4=EC=A0=95=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/resources/application.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 8304cf69..f8f17edb 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -36,4 +36,16 @@ logging: hibernate: orm: jdbc: - bind: trace \ No newline at end of file + bind: trace +cloud: + aws: + s3: + bucket: ${CLOUD_AWS_S3_BUCKET_NAME} + credentials: + access-key: ${CLOUD_AWS_CREDENTIALS_ACCESS_KEY} + secret-key: ${CLOUD_AWS_CREDENTIALS_SECRET_KEY} + region: + static: ${CLOUD_AWS_REGION_STATIC} + auto: false + stack: + auto: false From a394781925479ad9db13e04db228c903df62039b Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 10:37:30 +0900 Subject: [PATCH 037/311] =?UTF-8?q?refactor:=20=EC=83=9D=EC=84=B1=EC=9E=90?= =?UTF-8?q?=20=EC=A0=91=EA=B7=BC=EC=A7=80=EC=8B=9C=EC=9E=90=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD,=20=EB=A7=A4=EC=A7=81=20=EB=84=98=EB=B2=84=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/coffeemeet/server/user/domain/Birth.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/Birth.java b/src/main/java/coffeemeet/server/user/domain/Birth.java index 506fe396..e772f1db 100644 --- a/src/main/java/coffeemeet/server/user/domain/Birth.java +++ b/src/main/java/coffeemeet/server/user/domain/Birth.java @@ -2,21 +2,22 @@ import jakarta.persistence.Column; import jakarta.persistence.Embeddable; +import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.util.StringUtils; @Getter @Embeddable -@NoArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Birth { private static final int BIRTH_LENGTH = 4; - @Column(nullable = false, length = 4) + @Column(nullable = false, length = BIRTH_LENGTH) String year; - @Column(nullable = false, length = 4) + @Column(nullable = false, length = BIRTH_LENGTH) String day; public Birth(String year, String day) { From 18b42af1d2df0ac1cb63ab9ca011a02946c0bf3f Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 10:37:52 +0900 Subject: [PATCH 038/311] =?UTF-8?q?chore:=20cloud=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=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 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 903c2868..b6e90037 100644 --- a/build.gradle +++ b/build.gradle @@ -65,9 +65,12 @@ dependencies { /* Docs & UI */ testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' - testImplementation "com.epages:restdocs-api-spec-mockmvc:${restdocsApiSpecVersion}" + testImplementation 'com.epages:restdocs-api-spec-mockmvc:${restdocsApiSpecVersion}' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0' swaggerUI 'org.webjars:swagger-ui:4.11.1' + + /* Cloud */ + implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' } tasks.named('test') { From eabc8d04995f0b2e501f2d08bd234e953f718d42 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 10:39:45 +0900 Subject: [PATCH 039/311] =?UTF-8?q?refactor:=20=EA=B8=B0=EB=B3=B8=EA=B0=92?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EA=B0=9D=EC=B2=B4=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=EB=90=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD,=20AttributeOv?= =?UTF-8?q?erride=EB=A1=9C=20column=20=EC=A4=91=EB=B3=B5=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/domain/Certification.java | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/Certification.java b/src/main/java/coffeemeet/server/user/domain/Certification.java index 3c6b2577..4a472578 100644 --- a/src/main/java/coffeemeet/server/user/domain/Certification.java +++ b/src/main/java/coffeemeet/server/user/domain/Certification.java @@ -1,20 +1,22 @@ package coffeemeet.server.user.domain; +import jakarta.persistence.AttributeOverride; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import jakarta.persistence.Embedded; import lombok.Getter; -import lombok.NoArgsConstructor; -import org.springframework.util.StringUtils; @Getter @Embeddable -@NoArgsConstructor public class Certification { + private static final String DEFAULT_EMAIL = "default@default.com"; + private static final String DEFAULT = "default"; + @Embedded @Column(nullable = false) - private CompanyEmail companyEmail; + @AttributeOverride(name = "email", column = @Column(name = "company_email")) + private Email companyEmail; @Column(nullable = false) private String businessCardUrl; @@ -25,24 +27,15 @@ public class Certification { @Column(nullable = false) private String department; - public Certification(CompanyEmail companyEmail, String businessCardUrl, String department) { - validateBusinessCardUrl(businessCardUrl); - validateDepartment(department); - this.companyEmail = companyEmail; - this.businessCardUrl = businessCardUrl; - this.department = department; - } - - private void validateBusinessCardUrl(String businessCardUrl) { - if (!StringUtils.hasText(businessCardUrl)) { - throw new IllegalArgumentException("올바르지 않은 명함 url입니다."); - } + public Certification() { + this.companyEmail = new Email(DEFAULT_EMAIL); + this.businessCardUrl = DEFAULT; + this.department = DEFAULT; + isCertificated = false; } - private void validateDepartment(String department) { - if (!StringUtils.hasText(department)) { - throw new IllegalArgumentException("올바르지 않은 부서 이름입니다."); - } + public void updateBusinessCardUrl(String newBusinessCardUrl) { + this.businessCardUrl = newBusinessCardUrl; } public void certificate() { From 02d7de179cc47a04432eeade26d92834fedae079 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 10:40:02 +0900 Subject: [PATCH 040/311] =?UTF-8?q?refactor:=20CompanyEmail=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/domain/CompanyEmail.java | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 src/main/java/coffeemeet/server/user/domain/CompanyEmail.java diff --git a/src/main/java/coffeemeet/server/user/domain/CompanyEmail.java b/src/main/java/coffeemeet/server/user/domain/CompanyEmail.java deleted file mode 100644 index a9522bfe..00000000 --- a/src/main/java/coffeemeet/server/user/domain/CompanyEmail.java +++ /dev/null @@ -1,26 +0,0 @@ -package coffeemeet.server.user.domain; - -import coffeemeet.server.common.util.Patterns; -import jakarta.persistence.Embeddable; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@Embeddable -@NoArgsConstructor -public class CompanyEmail { - - private String companyEmail; - - public CompanyEmail(String companyEmail) { - validateCompanyEmail(companyEmail); - this.companyEmail = companyEmail; - } - - private void validateCompanyEmail(String companyEmail) { - if (!Patterns.EMAIL_PATTERN.matcher(companyEmail).matches()) { - throw new IllegalArgumentException("올바르지 않은 이메일입니다."); - } - } - -} From f9f8e354a9244db3f292c70431dd23d1fbc5ef4c Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 10:40:49 +0900 Subject: [PATCH 041/311] =?UTF-8?q?refactor:=20=EC=A0=91=EA=B7=BC=EC=A7=80?= =?UTF-8?q?=EC=8B=9C=EC=9E=90=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/coffeemeet/server/user/domain/Email.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/user/domain/Email.java b/src/main/java/coffeemeet/server/user/domain/Email.java index 14cd302e..e52f12d3 100644 --- a/src/main/java/coffeemeet/server/user/domain/Email.java +++ b/src/main/java/coffeemeet/server/user/domain/Email.java @@ -2,12 +2,13 @@ import coffeemeet.server.common.util.Patterns; import jakarta.persistence.Embeddable; +import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @Getter @Embeddable -@NoArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Email { private String email; From 1673e63e832bdd0ecf1d7b623d8111650ac6a02b Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 10:41:13 +0900 Subject: [PATCH 042/311] =?UTF-8?q?refactor:=20=EC=A0=91=EA=B7=BC=EC=A7=80?= =?UTF-8?q?=EC=8B=9C=EC=9E=90=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/user/domain/OAuthInfo.java | 3 ++- src/main/java/coffeemeet/server/user/domain/Profile.java | 3 ++- .../java/coffeemeet/server/user/domain/ReportInfo.java | 9 +++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java b/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java index da841c4c..16055bbe 100644 --- a/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java +++ b/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java @@ -3,13 +3,14 @@ import jakarta.persistence.Embeddable; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; +import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.util.StringUtils; @Getter @Embeddable -@NoArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class OAuthInfo { @Enumerated(value = EnumType.STRING) diff --git a/src/main/java/coffeemeet/server/user/domain/Profile.java b/src/main/java/coffeemeet/server/user/domain/Profile.java index 10aaa25a..97b82806 100644 --- a/src/main/java/coffeemeet/server/user/domain/Profile.java +++ b/src/main/java/coffeemeet/server/user/domain/Profile.java @@ -3,6 +3,7 @@ import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import jakarta.persistence.Embedded; +import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -10,7 +11,7 @@ @Getter @Embeddable -@NoArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Profile { private static final int NICKNAME_MAX_LENGTH = 20; diff --git a/src/main/java/coffeemeet/server/user/domain/ReportInfo.java b/src/main/java/coffeemeet/server/user/domain/ReportInfo.java index cee774c8..1bf0c209 100644 --- a/src/main/java/coffeemeet/server/user/domain/ReportInfo.java +++ b/src/main/java/coffeemeet/server/user/domain/ReportInfo.java @@ -3,15 +3,16 @@ import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import java.time.LocalDateTime; +import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @Getter @Embeddable -@NoArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class ReportInfo { - private static final int REPORT_COUNT_MIN_LENGTH = 0; + private static final int REPORT_MIN_COUNT = 0; @Column(nullable = false) private int reportedCount; @@ -27,13 +28,13 @@ public ReportInfo(int reportedCount, LocalDateTime sanctionPeriod) { } private void validateReportedCount(int reportedCount) { - if (reportedCount < 0) { + if (reportedCount < REPORT_MIN_COUNT) { throw new IllegalArgumentException("올바르지 않은 신고횟수입니다."); } } private void validateSanctionPeriod(LocalDateTime sanctionPeriod) { - if (sanctionPeriod != null) { + if (sanctionPeriod == null) { throw new IllegalArgumentException("올바르지 않은 제재 기간입니다."); } } From 051155345a19888f15b1791bda713e53e34674cf Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 10:41:55 +0900 Subject: [PATCH 043/311] =?UTF-8?q?feat:=20=EB=AA=85=ED=95=A8=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/coffeemeet/server/user/domain/User.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/coffeemeet/server/user/domain/User.java b/src/main/java/coffeemeet/server/user/domain/User.java index b7e9f0f5..3cef5706 100644 --- a/src/main/java/coffeemeet/server/user/domain/User.java +++ b/src/main/java/coffeemeet/server/user/domain/User.java @@ -57,4 +57,8 @@ public User( this.profile = profile; } + public void updateBusinessCardUrl(String newBusinessCardUrl) { + certification.updateBusinessCardUrl(newBusinessCardUrl); + } + } From cee7e4d112c5b7eb6e94d0dc01d7d4a2bff9de67 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 10:42:51 +0900 Subject: [PATCH 044/311] =?UTF-8?q?feat:=20s3=20=ED=82=A4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/BusinessCardS3KeyGenerator.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/coffeemeet/server/certification/service/BusinessCardS3KeyGenerator.java diff --git a/src/main/java/coffeemeet/server/certification/service/BusinessCardS3KeyGenerator.java b/src/main/java/coffeemeet/server/certification/service/BusinessCardS3KeyGenerator.java new file mode 100644 index 00000000..052bf629 --- /dev/null +++ b/src/main/java/coffeemeet/server/certification/service/BusinessCardS3KeyGenerator.java @@ -0,0 +1,14 @@ +package coffeemeet.server.certification.service; + +import java.time.LocalDateTime; +import java.util.UUID; +import org.springframework.stereotype.Service; + +@Service +public class BusinessCardS3KeyGenerator { + + public String generate() { + return String.format("BusinessCard-%s-%s", LocalDateTime.now(), UUID.randomUUID()); + } + +} From 9dda8b47a7541f95ba87b2fdd7d9895b88fe11b4 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 10:43:25 +0900 Subject: [PATCH 045/311] =?UTF-8?q?feat:=20s3=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/common/config/S3Config.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/config/S3Config.java diff --git a/src/main/java/coffeemeet/server/common/config/S3Config.java b/src/main/java/coffeemeet/server/common/config/S3Config.java new file mode 100644 index 00000000..67f8409a --- /dev/null +++ b/src/main/java/coffeemeet/server/common/config/S3Config.java @@ -0,0 +1,37 @@ +package coffeemeet.server.common.config; + +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class S3Config { + + private final String accessKey; + private final String secretKey; + private final String region; + + public S3Config( + @Value("${cloud.aws.credentials.access-key}") String accessKey, + @Value("${cloud.aws.credentials.secret-key}") String secretKey, + @Value("${cloud.aws.region.static}") String region) { + this.accessKey = accessKey; + this.secretKey = secretKey; + this.region = region; + } + + @Bean + public AmazonS3 amazonS3Client() { + BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey); + return AmazonS3ClientBuilder + .standard() + .withRegion(region) + .withCredentials(new AWSStaticCredentialsProvider(credentials)) + .build(); + } + +} From b8cdb87a7049bd77d8d10ea61b69c3dc8aee0dc7 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 10:45:40 +0900 Subject: [PATCH 046/311] =?UTF-8?q?feat:=20s3=20upload,=20delete,=20getUrl?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/common/media/S3MediaService.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/media/S3MediaService.java diff --git a/src/main/java/coffeemeet/server/common/media/S3MediaService.java b/src/main/java/coffeemeet/server/common/media/S3MediaService.java new file mode 100644 index 00000000..0d0f5932 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/media/S3MediaService.java @@ -0,0 +1,34 @@ +package coffeemeet.server.common.media; + +import com.amazonaws.services.s3.AmazonS3; +import java.io.File; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +@Service +public class S3MediaService { + + private final AmazonS3 amazonS3; + private final String bucketName; + + public S3MediaService( + AmazonS3 amazonS3, + @Value("${cloud.aws.s3.bucket}") String bucketName + ) { + this.amazonS3 = amazonS3; + this.bucketName = bucketName; + } + + public void upload(String key, File file) { + amazonS3.putObject(bucketName, key, file); + } + + public void delete(String key) { + amazonS3.deleteObject(bucketName, key); + } + + public String getUrl(String key) { + return amazonS3.getUrl(bucketName, key).toExternalForm(); + } + +} From 17197a1e4c53f8a8a9ef50dc056432c96a0eb1ea Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 10:47:50 +0900 Subject: [PATCH 047/311] =?UTF-8?q?feat:=20File=20=EB=B3=80=ED=99=98=20?= =?UTF-8?q?=EB=B0=8F=20=EC=82=AD=EC=A0=9C=20Util=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/common/util/FileUtils.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/util/FileUtils.java diff --git a/src/main/java/coffeemeet/server/common/util/FileUtils.java b/src/main/java/coffeemeet/server/common/util/FileUtils.java new file mode 100644 index 00000000..caf7f615 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/util/FileUtils.java @@ -0,0 +1,42 @@ +package coffeemeet.server.common.util; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.springframework.web.multipart.MultipartFile; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class FileUtils { + + private static final String MULTIPART_FILE_TRANSFER_ERROR = "MULTIPART FILE을 FILE로 변환 중 오류가 발생했습니다."; + private static final String FILE_DELETE_ERROR = "FILE 삭제 중 오류가 발생했습니다."; + + public static class FileIOException extends RuntimeException { + + public FileIOException(String message, Throwable e) { + super(message, e); + } + + } + + public static File convertMultipartFileToFile(MultipartFile multipartFile) { + try { + File file = File.createTempFile("temp", multipartFile.getOriginalFilename()); + multipartFile.transferTo(file); + return file; + } catch (IOException e) { + throw new FileIOException(MULTIPART_FILE_TRANSFER_ERROR, e); + } + } + + public static void delete(File file) { + try { + Files.delete(file.toPath()); + } catch (IOException e) { + throw new FileIOException(FILE_DELETE_ERROR, e); + } + } + +} From b42e405db4e612db807a597657ac7f19e4d4c948 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 10:48:16 +0900 Subject: [PATCH 048/311] =?UTF-8?q?feat:=20=EB=AA=85=ED=95=A8=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/service/UserService.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/main/java/coffeemeet/server/user/service/UserService.java diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java new file mode 100644 index 00000000..9502914a --- /dev/null +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -0,0 +1,23 @@ +package coffeemeet.server.user.service; + +import coffeemeet.server.user.domain.User; +import coffeemeet.server.user.repository.UserRepository; +import jakarta.persistence.EntityNotFoundException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class UserService { + + private final UserRepository userRepository; + + @Transactional + public void updateBusinessCardUrl(Long userId, String businessCardUrl) { + User user = userRepository.findById(userId) + .orElseThrow(EntityNotFoundException::new); // 에러 어떻게 처리할꺼임? + user.updateBusinessCardUrl(businessCardUrl); + } + +} From ad808905c3d23938729a77e8403c6729945f1cb3 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 10:49:29 +0900 Subject: [PATCH 049/311] =?UTF-8?q?feat:=20=EB=AA=85=ED=95=A8=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20controller=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/CertificationController.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/main/java/coffeemeet/server/certification/controller/CertificationController.java diff --git a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java new file mode 100644 index 00000000..59eb9616 --- /dev/null +++ b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java @@ -0,0 +1,38 @@ +package coffeemeet.server.certification.controller; + +import static org.springframework.http.HttpStatus.CREATED; + +import coffeemeet.server.certification.service.CertificationService; +import coffeemeet.server.common.util.FileUtils; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/certification") +public class CertificationController { + + private final CertificationService certificationService; + + @PostMapping("/users/{userId}/business-card") + @ResponseStatus(CREATED) + public void uploadBusinessCard( + @PathVariable("userId") + @NotNull(message = "유저 ID는 null일 수 없습니다.") + long userId, + @RequestPart("businessCard") + @NotNull(message = "명함 이미지는 null일 수 없습니다.") + MultipartFile businessCard + ) { + certificationService.uploadBusinessCard(userId, + FileUtils.convertMultipartFileToFile(businessCard)); + } + +} From efa39214dab2a385a1d79a78f6d89f018874f6ed Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 10:49:51 +0900 Subject: [PATCH 050/311] =?UTF-8?q?feat:=20=EB=AA=85=ED=95=A8=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20service=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CertificationService.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/main/java/coffeemeet/server/certification/service/CertificationService.java diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java new file mode 100644 index 00000000..61b9831c --- /dev/null +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -0,0 +1,26 @@ +package coffeemeet.server.certification.service; + +import coffeemeet.server.common.media.S3MediaService; +import coffeemeet.server.common.util.FileUtils; +import coffeemeet.server.user.service.UserService; +import java.io.File; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class CertificationService { + + private final S3MediaService s3MediaService; + private final UserService userService; + private final BusinessCardS3KeyGenerator businessCardS3KeyGenerator; + + public void uploadBusinessCard(long userId, File file) { + String key = businessCardS3KeyGenerator.generate(); + + s3MediaService.upload(key, file); + userService.updateBusinessCardUrl(userId, s3MediaService.getUrl(key)); + + FileUtils.delete(file); + } +} From 04fc63d8eaaa58d07bda7fe861e1a87d4b4d7835 Mon Sep 17 00:00:00 2001 From: Sangmin Park <70051888+smart-sangmin@users.noreply.github.com> Date: Mon, 23 Oct 2023 11:00:50 +0900 Subject: [PATCH 051/311] chore: Create auto_assign.yml --- .github/auto_assign.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/auto_assign.yml diff --git a/.github/auto_assign.yml b/.github/auto_assign.yml new file mode 100644 index 00000000..717af2a0 --- /dev/null +++ b/.github/auto_assign.yml @@ -0,0 +1 @@ +addAssignees: author From 237ccbac81907b98e0d7878307637751eac4a95c Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 11:03:28 +0900 Subject: [PATCH 052/311] =?UTF-8?q?chore:=20=EC=8C=8D=EB=94=B0=EC=98=B4?= =?UTF-8?q?=ED=91=9C=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 158 +++++++++++++++++++++++++-------------------------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/build.gradle b/build.gradle index b6e90037..4cecab6f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,119 +1,119 @@ import org.hidetake.gradle.swagger.generator.GenerateSwaggerUI buildscript { - ext { - restdocsApiSpecVersion = '0.18.3' // restdocsApiSpecVersion 버전 변수 설정 - } + ext { + restdocsApiSpecVersion = '0.18.3' // restdocsApiSpecVersion 버전 변수 설정 + } } plugins { - id 'java' - id 'org.springframework.boot' version '3.1.4' - id 'io.spring.dependency-management' version '1.1.3' - id 'com.epages.restdocs-api-spec' version "${restdocsApiSpecVersion}" - id 'org.hidetake.swagger.generator' version '2.18.2' + id 'java' + id 'org.springframework.boot' version '3.1.4' + id 'io.spring.dependency-management' version '1.1.3' + id 'com.epages.restdocs-api-spec' version "${restdocsApiSpecVersion}" + id 'org.hidetake.swagger.generator' version '2.18.2' } group = 'coffee-meet' version = '0.0.1-SNAPSHOT' java { - sourceCompatibility = '17' + sourceCompatibility = '17' } configurations { - compileOnly { - extendsFrom annotationProcessor - } + compileOnly { + extendsFrom annotationProcessor + } } repositories { - mavenCentral() + mavenCentral() } ext { - set('snippetsDir', file("build/generated-snippets")) + set('snippetsDir', file("build/generated-snippets")) } dependencies { - /* Database */ - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-data-redis' - runtimeOnly 'com.mysql:mysql-connector-j' - runtimeOnly 'com.h2database:h2' - - /* Spring */ - implementation 'org.springframework.boot:spring-boot-starter-validation' - implementation 'org.springframework.boot:spring-boot-starter-web' - - /* JWT */ - implementation 'io.jsonwebtoken:jjwt-api:0.11.5' - implementation 'io.jsonwebtoken:jjwt-impl:0.11.5' - implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5' - - /* Lombok */ - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' - - /* Test */ - testImplementation 'org.springframework.boot:spring-boot-starter-test' - testImplementation group: 'org.instancio', name: 'instancio-junit', version: '3.0.0' - - /* TestContainer */ - testImplementation "org.testcontainers:testcontainers:1.19.0" - testImplementation "org.testcontainers:junit-jupiter:1.19.0" - - /* Docs & UI */ - testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' - testImplementation 'com.epages:restdocs-api-spec-mockmvc:${restdocsApiSpecVersion}' - implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0' - swaggerUI 'org.webjars:swagger-ui:4.11.1' - - /* Cloud */ - implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' + /* Database */ + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-data-redis' + runtimeOnly 'com.mysql:mysql-connector-j' + runtimeOnly 'com.h2database:h2' + + /* Spring */ + implementation 'org.springframework.boot:spring-boot-starter-validation' + implementation 'org.springframework.boot:spring-boot-starter-web' + + /* JWT */ + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' + implementation 'io.jsonwebtoken:jjwt-impl:0.11.5' + implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5' + + /* Lombok */ + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + /* Test */ + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation group: 'org.instancio', name: 'instancio-junit', version: '3.0.0' + + /* TestContainer */ + testImplementation "org.testcontainers:testcontainers:1.19.0" + testImplementation "org.testcontainers:junit-jupiter:1.19.0" + + /* Docs & UI */ + testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' + testImplementation "com.epages:restdocs-api-spec-mockmvc:${restdocsApiSpecVersion}" + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0' + swaggerUI 'org.webjars:swagger-ui:4.11.1' + + /* Cloud */ + implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' } tasks.named('test') { - useJUnitPlatform() + useJUnitPlatform() } swaggerSources { - sample { - setInputFile(file("${project.buildDir}/api-spec/openapi3.yaml")) - } + sample { + setInputFile(file("${project.buildDir}/api-spec/openapi3.yaml")) + } } openapi3 { - servers = [ - { url = "http://localhost:8080" }, - { url = "http://13.209.253.204:8080" } - ] - title = "API 문서" - description = "RestDocsWithSwagger Docs" - version = "0.0.1" - format = "yaml" + servers = [ + { url = "http://localhost:8080" }, + { url = "http://13.209.253.204:8080" } + ] + title = "API 문서" + description = "RestDocsWithSwagger Docs" + version = "0.0.1" + format = "yaml" } tasks.withType(GenerateSwaggerUI) { - dependsOn 'openapi3' - doFirst { - def swaggerUIFile = file("${openapi3.outputDirectory}/openapi3.yaml") - - def securitySchemesContent = " securitySchemes:\n" + \ - " APIKey:\n" + \ - " type: apiKey\n" + \ - " name: Authorization\n" + \ - " in: header\n" + \ - "security:\n" + - " - APIKey: [] # Apply the security scheme here" - - swaggerUIFile.append securitySchemesContent - } + dependsOn 'openapi3' + doFirst { + def swaggerUIFile = file("${openapi3.outputDirectory}/openapi3.yaml") + + def securitySchemesContent = " securitySchemes:\n" + \ + " APIKey:\n" + \ + " type: apiKey\n" + \ + " name: Authorization\n" + \ + " in: header\n" + \ + "security:\n" + + " - APIKey: [] # Apply the security scheme here" + + swaggerUIFile.append securitySchemesContent + } } bootJar { - dependsOn generateSwaggerUISample - from("${generateSwaggerUISample.outputDir}") { - into 'static/docs' - } + dependsOn generateSwaggerUISample + from("${generateSwaggerUISample.outputDir}") { + into 'static/docs' + } } From c611af3b927c3cc1afdfff889691940beaf85cf5 Mon Sep 17 00:00:00 2001 From: Sangmin Park <70051888+smart-sangmin@users.noreply.github.com> Date: Mon, 23 Oct 2023 11:10:49 +0900 Subject: [PATCH 053/311] chore: Create CODEOWNERS --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000..cde7d794 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @smart-sangmin @1o18z @yumyeonghan From afd0f7f0e4fdf6962b72026c5c7c5122a3f5ad1a Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 11:57:18 +0900 Subject: [PATCH 054/311] =?UTF-8?q?refactor:=20CompanyEmail=20=EC=9E=AC?= =?UTF-8?q?=EC=83=9D=EC=84=B1,=20=EB=82=B4=EB=B6=80=EC=97=90=20=ED=9A=8C?= =?UTF-8?q?=EC=82=AC=20=EC=9D=B4=EB=A9=94=EC=9D=BC=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=ED=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/domain/CompanyEmail.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/main/java/coffeemeet/server/user/domain/CompanyEmail.java diff --git a/src/main/java/coffeemeet/server/user/domain/CompanyEmail.java b/src/main/java/coffeemeet/server/user/domain/CompanyEmail.java new file mode 100644 index 00000000..a9522bfe --- /dev/null +++ b/src/main/java/coffeemeet/server/user/domain/CompanyEmail.java @@ -0,0 +1,26 @@ +package coffeemeet.server.user.domain; + +import coffeemeet.server.common.util.Patterns; +import jakarta.persistence.Embeddable; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@NoArgsConstructor +public class CompanyEmail { + + private String companyEmail; + + public CompanyEmail(String companyEmail) { + validateCompanyEmail(companyEmail); + this.companyEmail = companyEmail; + } + + private void validateCompanyEmail(String companyEmail) { + if (!Patterns.EMAIL_PATTERN.matcher(companyEmail).matches()) { + throw new IllegalArgumentException("올바르지 않은 이메일입니다."); + } + } + +} From 5a80ad25c29be5473ceb7c16c70de18d63fe21c4 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 11:57:35 +0900 Subject: [PATCH 055/311] =?UTF-8?q?refactor:=20BaseEntity=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/coffeemeet/server/admin/domain/Admin.java | 4 +++- src/main/java/coffeemeet/server/report/domain/Report.java | 3 ++- src/main/java/coffeemeet/server/user/domain/User.java | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/coffeemeet/server/admin/domain/Admin.java b/src/main/java/coffeemeet/server/admin/domain/Admin.java index 2f122938..c5f4341c 100644 --- a/src/main/java/coffeemeet/server/admin/domain/Admin.java +++ b/src/main/java/coffeemeet/server/admin/domain/Admin.java @@ -1,5 +1,6 @@ package coffeemeet.server.admin.domain; +import coffeemeet.server.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Id; @@ -12,7 +13,7 @@ @Getter @Table(name = "admins") @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class Admin { +public class Admin extends BaseEntity { @Id @Column(nullable = false) @@ -20,4 +21,5 @@ public class Admin { @Column(nullable = false) private String password; + } diff --git a/src/main/java/coffeemeet/server/report/domain/Report.java b/src/main/java/coffeemeet/server/report/domain/Report.java index 1e1259f6..1ec564b5 100644 --- a/src/main/java/coffeemeet/server/report/domain/Report.java +++ b/src/main/java/coffeemeet/server/report/domain/Report.java @@ -1,5 +1,6 @@ package coffeemeet.server.report.domain; +import coffeemeet.server.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -16,7 +17,7 @@ @Getter @Table(name = "reports") @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class Report { +public class Report extends BaseEntity { private static final int TITLE_MAX_LENGTH = 20; private static final int REASON_MAX_LENGTH = 200; diff --git a/src/main/java/coffeemeet/server/user/domain/User.java b/src/main/java/coffeemeet/server/user/domain/User.java index 3cef5706..811aa3d9 100644 --- a/src/main/java/coffeemeet/server/user/domain/User.java +++ b/src/main/java/coffeemeet/server/user/domain/User.java @@ -1,6 +1,7 @@ package coffeemeet.server.user.domain; import coffeemeet.server.chatting_room.domain.ChattingRoom; +import coffeemeet.server.common.entity.AdvancedBaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; @@ -20,7 +21,7 @@ @Table(name = "users") @Where(clause = "is_deleted = false") @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class User { +public class User extends AdvancedBaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) From 267cda5bd2e03329d4da938750993252e1dec73f Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 11:59:31 +0900 Subject: [PATCH 056/311] refactor: Email -> CompanyEmail --- .../java/coffeemeet/server/user/domain/Certification.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/Certification.java b/src/main/java/coffeemeet/server/user/domain/Certification.java index 4a472578..e398f4b9 100644 --- a/src/main/java/coffeemeet/server/user/domain/Certification.java +++ b/src/main/java/coffeemeet/server/user/domain/Certification.java @@ -1,6 +1,5 @@ package coffeemeet.server.user.domain; -import jakarta.persistence.AttributeOverride; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import jakarta.persistence.Embedded; @@ -15,8 +14,7 @@ public class Certification { @Embedded @Column(nullable = false) - @AttributeOverride(name = "email", column = @Column(name = "company_email")) - private Email companyEmail; + private CompanyEmail companyEmail; @Column(nullable = false) private String businessCardUrl; @@ -28,7 +26,7 @@ public class Certification { private String department; public Certification() { - this.companyEmail = new Email(DEFAULT_EMAIL); + this.companyEmail = new CompanyEmail(DEFAULT_EMAIL); this.businessCardUrl = DEFAULT; this.department = DEFAULT; isCertificated = false; From 146a38abcb2ce90608a935bd511b3c46369deaa7 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 23 Oct 2023 12:06:01 +0900 Subject: [PATCH 057/311] =?UTF-8?q?refactor:=20=EC=A3=BC=EC=84=9D=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0,=20IllegalArgumentException=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/coffeemeet/server/user/service/UserService.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 9502914a..66625ce2 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -2,7 +2,6 @@ import coffeemeet.server.user.domain.User; import coffeemeet.server.user.repository.UserRepository; -import jakarta.persistence.EntityNotFoundException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -16,7 +15,7 @@ public class UserService { @Transactional public void updateBusinessCardUrl(Long userId, String businessCardUrl) { User user = userRepository.findById(userId) - .orElseThrow(EntityNotFoundException::new); // 에러 어떻게 처리할꺼임? + .orElseThrow(IllegalArgumentException::new); user.updateBusinessCardUrl(businessCardUrl); } From 979a4ac9f661af7ccc38edf5272d5b8fa94721a8 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 14:54:52 +0900 Subject: [PATCH 058/311] style: code formatting --- .../server/common/config/AuthWebConfig.java | 8 ++++++++ .../coffeemeet/server/common/util/FileUtils.java | 16 ++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java b/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java index 38715672..832bd391 100644 --- a/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java +++ b/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java @@ -2,9 +2,12 @@ import coffeemeet.server.auth.utils.JwtTokenProvider; import coffeemeet.server.auth.utils.converter.OAuthProviderConverter; +import coffeemeet.server.common.UserArgumentResolver; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration @@ -18,4 +21,9 @@ public void addFormatters(FormatterRegistry registry) { registry.addConverter(new OAuthProviderConverter()); } + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(new UserArgumentResolver(jwtTokenProvider)); + } + } diff --git a/src/main/java/coffeemeet/server/common/util/FileUtils.java b/src/main/java/coffeemeet/server/common/util/FileUtils.java index caf7f615..c0753eea 100644 --- a/src/main/java/coffeemeet/server/common/util/FileUtils.java +++ b/src/main/java/coffeemeet/server/common/util/FileUtils.java @@ -13,14 +13,6 @@ public final class FileUtils { private static final String MULTIPART_FILE_TRANSFER_ERROR = "MULTIPART FILE을 FILE로 변환 중 오류가 발생했습니다."; private static final String FILE_DELETE_ERROR = "FILE 삭제 중 오류가 발생했습니다."; - public static class FileIOException extends RuntimeException { - - public FileIOException(String message, Throwable e) { - super(message, e); - } - - } - public static File convertMultipartFileToFile(MultipartFile multipartFile) { try { File file = File.createTempFile("temp", multipartFile.getOriginalFilename()); @@ -39,4 +31,12 @@ public static void delete(File file) { } } + public static class FileIOException extends RuntimeException { + + public FileIOException(String message, Throwable e) { + super(message, e); + } + + } + } From c7d7e331d19a5901b22822eaef24ffbeaaf3d696 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 14:56:33 +0900 Subject: [PATCH 059/311] =?UTF-8?q?feat:=20AuthInfo=20=EB=A0=88=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 로직에 사용될 userId와 토큰 검증에 사용될 refreshToken --- src/main/java/coffeemeet/server/user/dto/AuthInfo.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/main/java/coffeemeet/server/user/dto/AuthInfo.java diff --git a/src/main/java/coffeemeet/server/user/dto/AuthInfo.java b/src/main/java/coffeemeet/server/user/dto/AuthInfo.java new file mode 100644 index 00000000..1366c4d4 --- /dev/null +++ b/src/main/java/coffeemeet/server/user/dto/AuthInfo.java @@ -0,0 +1,4 @@ +package coffeemeet.server.user.dto; + +public record AuthInfo(Long userId, String refreshToken) { +} From 25415da8a6b44c0bb66b1879b5cc045ab38f62ea Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 14:57:06 +0900 Subject: [PATCH 060/311] =?UTF-8?q?feat:=20Login=20annotation=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 - 로그인 확인할 때 사용 됨 --- .../coffeemeet/server/common/annotation/Login.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/annotation/Login.java diff --git a/src/main/java/coffeemeet/server/common/annotation/Login.java b/src/main/java/coffeemeet/server/common/annotation/Login.java new file mode 100644 index 00000000..7acf35b2 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/annotation/Login.java @@ -0,0 +1,12 @@ +package coffeemeet.server.common.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface Login { + +} From f940cfcb18997092baab8f5f06a42f18c2eca22f Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 14:59:45 +0900 Subject: [PATCH 061/311] =?UTF-8?q?feat:=20UserArgumentResolver=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 헤더로 넘어오는 AccessToken을 통해 AuthInfo 객체로 데이터 변환 기능 --- .../server/common/UserArgumentResolver.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/UserArgumentResolver.java diff --git a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java new file mode 100644 index 00000000..c6a5eb96 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java @@ -0,0 +1,45 @@ +package coffeemeet.server.common; + +import coffeemeet.server.auth.utils.JwtTokenProvider; +import coffeemeet.server.common.annotation.Login; +import coffeemeet.server.user.dto.AuthInfo; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +@Component +@RequiredArgsConstructor +public class UserArgumentResolver implements HandlerMethodArgumentResolver { + + private static final String AUTHENTICATION_FAILED_MESSAGE = "(%s)는 잘못된 권한 헤더입니다."; + + private final JwtTokenProvider jwtTokenProvider; + + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.getParameterType().equals(AuthInfo.class) && parameter.hasParameterAnnotation( + Login.class); + } + + @Override + public AuthInfo resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { + HttpServletRequest httpServletRequest = (HttpServletRequest) webRequest.getNativeRequest(); + String authHeader = httpServletRequest.getHeader("Authorization"); + + if (authHeader != null && authHeader.startsWith("Bearer ")) { + String token = authHeader.substring(7); + Long userId = jwtTokenProvider.extractUserId(token); + return new AuthInfo(userId, token); + } + throw new IllegalArgumentException( + String.format(AUTHENTICATION_FAILED_MESSAGE, authHeader) + ); + } + +} From 1a58b3381629d7a9d08704fe53c709dd0f1947c8 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 15:10:01 +0900 Subject: [PATCH 062/311] =?UTF-8?q?feat:=20CertificationController=20UserA?= =?UTF-8?q?rgumentResolver=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/CertificationController.java | 12 ++++++------ .../java/coffeemeet/server/user/dto/AuthInfo.java | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java index 59eb9616..33544eb7 100644 --- a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java +++ b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java @@ -3,10 +3,11 @@ import static org.springframework.http.HttpStatus.CREATED; import coffeemeet.server.certification.service.CertificationService; +import coffeemeet.server.common.annotation.Login; import coffeemeet.server.common.util.FileUtils; +import coffeemeet.server.user.dto.AuthInfo; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestPart; @@ -21,17 +22,16 @@ public class CertificationController { private final CertificationService certificationService; - @PostMapping("/users/{userId}/business-card") + @PostMapping("/users/business-card") @ResponseStatus(CREATED) public void uploadBusinessCard( - @PathVariable("userId") - @NotNull(message = "유저 ID는 null일 수 없습니다.") - long userId, + @Login + AuthInfo authInfo, @RequestPart("businessCard") @NotNull(message = "명함 이미지는 null일 수 없습니다.") MultipartFile businessCard ) { - certificationService.uploadBusinessCard(userId, + certificationService.uploadBusinessCard(authInfo.userId(), FileUtils.convertMultipartFileToFile(businessCard)); } diff --git a/src/main/java/coffeemeet/server/user/dto/AuthInfo.java b/src/main/java/coffeemeet/server/user/dto/AuthInfo.java index 1366c4d4..fac09343 100644 --- a/src/main/java/coffeemeet/server/user/dto/AuthInfo.java +++ b/src/main/java/coffeemeet/server/user/dto/AuthInfo.java @@ -1,4 +1,5 @@ package coffeemeet.server.user.dto; public record AuthInfo(Long userId, String refreshToken) { + } From d4edb827dd802e10c4cf166155febc55a4d3c135 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 16:06:16 +0900 Subject: [PATCH 063/311] =?UTF-8?q?feat:=20RefreshToken=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 - key : userId, value : 토큰값 --- .../server/auth/RefreshTokenRepository.java | 8 +++++++ .../server/auth/domain/RefreshToken.java | 23 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 src/main/java/coffeemeet/server/auth/RefreshTokenRepository.java create mode 100644 src/main/java/coffeemeet/server/auth/domain/RefreshToken.java diff --git a/src/main/java/coffeemeet/server/auth/RefreshTokenRepository.java b/src/main/java/coffeemeet/server/auth/RefreshTokenRepository.java new file mode 100644 index 00000000..e9e53608 --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/RefreshTokenRepository.java @@ -0,0 +1,8 @@ +package coffeemeet.server.auth; + +import coffeemeet.server.auth.domain.RefreshToken; +import org.springframework.data.repository.CrudRepository; + +public interface RefreshTokenRepository extends CrudRepository { + +} diff --git a/src/main/java/coffeemeet/server/auth/domain/RefreshToken.java b/src/main/java/coffeemeet/server/auth/domain/RefreshToken.java new file mode 100644 index 00000000..1b20301e --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/domain/RefreshToken.java @@ -0,0 +1,23 @@ +package coffeemeet.server.auth.domain; + +import lombok.Builder; +import lombok.Getter; +import org.springframework.data.annotation.Id; +import org.springframework.data.redis.core.RedisHash; + +@Getter +@RedisHash(value = "refresh", timeToLive = 1209600) +public class RefreshToken { + + @Id + private Long userId; + + private String value; + + @Builder + private RefreshToken(Long userId, String value) { + this.userId = userId; + this.value = value; + } + +} From 31830e0c17b710ad18a746af638ddcd1cfe0db62 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 16:07:14 +0900 Subject: [PATCH 064/311] =?UTF-8?q?feat:=20UserArgumentResolver=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 - refresh token 조회 로직 추가 --- .../server/common/UserArgumentResolver.java | 18 +++++++++++++++--- .../server/common/config/AuthWebConfig.java | 4 +++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java index c6a5eb96..ec5dedde 100644 --- a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java +++ b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java @@ -1,5 +1,7 @@ package coffeemeet.server.common; +import coffeemeet.server.auth.RefreshTokenRepository; +import coffeemeet.server.auth.domain.RefreshToken; import coffeemeet.server.auth.utils.JwtTokenProvider; import coffeemeet.server.common.annotation.Login; import coffeemeet.server.user.dto.AuthInfo; @@ -16,9 +18,12 @@ @RequiredArgsConstructor public class UserArgumentResolver implements HandlerMethodArgumentResolver { - private static final String AUTHENTICATION_FAILED_MESSAGE = "(%s)는 잘못된 권한 헤더입니다."; + private static final String HEADER_AUTHENTICATION_FAILED_MESSAGE = "(%s)는 잘못된 권한 헤더입니다."; + public static final String USER_AUTHENTICATION_FAILED_MESSAGE = "사용자(%s)의 갱신 토큰이 존재하지 않습니다."; private final JwtTokenProvider jwtTokenProvider; + private final RefreshTokenRepository refreshTokenRepository; + @Override public boolean supportsParameter(MethodParameter parameter) { @@ -35,11 +40,18 @@ public AuthInfo resolveArgument(MethodParameter parameter, ModelAndViewContainer if (authHeader != null && authHeader.startsWith("Bearer ")) { String token = authHeader.substring(7); Long userId = jwtTokenProvider.extractUserId(token); - return new AuthInfo(userId, token); + RefreshToken refreshToken = getRefreshToken(userId); + return new AuthInfo(userId, refreshToken.getValue()); } throw new IllegalArgumentException( - String.format(AUTHENTICATION_FAILED_MESSAGE, authHeader) + String.format(HEADER_AUTHENTICATION_FAILED_MESSAGE, authHeader) ); } + private RefreshToken getRefreshToken(Long userId) { + return refreshTokenRepository.findById(userId) + .orElseThrow(() -> new IllegalArgumentException(String.format( + USER_AUTHENTICATION_FAILED_MESSAGE, userId))); + } + } diff --git a/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java b/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java index 832bd391..43a234d2 100644 --- a/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java +++ b/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java @@ -1,5 +1,6 @@ package coffeemeet.server.common.config; +import coffeemeet.server.auth.RefreshTokenRepository; import coffeemeet.server.auth.utils.JwtTokenProvider; import coffeemeet.server.auth.utils.converter.OAuthProviderConverter; import coffeemeet.server.common.UserArgumentResolver; @@ -15,6 +16,7 @@ public class AuthWebConfig implements WebMvcConfigurer { private final JwtTokenProvider jwtTokenProvider; + private final RefreshTokenRepository refreshTokenRepository; @Override public void addFormatters(FormatterRegistry registry) { @@ -23,7 +25,7 @@ public void addFormatters(FormatterRegistry registry) { @Override public void addArgumentResolvers(List resolvers) { - resolvers.add(new UserArgumentResolver(jwtTokenProvider)); + resolvers.add(new UserArgumentResolver(jwtTokenProvider, refreshTokenRepository)); } } From 8e0f5adfac22779df4caa0df3451af35ec175241 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 16:07:46 +0900 Subject: [PATCH 065/311] style: code formatting --- .../java/coffeemeet/server/common/UserArgumentResolver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java index ec5dedde..3fb8b07e 100644 --- a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java +++ b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java @@ -18,8 +18,8 @@ @RequiredArgsConstructor public class UserArgumentResolver implements HandlerMethodArgumentResolver { - private static final String HEADER_AUTHENTICATION_FAILED_MESSAGE = "(%s)는 잘못된 권한 헤더입니다."; public static final String USER_AUTHENTICATION_FAILED_MESSAGE = "사용자(%s)의 갱신 토큰이 존재하지 않습니다."; + private static final String HEADER_AUTHENTICATION_FAILED_MESSAGE = "(%s)는 잘못된 권한 헤더입니다."; private final JwtTokenProvider jwtTokenProvider; private final RefreshTokenRepository refreshTokenRepository; From fc2dd45c20a156b9c769eeecda60553e3404314c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 16:08:00 +0900 Subject: [PATCH 066/311] =?UTF-8?q?feat:=20AuthService=EC=97=90=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/auth/service/AuthService.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index cde3a740..5b0e7b6c 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -16,6 +16,7 @@ import coffeemeet.server.user.repository.UserRepository; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -62,6 +63,13 @@ public AuthTokens signup(SignupRequest request) { return authTokensGenerator.generate(newUser.getId()); } + public Optional login(OAuthProvider oAuthProvider, String authCode) { + OAuthInfoResponse response = oauthMemberClientComposite.fetch(oAuthProvider, authCode); + Optional foundUser = userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( + response.oAuthProvider(), response.oAuthProviderId()); + return foundUser.map(user -> authTokensGenerator.generate(user.getId())); + } + private void checkDuplicateUser(OAuthInfoResponse response) { if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( response.oAuthProvider(), response.oAuthProviderId())) { From f5479d68b259faaa2ea7e985ad1048e12486f8d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 16:10:12 +0900 Subject: [PATCH 067/311] =?UTF-8?q?feat:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=EA=B3=BC=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EC=95=84=EC=9D=B4=EB=94=94=EB=A1=9C=20?= =?UTF-8?q?=EC=9C=A0=EC=A0=80=20=EC=A1=B0=ED=9A=8C=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=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 --- .../coffeemeet/server/user/repository/UserRepository.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/coffeemeet/server/user/repository/UserRepository.java b/src/main/java/coffeemeet/server/user/repository/UserRepository.java index a83cdb69..90da80fb 100644 --- a/src/main/java/coffeemeet/server/user/repository/UserRepository.java +++ b/src/main/java/coffeemeet/server/user/repository/UserRepository.java @@ -2,6 +2,7 @@ import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.User; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; public interface UserRepository extends JpaRepository { @@ -10,4 +11,7 @@ boolean existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( OAuthProvider oauthProvider, String oauthProviderId); + Optional getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( + OAuthProvider oAuthProvider, + String authCode); } From f141049267364ba5ceeda458917fd28e34af7609 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 16:10:48 +0900 Subject: [PATCH 068/311] style: code formatting --- .../coffeemeet/server/common/config/ControllerTestConfig.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java index f9f30ee2..32e9ec5b 100644 --- a/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java +++ b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java @@ -3,6 +3,7 @@ import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import coffeemeet.server.auth.RefreshTokenRepository; import coffeemeet.server.auth.utils.JwtTokenProvider; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; @@ -27,6 +28,9 @@ public abstract class ControllerTestConfig { @MockBean protected JwtTokenProvider jwtTokenProvider; + @MockBean + protected RefreshTokenRepository refreshTokenRepository; + @BeforeEach void setUp(WebApplicationContext ctx, RestDocumentationContextProvider restDocumentation) { mockMvc = MockMvcBuilders.webAppContextSetup(ctx) From 18093ad09c7fe16c446ccd4a5c7faa008d38fb43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 16:11:12 +0900 Subject: [PATCH 069/311] =?UTF-8?q?feat:=20AuthController=EC=97=90=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EB=B0=8F=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=8B=A4?= =?UTF-8?q?=ED=8C=A8=EC=8B=9C=20=EB=A6=AC=EB=8B=A4=EC=9D=B4=EB=A0=89?= =?UTF-8?q?=ED=8A=B8=20=EB=A1=9C=EC=A7=81=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/auth/controller/AuthController.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/auth/controller/AuthController.java b/src/main/java/coffeemeet/server/auth/controller/AuthController.java index 7ced79a7..77853a38 100644 --- a/src/main/java/coffeemeet/server/auth/controller/AuthController.java +++ b/src/main/java/coffeemeet/server/auth/controller/AuthController.java @@ -6,6 +6,7 @@ import coffeemeet.server.user.domain.OAuthProvider; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; +import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -14,6 +15,7 @@ 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.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @@ -28,7 +30,6 @@ public ResponseEntity redirectAuthCodeRequestUrl(@PathVariable OAuthProvid HttpServletResponse response) throws IOException { String redirectUrl = authService.getAuthCodeRequestUrl(oAuthProvider); response.sendRedirect(redirectUrl); - return new ResponseEntity<>(HttpStatus.FOUND); } @@ -37,4 +38,17 @@ public ResponseEntity signup(@RequestBody SignupRequest request) { return ResponseEntity.ok(authService.signup(request)); } + @GetMapping("/login/{oAuthProvider}") + public ResponseEntity login(@PathVariable OAuthProvider oAuthProvider, + @RequestParam String authCode, HttpServletResponse response) throws IOException { + Optional authTokens = authService.login(oAuthProvider, authCode); + if (authTokens.isPresent()) { + return ResponseEntity.ok(authTokens.get()); + } + + String signupUrl = "/oauth2/auth/sign-up"; + response.sendRedirect(signupUrl); + return new ResponseEntity<>(HttpStatus.FOUND); + } + } From e8fe5fd5dd041bafbe1eb5ed1abcade46def5822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 16:56:50 +0900 Subject: [PATCH 070/311] =?UTF-8?q?refactor:=20User=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=EC=9D=98=20=EC=9D=B8=EC=A6=9D=20=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=EC=99=80=20=EC=8B=A0=EA=B3=A0=20=EC=A0=95=EB=B3=B4=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 --- .../server/user/domain/ReportInfo.java | 24 +++---------------- .../coffeemeet/server/user/domain/User.java | 5 ++-- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/ReportInfo.java b/src/main/java/coffeemeet/server/user/domain/ReportInfo.java index 1bf0c209..5e920b75 100644 --- a/src/main/java/coffeemeet/server/user/domain/ReportInfo.java +++ b/src/main/java/coffeemeet/server/user/domain/ReportInfo.java @@ -3,13 +3,10 @@ import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import java.time.LocalDateTime; -import lombok.AccessLevel; import lombok.Getter; -import lombok.NoArgsConstructor; @Getter @Embeddable -@NoArgsConstructor(access = AccessLevel.PROTECTED) public class ReportInfo { private static final int REPORT_MIN_COUNT = 0; @@ -17,26 +14,11 @@ public class ReportInfo { @Column(nullable = false) private int reportedCount; - @Column(nullable = false) private LocalDateTime sanctionPeriod; - public ReportInfo(int reportedCount, LocalDateTime sanctionPeriod) { - validateReportedCount(reportedCount); - validateSanctionPeriod(sanctionPeriod); - this.reportedCount = reportedCount; - this.sanctionPeriod = sanctionPeriod; - } - - private void validateReportedCount(int reportedCount) { - if (reportedCount < REPORT_MIN_COUNT) { - throw new IllegalArgumentException("올바르지 않은 신고횟수입니다."); - } - } - - private void validateSanctionPeriod(LocalDateTime sanctionPeriod) { - if (sanctionPeriod == null) { - throw new IllegalArgumentException("올바르지 않은 제재 기간입니다."); - } + public ReportInfo() { + this.reportedCount = REPORT_MIN_COUNT; + this.sanctionPeriod = null; } } diff --git a/src/main/java/coffeemeet/server/user/domain/User.java b/src/main/java/coffeemeet/server/user/domain/User.java index 811aa3d9..ca575d69 100644 --- a/src/main/java/coffeemeet/server/user/domain/User.java +++ b/src/main/java/coffeemeet/server/user/domain/User.java @@ -36,11 +36,10 @@ public class User extends AdvancedBaseEntity { private Profile profile; @ManyToOne - @JoinColumn(name = "chatting_room_id", nullable = false) + @JoinColumn(name = "chatting_room_id") private ChattingRoom chattingRoom; @Embedded - @Column(nullable = false) private Certification certification; @Embedded @@ -56,6 +55,8 @@ public User( ) { this.oauthInfo = oauthInfo; this.profile = profile; + this.certification = new Certification(); + this.reportInfo = new ReportInfo(); } public void updateBusinessCardUrl(String newBusinessCardUrl) { From b5e8fa3ba845e9601cb5eb2e6732d96bd78bec7b Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 17:29:14 +0900 Subject: [PATCH 071/311] style: move package path --- .../auth/{ => infrastructure}/RefreshTokenRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/java/coffeemeet/server/auth/{ => infrastructure}/RefreshTokenRepository.java (80%) diff --git a/src/main/java/coffeemeet/server/auth/RefreshTokenRepository.java b/src/main/java/coffeemeet/server/auth/infrastructure/RefreshTokenRepository.java similarity index 80% rename from src/main/java/coffeemeet/server/auth/RefreshTokenRepository.java rename to src/main/java/coffeemeet/server/auth/infrastructure/RefreshTokenRepository.java index e9e53608..8fc81e0c 100644 --- a/src/main/java/coffeemeet/server/auth/RefreshTokenRepository.java +++ b/src/main/java/coffeemeet/server/auth/infrastructure/RefreshTokenRepository.java @@ -1,4 +1,4 @@ -package coffeemeet.server.auth; +package coffeemeet.server.auth.infrastructure; import coffeemeet.server.auth.domain.RefreshToken; import org.springframework.data.repository.CrudRepository; From 8ee8994e698590f70452c4c9d4a0bbabb67f770b Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 17:30:54 +0900 Subject: [PATCH 072/311] style: update imports --- .../java/coffeemeet/server/common/config/AuthWebConfig.java | 2 +- .../coffeemeet/server/common/config/ControllerTestConfig.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java b/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java index 43a234d2..7201ace4 100644 --- a/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java +++ b/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java @@ -1,6 +1,6 @@ package coffeemeet.server.common.config; -import coffeemeet.server.auth.RefreshTokenRepository; +import coffeemeet.server.auth.infrastructure.RefreshTokenRepository; import coffeemeet.server.auth.utils.JwtTokenProvider; import coffeemeet.server.auth.utils.converter.OAuthProviderConverter; import coffeemeet.server.common.UserArgumentResolver; diff --git a/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java index 32e9ec5b..7435039d 100644 --- a/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java +++ b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java @@ -3,7 +3,7 @@ import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import coffeemeet.server.auth.RefreshTokenRepository; +import coffeemeet.server.auth.infrastructure.RefreshTokenRepository; import coffeemeet.server.auth.utils.JwtTokenProvider; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; From bf856f31193e72a14229ec48ea46e14fd3ff82c6 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 17:31:26 +0900 Subject: [PATCH 073/311] refactor: update exception message --- .../java/coffeemeet/server/common/UserArgumentResolver.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java index 3fb8b07e..c078f682 100644 --- a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java +++ b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java @@ -1,7 +1,7 @@ package coffeemeet.server.common; -import coffeemeet.server.auth.RefreshTokenRepository; import coffeemeet.server.auth.domain.RefreshToken; +import coffeemeet.server.auth.infrastructure.RefreshTokenRepository; import coffeemeet.server.auth.utils.JwtTokenProvider; import coffeemeet.server.common.annotation.Login; import coffeemeet.server.user.dto.AuthInfo; @@ -18,7 +18,7 @@ @RequiredArgsConstructor public class UserArgumentResolver implements HandlerMethodArgumentResolver { - public static final String USER_AUTHENTICATION_FAILED_MESSAGE = "사용자(%s)의 갱신 토큰이 존재하지 않습니다."; + public static final String USER_AUTHENTICATION_FAILED_MESSAGE = "사용자(%s)의 재인증(로그인)이 필요합니다."; private static final String HEADER_AUTHENTICATION_FAILED_MESSAGE = "(%s)는 잘못된 권한 헤더입니다."; private final JwtTokenProvider jwtTokenProvider; From 597615415652500da7121f3b1bcccf7a86addbe4 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 17:32:13 +0900 Subject: [PATCH 074/311] feat: save refresh token MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 회원 가입 또는 로그인 시, 리프레시 토큰 레디스 저장소에 저장 기능 구현 --- .../server/auth/utils/AuthTokensGenerator.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java b/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java index 88f212c5..737e4f8a 100644 --- a/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java +++ b/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java @@ -1,5 +1,7 @@ package coffeemeet.server.auth.utils; +import coffeemeet.server.auth.domain.RefreshToken; +import coffeemeet.server.auth.infrastructure.RefreshTokenRepository; import java.util.Date; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -12,14 +14,16 @@ public class AuthTokensGenerator { private final JwtTokenProvider jwtTokenProvider; private final Long accessTokenExpireTime; private final Long refreshTokenExpireTime; + private final RefreshTokenRepository refreshTokenRepository; public AuthTokensGenerator(JwtTokenProvider jwtTokenProvider, @Value("${jwt.access-token-expire-time}") Long accessTokenExpireTime, - @Value("${jwt.refresh-token-expire-time}") Long refreshTokenExpireTime - ) { + @Value("${jwt.refresh-token-expire-time}") Long refreshTokenExpireTime, + RefreshTokenRepository refreshTokenRepository) { this.jwtTokenProvider = jwtTokenProvider; this.accessTokenExpireTime = accessTokenExpireTime; this.refreshTokenExpireTime = refreshTokenExpireTime; + this.refreshTokenRepository = refreshTokenRepository; } public AuthTokens generate(Long userId) { @@ -31,6 +35,12 @@ public AuthTokens generate(Long userId) { String accessToken = jwtTokenProvider.generate(subject, accessTokenExpiredAt); String refreshToken = jwtTokenProvider.generate(subject, refreshTokenExpiredAt); + RefreshToken refreshTokenEntity = RefreshToken.builder() + .userId(userId) + .value(refreshToken) + .build(); + refreshTokenRepository.save(refreshTokenEntity); + return AuthTokens.of( BEARER_TYPE + accessToken, BEARER_TYPE + refreshToken From 925ff62f6b8fd92031935e17e4034d111376327f Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 18:33:55 +0900 Subject: [PATCH 075/311] =?UTF-8?q?refactor:=20AuthController=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 - 회원가입 API 요청 데이터 검증 추가 - 로그인 API 수정 --- .../auth/controller/AuthController.java | 17 +++++------------ .../server/auth/dto/SignupRequest.java | 19 +++++-------------- .../server/auth/service/AuthService.java | 13 ++++++++----- 3 files changed, 18 insertions(+), 31 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/controller/AuthController.java b/src/main/java/coffeemeet/server/auth/controller/AuthController.java index 77853a38..68d96bef 100644 --- a/src/main/java/coffeemeet/server/auth/controller/AuthController.java +++ b/src/main/java/coffeemeet/server/auth/controller/AuthController.java @@ -5,8 +5,8 @@ import coffeemeet.server.auth.utils.AuthTokens; import coffeemeet.server.user.domain.OAuthProvider; import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; import java.io.IOException; -import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -34,21 +34,14 @@ public ResponseEntity redirectAuthCodeRequestUrl(@PathVariable OAuthProvid } @PostMapping("/sign-up") - public ResponseEntity signup(@RequestBody SignupRequest request) { + public ResponseEntity signup(@Valid @RequestBody SignupRequest request) { return ResponseEntity.ok(authService.signup(request)); } @GetMapping("/login/{oAuthProvider}") - public ResponseEntity login(@PathVariable OAuthProvider oAuthProvider, - @RequestParam String authCode, HttpServletResponse response) throws IOException { - Optional authTokens = authService.login(oAuthProvider, authCode); - if (authTokens.isPresent()) { - return ResponseEntity.ok(authTokens.get()); - } - - String signupUrl = "/oauth2/auth/sign-up"; - response.sendRedirect(signupUrl); - return new ResponseEntity<>(HttpStatus.FOUND); + public ResponseEntity login(@PathVariable OAuthProvider oAuthProvider, + @RequestParam String authCode) { + return ResponseEntity.ok(authService.login(oAuthProvider, authCode)); } } diff --git a/src/main/java/coffeemeet/server/auth/dto/SignupRequest.java b/src/main/java/coffeemeet/server/auth/dto/SignupRequest.java index 4cb8c8ee..76c798e3 100644 --- a/src/main/java/coffeemeet/server/auth/dto/SignupRequest.java +++ b/src/main/java/coffeemeet/server/auth/dto/SignupRequest.java @@ -2,27 +2,18 @@ import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.user.domain.OAuthProvider; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import java.util.List; public record SignupRequest( + @NotBlank String nickname, + @NotNull List keywords, + @NotBlank String authCode, OAuthProvider oAuthProvider ) { - public static SignupRequest of( - String nickname, - List keywords, - String authCode, - OAuthProvider oAuthProvider - ) { - return new SignupRequest( - nickname, - keywords, - authCode, - oAuthProvider - ); - } - } diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index 5b0e7b6c..d081a8b0 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -16,7 +16,6 @@ import coffeemeet.server.user.repository.UserRepository; import java.util.ArrayList; import java.util.List; -import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -25,6 +24,7 @@ public class AuthService { private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; + private static final String USER_NOT_REGISTERED_MESSAGE = "해당 아이디(%s)와 로그인 타입(%s)의 유저는 회원가입되지 않았습니다."; private final AuthCodeRequestUrlProviderComposite authCodeRequestUrlProviderComposite; private final OAuthMemberClientComposite oauthMemberClientComposite; @@ -63,11 +63,14 @@ public AuthTokens signup(SignupRequest request) { return authTokensGenerator.generate(newUser.getId()); } - public Optional login(OAuthProvider oAuthProvider, String authCode) { + public AuthTokens login(OAuthProvider oAuthProvider, String authCode) { OAuthInfoResponse response = oauthMemberClientComposite.fetch(oAuthProvider, authCode); - Optional foundUser = userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( - response.oAuthProvider(), response.oAuthProviderId()); - return foundUser.map(user -> authTokensGenerator.generate(user.getId())); + User foundUser = userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( + response.oAuthProvider(), response.oAuthProviderId()) + .orElseThrow(() -> new IllegalArgumentException( + String.format(USER_NOT_REGISTERED_MESSAGE, response.oAuthProviderId(), + response.oAuthProvider()))); + return authTokensGenerator.generate(foundUser.getId()); } private void checkDuplicateUser(OAuthInfoResponse response) { From 5ad2aa239ed7aad6bc77ac1888217f0549d1783b Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 18:50:11 +0900 Subject: [PATCH 076/311] =?UTF-8?q?feat:=20=ED=86=A0=ED=81=B0=20=EA=B0=B1?= =?UTF-8?q?=EC=8B=A0=20API=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 액세스 토큰이 만료 되면, 리프레시 토큰을 통해 액세스 토큰 재발급 - 리프레시 토큰도 만료 되면 예외 발생 --- .../auth/controller/AuthController.java | 7 +++++ .../server/auth/service/AuthService.java | 31 ++++++++++--------- .../auth/utils/AuthTokensGenerator.java | 2 +- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/controller/AuthController.java b/src/main/java/coffeemeet/server/auth/controller/AuthController.java index 68d96bef..a4cb4bf3 100644 --- a/src/main/java/coffeemeet/server/auth/controller/AuthController.java +++ b/src/main/java/coffeemeet/server/auth/controller/AuthController.java @@ -3,7 +3,9 @@ import coffeemeet.server.auth.dto.SignupRequest; import coffeemeet.server.auth.service.AuthService; import coffeemeet.server.auth.utils.AuthTokens; +import coffeemeet.server.common.annotation.Login; import coffeemeet.server.user.domain.OAuthProvider; +import coffeemeet.server.user.dto.AuthInfo; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import java.io.IOException; @@ -44,4 +46,9 @@ public ResponseEntity login(@PathVariable OAuthProvider oAuthProvide return ResponseEntity.ok(authService.login(oAuthProvider, authCode)); } + @PostMapping("/renew-token") + public ResponseEntity renew(@Login AuthInfo authInfo) { + return ResponseEntity.ok(authService.renew(authInfo.userId(), authInfo.refreshToken())); + } + } diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index d081a8b0..d19ddf5b 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -6,6 +6,7 @@ import coffeemeet.server.auth.dto.SignupRequest; import coffeemeet.server.auth.utils.AuthTokens; import coffeemeet.server.auth.utils.AuthTokensGenerator; +import coffeemeet.server.auth.utils.JwtTokenProvider; import coffeemeet.server.interest.domain.Interest; import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.interest.repository.InterestRepository; @@ -23,6 +24,7 @@ @RequiredArgsConstructor public class AuthService { + private static final String EXPIRED_REFRESH_TOKEN_MESSAGE = "리프레시 토큰이 만료되었습니다. 다시 로그인해 주세요."; private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; private static final String USER_NOT_REGISTERED_MESSAGE = "해당 아이디(%s)와 로그인 타입(%s)의 유저는 회원가입되지 않았습니다."; @@ -31,6 +33,7 @@ public class AuthService { private final UserRepository userRepository; private final InterestRepository interestRepository; private final AuthTokensGenerator authTokensGenerator; + private final JwtTokenProvider jwtTokenProvider; public String getAuthCodeRequestUrl(OAuthProvider oAuthProvider) { return authCodeRequestUrlProviderComposite.provide(oAuthProvider); @@ -42,19 +45,9 @@ public AuthTokens signup(SignupRequest request) { checkDuplicateUser(response); String profileImage = checkProfileImage(response.profileImage()); - User user = new User( - new OAuthInfo( - response.oAuthProvider(), - response.oAuthProviderId() - ), - Profile.builder() - .name(response.name()) - .nickname(request.nickname()) - .email(response.email()) - .profileImageUrl(profileImage) - .birth(response.birth()) - .build() - ); + User user = new User(new OAuthInfo(response.oAuthProvider(), response.oAuthProviderId()), + Profile.builder().name(response.name()).nickname(request.nickname()).email(response.email()) + .profileImageUrl(profileImage).birth(response.birth()).build()); User newUser = userRepository.save(user); @@ -66,13 +59,21 @@ public AuthTokens signup(SignupRequest request) { public AuthTokens login(OAuthProvider oAuthProvider, String authCode) { OAuthInfoResponse response = oauthMemberClientComposite.fetch(oAuthProvider, authCode); User foundUser = userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( - response.oAuthProvider(), response.oAuthProviderId()) - .orElseThrow(() -> new IllegalArgumentException( + response.oAuthProvider(), response.oAuthProviderId()).orElseThrow( + () -> new IllegalArgumentException( String.format(USER_NOT_REGISTERED_MESSAGE, response.oAuthProviderId(), response.oAuthProvider()))); return authTokensGenerator.generate(foundUser.getId()); } + public AuthTokens renew(Long userId, String refreshToken) { + if (jwtTokenProvider.isExpiredRefreshToken(refreshToken)) { + throw new IllegalArgumentException(EXPIRED_REFRESH_TOKEN_MESSAGE); + } else { + return authTokensGenerator.reissueAccessToken(userId, refreshToken); + } + } + private void checkDuplicateUser(OAuthInfoResponse response) { if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( response.oAuthProvider(), response.oAuthProviderId())) { diff --git a/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java b/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java index 737e4f8a..f530f173 100644 --- a/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java +++ b/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java @@ -47,7 +47,7 @@ public AuthTokens generate(Long userId) { ); } - public AuthTokens refreshJwtToken(Long userId, String refreshToken) { + public AuthTokens reissueAccessToken(Long userId, String refreshToken) { long now = (new Date()).getTime(); Date accessTokenExpiredAt = new Date(now + accessTokenExpireTime); From 74cd37745671670eacb03f6993d48b3709f037b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 23:33:14 +0900 Subject: [PATCH 077/311] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EB=B0=8F=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0?= =?UTF-8?q?=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 --- .../repository/InterestRepository.java | 2 ++ .../user/controller/UserController.java | 32 +++++++++++++++++++ .../user/repository/UserRepository.java | 2 ++ .../server/user/service/UserService.java | 22 +++++++++++++ 4 files changed, 58 insertions(+) create mode 100644 src/main/java/coffeemeet/server/user/controller/UserController.java diff --git a/src/main/java/coffeemeet/server/interest/repository/InterestRepository.java b/src/main/java/coffeemeet/server/interest/repository/InterestRepository.java index 1440537b..933d0fcf 100644 --- a/src/main/java/coffeemeet/server/interest/repository/InterestRepository.java +++ b/src/main/java/coffeemeet/server/interest/repository/InterestRepository.java @@ -1,8 +1,10 @@ package coffeemeet.server.interest.repository; import coffeemeet.server.interest.domain.Interest; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; public interface InterestRepository extends JpaRepository { + List findAllByUserId(Long userId); } diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java new file mode 100644 index 00000000..86131025 --- /dev/null +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -0,0 +1,32 @@ +package coffeemeet.server.user.controller; + +import coffeemeet.server.common.annotation.Login; +import coffeemeet.server.user.dto.AuthInfo; +import coffeemeet.server.user.dto.MyProfileResponse; +import coffeemeet.server.user.dto.UserProfileResponse; +import coffeemeet.server.user.service.UserService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/user") +public class UserController { + + private final UserService userService; + + @GetMapping("/{nickname}") + public ResponseEntity findUserProfile(@PathVariable String nickname) { + return ResponseEntity.ok(userService.findUserProfile(nickname)); + } + + @GetMapping("/me") + public ResponseEntity findMyProfile(@Login AuthInfo authInfo) { + return ResponseEntity.ok(userService.findMyProfile(authInfo.userId())); + } + +} diff --git a/src/main/java/coffeemeet/server/user/repository/UserRepository.java b/src/main/java/coffeemeet/server/user/repository/UserRepository.java index 90da80fb..a10cd24b 100644 --- a/src/main/java/coffeemeet/server/user/repository/UserRepository.java +++ b/src/main/java/coffeemeet/server/user/repository/UserRepository.java @@ -14,4 +14,6 @@ boolean existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( Optional getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( OAuthProvider oAuthProvider, String authCode); + + Optional findUserByProfileNickname(String nickname); } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 66625ce2..03743816 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -1,7 +1,12 @@ package coffeemeet.server.user.service; +import coffeemeet.server.interest.domain.Interest; +import coffeemeet.server.interest.repository.InterestRepository; import coffeemeet.server.user.domain.User; +import coffeemeet.server.user.dto.MyProfileResponse; +import coffeemeet.server.user.dto.UserProfileResponse; import coffeemeet.server.user.repository.UserRepository; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -11,6 +16,7 @@ public class UserService { private final UserRepository userRepository; + private final InterestRepository interestRepository; @Transactional public void updateBusinessCardUrl(Long userId, String businessCardUrl) { @@ -19,4 +25,20 @@ public void updateBusinessCardUrl(Long userId, String businessCardUrl) { user.updateBusinessCardUrl(businessCardUrl); } + public UserProfileResponse findUserProfile(String nickname) { + User user = userRepository.findUserByProfileNickname(nickname) + .orElseThrow(IllegalArgumentException::new); + + List interests = interestRepository.findAllByUserId(user.getId()); + return UserProfileResponse.from(user, interests); + } + + public MyProfileResponse findMyProfile(Long userId) { + User user = userRepository.findById(userId) + .orElseThrow(IllegalArgumentException::new); + + List interests = interestRepository.findAllByUserId(userId); + return MyProfileResponse.from(user, interests); + } + } From bd6f61da852e2700fc2aac6b189cc4805348adad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 23:35:19 +0900 Subject: [PATCH 078/311] =?UTF-8?q?feat:=20=ED=94=84=EB=A1=9C=ED=95=84=20D?= =?UTF-8?q?TO=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/dto/MyProfileResponse.java | 43 +++++++++++++++++++ .../server/user/dto/UserProfileResponse.java | 28 ++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java create mode 100644 src/main/java/coffeemeet/server/user/dto/UserProfileResponse.java diff --git a/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java b/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java new file mode 100644 index 00000000..b3d1afd1 --- /dev/null +++ b/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java @@ -0,0 +1,43 @@ +package coffeemeet.server.user.dto; + +import coffeemeet.server.interest.domain.Interest; +import coffeemeet.server.interest.domain.Keyword; +import coffeemeet.server.user.domain.User; +import java.time.LocalDateTime; +import java.util.List; + +public record MyProfileResponse( + String name, + String nickname, + String email, + String profileImageUrl, + String birthYear, + String birthDay, + int reportedCount, + LocalDateTime sanctionPeriod, + String companyEmail, + String department, + List interests +) { + + public static MyProfileResponse from(User user, List interests) { + List keywords = interests.stream() + .map(Interest::getKeyword) + .toList(); + + return new MyProfileResponse( + user.getProfile().getName(), + user.getProfile().getNickname(), + user.getProfile().getEmail().getEmail(), + user.getProfile().getProfileImageUrl(), + user.getProfile().getBirth().getYear(), + user.getProfile().getBirth().getDay(), + user.getReportInfo().getReportedCount(), + user.getReportInfo().getSanctionPeriod(), + user.getCertification().getCompanyEmail().getCompanyEmail(), + user.getCertification().getDepartment(), + keywords + ); + } + +} diff --git a/src/main/java/coffeemeet/server/user/dto/UserProfileResponse.java b/src/main/java/coffeemeet/server/user/dto/UserProfileResponse.java new file mode 100644 index 00000000..f39a26df --- /dev/null +++ b/src/main/java/coffeemeet/server/user/dto/UserProfileResponse.java @@ -0,0 +1,28 @@ +package coffeemeet.server.user.dto; + +import coffeemeet.server.interest.domain.Interest; +import coffeemeet.server.interest.domain.Keyword; +import coffeemeet.server.user.domain.User; +import java.util.List; + +public record UserProfileResponse( + String nickname, + String profileImageUrl, + String department, + List interests +) { + + public static UserProfileResponse from(User user, List interests) { + List keywords = interests.stream() + .map(Interest::getKeyword) + .toList(); + + return new UserProfileResponse( + user.getProfile().getNickname(), + user.getProfile().getProfileImageUrl(), + user.getCertification().getDepartment(), + keywords + ); + } + +} From af923333fc5c31dfd564702ee6b1f4afdf1a5363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 23 Oct 2023 23:35:35 +0900 Subject: [PATCH 079/311] =?UTF-8?q?style:=20=EA=B3=B5=EB=B0=B1=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/coffeemeet/server/common/UserArgumentResolver.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java index 3fb8b07e..671d139b 100644 --- a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java +++ b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java @@ -24,7 +24,6 @@ public class UserArgumentResolver implements HandlerMethodArgumentResolver { private final JwtTokenProvider jwtTokenProvider; private final RefreshTokenRepository refreshTokenRepository; - @Override public boolean supportsParameter(MethodParameter parameter) { return parameter.getParameterType().equals(AuthInfo.class) && parameter.hasParameterAnnotation( From d9df55164346dee76473262c4813d5ace704e5c2 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 17:29:14 +0900 Subject: [PATCH 080/311] style: move package path --- .../auth/{ => infrastructure}/RefreshTokenRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/java/coffeemeet/server/auth/{ => infrastructure}/RefreshTokenRepository.java (80%) diff --git a/src/main/java/coffeemeet/server/auth/RefreshTokenRepository.java b/src/main/java/coffeemeet/server/auth/infrastructure/RefreshTokenRepository.java similarity index 80% rename from src/main/java/coffeemeet/server/auth/RefreshTokenRepository.java rename to src/main/java/coffeemeet/server/auth/infrastructure/RefreshTokenRepository.java index e9e53608..8fc81e0c 100644 --- a/src/main/java/coffeemeet/server/auth/RefreshTokenRepository.java +++ b/src/main/java/coffeemeet/server/auth/infrastructure/RefreshTokenRepository.java @@ -1,4 +1,4 @@ -package coffeemeet.server.auth; +package coffeemeet.server.auth.infrastructure; import coffeemeet.server.auth.domain.RefreshToken; import org.springframework.data.repository.CrudRepository; From 46e1972cb06a899dfc9d3712f9823e85be89e67b Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 17:30:54 +0900 Subject: [PATCH 081/311] style: update imports --- .../java/coffeemeet/server/common/config/AuthWebConfig.java | 2 +- .../coffeemeet/server/common/config/ControllerTestConfig.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java b/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java index 43a234d2..7201ace4 100644 --- a/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java +++ b/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java @@ -1,6 +1,6 @@ package coffeemeet.server.common.config; -import coffeemeet.server.auth.RefreshTokenRepository; +import coffeemeet.server.auth.infrastructure.RefreshTokenRepository; import coffeemeet.server.auth.utils.JwtTokenProvider; import coffeemeet.server.auth.utils.converter.OAuthProviderConverter; import coffeemeet.server.common.UserArgumentResolver; diff --git a/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java index 32e9ec5b..7435039d 100644 --- a/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java +++ b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java @@ -3,7 +3,7 @@ import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import coffeemeet.server.auth.RefreshTokenRepository; +import coffeemeet.server.auth.infrastructure.RefreshTokenRepository; import coffeemeet.server.auth.utils.JwtTokenProvider; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; From a69e18a820513b68d4861ee2ee3b24a94a09fbc1 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 17:31:26 +0900 Subject: [PATCH 082/311] refactor: update exception message --- .../java/coffeemeet/server/common/UserArgumentResolver.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java index 671d139b..ac899e39 100644 --- a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java +++ b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java @@ -1,7 +1,7 @@ package coffeemeet.server.common; -import coffeemeet.server.auth.RefreshTokenRepository; import coffeemeet.server.auth.domain.RefreshToken; +import coffeemeet.server.auth.infrastructure.RefreshTokenRepository; import coffeemeet.server.auth.utils.JwtTokenProvider; import coffeemeet.server.common.annotation.Login; import coffeemeet.server.user.dto.AuthInfo; @@ -18,7 +18,7 @@ @RequiredArgsConstructor public class UserArgumentResolver implements HandlerMethodArgumentResolver { - public static final String USER_AUTHENTICATION_FAILED_MESSAGE = "사용자(%s)의 갱신 토큰이 존재하지 않습니다."; + public static final String USER_AUTHENTICATION_FAILED_MESSAGE = "사용자(%s)의 재인증(로그인)이 필요합니다."; private static final String HEADER_AUTHENTICATION_FAILED_MESSAGE = "(%s)는 잘못된 권한 헤더입니다."; private final JwtTokenProvider jwtTokenProvider; From 6218e5d6d4c34a9c51e9eb0a7603c37b8b9d9a82 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 17:32:13 +0900 Subject: [PATCH 083/311] feat: save refresh token MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 회원 가입 또는 로그인 시, 리프레시 토큰 레디스 저장소에 저장 기능 구현 --- .../server/auth/utils/AuthTokensGenerator.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java b/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java index 88f212c5..737e4f8a 100644 --- a/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java +++ b/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java @@ -1,5 +1,7 @@ package coffeemeet.server.auth.utils; +import coffeemeet.server.auth.domain.RefreshToken; +import coffeemeet.server.auth.infrastructure.RefreshTokenRepository; import java.util.Date; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -12,14 +14,16 @@ public class AuthTokensGenerator { private final JwtTokenProvider jwtTokenProvider; private final Long accessTokenExpireTime; private final Long refreshTokenExpireTime; + private final RefreshTokenRepository refreshTokenRepository; public AuthTokensGenerator(JwtTokenProvider jwtTokenProvider, @Value("${jwt.access-token-expire-time}") Long accessTokenExpireTime, - @Value("${jwt.refresh-token-expire-time}") Long refreshTokenExpireTime - ) { + @Value("${jwt.refresh-token-expire-time}") Long refreshTokenExpireTime, + RefreshTokenRepository refreshTokenRepository) { this.jwtTokenProvider = jwtTokenProvider; this.accessTokenExpireTime = accessTokenExpireTime; this.refreshTokenExpireTime = refreshTokenExpireTime; + this.refreshTokenRepository = refreshTokenRepository; } public AuthTokens generate(Long userId) { @@ -31,6 +35,12 @@ public AuthTokens generate(Long userId) { String accessToken = jwtTokenProvider.generate(subject, accessTokenExpiredAt); String refreshToken = jwtTokenProvider.generate(subject, refreshTokenExpiredAt); + RefreshToken refreshTokenEntity = RefreshToken.builder() + .userId(userId) + .value(refreshToken) + .build(); + refreshTokenRepository.save(refreshTokenEntity); + return AuthTokens.of( BEARER_TYPE + accessToken, BEARER_TYPE + refreshToken From 89db54c5f74d9668b31224997a40043c97309fa9 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 18:33:55 +0900 Subject: [PATCH 084/311] =?UTF-8?q?refactor:=20AuthController=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 - 회원가입 API 요청 데이터 검증 추가 - 로그인 API 수정 --- .../auth/controller/AuthController.java | 17 +++++------------ .../server/auth/dto/SignupRequest.java | 19 +++++-------------- .../server/auth/service/AuthService.java | 13 ++++++++----- 3 files changed, 18 insertions(+), 31 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/controller/AuthController.java b/src/main/java/coffeemeet/server/auth/controller/AuthController.java index 77853a38..68d96bef 100644 --- a/src/main/java/coffeemeet/server/auth/controller/AuthController.java +++ b/src/main/java/coffeemeet/server/auth/controller/AuthController.java @@ -5,8 +5,8 @@ import coffeemeet.server.auth.utils.AuthTokens; import coffeemeet.server.user.domain.OAuthProvider; import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; import java.io.IOException; -import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -34,21 +34,14 @@ public ResponseEntity redirectAuthCodeRequestUrl(@PathVariable OAuthProvid } @PostMapping("/sign-up") - public ResponseEntity signup(@RequestBody SignupRequest request) { + public ResponseEntity signup(@Valid @RequestBody SignupRequest request) { return ResponseEntity.ok(authService.signup(request)); } @GetMapping("/login/{oAuthProvider}") - public ResponseEntity login(@PathVariable OAuthProvider oAuthProvider, - @RequestParam String authCode, HttpServletResponse response) throws IOException { - Optional authTokens = authService.login(oAuthProvider, authCode); - if (authTokens.isPresent()) { - return ResponseEntity.ok(authTokens.get()); - } - - String signupUrl = "/oauth2/auth/sign-up"; - response.sendRedirect(signupUrl); - return new ResponseEntity<>(HttpStatus.FOUND); + public ResponseEntity login(@PathVariable OAuthProvider oAuthProvider, + @RequestParam String authCode) { + return ResponseEntity.ok(authService.login(oAuthProvider, authCode)); } } diff --git a/src/main/java/coffeemeet/server/auth/dto/SignupRequest.java b/src/main/java/coffeemeet/server/auth/dto/SignupRequest.java index 4cb8c8ee..76c798e3 100644 --- a/src/main/java/coffeemeet/server/auth/dto/SignupRequest.java +++ b/src/main/java/coffeemeet/server/auth/dto/SignupRequest.java @@ -2,27 +2,18 @@ import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.user.domain.OAuthProvider; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import java.util.List; public record SignupRequest( + @NotBlank String nickname, + @NotNull List keywords, + @NotBlank String authCode, OAuthProvider oAuthProvider ) { - public static SignupRequest of( - String nickname, - List keywords, - String authCode, - OAuthProvider oAuthProvider - ) { - return new SignupRequest( - nickname, - keywords, - authCode, - oAuthProvider - ); - } - } diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index 5b0e7b6c..d081a8b0 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -16,7 +16,6 @@ import coffeemeet.server.user.repository.UserRepository; import java.util.ArrayList; import java.util.List; -import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -25,6 +24,7 @@ public class AuthService { private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; + private static final String USER_NOT_REGISTERED_MESSAGE = "해당 아이디(%s)와 로그인 타입(%s)의 유저는 회원가입되지 않았습니다."; private final AuthCodeRequestUrlProviderComposite authCodeRequestUrlProviderComposite; private final OAuthMemberClientComposite oauthMemberClientComposite; @@ -63,11 +63,14 @@ public AuthTokens signup(SignupRequest request) { return authTokensGenerator.generate(newUser.getId()); } - public Optional login(OAuthProvider oAuthProvider, String authCode) { + public AuthTokens login(OAuthProvider oAuthProvider, String authCode) { OAuthInfoResponse response = oauthMemberClientComposite.fetch(oAuthProvider, authCode); - Optional foundUser = userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( - response.oAuthProvider(), response.oAuthProviderId()); - return foundUser.map(user -> authTokensGenerator.generate(user.getId())); + User foundUser = userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( + response.oAuthProvider(), response.oAuthProviderId()) + .orElseThrow(() -> new IllegalArgumentException( + String.format(USER_NOT_REGISTERED_MESSAGE, response.oAuthProviderId(), + response.oAuthProvider()))); + return authTokensGenerator.generate(foundUser.getId()); } private void checkDuplicateUser(OAuthInfoResponse response) { From 69e60ca33c02ca4617f5646bb5dfdbe6df49c240 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 23 Oct 2023 18:50:11 +0900 Subject: [PATCH 085/311] =?UTF-8?q?feat:=20=ED=86=A0=ED=81=B0=20=EA=B0=B1?= =?UTF-8?q?=EC=8B=A0=20API=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 액세스 토큰이 만료 되면, 리프레시 토큰을 통해 액세스 토큰 재발급 - 리프레시 토큰도 만료 되면 예외 발생 --- .../auth/controller/AuthController.java | 7 +++++ .../server/auth/service/AuthService.java | 31 ++++++++++--------- .../auth/utils/AuthTokensGenerator.java | 2 +- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/controller/AuthController.java b/src/main/java/coffeemeet/server/auth/controller/AuthController.java index 68d96bef..a4cb4bf3 100644 --- a/src/main/java/coffeemeet/server/auth/controller/AuthController.java +++ b/src/main/java/coffeemeet/server/auth/controller/AuthController.java @@ -3,7 +3,9 @@ import coffeemeet.server.auth.dto.SignupRequest; import coffeemeet.server.auth.service.AuthService; import coffeemeet.server.auth.utils.AuthTokens; +import coffeemeet.server.common.annotation.Login; import coffeemeet.server.user.domain.OAuthProvider; +import coffeemeet.server.user.dto.AuthInfo; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import java.io.IOException; @@ -44,4 +46,9 @@ public ResponseEntity login(@PathVariable OAuthProvider oAuthProvide return ResponseEntity.ok(authService.login(oAuthProvider, authCode)); } + @PostMapping("/renew-token") + public ResponseEntity renew(@Login AuthInfo authInfo) { + return ResponseEntity.ok(authService.renew(authInfo.userId(), authInfo.refreshToken())); + } + } diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index d081a8b0..d19ddf5b 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -6,6 +6,7 @@ import coffeemeet.server.auth.dto.SignupRequest; import coffeemeet.server.auth.utils.AuthTokens; import coffeemeet.server.auth.utils.AuthTokensGenerator; +import coffeemeet.server.auth.utils.JwtTokenProvider; import coffeemeet.server.interest.domain.Interest; import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.interest.repository.InterestRepository; @@ -23,6 +24,7 @@ @RequiredArgsConstructor public class AuthService { + private static final String EXPIRED_REFRESH_TOKEN_MESSAGE = "리프레시 토큰이 만료되었습니다. 다시 로그인해 주세요."; private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; private static final String USER_NOT_REGISTERED_MESSAGE = "해당 아이디(%s)와 로그인 타입(%s)의 유저는 회원가입되지 않았습니다."; @@ -31,6 +33,7 @@ public class AuthService { private final UserRepository userRepository; private final InterestRepository interestRepository; private final AuthTokensGenerator authTokensGenerator; + private final JwtTokenProvider jwtTokenProvider; public String getAuthCodeRequestUrl(OAuthProvider oAuthProvider) { return authCodeRequestUrlProviderComposite.provide(oAuthProvider); @@ -42,19 +45,9 @@ public AuthTokens signup(SignupRequest request) { checkDuplicateUser(response); String profileImage = checkProfileImage(response.profileImage()); - User user = new User( - new OAuthInfo( - response.oAuthProvider(), - response.oAuthProviderId() - ), - Profile.builder() - .name(response.name()) - .nickname(request.nickname()) - .email(response.email()) - .profileImageUrl(profileImage) - .birth(response.birth()) - .build() - ); + User user = new User(new OAuthInfo(response.oAuthProvider(), response.oAuthProviderId()), + Profile.builder().name(response.name()).nickname(request.nickname()).email(response.email()) + .profileImageUrl(profileImage).birth(response.birth()).build()); User newUser = userRepository.save(user); @@ -66,13 +59,21 @@ public AuthTokens signup(SignupRequest request) { public AuthTokens login(OAuthProvider oAuthProvider, String authCode) { OAuthInfoResponse response = oauthMemberClientComposite.fetch(oAuthProvider, authCode); User foundUser = userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( - response.oAuthProvider(), response.oAuthProviderId()) - .orElseThrow(() -> new IllegalArgumentException( + response.oAuthProvider(), response.oAuthProviderId()).orElseThrow( + () -> new IllegalArgumentException( String.format(USER_NOT_REGISTERED_MESSAGE, response.oAuthProviderId(), response.oAuthProvider()))); return authTokensGenerator.generate(foundUser.getId()); } + public AuthTokens renew(Long userId, String refreshToken) { + if (jwtTokenProvider.isExpiredRefreshToken(refreshToken)) { + throw new IllegalArgumentException(EXPIRED_REFRESH_TOKEN_MESSAGE); + } else { + return authTokensGenerator.reissueAccessToken(userId, refreshToken); + } + } + private void checkDuplicateUser(OAuthInfoResponse response) { if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( response.oAuthProvider(), response.oAuthProviderId())) { diff --git a/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java b/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java index 737e4f8a..f530f173 100644 --- a/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java +++ b/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java @@ -47,7 +47,7 @@ public AuthTokens generate(Long userId) { ); } - public AuthTokens refreshJwtToken(Long userId, String refreshToken) { + public AuthTokens reissueAccessToken(Long userId, String refreshToken) { long now = (new Date()).getTime(); Date accessTokenExpiredAt = new Date(now + accessTokenExpireTime); From 489d116c3ea359c136b58171adc13b1ccd8d7ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 24 Oct 2023 00:10:16 +0900 Subject: [PATCH 086/311] =?UTF-8?q?refactor:=20from=EC=9D=84=20of=EB=A1=9C?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/user/dto/MyProfileResponse.java | 2 +- .../java/coffeemeet/server/user/dto/UserProfileResponse.java | 2 +- src/main/java/coffeemeet/server/user/service/UserService.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java b/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java index b3d1afd1..eb9dc90b 100644 --- a/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java +++ b/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java @@ -20,7 +20,7 @@ public record MyProfileResponse( List interests ) { - public static MyProfileResponse from(User user, List interests) { + public static MyProfileResponse of(User user, List interests) { List keywords = interests.stream() .map(Interest::getKeyword) .toList(); diff --git a/src/main/java/coffeemeet/server/user/dto/UserProfileResponse.java b/src/main/java/coffeemeet/server/user/dto/UserProfileResponse.java index f39a26df..cc396249 100644 --- a/src/main/java/coffeemeet/server/user/dto/UserProfileResponse.java +++ b/src/main/java/coffeemeet/server/user/dto/UserProfileResponse.java @@ -12,7 +12,7 @@ public record UserProfileResponse( List interests ) { - public static UserProfileResponse from(User user, List interests) { + public static UserProfileResponse of(User user, List interests) { List keywords = interests.stream() .map(Interest::getKeyword) .toList(); diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 03743816..40e64067 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -30,7 +30,7 @@ public UserProfileResponse findUserProfile(String nickname) { .orElseThrow(IllegalArgumentException::new); List interests = interestRepository.findAllByUserId(user.getId()); - return UserProfileResponse.from(user, interests); + return UserProfileResponse.of(user, interests); } public MyProfileResponse findMyProfile(Long userId) { @@ -38,7 +38,7 @@ public MyProfileResponse findMyProfile(Long userId) { .orElseThrow(IllegalArgumentException::new); List interests = interestRepository.findAllByUserId(userId); - return MyProfileResponse.from(user, interests); + return MyProfileResponse.of(user, interests); } } From acc9c047668b887c72e7b112768cbdd44597bdc8 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 24 Oct 2023 14:45:07 +0900 Subject: [PATCH 087/311] =?UTF-8?q?feat:=20AuthService,=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=95=84=EC=9B=83=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 레디스 저장소의 사용자 refresh token 삭제 --- .../java/coffeemeet/server/auth/service/AuthService.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index d19ddf5b..4c7257a5 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -4,6 +4,7 @@ import coffeemeet.server.auth.domain.client.OAuthMemberClientComposite; import coffeemeet.server.auth.dto.OAuthInfoResponse; import coffeemeet.server.auth.dto.SignupRequest; +import coffeemeet.server.auth.infrastructure.RefreshTokenRepository; import coffeemeet.server.auth.utils.AuthTokens; import coffeemeet.server.auth.utils.AuthTokensGenerator; import coffeemeet.server.auth.utils.JwtTokenProvider; @@ -34,6 +35,7 @@ public class AuthService { private final InterestRepository interestRepository; private final AuthTokensGenerator authTokensGenerator; private final JwtTokenProvider jwtTokenProvider; + private final RefreshTokenRepository refreshTokenRepository; public String getAuthCodeRequestUrl(OAuthProvider oAuthProvider) { return authCodeRequestUrlProviderComposite.provide(oAuthProvider); @@ -74,6 +76,10 @@ public AuthTokens renew(Long userId, String refreshToken) { } } + public void logout(Long userId) { + refreshTokenRepository.deleteById(userId); + } + private void checkDuplicateUser(OAuthInfoResponse response) { if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( response.oAuthProvider(), response.oAuthProviderId())) { From dfe66e8a6cb93ef3643d693cdddb3f32344add63 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 24 Oct 2023 14:45:33 +0900 Subject: [PATCH 088/311] =?UTF-8?q?feat:=20AuthController,=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=95=84=EC=9B=83=20API=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/auth/controller/AuthController.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/coffeemeet/server/auth/controller/AuthController.java b/src/main/java/coffeemeet/server/auth/controller/AuthController.java index a4cb4bf3..0f450e5c 100644 --- a/src/main/java/coffeemeet/server/auth/controller/AuthController.java +++ b/src/main/java/coffeemeet/server/auth/controller/AuthController.java @@ -51,4 +51,10 @@ public ResponseEntity renew(@Login AuthInfo authInfo) { return ResponseEntity.ok(authService.renew(authInfo.userId(), authInfo.refreshToken())); } + @PostMapping("/logout") + public ResponseEntity logout(@Login @RequestBody AuthInfo authInfo) { + authService.logout(authInfo.userId()); + return ResponseEntity.noContent().build(); + } + } From 41d0aaafca6b69f7bee5d72a1c6beb8d59315534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 24 Oct 2023 14:59:54 +0900 Subject: [PATCH 089/311] =?UTF-8?q?feat:=20User=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=EC=97=90=20=EC=A0=95=EB=B3=B4=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8=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 --- .../java/coffeemeet/server/user/domain/Profile.java | 10 ++++++++++ src/main/java/coffeemeet/server/user/domain/User.java | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/src/main/java/coffeemeet/server/user/domain/Profile.java b/src/main/java/coffeemeet/server/user/domain/Profile.java index 97b82806..cc075942 100644 --- a/src/main/java/coffeemeet/server/user/domain/Profile.java +++ b/src/main/java/coffeemeet/server/user/domain/Profile.java @@ -69,4 +69,14 @@ private void validateProfileImage(String profileImageUrl) { } } + public void updateNickname(String nickname) { + validateNickname(nickname); + this.nickname = nickname; + } + + public void updateProfileImageUrl(String profileImageUrl) { + validateProfileImage(profileImageUrl); + this.profileImageUrl = profileImageUrl; + } + } diff --git a/src/main/java/coffeemeet/server/user/domain/User.java b/src/main/java/coffeemeet/server/user/domain/User.java index ca575d69..b28172da 100644 --- a/src/main/java/coffeemeet/server/user/domain/User.java +++ b/src/main/java/coffeemeet/server/user/domain/User.java @@ -63,4 +63,8 @@ public void updateBusinessCardUrl(String newBusinessCardUrl) { certification.updateBusinessCardUrl(newBusinessCardUrl); } + public void updateProfileImageUrl(String profileImageUrl) { + this.profile.updateProfileImageUrl(profileImageUrl); + } + } From 0fc7cdd3c3146e3a99d5195254c949658735af4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 24 Oct 2023 15:01:18 +0900 Subject: [PATCH 090/311] =?UTF-8?q?feat:=20=EA=B4=80=EC=8B=AC=EC=82=AC=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/interest/domain/Keyword.java | 10 ++++ .../interest/service/InterestService.java | 49 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 src/main/java/coffeemeet/server/interest/service/InterestService.java diff --git a/src/main/java/coffeemeet/server/interest/domain/Keyword.java b/src/main/java/coffeemeet/server/interest/domain/Keyword.java index 717ad9e5..6b2f9aea 100644 --- a/src/main/java/coffeemeet/server/interest/domain/Keyword.java +++ b/src/main/java/coffeemeet/server/interest/domain/Keyword.java @@ -4,5 +4,15 @@ public enum Keyword { COOK, GAME, EXERCISE, + ; + + public static boolean isValidKeyword(String keyword) { + for (Keyword key : Keyword.values()) { + if (key.name().equals(keyword)) { + return true; + } + } + return false; + } } diff --git a/src/main/java/coffeemeet/server/interest/service/InterestService.java b/src/main/java/coffeemeet/server/interest/service/InterestService.java new file mode 100644 index 00000000..0541e43f --- /dev/null +++ b/src/main/java/coffeemeet/server/interest/service/InterestService.java @@ -0,0 +1,49 @@ +package coffeemeet.server.interest.service; + +import coffeemeet.server.interest.domain.Interest; +import coffeemeet.server.interest.domain.Keyword; +import coffeemeet.server.interest.repository.InterestRepository; +import coffeemeet.server.user.domain.User; +import coffeemeet.server.user.repository.UserRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class InterestService { + + private static final int MAX_INTERESTS = 3; + + private final InterestRepository interestRepository; + private final UserRepository userRepository; + + @Transactional + public void updateInterests(Long userId, List interests) { + validateInterests(interests); + + for (Keyword interest : interests) { + if (!Keyword.isValidKeyword(interest.name())) { + throw new IllegalArgumentException("유효한 관심사가 아닙니다."); + } + } + User user = userRepository.findById(userId) + .orElseThrow(() -> new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); + + List currentInterests = interestRepository.findAllByUserId(userId); + interestRepository.deleteAll(currentInterests); + + for (Keyword keyword : interests) { + Interest newInterest = new Interest(keyword, user); + interestRepository.save(newInterest); + } + } + + private void validateInterests(List interests) { + if (interests.isEmpty() || interests.size() > MAX_INTERESTS) { + throw new IllegalArgumentException("최소 1개, 최대 3개의 관심사를 선택하세요."); + } + } + +} From 3e378e38e93fe01345f76c2a258c76d9dd29e59d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 24 Oct 2023 15:01:32 +0900 Subject: [PATCH 091/311] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A0=95=EB=B3=B4=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=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 --- .../user/controller/UserController.java | 19 +++++++++++++ .../server/user/dto/UpdateProfileRequest.java | 9 +++++++ .../server/user/service/UserService.java | 27 +++++++++++++++++-- 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index 86131025..3a5f14fd 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -3,13 +3,18 @@ import coffeemeet.server.common.annotation.Login; import coffeemeet.server.user.dto.AuthInfo; import coffeemeet.server.user.dto.MyProfileResponse; +import coffeemeet.server.user.dto.UpdateProfileRequest; import coffeemeet.server.user.dto.UserProfileResponse; import coffeemeet.server.user.service.UserService; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @@ -29,4 +34,18 @@ public ResponseEntity findMyProfile(@Login AuthInfo authInfo) return ResponseEntity.ok(userService.findMyProfile(authInfo.userId())); } + @PatchMapping("/me/profile-image") + public ResponseEntity updateProfileImage(@Login AuthInfo authInfo, + @RequestParam String profileImageUrl) { + userService.updateProfileImage(authInfo.userId(), profileImageUrl); + return ResponseEntity.noContent().build(); + } + + @PatchMapping("/me") + public ResponseEntity updateProfileInfo(@Login AuthInfo authInfo, + @Valid @RequestBody UpdateProfileRequest request) { + userService.updateProfileInfo(authInfo.userId(), request.nickname(), request.interests()); + return ResponseEntity.noContent().build(); + } + } diff --git a/src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java b/src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java new file mode 100644 index 00000000..5cab1ba4 --- /dev/null +++ b/src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java @@ -0,0 +1,9 @@ +package coffeemeet.server.user.dto; + +import coffeemeet.server.interest.domain.Keyword; +import jakarta.validation.constraints.NotBlank; +import java.util.List; + +public record UpdateProfileRequest(@NotBlank String nickname, List interests) { + +} diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 40e64067..269ad88b 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -1,7 +1,9 @@ package coffeemeet.server.user.service; import coffeemeet.server.interest.domain.Interest; +import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.interest.repository.InterestRepository; +import coffeemeet.server.interest.service.InterestService; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.dto.MyProfileResponse; import coffeemeet.server.user.dto.UserProfileResponse; @@ -17,6 +19,7 @@ public class UserService { private final UserRepository userRepository; private final InterestRepository interestRepository; + private final InterestService interestService; @Transactional public void updateBusinessCardUrl(Long userId, String businessCardUrl) { @@ -27,7 +30,7 @@ public void updateBusinessCardUrl(Long userId, String businessCardUrl) { public UserProfileResponse findUserProfile(String nickname) { User user = userRepository.findUserByProfileNickname(nickname) - .orElseThrow(IllegalArgumentException::new); + .orElseThrow(() -> new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); List interests = interestRepository.findAllByUserId(user.getId()); return UserProfileResponse.of(user, interests); @@ -35,10 +38,30 @@ public UserProfileResponse findUserProfile(String nickname) { public MyProfileResponse findMyProfile(Long userId) { User user = userRepository.findById(userId) - .orElseThrow(IllegalArgumentException::new); + .orElseThrow(() -> new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); List interests = interestRepository.findAllByUserId(userId); return MyProfileResponse.of(user, interests); } + @Transactional + public void updateProfileImage(Long userId, String profileImageUrl) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); + user.updateProfileImageUrl(profileImageUrl); + } + + @Transactional + public void updateProfileInfo(Long userId, String nickname, List interests) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); + + if (nickname != null) { + user.getProfile().updateNickname(nickname); + } + if (interests != null && !interests.isEmpty()) { + interestService.updateInterests(userId, interests); + } + } + } From a6a5fbc9ca90c2e0b700bbe1ac004421a27bbb1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 24 Oct 2023 17:15:31 +0900 Subject: [PATCH 092/311] =?UTF-8?q?refactor:=20=ED=94=84=EB=A1=9C=ED=95=84?= =?UTF-8?q?=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20DTO=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B2=80=EC=A6=9D=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/user/controller/UserController.java | 6 +++--- .../server/user/dto/UpdateProfileImageUrlRequest.java | 7 +++++++ .../coffeemeet/server/user/dto/UpdateProfileRequest.java | 5 ++++- .../java/coffeemeet/server/user/service/UserService.java | 8 ++------ 4 files changed, 16 insertions(+), 10 deletions(-) create mode 100644 src/main/java/coffeemeet/server/user/dto/UpdateProfileImageUrlRequest.java diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index 3a5f14fd..c7223d70 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -3,6 +3,7 @@ import coffeemeet.server.common.annotation.Login; import coffeemeet.server.user.dto.AuthInfo; import coffeemeet.server.user.dto.MyProfileResponse; +import coffeemeet.server.user.dto.UpdateProfileImageUrlRequest; import coffeemeet.server.user.dto.UpdateProfileRequest; import coffeemeet.server.user.dto.UserProfileResponse; import coffeemeet.server.user.service.UserService; @@ -14,7 +15,6 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @@ -36,8 +36,8 @@ public ResponseEntity findMyProfile(@Login AuthInfo authInfo) @PatchMapping("/me/profile-image") public ResponseEntity updateProfileImage(@Login AuthInfo authInfo, - @RequestParam String profileImageUrl) { - userService.updateProfileImage(authInfo.userId(), profileImageUrl); + @Valid @RequestBody UpdateProfileImageUrlRequest request) { + userService.updateProfileImage(authInfo.userId(), request.profileImageUrl()); return ResponseEntity.noContent().build(); } diff --git a/src/main/java/coffeemeet/server/user/dto/UpdateProfileImageUrlRequest.java b/src/main/java/coffeemeet/server/user/dto/UpdateProfileImageUrlRequest.java new file mode 100644 index 00000000..7f1c54ca --- /dev/null +++ b/src/main/java/coffeemeet/server/user/dto/UpdateProfileImageUrlRequest.java @@ -0,0 +1,7 @@ +package coffeemeet.server.user.dto; + +import jakarta.validation.constraints.NotBlank; + +public record UpdateProfileImageUrlRequest(@NotBlank String profileImageUrl) { + +} diff --git a/src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java b/src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java index 5cab1ba4..a0458198 100644 --- a/src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java +++ b/src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java @@ -2,8 +2,11 @@ import coffeemeet.server.interest.domain.Keyword; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import java.util.List; -public record UpdateProfileRequest(@NotBlank String nickname, List interests) { +public record UpdateProfileRequest(@NotBlank String nickname, + @NotNull @Size(min = 1, max = 3) List interests) { } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 269ad88b..78f3c518 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -56,12 +56,8 @@ public void updateProfileInfo(Long userId, String nickname, List intere User user = userRepository.findById(userId) .orElseThrow(() -> new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); - if (nickname != null) { - user.getProfile().updateNickname(nickname); - } - if (interests != null && !interests.isEmpty()) { - interestService.updateInterests(userId, interests); - } + user.getProfile().updateNickname(nickname); + interestService.updateInterests(userId, interests); } } From 95432e454c7f052f9958313489c9af25a18b59ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 24 Oct 2023 17:17:08 +0900 Subject: [PATCH 093/311] =?UTF-8?q?refactor:=20=EA=B4=80=EC=8B=AC=EC=82=AC?= =?UTF-8?q?=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/interest/domain/Keyword.java | 10 ---------- .../server/interest/service/InterestService.java | 14 ++++---------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/src/main/java/coffeemeet/server/interest/domain/Keyword.java b/src/main/java/coffeemeet/server/interest/domain/Keyword.java index 6b2f9aea..717ad9e5 100644 --- a/src/main/java/coffeemeet/server/interest/domain/Keyword.java +++ b/src/main/java/coffeemeet/server/interest/domain/Keyword.java @@ -4,15 +4,5 @@ public enum Keyword { COOK, GAME, EXERCISE, - ; - - public static boolean isValidKeyword(String keyword) { - for (Keyword key : Keyword.values()) { - if (key.name().equals(keyword)) { - return true; - } - } - return false; - } } diff --git a/src/main/java/coffeemeet/server/interest/service/InterestService.java b/src/main/java/coffeemeet/server/interest/service/InterestService.java index 0541e43f..a9906ed2 100644 --- a/src/main/java/coffeemeet/server/interest/service/InterestService.java +++ b/src/main/java/coffeemeet/server/interest/service/InterestService.java @@ -14,20 +14,20 @@ @RequiredArgsConstructor public class InterestService { - private static final int MAX_INTERESTS = 3; - private final InterestRepository interestRepository; private final UserRepository userRepository; @Transactional public void updateInterests(Long userId, List interests) { - validateInterests(interests); for (Keyword interest : interests) { - if (!Keyword.isValidKeyword(interest.name())) { + try { + Keyword.valueOf(interest.name()); + } catch (IllegalArgumentException e) { throw new IllegalArgumentException("유효한 관심사가 아닙니다."); } } + User user = userRepository.findById(userId) .orElseThrow(() -> new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); @@ -40,10 +40,4 @@ public void updateInterests(Long userId, List interests) { } } - private void validateInterests(List interests) { - if (interests.isEmpty() || interests.size() > MAX_INTERESTS) { - throw new IllegalArgumentException("최소 1개, 최대 3개의 관심사를 선택하세요."); - } - } - } From 31e442f5c6ea05b08316e31f1178a773a5acf495 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 04:53:54 +0900 Subject: [PATCH 094/311] =?UTF-8?q?chore:=20mail=20=EC=84=A4=EC=A0=95=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/resources/application.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index f8f17edb..e029a289 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -19,6 +19,18 @@ spring: port: ${REDIS_PORT} password: ${REDIS_PASSWORD} + mail: + host: ${MAIL_HOST} + port: ${MAIL_PORT} + username: ${MAIL_USERNAME} + password: ${MAIL_PASSWORD} + properties: + mail: + smtp: + auth: true + starttls: + enable: true + jwt: secret-key: ${JWT_SECRET_KEY} access-token-expire-time: ${ACCESS_TOKEN_EXPIRE_TIME} From cd58b933bec266eb22f7d1a046c5fc08c9111923 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 04:54:04 +0900 Subject: [PATCH 095/311] =?UTF-8?q?chore:=20mail=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=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 | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 4cecab6f..2a9b8a27 100644 --- a/build.gradle +++ b/build.gradle @@ -45,6 +45,7 @@ dependencies { /* Spring */ implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-mail' /* JWT */ implementation 'io.jsonwebtoken:jjwt-api:0.11.5' @@ -99,12 +100,12 @@ tasks.withType(GenerateSwaggerUI) { doFirst { def swaggerUIFile = file("${openapi3.outputDirectory}/openapi3.yaml") - def securitySchemesContent = " securitySchemes:\n" + \ - " APIKey:\n" + \ - " type: apiKey\n" + \ - " name: Authorization\n" + \ - " in: header\n" + \ - "security:\n" + + def securitySchemesContent = " securitySchemes:\n" + \ + " APIKey:\n" + \ + " type: apiKey\n" + \ + " name: Authorization\n" + \ + " in: header\n" + \ + "security:\n" + " - APIKey: [] # Apply the security scheme here" swaggerUIFile.append securitySchemesContent From 1437a25d38293bb76dfeb516c6358aed1d9c7d53 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 04:54:20 +0900 Subject: [PATCH 096/311] =?UTF-8?q?refactor:=20BusinessCardS3KeyGenerator?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/BusinessCardS3KeyGenerator.java | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 src/main/java/coffeemeet/server/certification/service/BusinessCardS3KeyGenerator.java diff --git a/src/main/java/coffeemeet/server/certification/service/BusinessCardS3KeyGenerator.java b/src/main/java/coffeemeet/server/certification/service/BusinessCardS3KeyGenerator.java deleted file mode 100644 index 052bf629..00000000 --- a/src/main/java/coffeemeet/server/certification/service/BusinessCardS3KeyGenerator.java +++ /dev/null @@ -1,14 +0,0 @@ -package coffeemeet.server.certification.service; - -import java.time.LocalDateTime; -import java.util.UUID; -import org.springframework.stereotype.Service; - -@Service -public class BusinessCardS3KeyGenerator { - - public String generate() { - return String.format("BusinessCard-%s-%s", LocalDateTime.now(), UUID.randomUUID()); - } - -} From 8f28bb578a3efcd095868719e51d8d0b84bd32ee Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 04:54:43 +0900 Subject: [PATCH 097/311] =?UTF-8?q?feat:=20EmailDto=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/certification/dto/EmailDto.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/coffeemeet/server/certification/dto/EmailDto.java diff --git a/src/main/java/coffeemeet/server/certification/dto/EmailDto.java b/src/main/java/coffeemeet/server/certification/dto/EmailDto.java new file mode 100644 index 00000000..b86752a7 --- /dev/null +++ b/src/main/java/coffeemeet/server/certification/dto/EmailDto.java @@ -0,0 +1,11 @@ +package coffeemeet.server.certification.dto; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotNull; + +public record EmailDto( + @Email @NotNull + String companyEmail +) { + +} From 96b6d869b66d3b6a8217fb4ee2b011b8fcbc69fc Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 04:56:34 +0900 Subject: [PATCH 098/311] =?UTF-8?q?feat:=20Email=20=EB=B3=B4=EB=82=B4?= =?UTF-8?q?=EA=B8=B0=20=EB=B0=8F=20=EC=9D=B8=EC=A6=9D=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=B0=9C=EA=B8=89=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/common/media/EmailService.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/media/EmailService.java diff --git a/src/main/java/coffeemeet/server/common/media/EmailService.java b/src/main/java/coffeemeet/server/common/media/EmailService.java new file mode 100644 index 00000000..6dd1a684 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/media/EmailService.java @@ -0,0 +1,41 @@ +package coffeemeet.server.common.media; + +import coffeemeet.server.user.domain.CompanyEmail; +import java.util.random.RandomGenerator; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.stereotype.Service; + +@Service +public class EmailService { + + private static final RandomGenerator randomGenerator = RandomGenerator.getDefault(); + private final JavaMailSender javaMailSender; + private final String sender; + + public EmailService(JavaMailSender javaMailSender, + @Value("${spring.mail.username}") String sender) { + this.javaMailSender = javaMailSender; + this.sender = sender; + } + + public void sendVerificationMail(CompanyEmail companyMail, String verificationCode) { + SimpleMailMessage mailMessage = new SimpleMailMessage(); + mailMessage.setFrom(sender); + mailMessage.setTo(companyMail.getCompanyEmail()); + + String subject = "[coffee-meet] 커피밋 사용을 위해 이메일 인증을 완료해주세요"; + mailMessage.setSubject(subject); + + String text = String.format("인증번호: %s", verificationCode); + mailMessage.setText(text); + + javaMailSender.send(mailMessage); + } + + public String generateVerificationCode() { + return String.format("%06d", randomGenerator.nextInt(1000000)); + } + +} From 7017f06fcc95b3f4aad57f9a326e2a1b30435fb8 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 04:56:58 +0900 Subject: [PATCH 099/311] =?UTF-8?q?feat:=20=EC=9D=B8=EC=A6=9D=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20redis=20=EA=B0=9D=EC=B2=B4=20=EB=B0=8F=20=EB=A0=88?= =?UTF-8?q?=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/VerificationCode.java | 23 +++++++++++++++++++ .../VerificationCodeRepository.java | 8 +++++++ 2 files changed, 31 insertions(+) create mode 100644 src/main/java/coffeemeet/server/certification/domain/VerificationCode.java create mode 100644 src/main/java/coffeemeet/server/certification/repository/VerificationCodeRepository.java diff --git a/src/main/java/coffeemeet/server/certification/domain/VerificationCode.java b/src/main/java/coffeemeet/server/certification/domain/VerificationCode.java new file mode 100644 index 00000000..6f60c09d --- /dev/null +++ b/src/main/java/coffeemeet/server/certification/domain/VerificationCode.java @@ -0,0 +1,23 @@ +package coffeemeet.server.certification.domain; + +import java.time.LocalDateTime; +import lombok.Getter; +import org.springframework.data.annotation.Id; +import org.springframework.data.redis.core.RedisHash; + +@Getter +@RedisHash(value = "verification_code", timeToLive = 360) +public class VerificationCode { + + @Id + private Long userId; + private String code; + private LocalDateTime createdAt; + + public VerificationCode(Long userId, String code, LocalDateTime createdAt) { + this.userId = userId; + this.code = code; + this.createdAt = createdAt; + } + +} diff --git a/src/main/java/coffeemeet/server/certification/repository/VerificationCodeRepository.java b/src/main/java/coffeemeet/server/certification/repository/VerificationCodeRepository.java new file mode 100644 index 00000000..29fed45a --- /dev/null +++ b/src/main/java/coffeemeet/server/certification/repository/VerificationCodeRepository.java @@ -0,0 +1,8 @@ +package coffeemeet.server.certification.repository; + +import coffeemeet.server.certification.domain.VerificationCode; +import org.springframework.data.repository.CrudRepository; + +public interface VerificationCodeRepository extends CrudRepository { + +} From 12510944bea8b51953f5d6aa13d626f9d27f8479 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 04:58:39 +0900 Subject: [PATCH 100/311] =?UTF-8?q?refactor:=20generateBusinessCardKey=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EB=A1=9C=EC=A7=81=20S3MediaService=20?= =?UTF-8?q?=EC=95=88=EC=9C=BC=EB=A1=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/common/media/S3MediaService.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/coffeemeet/server/common/media/S3MediaService.java b/src/main/java/coffeemeet/server/common/media/S3MediaService.java index 0d0f5932..265caf7f 100644 --- a/src/main/java/coffeemeet/server/common/media/S3MediaService.java +++ b/src/main/java/coffeemeet/server/common/media/S3MediaService.java @@ -2,6 +2,8 @@ import com.amazonaws.services.s3.AmazonS3; import java.io.File; +import java.time.LocalDateTime; +import java.util.UUID; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -31,4 +33,8 @@ public String getUrl(String key) { return amazonS3.getUrl(bucketName, key).toExternalForm(); } + public String generateBusinessCardKey() { + return String.format("BusinessCard-%s-%s", LocalDateTime.now(), UUID.randomUUID()); + } + } From 70d589017ffcdbd7dc478b7cc784d1fe51cf1376 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 04:59:29 +0900 Subject: [PATCH 101/311] =?UTF-8?q?feat:=20=EC=9D=B8=EC=A6=9D=20=EB=A9=94?= =?UTF-8?q?=EC=9D=BC=20=EB=B3=B4=EB=82=B4=EA=B8=B0=20Controller=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/CertificationController.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java index 33544eb7..8b2f696d 100644 --- a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java +++ b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java @@ -1,14 +1,18 @@ package coffeemeet.server.certification.controller; import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.HttpStatus.OK; +import coffeemeet.server.certification.dto.EmailDto; import coffeemeet.server.certification.service.CertificationService; import coffeemeet.server.common.annotation.Login; import coffeemeet.server.common.util.FileUtils; import coffeemeet.server.user.dto.AuthInfo; +import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; 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.RequestPart; import org.springframework.web.bind.annotation.ResponseStatus; @@ -28,11 +32,22 @@ public void uploadBusinessCard( @Login AuthInfo authInfo, @RequestPart("businessCard") - @NotNull(message = "명함 이미지는 null일 수 없습니다.") + @NotNull MultipartFile businessCard ) { certificationService.uploadBusinessCard(authInfo.userId(), FileUtils.convertMultipartFileToFile(businessCard)); } + @PostMapping("users/company-mail") + @ResponseStatus(OK) + public void verifyMail( + @Login + AuthInfo authInfo, + @RequestBody @Valid + EmailDto emailDto + ) { + certificationService.verifyMail(authInfo.userId(), emailDto.companyEmail()); + } + } From f787d932987cf79212fde05335795c4e40f7ac07 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 04:59:35 +0900 Subject: [PATCH 102/311] =?UTF-8?q?feat:=20=EC=9D=B8=EC=A6=9D=20=EB=A9=94?= =?UTF-8?q?=EC=9D=BC=20=EB=B3=B4=EB=82=B4=EA=B8=B0=20Service=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CertificationService.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java index 61b9831c..b251bf60 100644 --- a/src/main/java/coffeemeet/server/certification/service/CertificationService.java +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -1,9 +1,14 @@ package coffeemeet.server.certification.service; +import coffeemeet.server.certification.domain.VerificationCode; +import coffeemeet.server.certification.repository.VerificationCodeRepository; +import coffeemeet.server.common.media.EmailService; import coffeemeet.server.common.media.S3MediaService; import coffeemeet.server.common.util.FileUtils; +import coffeemeet.server.user.domain.CompanyEmail; import coffeemeet.server.user.service.UserService; import java.io.File; +import java.time.LocalDateTime; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -13,14 +18,22 @@ public class CertificationService { private final S3MediaService s3MediaService; private final UserService userService; - private final BusinessCardS3KeyGenerator businessCardS3KeyGenerator; + private final EmailService emailService; + private final VerificationCodeRepository verificationCodeRepository; public void uploadBusinessCard(long userId, File file) { - String key = businessCardS3KeyGenerator.generate(); - + String key = s3MediaService.generateBusinessCardKey(); s3MediaService.upload(key, file); userService.updateBusinessCardUrl(userId, s3MediaService.getUrl(key)); FileUtils.delete(file); } + + public void verifyMail(Long userId, String companyEmail) { + String verificationCode = emailService.generateVerificationCode(); + emailService.sendVerificationMail(new CompanyEmail(companyEmail), verificationCode); + verificationCodeRepository.save( + new VerificationCode(userId, verificationCode, LocalDateTime.now())); + } + } From f00464f6a2368ea25c473363002b5680095dacaa Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 06:01:23 +0900 Subject: [PATCH 103/311] =?UTF-8?q?feat:=20=EC=A4=91=EB=B3=B5=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84=20=EB=B0=8F?= =?UTF-8?q?=20=EC=9D=B8=EC=A6=9D=EC=BD=94=EB=93=9C=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CertificationService.java | 16 +++++++++++++--- .../server/common/media/EmailService.java | 6 ------ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java index b251bf60..b7c4fe9f 100644 --- a/src/main/java/coffeemeet/server/certification/service/CertificationService.java +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -9,6 +9,7 @@ import coffeemeet.server.user.service.UserService; import java.io.File; import java.time.LocalDateTime; +import java.util.random.RandomGenerator; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -16,6 +17,8 @@ @RequiredArgsConstructor public class CertificationService { + private static final RandomGenerator randomGenerator = RandomGenerator.getDefault(); + private final S3MediaService s3MediaService; private final UserService userService; private final EmailService emailService; @@ -29,11 +32,18 @@ public void uploadBusinessCard(long userId, File file) { FileUtils.delete(file); } - public void verifyMail(Long userId, String companyEmail) { - String verificationCode = emailService.generateVerificationCode(); - emailService.sendVerificationMail(new CompanyEmail(companyEmail), verificationCode); + public void sendVerificationMail(Long userId, String email) { + CompanyEmail companyEmail = new CompanyEmail(email); + userService.validateDuplicatedCompanyEmail(companyEmail); + + String verificationCode = generateVerificationCode(); + emailService.sendVerificationMail(companyEmail, verificationCode); verificationCodeRepository.save( new VerificationCode(userId, verificationCode, LocalDateTime.now())); } + private String generateVerificationCode() { + return String.format("%06d", randomGenerator.nextInt(1000000)); + } + } diff --git a/src/main/java/coffeemeet/server/common/media/EmailService.java b/src/main/java/coffeemeet/server/common/media/EmailService.java index 6dd1a684..ddb8abe8 100644 --- a/src/main/java/coffeemeet/server/common/media/EmailService.java +++ b/src/main/java/coffeemeet/server/common/media/EmailService.java @@ -1,7 +1,6 @@ package coffeemeet.server.common.media; import coffeemeet.server.user.domain.CompanyEmail; -import java.util.random.RandomGenerator; import org.springframework.beans.factory.annotation.Value; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; @@ -10,7 +9,6 @@ @Service public class EmailService { - private static final RandomGenerator randomGenerator = RandomGenerator.getDefault(); private final JavaMailSender javaMailSender; private final String sender; @@ -34,8 +32,4 @@ public void sendVerificationMail(CompanyEmail companyMail, String verificationCo javaMailSender.send(mailMessage); } - public String generateVerificationCode() { - return String.format("%06d", randomGenerator.nextInt(1000000)); - } - } From b2eba06d0e65bf9e5f306a9f77726d1e29e3ec74 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 06:01:45 +0900 Subject: [PATCH 104/311] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../certification/controller/CertificationController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java index 8b2f696d..3b3e91e0 100644 --- a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java +++ b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java @@ -41,13 +41,13 @@ public void uploadBusinessCard( @PostMapping("users/company-mail") @ResponseStatus(OK) - public void verifyMail( + public void sendVerificationMail( @Login AuthInfo authInfo, @RequestBody @Valid EmailDto emailDto ) { - certificationService.verifyMail(authInfo.userId(), emailDto.companyEmail()); + certificationService.sendVerificationMail(authInfo.userId(), emailDto.companyEmail()); } } From 068f870f0aab258c608978fabb14863033bb91f1 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 06:02:18 +0900 Subject: [PATCH 105/311] =?UTF-8?q?feat:=20CompanyEmail=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=EA=B2=80=EC=82=AC=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/repository/UserRepository.java | 4 ++++ .../coffeemeet/server/user/service/UserService.java | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/main/java/coffeemeet/server/user/repository/UserRepository.java b/src/main/java/coffeemeet/server/user/repository/UserRepository.java index a10cd24b..dd44536c 100644 --- a/src/main/java/coffeemeet/server/user/repository/UserRepository.java +++ b/src/main/java/coffeemeet/server/user/repository/UserRepository.java @@ -1,5 +1,6 @@ package coffeemeet.server.user.repository; +import coffeemeet.server.user.domain.CompanyEmail; import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.User; import java.util.Optional; @@ -16,4 +17,7 @@ Optional getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( String authCode); Optional findUserByProfileNickname(String nickname); + + boolean existsByCertification_CompanyEmail(CompanyEmail companyEmail); + } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 78f3c518..ed7fc32e 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -3,6 +3,7 @@ import coffeemeet.server.interest.domain.Interest; import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.interest.repository.InterestRepository; +import coffeemeet.server.user.domain.CompanyEmail; import coffeemeet.server.interest.service.InterestService; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.dto.MyProfileResponse; @@ -15,8 +16,11 @@ @Service @RequiredArgsConstructor +@Transactional(readOnly = true) public class UserService { + public static final String EXISTED_COMPANY_EMAIL_ERROR = "이미 사용 중인 회사이메일입니다."; + private final UserRepository userRepository; private final InterestRepository interestRepository; private final InterestService interestService; @@ -28,6 +32,12 @@ public void updateBusinessCardUrl(Long userId, String businessCardUrl) { user.updateBusinessCardUrl(businessCardUrl); } + public void validateDuplicatedCompanyEmail(CompanyEmail companyEmail) { + if (userRepository.existsByCertification_CompanyEmail(companyEmail)) { + throw new IllegalArgumentException(EXISTED_COMPANY_EMAIL_ERROR); + } + } + public UserProfileResponse findUserProfile(String nickname) { User user = userRepository.findUserByProfileNickname(nickname) .orElseThrow(() -> new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); From a65751579600a40412c6bcde7b3fc9758e13ab40 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 06:58:24 +0900 Subject: [PATCH 106/311] =?UTF-8?q?feat:=20CompanyEmail=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/user/domain/Certification.java | 4 ++++ src/main/java/coffeemeet/server/user/domain/User.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/main/java/coffeemeet/server/user/domain/Certification.java b/src/main/java/coffeemeet/server/user/domain/Certification.java index e398f4b9..a03ff9a5 100644 --- a/src/main/java/coffeemeet/server/user/domain/Certification.java +++ b/src/main/java/coffeemeet/server/user/domain/Certification.java @@ -36,6 +36,10 @@ public void updateBusinessCardUrl(String newBusinessCardUrl) { this.businessCardUrl = newBusinessCardUrl; } + public void updateCompanyEmail(CompanyEmail newCompanyEmail) { + this.companyEmail = newCompanyEmail; + } + public void certificate() { isCertificated = true; } diff --git a/src/main/java/coffeemeet/server/user/domain/User.java b/src/main/java/coffeemeet/server/user/domain/User.java index b28172da..964ea639 100644 --- a/src/main/java/coffeemeet/server/user/domain/User.java +++ b/src/main/java/coffeemeet/server/user/domain/User.java @@ -63,6 +63,10 @@ public void updateBusinessCardUrl(String newBusinessCardUrl) { certification.updateBusinessCardUrl(newBusinessCardUrl); } + public void updateCompanyEmail(CompanyEmail newCompanyEmail) { + certification.updateCompanyEmail(newCompanyEmail); + } + public void updateProfileImageUrl(String profileImageUrl) { this.profile.updateProfileImageUrl(profileImageUrl); } From 1056159c68ca7036456c0eea651aea2f0cb4ad89 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 07:00:16 +0900 Subject: [PATCH 107/311] =?UTF-8?q?feat:=20CompanyEmail=20Update=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC=ED=98=84=20=EB=B0=8F=20?= =?UTF-8?q?getUserById=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/service/UserService.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index ed7fc32e..85e57b09 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -27,8 +27,7 @@ public class UserService { @Transactional public void updateBusinessCardUrl(Long userId, String businessCardUrl) { - User user = userRepository.findById(userId) - .orElseThrow(IllegalArgumentException::new); + User user = getUserById(userId); user.updateBusinessCardUrl(businessCardUrl); } @@ -47,6 +46,7 @@ public UserProfileResponse findUserProfile(String nickname) { } public MyProfileResponse findMyProfile(Long userId) { + User user = getUserById(userId); User user = userRepository.findById(userId) .orElseThrow(() -> new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); @@ -54,6 +54,16 @@ public MyProfileResponse findMyProfile(Long userId) { return MyProfileResponse.of(user, interests); } + @Transactional + public void updateCompanyEmail(Long userId, CompanyEmail companyEmail) { + User user = getUserById(userId); + user.updateCompanyEmail(companyEmail); + } + + private User getUserById(Long userId) { + return userRepository.findById(userId) + .orElseThrow(IllegalArgumentException::new); + } @Transactional public void updateProfileImage(Long userId, String profileImageUrl) { User user = userRepository.findById(userId) From 6b78c261ad6ea2ae5766fdc3f545b489c11831bc Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 07:38:33 +0900 Subject: [PATCH 108/311] =?UTF-8?q?feat:=20=EC=9D=B8=EC=A6=9D=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20DTO=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/certification/dto/VerificationCodeDto.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/coffeemeet/server/certification/dto/VerificationCodeDto.java diff --git a/src/main/java/coffeemeet/server/certification/dto/VerificationCodeDto.java b/src/main/java/coffeemeet/server/certification/dto/VerificationCodeDto.java new file mode 100644 index 00000000..2e6df7a4 --- /dev/null +++ b/src/main/java/coffeemeet/server/certification/dto/VerificationCodeDto.java @@ -0,0 +1,11 @@ +package coffeemeet.server.certification.dto; + +import jakarta.validation.constraints.NotNull; +import org.hibernate.validator.constraints.Length; + +public record VerificationCodeDto( + @NotNull @Length(min = 6, max = 6) + String verificationCode +) { + +} From 5e5ce23169dfd128c296c5fbfadc867a107563ce Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 07:39:18 +0900 Subject: [PATCH 109/311] =?UTF-8?q?refactor:=20Long=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95,=20class=20=EC=9D=B4=EB=A6=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/VerificationCodeRepository.java | 8 -------- .../repository/VerificationVoRepository.java | 8 ++++++++ 2 files changed, 8 insertions(+), 8 deletions(-) delete mode 100644 src/main/java/coffeemeet/server/certification/repository/VerificationCodeRepository.java create mode 100644 src/main/java/coffeemeet/server/certification/repository/VerificationVoRepository.java diff --git a/src/main/java/coffeemeet/server/certification/repository/VerificationCodeRepository.java b/src/main/java/coffeemeet/server/certification/repository/VerificationCodeRepository.java deleted file mode 100644 index 29fed45a..00000000 --- a/src/main/java/coffeemeet/server/certification/repository/VerificationCodeRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package coffeemeet.server.certification.repository; - -import coffeemeet.server.certification.domain.VerificationCode; -import org.springframework.data.repository.CrudRepository; - -public interface VerificationCodeRepository extends CrudRepository { - -} diff --git a/src/main/java/coffeemeet/server/certification/repository/VerificationVoRepository.java b/src/main/java/coffeemeet/server/certification/repository/VerificationVoRepository.java new file mode 100644 index 00000000..0682d26e --- /dev/null +++ b/src/main/java/coffeemeet/server/certification/repository/VerificationVoRepository.java @@ -0,0 +1,8 @@ +package coffeemeet.server.certification.repository; + +import coffeemeet.server.certification.domain.VerificationVo; +import org.springframework.data.repository.CrudRepository; + +public interface VerificationVoRepository extends CrudRepository { + +} From eba9cc3d7a2395df2a71f5e0935c1720825b6e8a Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 07:39:52 +0900 Subject: [PATCH 110/311] =?UTF-8?q?refactor:=20class=20=EC=9D=B4=EB=A6=84?= =?UTF-8?q?=20=EC=88=98=EC=A0=95,=20=ED=9A=8C=EC=82=AC=20=EC=9D=B4?= =?UTF-8?q?=EB=A9=94=EC=9D=BC=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{VerificationCode.java => VerificationVo.java} | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) rename src/main/java/coffeemeet/server/certification/domain/{VerificationCode.java => VerificationVo.java} (54%) diff --git a/src/main/java/coffeemeet/server/certification/domain/VerificationCode.java b/src/main/java/coffeemeet/server/certification/domain/VerificationVo.java similarity index 54% rename from src/main/java/coffeemeet/server/certification/domain/VerificationCode.java rename to src/main/java/coffeemeet/server/certification/domain/VerificationVo.java index 6f60c09d..74337e56 100644 --- a/src/main/java/coffeemeet/server/certification/domain/VerificationCode.java +++ b/src/main/java/coffeemeet/server/certification/domain/VerificationVo.java @@ -1,23 +1,26 @@ package coffeemeet.server.certification.domain; +import coffeemeet.server.user.domain.CompanyEmail; import java.time.LocalDateTime; import lombok.Getter; import org.springframework.data.annotation.Id; import org.springframework.data.redis.core.RedisHash; @Getter -@RedisHash(value = "verification_code", timeToLive = 360) -public class VerificationCode { +@RedisHash(value = "verification_vo", timeToLive = 360) +public class VerificationVo { @Id private Long userId; + private CompanyEmail companyEmail; private String code; private LocalDateTime createdAt; - public VerificationCode(Long userId, String code, LocalDateTime createdAt) { + public VerificationVo(Long userId, CompanyEmail companyEmail, String code, + LocalDateTime createdAt) { this.userId = userId; + this.companyEmail = companyEmail; this.code = code; this.createdAt = createdAt; } - } From 1405f10a029c79404425a40f04eec779dd578afe Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 07:40:39 +0900 Subject: [PATCH 111/311] =?UTF-8?q?feat:=20=EC=9D=B4=EB=A9=94=EC=9D=BC=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20Service=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CertificationService.java | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java index b7c4fe9f..6a79b041 100644 --- a/src/main/java/coffeemeet/server/certification/service/CertificationService.java +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -1,7 +1,7 @@ package coffeemeet.server.certification.service; -import coffeemeet.server.certification.domain.VerificationCode; -import coffeemeet.server.certification.repository.VerificationCodeRepository; +import coffeemeet.server.certification.domain.VerificationVo; +import coffeemeet.server.certification.repository.VerificationVoRepository; import coffeemeet.server.common.media.EmailService; import coffeemeet.server.common.media.S3MediaService; import coffeemeet.server.common.util.FileUtils; @@ -17,12 +17,14 @@ @RequiredArgsConstructor public class CertificationService { - private static final RandomGenerator randomGenerator = RandomGenerator.getDefault(); + public static final String VERIFICATION_CODE_NOT_FOUND = "인증번호 기간이 만료되었거나 해당 유저가 인증 번호를 요청한 기록이 없습니다."; + public static final String WRONG_VERIFICATION_CODE = "잘못된 인증번호입니다."; + private static final RandomGenerator RANDOM_GENERATOR = RandomGenerator.getDefault(); private final S3MediaService s3MediaService; private final UserService userService; private final EmailService emailService; - private final VerificationCodeRepository verificationCodeRepository; + private final VerificationVoRepository verificationVoRepository; public void uploadBusinessCard(long userId, File file) { String key = s3MediaService.generateBusinessCardKey(); @@ -38,12 +40,24 @@ public void sendVerificationMail(Long userId, String email) { String verificationCode = generateVerificationCode(); emailService.sendVerificationMail(companyEmail, verificationCode); - verificationCodeRepository.save( - new VerificationCode(userId, verificationCode, LocalDateTime.now())); + verificationVoRepository.save( + new VerificationVo(userId, companyEmail, verificationCode, LocalDateTime.now())); } private String generateVerificationCode() { - return String.format("%06d", randomGenerator.nextInt(1000000)); + return String.format("%06d", RANDOM_GENERATOR.nextInt(1000000)); } + public void verifyEmail(Long userId, String verificationCode) { + System.out.println(userId); + VerificationVo verificationVo = verificationVoRepository.findById(userId) + .orElseThrow( + () -> new IllegalArgumentException(VERIFICATION_CODE_NOT_FOUND)); + + if (!verificationVo.getCode().equals(verificationCode)) { + throw new IllegalArgumentException(WRONG_VERIFICATION_CODE); + } + + userService.updateCompanyEmail(userId, verificationVo.getCompanyEmail()); + } } From a1206e3e22e2a407387079ad027e97c73ca71eb2 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 07:41:22 +0900 Subject: [PATCH 112/311] =?UTF-8?q?feat:=20=EC=9D=B4=EB=A9=94=EC=9D=BC=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20Controller=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/CertificationController.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java index 3b3e91e0..ac6fb0f8 100644 --- a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java +++ b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java @@ -4,6 +4,7 @@ import static org.springframework.http.HttpStatus.OK; import coffeemeet.server.certification.dto.EmailDto; +import coffeemeet.server.certification.dto.VerificationCodeDto; import coffeemeet.server.certification.service.CertificationService; import coffeemeet.server.common.annotation.Login; import coffeemeet.server.common.util.FileUtils; @@ -39,7 +40,7 @@ public void uploadBusinessCard( FileUtils.convertMultipartFileToFile(businessCard)); } - @PostMapping("users/company-mail") + @PostMapping("/users/company-mail") @ResponseStatus(OK) public void sendVerificationMail( @Login @@ -50,4 +51,14 @@ public void sendVerificationMail( certificationService.sendVerificationMail(authInfo.userId(), emailDto.companyEmail()); } + @PostMapping("/users/company-mail/verification") + public void verifyEmail( + @Login + AuthInfo authInfo, + @RequestBody @Valid + VerificationCodeDto verificationCodeDto + ) { + certificationService.verifyEmail(authInfo.userId(), verificationCodeDto.verificationCode()); + } + } From 19b9f9811f7f0d6c263394e602c5e3d27a2f5269 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 07:43:53 +0900 Subject: [PATCH 113/311] =?UTF-8?q?refactor:=20=EB=94=94=EB=B2=84=EA=B9=85?= =?UTF-8?q?=EC=9A=A9=20sout=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/certification/service/CertificationService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java index 6a79b041..9ca0b183 100644 --- a/src/main/java/coffeemeet/server/certification/service/CertificationService.java +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -49,7 +49,6 @@ private String generateVerificationCode() { } public void verifyEmail(Long userId, String verificationCode) { - System.out.println(userId); VerificationVo verificationVo = verificationVoRepository.findById(userId) .orElseThrow( () -> new IllegalArgumentException(VERIFICATION_CODE_NOT_FOUND)); From f446cbfb96160688e9612f6768abaace19a1fade Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 07:49:52 +0900 Subject: [PATCH 114/311] =?UTF-8?q?refactor:=20=EC=9D=B8=EC=A6=9D=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20->=20=EC=9D=B8=EC=A6=9D=EC=BD=94=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/certification/service/CertificationService.java | 4 ++-- .../java/coffeemeet/server/common/media/EmailService.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java index 9ca0b183..271cf527 100644 --- a/src/main/java/coffeemeet/server/certification/service/CertificationService.java +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -17,8 +17,8 @@ @RequiredArgsConstructor public class CertificationService { - public static final String VERIFICATION_CODE_NOT_FOUND = "인증번호 기간이 만료되었거나 해당 유저가 인증 번호를 요청한 기록이 없습니다."; - public static final String WRONG_VERIFICATION_CODE = "잘못된 인증번호입니다."; + public static final String VERIFICATION_CODE_NOT_FOUND = "인증코드 기간이 만료되었거나 해당 유저가 인증 번호를 요청한 기록이 없습니다."; + public static final String WRONG_VERIFICATION_CODE = "잘못된 인증코드입니다."; private static final RandomGenerator RANDOM_GENERATOR = RandomGenerator.getDefault(); private final S3MediaService s3MediaService; diff --git a/src/main/java/coffeemeet/server/common/media/EmailService.java b/src/main/java/coffeemeet/server/common/media/EmailService.java index ddb8abe8..98441df0 100644 --- a/src/main/java/coffeemeet/server/common/media/EmailService.java +++ b/src/main/java/coffeemeet/server/common/media/EmailService.java @@ -26,7 +26,7 @@ public void sendVerificationMail(CompanyEmail companyMail, String verificationCo String subject = "[coffee-meet] 커피밋 사용을 위해 이메일 인증을 완료해주세요"; mailMessage.setSubject(subject); - String text = String.format("인증번호: %s", verificationCode); + String text = String.format("인증코드: %s", verificationCode); mailMessage.setText(text); javaMailSender.send(mailMessage); From 3ff17480355700035ca59e90620a153783aab30c Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 17:14:58 +0900 Subject: [PATCH 115/311] =?UTF-8?q?refactor:=20=EC=BB=A8=EB=B2=A4=EC=85=98?= =?UTF-8?q?=EC=97=90=20=EB=A7=9E=EC=B6=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/CertificationController.java | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java index ac6fb0f8..5c87a263 100644 --- a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java +++ b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java @@ -1,8 +1,5 @@ package coffeemeet.server.certification.controller; -import static org.springframework.http.HttpStatus.CREATED; -import static org.springframework.http.HttpStatus.OK; - import coffeemeet.server.certification.dto.EmailDto; import coffeemeet.server.certification.dto.VerificationCodeDto; import coffeemeet.server.certification.service.CertificationService; @@ -12,11 +9,11 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; 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.RequestPart; -import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @@ -28,37 +25,39 @@ public class CertificationController { private final CertificationService certificationService; @PostMapping("/users/business-card") - @ResponseStatus(CREATED) - public void uploadBusinessCard( + public ResponseEntity uploadBusinessCard( @Login AuthInfo authInfo, - @RequestPart("businessCard") @NotNull + @RequestPart("businessCard") MultipartFile businessCard ) { certificationService.uploadBusinessCard(authInfo.userId(), FileUtils.convertMultipartFileToFile(businessCard)); + return ResponseEntity.ok().build(); } @PostMapping("/users/company-mail") - @ResponseStatus(OK) - public void sendVerificationMail( + public ResponseEntity sendVerificationCodeByEmail( @Login AuthInfo authInfo, - @RequestBody @Valid + @Valid @RequestBody EmailDto emailDto ) { certificationService.sendVerificationMail(authInfo.userId(), emailDto.companyEmail()); + return ResponseEntity.ok().build(); + } @PostMapping("/users/company-mail/verification") - public void verifyEmail( + public ResponseEntity verifyEmail( @Login AuthInfo authInfo, - @RequestBody @Valid + @Valid @RequestBody VerificationCodeDto verificationCodeDto ) { certificationService.verifyEmail(authInfo.userId(), verificationCodeDto.verificationCode()); + return ResponseEntity.ok().build(); } } From 7bbd171e32c51fbb86c57ffa6b4e5144a8731b87 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 17:15:42 +0900 Subject: [PATCH 116/311] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/certification/service/CertificationService.java | 3 ++- src/main/java/coffeemeet/server/common/media/EmailService.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java index 271cf527..f08d932b 100644 --- a/src/main/java/coffeemeet/server/certification/service/CertificationService.java +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -39,7 +39,7 @@ public void sendVerificationMail(Long userId, String email) { userService.validateDuplicatedCompanyEmail(companyEmail); String verificationCode = generateVerificationCode(); - emailService.sendVerificationMail(companyEmail, verificationCode); + emailService.sendVerificationCode(companyEmail, verificationCode); verificationVoRepository.save( new VerificationVo(userId, companyEmail, verificationCode, LocalDateTime.now())); } @@ -59,4 +59,5 @@ public void verifyEmail(Long userId, String verificationCode) { userService.updateCompanyEmail(userId, verificationVo.getCompanyEmail()); } + } diff --git a/src/main/java/coffeemeet/server/common/media/EmailService.java b/src/main/java/coffeemeet/server/common/media/EmailService.java index 98441df0..3542a28f 100644 --- a/src/main/java/coffeemeet/server/common/media/EmailService.java +++ b/src/main/java/coffeemeet/server/common/media/EmailService.java @@ -18,7 +18,7 @@ public EmailService(JavaMailSender javaMailSender, this.sender = sender; } - public void sendVerificationMail(CompanyEmail companyMail, String verificationCode) { + public void sendVerificationCode(CompanyEmail companyMail, String verificationCode) { SimpleMailMessage mailMessage = new SimpleMailMessage(); mailMessage.setFrom(sender); mailMessage.setTo(companyMail.getCompanyEmail()); From 9ec957ba48ddd6a7c48f12013874cba72c01fd92 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 17:24:51 +0900 Subject: [PATCH 117/311] =?UTF-8?q?refactor:=20=EC=85=8D=EC=84=B1=EC=9E=90?= =?UTF-8?q?=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=EC=97=90=20LocalDateTim?= =?UTF-8?q?e=20=EC=82=AD=EC=A0=9C,=20=ED=81=B4=EB=9E=98=EC=8A=A4=EB=AA=85?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{VerificationVo.java => EmailVerification.java} | 10 +++++----- .../repository/VerificationVoRepository.java | 4 ++-- .../certification/service/CertificationService.java | 11 +++++------ 3 files changed, 12 insertions(+), 13 deletions(-) rename src/main/java/coffeemeet/server/certification/domain/{VerificationVo.java => EmailVerification.java} (67%) diff --git a/src/main/java/coffeemeet/server/certification/domain/VerificationVo.java b/src/main/java/coffeemeet/server/certification/domain/EmailVerification.java similarity index 67% rename from src/main/java/coffeemeet/server/certification/domain/VerificationVo.java rename to src/main/java/coffeemeet/server/certification/domain/EmailVerification.java index 74337e56..f41c6c3e 100644 --- a/src/main/java/coffeemeet/server/certification/domain/VerificationVo.java +++ b/src/main/java/coffeemeet/server/certification/domain/EmailVerification.java @@ -7,8 +7,8 @@ import org.springframework.data.redis.core.RedisHash; @Getter -@RedisHash(value = "verification_vo", timeToLive = 360) -public class VerificationVo { +@RedisHash(value = "email_verification", timeToLive = 360) +public class EmailVerification { @Id private Long userId; @@ -16,11 +16,11 @@ public class VerificationVo { private String code; private LocalDateTime createdAt; - public VerificationVo(Long userId, CompanyEmail companyEmail, String code, - LocalDateTime createdAt) { + public EmailVerification(Long userId, CompanyEmail companyEmail, String code) { this.userId = userId; this.companyEmail = companyEmail; this.code = code; - this.createdAt = createdAt; + this.createdAt = LocalDateTime.now(); } + } diff --git a/src/main/java/coffeemeet/server/certification/repository/VerificationVoRepository.java b/src/main/java/coffeemeet/server/certification/repository/VerificationVoRepository.java index 0682d26e..423bbde0 100644 --- a/src/main/java/coffeemeet/server/certification/repository/VerificationVoRepository.java +++ b/src/main/java/coffeemeet/server/certification/repository/VerificationVoRepository.java @@ -1,8 +1,8 @@ package coffeemeet.server.certification.repository; -import coffeemeet.server.certification.domain.VerificationVo; +import coffeemeet.server.certification.domain.EmailVerification; import org.springframework.data.repository.CrudRepository; -public interface VerificationVoRepository extends CrudRepository { +public interface VerificationVoRepository extends CrudRepository { } diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java index f08d932b..eaefe2ad 100644 --- a/src/main/java/coffeemeet/server/certification/service/CertificationService.java +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -1,6 +1,6 @@ package coffeemeet.server.certification.service; -import coffeemeet.server.certification.domain.VerificationVo; +import coffeemeet.server.certification.domain.EmailVerification; import coffeemeet.server.certification.repository.VerificationVoRepository; import coffeemeet.server.common.media.EmailService; import coffeemeet.server.common.media.S3MediaService; @@ -8,7 +8,6 @@ import coffeemeet.server.user.domain.CompanyEmail; import coffeemeet.server.user.service.UserService; import java.io.File; -import java.time.LocalDateTime; import java.util.random.RandomGenerator; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -41,7 +40,7 @@ public void sendVerificationMail(Long userId, String email) { String verificationCode = generateVerificationCode(); emailService.sendVerificationCode(companyEmail, verificationCode); verificationVoRepository.save( - new VerificationVo(userId, companyEmail, verificationCode, LocalDateTime.now())); + new EmailVerification(userId, companyEmail, verificationCode)); } private String generateVerificationCode() { @@ -49,15 +48,15 @@ private String generateVerificationCode() { } public void verifyEmail(Long userId, String verificationCode) { - VerificationVo verificationVo = verificationVoRepository.findById(userId) + EmailVerification emailVerification = verificationVoRepository.findById(userId) .orElseThrow( () -> new IllegalArgumentException(VERIFICATION_CODE_NOT_FOUND)); - if (!verificationVo.getCode().equals(verificationCode)) { + if (!emailVerification.getCode().equals(verificationCode)) { throw new IllegalArgumentException(WRONG_VERIFICATION_CODE); } - userService.updateCompanyEmail(userId, verificationVo.getCompanyEmail()); + userService.updateCompanyEmail(userId, emailVerification.getCompanyEmail()); } } From d714a90675e787132fe4495a202f968bb95b6109 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 17:49:58 +0900 Subject: [PATCH 118/311] =?UTF-8?q?refactor:=20=EA=B2=80=EC=A6=9D=EB=A1=9C?= =?UTF-8?q?=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 --- .../java/coffeemeet/server/user/domain/Certification.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/coffeemeet/server/user/domain/Certification.java b/src/main/java/coffeemeet/server/user/domain/Certification.java index a03ff9a5..0fe8be55 100644 --- a/src/main/java/coffeemeet/server/user/domain/Certification.java +++ b/src/main/java/coffeemeet/server/user/domain/Certification.java @@ -33,9 +33,16 @@ public Certification() { } public void updateBusinessCardUrl(String newBusinessCardUrl) { + validateBusinessCardUrl(newBusinessCardUrl); this.businessCardUrl = newBusinessCardUrl; } + private void validateBusinessCardUrl(String businessCardUrl) { + if (businessCardUrl == null) { + throw new IllegalArgumentException("잘못된 명함 URL입니다."); + } + } + public void updateCompanyEmail(CompanyEmail newCompanyEmail) { this.companyEmail = newCompanyEmail; } From 42f69ba0e49a7e21d0bb4603855e961b0d926fab Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 17:50:15 +0900 Subject: [PATCH 119/311] =?UTF-8?q?refactor:=20=ED=8C=8C=EB=9D=BC=EB=AF=B8?= =?UTF-8?q?=ED=84=B0=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/coffeemeet/server/user/domain/Profile.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/Profile.java b/src/main/java/coffeemeet/server/user/domain/Profile.java index cc075942..04545fc3 100644 --- a/src/main/java/coffeemeet/server/user/domain/Profile.java +++ b/src/main/java/coffeemeet/server/user/domain/Profile.java @@ -69,14 +69,14 @@ private void validateProfileImage(String profileImageUrl) { } } - public void updateNickname(String nickname) { + public void updateNickname(String newNickname) { validateNickname(nickname); - this.nickname = nickname; + this.nickname = newNickname; } - public void updateProfileImageUrl(String profileImageUrl) { + public void updateProfileImageUrl(String newProfileImageUrl) { validateProfileImage(profileImageUrl); - this.profileImageUrl = profileImageUrl; + this.profileImageUrl = newProfileImageUrl; } } From e7394a106f005564544f6b94bfb384f85cabefbd Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 17:50:52 +0900 Subject: [PATCH 120/311] =?UTF-8?q?refactor:=20getUserById=EB=A1=9C=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/service/UserService.java | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 85e57b09..247cf504 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -3,8 +3,8 @@ import coffeemeet.server.interest.domain.Interest; import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.interest.repository.InterestRepository; -import coffeemeet.server.user.domain.CompanyEmail; import coffeemeet.server.interest.service.InterestService; +import coffeemeet.server.user.domain.CompanyEmail; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.dto.MyProfileResponse; import coffeemeet.server.user.dto.UserProfileResponse; @@ -47,9 +47,6 @@ public UserProfileResponse findUserProfile(String nickname) { public MyProfileResponse findMyProfile(Long userId) { User user = getUserById(userId); - User user = userRepository.findById(userId) - .orElseThrow(() -> new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); - List interests = interestRepository.findAllByUserId(userId); return MyProfileResponse.of(user, interests); } @@ -60,24 +57,22 @@ public void updateCompanyEmail(Long userId, CompanyEmail companyEmail) { user.updateCompanyEmail(companyEmail); } - private User getUserById(Long userId) { - return userRepository.findById(userId) - .orElseThrow(IllegalArgumentException::new); - } @Transactional public void updateProfileImage(Long userId, String profileImageUrl) { - User user = userRepository.findById(userId) - .orElseThrow(() -> new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); + User user = getUserById(userId); user.updateProfileImageUrl(profileImageUrl); } @Transactional public void updateProfileInfo(Long userId, String nickname, List interests) { - User user = userRepository.findById(userId) - .orElseThrow(() -> new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); - - user.getProfile().updateNickname(nickname); + User user = getUserById(userId); + user.updateNickname(nickname); interestService.updateInterests(userId, interests); } + private User getUserById(Long userId) { + return userRepository.findById(userId) + .orElseThrow(IllegalArgumentException::new); + } + } From 8c6c41b0b1d120fc3c2e043d70663e388617cb6e Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 24 Oct 2023 17:52:27 +0900 Subject: [PATCH 121/311] =?UTF-8?q?refactor:=20=EC=BB=A8=EB=B2=A4=EC=85=98?= =?UTF-8?q?=EC=97=90=20=EB=A7=9E=EA=B2=8C=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F?= =?UTF-8?q?=20updateNickName=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/user/domain/User.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/User.java b/src/main/java/coffeemeet/server/user/domain/User.java index 964ea639..758fd1a0 100644 --- a/src/main/java/coffeemeet/server/user/domain/User.java +++ b/src/main/java/coffeemeet/server/user/domain/User.java @@ -57,18 +57,23 @@ public User( this.profile = profile; this.certification = new Certification(); this.reportInfo = new ReportInfo(); + this.isDeleted = false; } public void updateBusinessCardUrl(String newBusinessCardUrl) { - certification.updateBusinessCardUrl(newBusinessCardUrl); + this.certification.updateBusinessCardUrl(newBusinessCardUrl); } public void updateCompanyEmail(CompanyEmail newCompanyEmail) { - certification.updateCompanyEmail(newCompanyEmail); + this.certification.updateCompanyEmail(newCompanyEmail); } - public void updateProfileImageUrl(String profileImageUrl) { - this.profile.updateProfileImageUrl(profileImageUrl); + public void updateProfileImageUrl(String newProfileImageUrl) { + this.profile.updateProfileImageUrl(newProfileImageUrl); + } + + public void updateNickname(String newNickname) { + this.profile.updateNickname(newNickname); } } From 6fd5660ed33beda0710a85d6cb7e9a0059692c9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 24 Oct 2023 18:57:51 +0900 Subject: [PATCH 122/311] =?UTF-8?q?feat:=20UserFixture=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 --- .../common/fixture/entity/UserFixture.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java diff --git a/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java b/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java new file mode 100644 index 00000000..0e31821d --- /dev/null +++ b/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java @@ -0,0 +1,56 @@ +package coffeemeet.server.common.fixture.entity; + +import static org.instancio.Select.field; + +import coffeemeet.server.user.domain.Birth; +import coffeemeet.server.user.domain.Certification; +import coffeemeet.server.user.domain.CompanyEmail; +import coffeemeet.server.user.domain.Email; +import coffeemeet.server.user.domain.Profile; +import coffeemeet.server.user.domain.User; +import org.instancio.Instancio; + +public class UserFixture { + + public static User user() { + return Instancio.of(User.class) + .set(field(User::getProfile), profile()) + .set(field(User::getCertification), certification()) + .ignore(field(User::isDeleted)) + .create(); + } + + private static Birth birth() { + return Instancio.of(Birth.class) + .generate(field(Birth::getYear), gen -> gen.ints().range(1000, 9999)) + .generate(field(Birth::getDay), gen -> gen.ints().range(1000, 9999)) + .create(); + } + + private static Profile profile() { + return Instancio.of(Profile.class) + .set(field(Profile::getBirth), birth()) + .set(field(Profile::getEmail), email()) + .generate(field(Profile::getNickname), gen -> gen.string().maxLength(20)) + .create(); + } + + private static Certification certification() { + return Instancio.of(Certification.class) + .set(field(Certification::getCompanyEmail), companyEmail()) + .create(); + } + + private static Email email() { + return Instancio.of(Email.class) + .generate(field(Email::getEmail), gen -> gen.net().email()) + .create(); + } + + private static CompanyEmail companyEmail() { + return Instancio.of(CompanyEmail.class) + .generate(field(CompanyEmail::getCompanyEmail), gen -> gen.net().email()) + .create(); + } + +} From f6b81c12503fa2ce653325d42ed74f008e288231 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 25 Oct 2023 15:18:41 +0900 Subject: [PATCH 123/311] =?UTF-8?q?fix:=20@RequestBody=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/auth/controller/AuthController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/auth/controller/AuthController.java b/src/main/java/coffeemeet/server/auth/controller/AuthController.java index 0f450e5c..847acd7d 100644 --- a/src/main/java/coffeemeet/server/auth/controller/AuthController.java +++ b/src/main/java/coffeemeet/server/auth/controller/AuthController.java @@ -52,7 +52,7 @@ public ResponseEntity renew(@Login AuthInfo authInfo) { } @PostMapping("/logout") - public ResponseEntity logout(@Login @RequestBody AuthInfo authInfo) { + public ResponseEntity logout(@Login AuthInfo authInfo) { authService.logout(authInfo.userId()); return ResponseEntity.noContent().build(); } From 32f42681814a12dfa871cae3c412a9cc1130baa2 Mon Sep 17 00:00:00 2001 From: Sangmin Park <70051888+smart-sangmin@users.noreply.github.com> Date: Wed, 25 Oct 2023 15:21:09 +0900 Subject: [PATCH 124/311] docs: refactor.md --- .github/ISSUE_TEMPLATE/refactor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/refactor.md b/.github/ISSUE_TEMPLATE/refactor.md index 25b394ab..d2b2e118 100644 --- a/.github/ISSUE_TEMPLATE/refactor.md +++ b/.github/ISSUE_TEMPLATE/refactor.md @@ -1,7 +1,7 @@ --- name: refactor issue template about: 'about need to refactor ' -title: " [Refactor] " +title: "🦾 [Refactor] " labels: Refactor assignees: '' From 1c6137ff5765e10ead22f5e43080580962a589e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Wed, 25 Oct 2023 01:59:30 +0900 Subject: [PATCH 125/311] =?UTF-8?q?refactor:=20=ED=94=84=EB=A1=9C=ED=95=84?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=20=EC=88=98=EC=A0=95=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=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 --- .../server/user/controller/UserController.java | 3 ++- src/main/java/coffeemeet/server/user/domain/Profile.java | 9 +++++++++ src/main/java/coffeemeet/server/user/domain/User.java | 8 ++++++++ .../coffeemeet/server/user/dto/UpdateProfileRequest.java | 2 ++ .../java/coffeemeet/server/user/service/UserService.java | 7 ++++++- 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index c7223d70..2f4cb15a 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -44,7 +44,8 @@ public ResponseEntity updateProfileImage(@Login AuthInfo authInfo, @PatchMapping("/me") public ResponseEntity updateProfileInfo(@Login AuthInfo authInfo, @Valid @RequestBody UpdateProfileRequest request) { - userService.updateProfileInfo(authInfo.userId(), request.nickname(), request.interests()); + userService.updateProfileInfo(authInfo.userId(), request.nickname(), request.email(), + request.name(), request.interests()); return ResponseEntity.noContent().build(); } diff --git a/src/main/java/coffeemeet/server/user/domain/Profile.java b/src/main/java/coffeemeet/server/user/domain/Profile.java index 04545fc3..0c12e34c 100644 --- a/src/main/java/coffeemeet/server/user/domain/Profile.java +++ b/src/main/java/coffeemeet/server/user/domain/Profile.java @@ -79,4 +79,13 @@ public void updateProfileImageUrl(String newProfileImageUrl) { this.profileImageUrl = newProfileImageUrl; } + public void updateEmail(String newEmail) { + this.email = new Email(newEmail); + } + + public void updateName(String newName) { + validateName(newName); + this.name = newName; + } + } diff --git a/src/main/java/coffeemeet/server/user/domain/User.java b/src/main/java/coffeemeet/server/user/domain/User.java index 758fd1a0..2b723938 100644 --- a/src/main/java/coffeemeet/server/user/domain/User.java +++ b/src/main/java/coffeemeet/server/user/domain/User.java @@ -76,4 +76,12 @@ public void updateNickname(String newNickname) { this.profile.updateNickname(newNickname); } + public void updateEmail(String newEmail) { + this.profile.updateEmail(newEmail); + } + + public void updateName(String newName) { + this.profile.updateName(newName); + } + } diff --git a/src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java b/src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java index a0458198..1add0598 100644 --- a/src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java +++ b/src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java @@ -7,6 +7,8 @@ import java.util.List; public record UpdateProfileRequest(@NotBlank String nickname, + @NotBlank String email, + @NotBlank String name, @NotNull @Size(min = 1, max = 3) List interests) { } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 247cf504..16a43f2e 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -64,9 +64,14 @@ public void updateProfileImage(Long userId, String profileImageUrl) { } @Transactional - public void updateProfileInfo(Long userId, String nickname, List interests) { + public void updateProfileInfo(Long userId, String nickname, String email, String name, + List interests) { User user = getUserById(userId); + user.updateNickname(nickname); + user.updateEmail(email); + user.updateName(name); + interestService.updateInterests(userId, interests); } From f41a5aa47043bebc37f028a6137883d53a41645a Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 25 Oct 2023 15:43:40 +0900 Subject: [PATCH 126/311] =?UTF-8?q?refactor:=20UpdateProfileRequest=20dto?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - email 제거 --- .../coffeemeet/server/user/controller/UserController.java | 4 ++-- src/main/java/coffeemeet/server/user/domain/User.java | 4 ---- .../java/coffeemeet/server/user/dto/UpdateProfileRequest.java | 1 - src/main/java/coffeemeet/server/user/service/UserService.java | 3 +-- 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index 2f4cb15a..c46827b4 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -44,8 +44,8 @@ public ResponseEntity updateProfileImage(@Login AuthInfo authInfo, @PatchMapping("/me") public ResponseEntity updateProfileInfo(@Login AuthInfo authInfo, @Valid @RequestBody UpdateProfileRequest request) { - userService.updateProfileInfo(authInfo.userId(), request.nickname(), request.email(), - request.name(), request.interests()); + userService.updateProfileInfo(authInfo.userId(), request.nickname(), request.name(), + request.interests()); return ResponseEntity.noContent().build(); } diff --git a/src/main/java/coffeemeet/server/user/domain/User.java b/src/main/java/coffeemeet/server/user/domain/User.java index 2b723938..f6928142 100644 --- a/src/main/java/coffeemeet/server/user/domain/User.java +++ b/src/main/java/coffeemeet/server/user/domain/User.java @@ -76,10 +76,6 @@ public void updateNickname(String newNickname) { this.profile.updateNickname(newNickname); } - public void updateEmail(String newEmail) { - this.profile.updateEmail(newEmail); - } - public void updateName(String newName) { this.profile.updateName(newName); } diff --git a/src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java b/src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java index 1add0598..8a8c7e1d 100644 --- a/src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java +++ b/src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java @@ -7,7 +7,6 @@ import java.util.List; public record UpdateProfileRequest(@NotBlank String nickname, - @NotBlank String email, @NotBlank String name, @NotNull @Size(min = 1, max = 3) List interests) { diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 16a43f2e..f953ae2c 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -64,12 +64,11 @@ public void updateProfileImage(Long userId, String profileImageUrl) { } @Transactional - public void updateProfileInfo(Long userId, String nickname, String email, String name, + public void updateProfileInfo(Long userId, String nickname, String name, List interests) { User user = getUserById(userId); user.updateNickname(nickname); - user.updateEmail(email); user.updateName(name); interestService.updateInterests(userId, interests); From af74e65ff68a5e344d8dfe08efa507dd4b2a1201 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 25 Oct 2023 16:54:46 +0900 Subject: [PATCH 127/311] =?UTF-8?q?refactor:=20KeyType=20=EC=9D=B4?= =?UTF-8?q?=EB=84=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 중복 되는 로직 통합 - KeyType 이넘 객체로 구분 --- .../server/common/media/S3MediaService.java | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/common/media/S3MediaService.java b/src/main/java/coffeemeet/server/common/media/S3MediaService.java index 265caf7f..8ed1bad1 100644 --- a/src/main/java/coffeemeet/server/common/media/S3MediaService.java +++ b/src/main/java/coffeemeet/server/common/media/S3MediaService.java @@ -4,6 +4,7 @@ import java.io.File; import java.time.LocalDateTime; import java.util.UUID; +import lombok.Getter; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -33,8 +34,31 @@ public String getUrl(String key) { return amazonS3.getUrl(bucketName, key).toExternalForm(); } - public String generateBusinessCardKey() { - return String.format("BusinessCard-%s-%s", LocalDateTime.now(), UUID.randomUUID()); + public String generateKey(KeyType keyType) { + return String.format("%s-%s-%s", keyType.value, LocalDateTime.now(), + UUID.randomUUID()); + } + + public String extractKey(String s3Url, KeyType keyType) { + int startIndex = s3Url.indexOf(keyType.value); + if (startIndex == -1) { + throw new IllegalArgumentException("올바르지 않은 S3 URL입니다."); + } + return s3Url.substring(startIndex); + } + + @Getter + public enum KeyType { + BUSINESS_CARD("BusinessCard"), + PROFILE_IMAGE("ProfileImage"), + ; + + private String value; + + KeyType(String value) { + this.value = value; + } + } } From 173ee97691b46e4daf1333c34d72d32275d64841 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 25 Oct 2023 16:55:22 +0900 Subject: [PATCH 128/311] =?UTF-8?q?refactor:=20uploadBusinessCard()=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/certification/service/CertificationService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java index eaefe2ad..2c44c6ae 100644 --- a/src/main/java/coffeemeet/server/certification/service/CertificationService.java +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -1,5 +1,7 @@ package coffeemeet.server.certification.service; +import static coffeemeet.server.common.media.S3MediaService.KeyType.BUSINESS_CARD; + import coffeemeet.server.certification.domain.EmailVerification; import coffeemeet.server.certification.repository.VerificationVoRepository; import coffeemeet.server.common.media.EmailService; @@ -26,7 +28,7 @@ public class CertificationService { private final VerificationVoRepository verificationVoRepository; public void uploadBusinessCard(long userId, File file) { - String key = s3MediaService.generateBusinessCardKey(); + String key = s3MediaService.generateKey(BUSINESS_CARD); s3MediaService.upload(key, file); userService.updateBusinessCardUrl(userId, s3MediaService.getUrl(key)); From cd83a9cc57e8f586486f4ac6fdb56862d0b6b9c2 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 25 Oct 2023 16:56:56 +0900 Subject: [PATCH 129/311] =?UTF-8?q?feat:=20updateProfileImage=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 - 기존 프로필 이미지 제거 - 새 프로필 이미지 s3 저장 후, 해당 Url 사용자 정보에 업데이트 --- .../server/user/service/UserService.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index f953ae2c..fdddd9fd 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -1,5 +1,8 @@ package coffeemeet.server.user.service; +import static coffeemeet.server.common.media.S3MediaService.KeyType.PROFILE_IMAGE; + +import coffeemeet.server.common.media.S3MediaService; import coffeemeet.server.interest.domain.Interest; import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.interest.repository.InterestRepository; @@ -9,6 +12,7 @@ import coffeemeet.server.user.dto.MyProfileResponse; import coffeemeet.server.user.dto.UserProfileResponse; import coffeemeet.server.user.repository.UserRepository; +import java.io.File; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -21,6 +25,7 @@ public class UserService { public static final String EXISTED_COMPANY_EMAIL_ERROR = "이미 사용 중인 회사이메일입니다."; + private final S3MediaService s3MediaService; private final UserRepository userRepository; private final InterestRepository interestRepository; private final InterestService interestService; @@ -58,9 +63,18 @@ public void updateCompanyEmail(Long userId, CompanyEmail companyEmail) { } @Transactional - public void updateProfileImage(Long userId, String profileImageUrl) { + public void updateProfileImage(Long userId, File file) { User user = getUserById(userId); - user.updateProfileImageUrl(profileImageUrl); + deleteCurrentProfileImage(user); + String key = s3MediaService.generateKey(PROFILE_IMAGE); + s3MediaService.upload(key, file); + user.updateProfileImageUrl(s3MediaService.getUrl(key)); + } + + private void deleteCurrentProfileImage(User user) { + String currentKey = s3MediaService.extractKey(user.getProfile().getProfileImageUrl(), + PROFILE_IMAGE); + s3MediaService.delete(currentKey); } @Transactional From 76034244fa91a6bd19019718bb275d9884e30e20 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 25 Oct 2023 16:57:11 +0900 Subject: [PATCH 130/311] =?UTF-8?q?feat:=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20API=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/controller/UserController.java | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index c46827b4..a309bd67 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -1,13 +1,14 @@ package coffeemeet.server.user.controller; import coffeemeet.server.common.annotation.Login; +import coffeemeet.server.common.util.FileUtils; import coffeemeet.server.user.dto.AuthInfo; import coffeemeet.server.user.dto.MyProfileResponse; -import coffeemeet.server.user.dto.UpdateProfileImageUrlRequest; import coffeemeet.server.user.dto.UpdateProfileRequest; import coffeemeet.server.user.dto.UserProfileResponse; import coffeemeet.server.user.service.UserService; import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; @@ -15,7 +16,9 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; @RestController @RequiredArgsConstructor @@ -35,18 +38,22 @@ public ResponseEntity findMyProfile(@Login AuthInfo authInfo) } @PatchMapping("/me/profile-image") - public ResponseEntity updateProfileImage(@Login AuthInfo authInfo, - @Valid @RequestBody UpdateProfileImageUrlRequest request) { - userService.updateProfileImage(authInfo.userId(), request.profileImageUrl()); - return ResponseEntity.noContent().build(); + public ResponseEntity updateProfileImage( + @Login AuthInfo authInfo, + @NotNull + @RequestPart("profileImage") + MultipartFile profileImage) { + userService.updateProfileImage( + authInfo.userId(), + FileUtils.convertMultipartFileToFile(profileImage)); + return ResponseEntity.ok().build(); } @PatchMapping("/me") public ResponseEntity updateProfileInfo(@Login AuthInfo authInfo, @Valid @RequestBody UpdateProfileRequest request) { - userService.updateProfileInfo(authInfo.userId(), request.nickname(), request.name(), - request.interests()); - return ResponseEntity.noContent().build(); + userService.updateProfileInfo(authInfo.userId(), request.nickname(), request.interests()); + return ResponseEntity.ok().build(); } } From 0f8b5f39004242c1b8c118372797f9bd3a1a5142 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 25 Oct 2023 17:04:55 +0900 Subject: [PATCH 131/311] =?UTF-8?q?fix:=20updateProfileInfo=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/user/controller/UserController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index a309bd67..4373edd6 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -52,7 +52,8 @@ public ResponseEntity updateProfileImage( @PatchMapping("/me") public ResponseEntity updateProfileInfo(@Login AuthInfo authInfo, @Valid @RequestBody UpdateProfileRequest request) { - userService.updateProfileInfo(authInfo.userId(), request.nickname(), request.interests()); + userService.updateProfileInfo(authInfo.userId(), request.nickname(), request.name(), + request.interests()); return ResponseEntity.ok().build(); } From 8e4834d56796b32f343536f85880efe24fb2e779 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 25 Oct 2023 17:16:50 +0900 Subject: [PATCH 132/311] =?UTF-8?q?fix:=20http=20method=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 --- .../java/coffeemeet/server/user/controller/UserController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index 4373edd6..02c32302 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; +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.RequestPart; @@ -37,7 +38,7 @@ public ResponseEntity findMyProfile(@Login AuthInfo authInfo) return ResponseEntity.ok(userService.findMyProfile(authInfo.userId())); } - @PatchMapping("/me/profile-image") + @PostMapping("/me/profile-image") public ResponseEntity updateProfileImage( @Login AuthInfo authInfo, @NotNull From c850461677c238eb0a1038f3ef454945837f0e2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Wed, 25 Oct 2023 18:00:30 +0900 Subject: [PATCH 133/311] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=20=ED=83=88?= =?UTF-8?q?=ED=87=B4=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 --- .../server/auth/controller/AuthController.java | 8 +++++++- .../coffeemeet/server/auth/service/AuthService.java | 10 ++++++++++ .../coffeemeet/server/user/service/UserService.java | 6 ++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/auth/controller/AuthController.java b/src/main/java/coffeemeet/server/auth/controller/AuthController.java index 847acd7d..11324691 100644 --- a/src/main/java/coffeemeet/server/auth/controller/AuthController.java +++ b/src/main/java/coffeemeet/server/auth/controller/AuthController.java @@ -54,7 +54,13 @@ public ResponseEntity renew(@Login AuthInfo authInfo) { @PostMapping("/logout") public ResponseEntity logout(@Login AuthInfo authInfo) { authService.logout(authInfo.userId()); - return ResponseEntity.noContent().build(); + return ResponseEntity.ok().build(); + } + + @PostMapping("/delete") + public ResponseEntity delete(@Login AuthInfo authInfo) { + authService.delete(authInfo.userId()); + return ResponseEntity.ok().build(); } } diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index 4c7257a5..5b4f4325 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -16,10 +16,12 @@ import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.repository.UserRepository; +import coffeemeet.server.user.service.UserService; import java.util.ArrayList; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor @@ -35,12 +37,14 @@ public class AuthService { private final InterestRepository interestRepository; private final AuthTokensGenerator authTokensGenerator; private final JwtTokenProvider jwtTokenProvider; + private final UserService userService; private final RefreshTokenRepository refreshTokenRepository; public String getAuthCodeRequestUrl(OAuthProvider oAuthProvider) { return authCodeRequestUrlProviderComposite.provide(oAuthProvider); } + @Transactional public AuthTokens signup(SignupRequest request) { OAuthInfoResponse response = oauthMemberClientComposite.fetch(request.oAuthProvider(), request.authCode()); @@ -80,6 +84,12 @@ public void logout(Long userId) { refreshTokenRepository.deleteById(userId); } + @Transactional + public void delete(Long userId) { + userService.deleteUser(userId); + refreshTokenRepository.deleteById(userId); + } + private void checkDuplicateUser(OAuthInfoResponse response) { if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( response.oAuthProvider(), response.oAuthProviderId())) { diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index fdddd9fd..cc2c6f74 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -88,6 +88,12 @@ public void updateProfileInfo(Long userId, String nickname, String name, interestService.updateInterests(userId, interests); } + @Transactional + public void deleteUser(Long userId) { + interestRepository.deleteById(userId); + userRepository.deleteById(userId); + } + private User getUserById(Long userId) { return userRepository.findById(userId) .orElseThrow(IllegalArgumentException::new); From b186c1468f871ae76b88a64fab5bbbc5fbf6c0bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 24 Oct 2023 23:20:35 +0900 Subject: [PATCH 134/311] =?UTF-8?q?refactor:=20=EB=B0=98=ED=99=98=EA=B0=92?= =?UTF-8?q?=EC=9D=B4=20=EC=97=86=EC=9D=84=20=EC=8B=9C=20200(OK)=EB=A5=BC?= =?UTF-8?q?=20=EB=B0=98=ED=99=98=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/auth/controller/AuthController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/auth/controller/AuthController.java b/src/main/java/coffeemeet/server/auth/controller/AuthController.java index 847acd7d..688466e0 100644 --- a/src/main/java/coffeemeet/server/auth/controller/AuthController.java +++ b/src/main/java/coffeemeet/server/auth/controller/AuthController.java @@ -54,7 +54,7 @@ public ResponseEntity renew(@Login AuthInfo authInfo) { @PostMapping("/logout") public ResponseEntity logout(@Login AuthInfo authInfo) { authService.logout(authInfo.userId()); - return ResponseEntity.noContent().build(); + return ResponseEntity.ok().build(); } } From 692e1d1fd13d50380b27324fc68f491c24c53b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Wed, 25 Oct 2023 01:31:11 +0900 Subject: [PATCH 135/311] =?UTF-8?q?feat:=20=EB=8B=89=EB=84=A4=EC=9E=84=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=20=EA=B2=80=EC=82=AC=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/auth/service/AuthService.java | 14 +++++++++++--- .../server/user/controller/UserController.java | 7 +++++++ .../server/user/service/UserService.java | 8 ++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index 4c7257a5..59202471 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -44,11 +44,12 @@ public String getAuthCodeRequestUrl(OAuthProvider oAuthProvider) { public AuthTokens signup(SignupRequest request) { OAuthInfoResponse response = oauthMemberClientComposite.fetch(request.oAuthProvider(), request.authCode()); - checkDuplicateUser(response); + checkDuplicatedUser(response); String profileImage = checkProfileImage(response.profileImage()); + String nickname = checkDuplicatedNickname(request.nickname()); User user = new User(new OAuthInfo(response.oAuthProvider(), response.oAuthProviderId()), - Profile.builder().name(response.name()).nickname(request.nickname()).email(response.email()) + Profile.builder().name(response.name()).nickname(nickname).email(response.email()) .profileImageUrl(profileImage).birth(response.birth()).build()); User newUser = userRepository.save(user); @@ -80,7 +81,7 @@ public void logout(Long userId) { refreshTokenRepository.deleteById(userId); } - private void checkDuplicateUser(OAuthInfoResponse response) { + private void checkDuplicatedUser(OAuthInfoResponse response) { if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( response.oAuthProvider(), response.oAuthProviderId())) { throw new IllegalArgumentException(ALREADY_REGISTERED_MESSAGE); @@ -94,6 +95,13 @@ private String checkProfileImage(String profileImage) { return profileImage; } + private String checkDuplicatedNickname(String nickname) { + if (userRepository.findUserByProfileNickname(nickname).isPresent()) { + throw new IllegalArgumentException("중복된 닉네임입니다."); + } + return nickname; + } + private void generateInterests(SignupRequest request, User newUser) { List interests = new ArrayList<>(); for (Keyword value : request.keywords()) { diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index 02c32302..89a9edcb 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -18,6 +18,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestPart; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @@ -58,4 +59,10 @@ public ResponseEntity updateProfileInfo(@Login AuthInfo authInfo, return ResponseEntity.ok().build(); } + @GetMapping("/duplicate") + public ResponseEntity checkDuplicatedNickname(@RequestParam String nickname) { + userService.checkDuplicatedNickname(nickname); + return ResponseEntity.ok().build(); + } + } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index fdddd9fd..ec265108 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -82,12 +82,20 @@ public void updateProfileInfo(Long userId, String nickname, String name, List interests) { User user = getUserById(userId); + checkDuplicatedNickname(nickname); + user.updateNickname(nickname); user.updateName(name); interestService.updateInterests(userId, interests); } + public void checkDuplicatedNickname(String nickname) { + if (userRepository.findUserByProfileNickname(nickname).isPresent()) { + throw new IllegalArgumentException("이미 존재하는 닉네임입니다."); + } + } + private User getUserById(Long userId) { return userRepository.findById(userId) .orElseThrow(IllegalArgumentException::new); From 827f8bbbabae51fef099149f7c2ffe05529fa4e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Wed, 25 Oct 2023 09:24:53 +0900 Subject: [PATCH 136/311] =?UTF-8?q?refactor:=20=EA=B4=80=EC=8B=AC=EC=82=AC?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=AA=85=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 --- .../coffeemeet/server/auth/service/AuthService.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index 59202471..da75701a 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -53,8 +53,7 @@ public AuthTokens signup(SignupRequest request) { .profileImageUrl(profileImage).birth(response.birth()).build()); User newUser = userRepository.save(user); - - generateInterests(request, newUser); + saveInterests(request, newUser); return authTokensGenerator.generate(newUser.getId()); } @@ -95,14 +94,7 @@ private String checkProfileImage(String profileImage) { return profileImage; } - private String checkDuplicatedNickname(String nickname) { - if (userRepository.findUserByProfileNickname(nickname).isPresent()) { - throw new IllegalArgumentException("중복된 닉네임입니다."); - } - return nickname; - } - - private void generateInterests(SignupRequest request, User newUser) { + private void saveInterests(SignupRequest request, User newUser) { List interests = new ArrayList<>(); for (Keyword value : request.keywords()) { interests.add(new Interest(value, newUser)); From f9e0ff27c7cf4b507f4ea1d4bb7d1484cff56a66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Wed, 25 Oct 2023 09:26:39 +0900 Subject: [PATCH 137/311] =?UTF-8?q?refactor:=20=EA=B8=B0=EB=B3=B8=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20URL=EC=9D=84=20=EC=83=81=EC=88=98?= =?UTF-8?q?=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/coffeemeet/server/auth/service/AuthService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index da75701a..3453b61f 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -28,6 +28,7 @@ public class AuthService { private static final String EXPIRED_REFRESH_TOKEN_MESSAGE = "리프레시 토큰이 만료되었습니다. 다시 로그인해 주세요."; private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; private static final String USER_NOT_REGISTERED_MESSAGE = "해당 아이디(%s)와 로그인 타입(%s)의 유저는 회원가입되지 않았습니다."; + private static final String DEFAULT_IMAGE_URL = "기본 이미지 URL"; private final AuthCodeRequestUrlProviderComposite authCodeRequestUrlProviderComposite; private final OAuthMemberClientComposite oauthMemberClientComposite; @@ -89,7 +90,7 @@ private void checkDuplicatedUser(OAuthInfoResponse response) { private String checkProfileImage(String profileImage) { if (profileImage == null) { - profileImage = "기본 이미지 URL"; + profileImage = DEFAULT_IMAGE_URL; } return profileImage; } From 59f6c41a7109c660a2d10fa78f748d7f8ffab1a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Wed, 25 Oct 2023 09:27:29 +0900 Subject: [PATCH 138/311] =?UTF-8?q?refactor:=20AuthService=EC=9D=98=20?= =?UTF-8?q?=EB=8B=89=EB=84=A4=EC=9E=84,=20=EC=9C=A0=EC=A0=80=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=EA=B2=80=EC=82=AC=20=EB=A1=9C=EC=A7=81=EC=9D=84=20?= =?UTF-8?q?UserService=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/auth/service/AuthService.java | 17 ++++++----------- .../server/user/service/UserService.java | 9 +++++++++ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index 3453b61f..abbaaeb6 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -16,6 +16,7 @@ import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.repository.UserRepository; +import coffeemeet.server.user.service.UserService; import java.util.ArrayList; import java.util.List; import lombok.RequiredArgsConstructor; @@ -26,12 +27,12 @@ public class AuthService { private static final String EXPIRED_REFRESH_TOKEN_MESSAGE = "리프레시 토큰이 만료되었습니다. 다시 로그인해 주세요."; - private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; private static final String USER_NOT_REGISTERED_MESSAGE = "해당 아이디(%s)와 로그인 타입(%s)의 유저는 회원가입되지 않았습니다."; private static final String DEFAULT_IMAGE_URL = "기본 이미지 URL"; private final AuthCodeRequestUrlProviderComposite authCodeRequestUrlProviderComposite; private final OAuthMemberClientComposite oauthMemberClientComposite; + private final UserService userService; private final UserRepository userRepository; private final InterestRepository interestRepository; private final AuthTokensGenerator authTokensGenerator; @@ -45,12 +46,13 @@ public String getAuthCodeRequestUrl(OAuthProvider oAuthProvider) { public AuthTokens signup(SignupRequest request) { OAuthInfoResponse response = oauthMemberClientComposite.fetch(request.oAuthProvider(), request.authCode()); - checkDuplicatedUser(response); + + userService.checkDuplicatedUser(response); + userService.checkDuplicatedNickname(request.nickname()); String profileImage = checkProfileImage(response.profileImage()); - String nickname = checkDuplicatedNickname(request.nickname()); User user = new User(new OAuthInfo(response.oAuthProvider(), response.oAuthProviderId()), - Profile.builder().name(response.name()).nickname(nickname).email(response.email()) + Profile.builder().name(response.name()).nickname(request.nickname()).email(response.email()) .profileImageUrl(profileImage).birth(response.birth()).build()); User newUser = userRepository.save(user); @@ -81,13 +83,6 @@ public void logout(Long userId) { refreshTokenRepository.deleteById(userId); } - private void checkDuplicatedUser(OAuthInfoResponse response) { - if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( - response.oAuthProvider(), response.oAuthProviderId())) { - throw new IllegalArgumentException(ALREADY_REGISTERED_MESSAGE); - } - } - private String checkProfileImage(String profileImage) { if (profileImage == null) { profileImage = DEFAULT_IMAGE_URL; diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index ec265108..07e19339 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -1,5 +1,6 @@ package coffeemeet.server.user.service; +import coffeemeet.server.auth.dto.OAuthInfoResponse; import static coffeemeet.server.common.media.S3MediaService.KeyType.PROFILE_IMAGE; import coffeemeet.server.common.media.S3MediaService; @@ -24,6 +25,7 @@ public class UserService { public static final String EXISTED_COMPANY_EMAIL_ERROR = "이미 사용 중인 회사이메일입니다."; + private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; private final S3MediaService s3MediaService; private final UserRepository userRepository; @@ -96,6 +98,13 @@ public void checkDuplicatedNickname(String nickname) { } } + public void checkDuplicatedUser(OAuthInfoResponse response) { + if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( + response.oAuthProvider(), response.oAuthProviderId())) { + throw new IllegalArgumentException(ALREADY_REGISTERED_MESSAGE); + } + } + private User getUserById(Long userId) { return userRepository.findById(userId) .orElseThrow(IllegalArgumentException::new); From 785a348fdddcbd11776cc4698f2c804dc0363b51 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 25 Oct 2023 18:09:43 +0900 Subject: [PATCH 139/311] =?UTF-8?q?refactor:=20=EC=A0=91=EA=B7=BC=EC=A0=9C?= =?UTF-8?q?=EC=96=B4=EC=9E=90=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/coffeemeet/server/user/service/UserService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 07e19339..8eae0f17 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -24,7 +24,7 @@ @Transactional(readOnly = true) public class UserService { - public static final String EXISTED_COMPANY_EMAIL_ERROR = "이미 사용 중인 회사이메일입니다."; + private static final String EXISTED_COMPANY_EMAIL_ERROR = "이미 사용 중인 회사이메일입니다."; private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; private final S3MediaService s3MediaService; From 4b3b61ef94100f95e447ca883494e7ebefb6f2e1 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 25 Oct 2023 18:14:59 +0900 Subject: [PATCH 140/311] =?UTF-8?q?refactor:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=8F=AC=EB=A9=A7=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/user/controller/UserController.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index 89a9edcb..c3c3e47e 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -8,6 +8,7 @@ import coffeemeet.server.user.dto.UserProfileResponse; import coffeemeet.server.user.service.UserService; import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; @@ -42,9 +43,8 @@ public ResponseEntity findMyProfile(@Login AuthInfo authInfo) @PostMapping("/me/profile-image") public ResponseEntity updateProfileImage( @Login AuthInfo authInfo, - @NotNull @RequestPart("profileImage") - MultipartFile profileImage) { + @NotNull MultipartFile profileImage) { userService.updateProfileImage( authInfo.userId(), FileUtils.convertMultipartFileToFile(profileImage)); @@ -60,7 +60,7 @@ public ResponseEntity updateProfileInfo(@Login AuthInfo authInfo, } @GetMapping("/duplicate") - public ResponseEntity checkDuplicatedNickname(@RequestParam String nickname) { + public ResponseEntity checkDuplicatedNickname(@RequestParam @NotBlank String nickname) { userService.checkDuplicatedNickname(nickname); return ResponseEntity.ok().build(); } From c8ae9f6e9ebd844a3f53c3cdde0f1a95d3d1aa2a Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 25 Oct 2023 18:15:15 +0900 Subject: [PATCH 141/311] =?UTF-8?q?refactor:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=8F=AC=EB=A9=A7=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/user/controller/UserController.java | 2 +- src/main/java/coffeemeet/server/user/service/UserService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index c3c3e47e..94573aa4 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -18,8 +18,8 @@ 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.RequestPart; import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 8eae0f17..188eb9cf 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -1,8 +1,8 @@ package coffeemeet.server.user.service; -import coffeemeet.server.auth.dto.OAuthInfoResponse; import static coffeemeet.server.common.media.S3MediaService.KeyType.PROFILE_IMAGE; +import coffeemeet.server.auth.dto.OAuthInfoResponse; import coffeemeet.server.common.media.S3MediaService; import coffeemeet.server.interest.domain.Interest; import coffeemeet.server.interest.domain.Keyword; From dbf93fe4138d4c6332f035e7d1b8ca2b32194245 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Wed, 25 Oct 2023 18:27:50 +0900 Subject: [PATCH 142/311] =?UTF-8?q?fix:=20H2=20=EC=98=88=EC=95=BD=EC=96=B4?= =?UTF-8?q?=EC=99=80=20=EA=B2=B9=EC=B9=98=EB=8A=94=20=EC=BB=AC=EB=9F=BC=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 --- .../coffeemeet/server/user/domain/Birth.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/Birth.java b/src/main/java/coffeemeet/server/user/domain/Birth.java index e772f1db..b987b586 100644 --- a/src/main/java/coffeemeet/server/user/domain/Birth.java +++ b/src/main/java/coffeemeet/server/user/domain/Birth.java @@ -15,26 +15,26 @@ public class Birth { private static final int BIRTH_LENGTH = 4; @Column(nullable = false, length = BIRTH_LENGTH) - String year; + String birthYear; @Column(nullable = false, length = BIRTH_LENGTH) - String day; + String birthDay; - public Birth(String year, String day) { - validateYear(year); - validateDay(day); - this.year = year; - this.day = day; + public Birth(String birthYear, String birthDay) { + validateYear(birthYear); + validateDay(birthDay); + this.birthYear = birthYear; + this.birthDay = birthDay; } - private void validateYear(String year) { - if (!StringUtils.hasText(year) || year.length() != BIRTH_LENGTH) { + private void validateYear(String birthYear) { + if (!StringUtils.hasText(birthYear) || birthYear.length() != BIRTH_LENGTH) { throw new IllegalArgumentException("올바르지 않은 연도 형식입니다."); } } - private void validateDay(String day) { - if (!StringUtils.hasText(day) || day.length() != BIRTH_LENGTH) { + private void validateDay(String birthDay) { + if (!StringUtils.hasText(birthDay) || birthDay.length() != BIRTH_LENGTH) { throw new IllegalArgumentException("올바르지 않은 날짜 형식입니다."); } } From be9fa64f3f7e1995421db323b0639f42d7ebf5e3 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 25 Oct 2023 18:32:18 +0900 Subject: [PATCH 143/311] =?UTF-8?q?fix:=20merge=20conflict=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/auth/service/AuthService.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index 2dc3f8a9..f73ab0e2 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -38,7 +38,6 @@ public class AuthService { private final InterestRepository interestRepository; private final AuthTokensGenerator authTokensGenerator; private final JwtTokenProvider jwtTokenProvider; - private final UserService userService; private final RefreshTokenRepository refreshTokenRepository; public String getAuthCodeRequestUrl(OAuthProvider oAuthProvider) { @@ -92,13 +91,6 @@ public void delete(Long userId) { refreshTokenRepository.deleteById(userId); } - private void checkDuplicateUser(OAuthInfoResponse response) { - if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( - response.oAuthProvider(), response.oAuthProviderId())) { - throw new IllegalArgumentException(ALREADY_REGISTERED_MESSAGE); - } - } - private String checkProfileImage(String profileImage) { if (profileImage == null) { profileImage = DEFAULT_IMAGE_URL; From 474fb8ede7edb415ed56aff05b01374262491662 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 25 Oct 2023 18:39:22 +0900 Subject: [PATCH 144/311] =?UTF-8?q?fix:=20merge=20conflict=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/user/dto/MyProfileResponse.java | 4 ++-- .../coffeemeet/server/common/fixture/entity/UserFixture.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java b/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java index eb9dc90b..05318718 100644 --- a/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java +++ b/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java @@ -30,8 +30,8 @@ public static MyProfileResponse of(User user, List interests) { user.getProfile().getNickname(), user.getProfile().getEmail().getEmail(), user.getProfile().getProfileImageUrl(), - user.getProfile().getBirth().getYear(), - user.getProfile().getBirth().getDay(), + user.getProfile().getBirth().getBirthYear(), + user.getProfile().getBirth().getBirthDay(), user.getReportInfo().getReportedCount(), user.getReportInfo().getSanctionPeriod(), user.getCertification().getCompanyEmail().getCompanyEmail(), diff --git a/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java b/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java index 0e31821d..868b1ae1 100644 --- a/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java @@ -22,8 +22,8 @@ public static User user() { private static Birth birth() { return Instancio.of(Birth.class) - .generate(field(Birth::getYear), gen -> gen.ints().range(1000, 9999)) - .generate(field(Birth::getDay), gen -> gen.ints().range(1000, 9999)) + .generate(field(Birth::getBirthYear), gen -> gen.ints().range(1000, 9999)) + .generate(field(Birth::getBirthDay), gen -> gen.ints().range(1000, 9999)) .create(); } From 68a19a3cd360b08a2cb9438882966415f6677238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Wed, 25 Oct 2023 23:19:52 +0900 Subject: [PATCH 145/311] =?UTF-8?q?style:=20auth=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/controller/AuthController.java | 33 +------- .../auth/{utils => domain}/AuthTokens.java | 2 +- .../AuthTokensGenerator.java | 5 +- .../{utils => domain}/JwtTokenProvider.java | 2 +- .../RefreshTokenRepository.java | 2 +- .../server/auth/service/AuthService.java | 76 +------------------ .../server/common/UserArgumentResolver.java | 4 +- .../server/common/config/AuthWebConfig.java | 6 +- .../authcode/AuthCodeRequestUrlProvider.java | 2 +- .../AuthCodeRequestUrlProviderComposite.java | 2 +- .../common/config/ControllerTestConfig.java | 4 +- 11 files changed, 20 insertions(+), 118 deletions(-) rename src/main/java/coffeemeet/server/auth/{utils => domain}/AuthTokens.java (86%) rename src/main/java/coffeemeet/server/auth/{utils => domain}/AuthTokensGenerator.java (92%) rename src/main/java/coffeemeet/server/auth/{utils => domain}/JwtTokenProvider.java (98%) rename src/main/java/coffeemeet/server/auth/{infrastructure => repository}/RefreshTokenRepository.java (80%) rename src/main/java/coffeemeet/server/{auth/domain => oauth}/authcode/AuthCodeRequestUrlProvider.java (76%) rename src/main/java/coffeemeet/server/{auth/domain => oauth}/authcode/AuthCodeRequestUrlProviderComposite.java (96%) diff --git a/src/main/java/coffeemeet/server/auth/controller/AuthController.java b/src/main/java/coffeemeet/server/auth/controller/AuthController.java index 11324691..5ba14558 100644 --- a/src/main/java/coffeemeet/server/auth/controller/AuthController.java +++ b/src/main/java/coffeemeet/server/auth/controller/AuthController.java @@ -1,51 +1,22 @@ package coffeemeet.server.auth.controller; -import coffeemeet.server.auth.dto.SignupRequest; +import coffeemeet.server.auth.domain.AuthTokens; import coffeemeet.server.auth.service.AuthService; -import coffeemeet.server.auth.utils.AuthTokens; import coffeemeet.server.common.annotation.Login; -import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.dto.AuthInfo; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.validation.Valid; -import java.io.IOException; import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; 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.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @RequiredArgsConstructor -@RequestMapping("/oauth2/auth") +@RequestMapping("/auth") public class AuthController { private final AuthService authService; - @GetMapping("/{oAuthProvider}") - public ResponseEntity redirectAuthCodeRequestUrl(@PathVariable OAuthProvider oAuthProvider, - HttpServletResponse response) throws IOException { - String redirectUrl = authService.getAuthCodeRequestUrl(oAuthProvider); - response.sendRedirect(redirectUrl); - return new ResponseEntity<>(HttpStatus.FOUND); - } - - @PostMapping("/sign-up") - public ResponseEntity signup(@Valid @RequestBody SignupRequest request) { - return ResponseEntity.ok(authService.signup(request)); - } - - @GetMapping("/login/{oAuthProvider}") - public ResponseEntity login(@PathVariable OAuthProvider oAuthProvider, - @RequestParam String authCode) { - return ResponseEntity.ok(authService.login(oAuthProvider, authCode)); - } - @PostMapping("/renew-token") public ResponseEntity renew(@Login AuthInfo authInfo) { return ResponseEntity.ok(authService.renew(authInfo.userId(), authInfo.refreshToken())); diff --git a/src/main/java/coffeemeet/server/auth/utils/AuthTokens.java b/src/main/java/coffeemeet/server/auth/domain/AuthTokens.java similarity index 86% rename from src/main/java/coffeemeet/server/auth/utils/AuthTokens.java rename to src/main/java/coffeemeet/server/auth/domain/AuthTokens.java index cdbfaf21..4d3de1c0 100644 --- a/src/main/java/coffeemeet/server/auth/utils/AuthTokens.java +++ b/src/main/java/coffeemeet/server/auth/domain/AuthTokens.java @@ -1,4 +1,4 @@ -package coffeemeet.server.auth.utils; +package coffeemeet.server.auth.domain; public record AuthTokens( String accessToken, diff --git a/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java b/src/main/java/coffeemeet/server/auth/domain/AuthTokensGenerator.java similarity index 92% rename from src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java rename to src/main/java/coffeemeet/server/auth/domain/AuthTokensGenerator.java index f530f173..b4620ef7 100644 --- a/src/main/java/coffeemeet/server/auth/utils/AuthTokensGenerator.java +++ b/src/main/java/coffeemeet/server/auth/domain/AuthTokensGenerator.java @@ -1,7 +1,6 @@ -package coffeemeet.server.auth.utils; +package coffeemeet.server.auth.domain; -import coffeemeet.server.auth.domain.RefreshToken; -import coffeemeet.server.auth.infrastructure.RefreshTokenRepository; +import coffeemeet.server.auth.repository.RefreshTokenRepository; import java.util.Date; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; diff --git a/src/main/java/coffeemeet/server/auth/utils/JwtTokenProvider.java b/src/main/java/coffeemeet/server/auth/domain/JwtTokenProvider.java similarity index 98% rename from src/main/java/coffeemeet/server/auth/utils/JwtTokenProvider.java rename to src/main/java/coffeemeet/server/auth/domain/JwtTokenProvider.java index 516754cd..2b6fb6c4 100644 --- a/src/main/java/coffeemeet/server/auth/utils/JwtTokenProvider.java +++ b/src/main/java/coffeemeet/server/auth/domain/JwtTokenProvider.java @@ -1,4 +1,4 @@ -package coffeemeet.server.auth.utils; +package coffeemeet.server.auth.domain; import io.jsonwebtoken.Claims; import io.jsonwebtoken.ExpiredJwtException; diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/RefreshTokenRepository.java b/src/main/java/coffeemeet/server/auth/repository/RefreshTokenRepository.java similarity index 80% rename from src/main/java/coffeemeet/server/auth/infrastructure/RefreshTokenRepository.java rename to src/main/java/coffeemeet/server/auth/repository/RefreshTokenRepository.java index 8fc81e0c..436fca30 100644 --- a/src/main/java/coffeemeet/server/auth/infrastructure/RefreshTokenRepository.java +++ b/src/main/java/coffeemeet/server/auth/repository/RefreshTokenRepository.java @@ -1,4 +1,4 @@ -package coffeemeet.server.auth.infrastructure; +package coffeemeet.server.auth.repository; import coffeemeet.server.auth.domain.RefreshToken; import org.springframework.data.repository.CrudRepository; diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index f73ab0e2..32fe3e54 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -1,24 +1,10 @@ package coffeemeet.server.auth.service; -import coffeemeet.server.auth.domain.authcode.AuthCodeRequestUrlProviderComposite; -import coffeemeet.server.auth.domain.client.OAuthMemberClientComposite; -import coffeemeet.server.auth.dto.OAuthInfoResponse; -import coffeemeet.server.auth.dto.SignupRequest; -import coffeemeet.server.auth.infrastructure.RefreshTokenRepository; -import coffeemeet.server.auth.utils.AuthTokens; -import coffeemeet.server.auth.utils.AuthTokensGenerator; -import coffeemeet.server.auth.utils.JwtTokenProvider; -import coffeemeet.server.interest.domain.Interest; -import coffeemeet.server.interest.domain.Keyword; -import coffeemeet.server.interest.repository.InterestRepository; -import coffeemeet.server.user.domain.OAuthInfo; -import coffeemeet.server.user.domain.OAuthProvider; -import coffeemeet.server.user.domain.Profile; -import coffeemeet.server.user.domain.User; -import coffeemeet.server.user.repository.UserRepository; +import coffeemeet.server.auth.domain.AuthTokens; +import coffeemeet.server.auth.domain.AuthTokensGenerator; +import coffeemeet.server.auth.domain.JwtTokenProvider; +import coffeemeet.server.auth.repository.RefreshTokenRepository; import coffeemeet.server.user.service.UserService; -import java.util.ArrayList; -import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -28,51 +14,12 @@ public class AuthService { private static final String EXPIRED_REFRESH_TOKEN_MESSAGE = "리프레시 토큰이 만료되었습니다. 다시 로그인해 주세요."; - private static final String USER_NOT_REGISTERED_MESSAGE = "해당 아이디(%s)와 로그인 타입(%s)의 유저는 회원가입되지 않았습니다."; - private static final String DEFAULT_IMAGE_URL = "기본 이미지 URL"; - private final AuthCodeRequestUrlProviderComposite authCodeRequestUrlProviderComposite; - private final OAuthMemberClientComposite oauthMemberClientComposite; private final UserService userService; - private final UserRepository userRepository; - private final InterestRepository interestRepository; private final AuthTokensGenerator authTokensGenerator; private final JwtTokenProvider jwtTokenProvider; private final RefreshTokenRepository refreshTokenRepository; - public String getAuthCodeRequestUrl(OAuthProvider oAuthProvider) { - return authCodeRequestUrlProviderComposite.provide(oAuthProvider); - } - - @Transactional - public AuthTokens signup(SignupRequest request) { - OAuthInfoResponse response = oauthMemberClientComposite.fetch(request.oAuthProvider(), - request.authCode()); - - userService.checkDuplicatedUser(response); - userService.checkDuplicatedNickname(request.nickname()); - String profileImage = checkProfileImage(response.profileImage()); - - User user = new User(new OAuthInfo(response.oAuthProvider(), response.oAuthProviderId()), - Profile.builder().name(response.name()).nickname(request.nickname()).email(response.email()) - .profileImageUrl(profileImage).birth(response.birth()).build()); - - User newUser = userRepository.save(user); - saveInterests(request, newUser); - - return authTokensGenerator.generate(newUser.getId()); - } - - public AuthTokens login(OAuthProvider oAuthProvider, String authCode) { - OAuthInfoResponse response = oauthMemberClientComposite.fetch(oAuthProvider, authCode); - User foundUser = userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( - response.oAuthProvider(), response.oAuthProviderId()).orElseThrow( - () -> new IllegalArgumentException( - String.format(USER_NOT_REGISTERED_MESSAGE, response.oAuthProviderId(), - response.oAuthProvider()))); - return authTokensGenerator.generate(foundUser.getId()); - } - public AuthTokens renew(Long userId, String refreshToken) { if (jwtTokenProvider.isExpiredRefreshToken(refreshToken)) { throw new IllegalArgumentException(EXPIRED_REFRESH_TOKEN_MESSAGE); @@ -91,19 +38,4 @@ public void delete(Long userId) { refreshTokenRepository.deleteById(userId); } - private String checkProfileImage(String profileImage) { - if (profileImage == null) { - profileImage = DEFAULT_IMAGE_URL; - } - return profileImage; - } - - private void saveInterests(SignupRequest request, User newUser) { - List interests = new ArrayList<>(); - for (Keyword value : request.keywords()) { - interests.add(new Interest(value, newUser)); - } - interestRepository.saveAll(interests); - } - } diff --git a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java index ac899e39..8a97a0a0 100644 --- a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java +++ b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java @@ -1,8 +1,8 @@ package coffeemeet.server.common; +import coffeemeet.server.auth.domain.JwtTokenProvider; import coffeemeet.server.auth.domain.RefreshToken; -import coffeemeet.server.auth.infrastructure.RefreshTokenRepository; -import coffeemeet.server.auth.utils.JwtTokenProvider; +import coffeemeet.server.auth.repository.RefreshTokenRepository; import coffeemeet.server.common.annotation.Login; import coffeemeet.server.user.dto.AuthInfo; import jakarta.servlet.http.HttpServletRequest; diff --git a/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java b/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java index 7201ace4..49d145eb 100644 --- a/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java +++ b/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java @@ -1,9 +1,9 @@ package coffeemeet.server.common.config; -import coffeemeet.server.auth.infrastructure.RefreshTokenRepository; -import coffeemeet.server.auth.utils.JwtTokenProvider; -import coffeemeet.server.auth.utils.converter.OAuthProviderConverter; +import coffeemeet.server.auth.domain.JwtTokenProvider; +import coffeemeet.server.auth.repository.RefreshTokenRepository; import coffeemeet.server.common.UserArgumentResolver; +import coffeemeet.server.oauth.utils.converter.OAuthProviderConverter; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/coffeemeet/server/auth/domain/authcode/AuthCodeRequestUrlProvider.java b/src/main/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProvider.java similarity index 76% rename from src/main/java/coffeemeet/server/auth/domain/authcode/AuthCodeRequestUrlProvider.java rename to src/main/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProvider.java index e7687c4c..c22a7841 100644 --- a/src/main/java/coffeemeet/server/auth/domain/authcode/AuthCodeRequestUrlProvider.java +++ b/src/main/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProvider.java @@ -1,4 +1,4 @@ -package coffeemeet.server.auth.domain.authcode; +package coffeemeet.server.oauth.authcode; import coffeemeet.server.user.domain.OAuthProvider; diff --git a/src/main/java/coffeemeet/server/auth/domain/authcode/AuthCodeRequestUrlProviderComposite.java b/src/main/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderComposite.java similarity index 96% rename from src/main/java/coffeemeet/server/auth/domain/authcode/AuthCodeRequestUrlProviderComposite.java rename to src/main/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderComposite.java index f4d36b79..290c7edb 100644 --- a/src/main/java/coffeemeet/server/auth/domain/authcode/AuthCodeRequestUrlProviderComposite.java +++ b/src/main/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderComposite.java @@ -1,4 +1,4 @@ -package coffeemeet.server.auth.domain.authcode; +package coffeemeet.server.oauth.authcode; import coffeemeet.server.user.domain.OAuthProvider; import java.util.Map; diff --git a/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java index 7435039d..f7c773d8 100644 --- a/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java +++ b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java @@ -3,8 +3,8 @@ import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import coffeemeet.server.auth.infrastructure.RefreshTokenRepository; -import coffeemeet.server.auth.utils.JwtTokenProvider; +import coffeemeet.server.auth.domain.JwtTokenProvider; +import coffeemeet.server.auth.repository.RefreshTokenRepository; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; From 7227d6da97032ba4f039bd954767b198062ecdfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Wed, 25 Oct 2023 23:20:23 +0900 Subject: [PATCH 146/311] =?UTF-8?q?style:=20user=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/controller/UserController.java | 14 +++++ .../{auth => user}/dto/SignupRequest.java | 2 +- .../server/user/service/UserService.java | 59 ++++++++++++++++++- 3 files changed, 72 insertions(+), 3 deletions(-) rename src/main/java/coffeemeet/server/{auth => user}/dto/SignupRequest.java (91%) diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index 94573aa4..515573a2 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -1,9 +1,12 @@ package coffeemeet.server.user.controller; +import coffeemeet.server.auth.domain.AuthTokens; import coffeemeet.server.common.annotation.Login; import coffeemeet.server.common.util.FileUtils; +import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.dto.AuthInfo; import coffeemeet.server.user.dto.MyProfileResponse; +import coffeemeet.server.user.dto.SignupRequest; import coffeemeet.server.user.dto.UpdateProfileRequest; import coffeemeet.server.user.dto.UserProfileResponse; import coffeemeet.server.user.service.UserService; @@ -30,6 +33,17 @@ public class UserController { private final UserService userService; + @PostMapping("/sign-up") + public ResponseEntity signup(@Valid @RequestBody SignupRequest request) { + return ResponseEntity.ok(userService.signup(request)); + } + + @GetMapping("/login/{oAuthProvider}") + public ResponseEntity login(@PathVariable OAuthProvider oAuthProvider, + @RequestParam String authCode) { + return ResponseEntity.ok(userService.login(oAuthProvider, authCode)); + } + @GetMapping("/{nickname}") public ResponseEntity findUserProfile(@PathVariable String nickname) { return ResponseEntity.ok(userService.findUserProfile(nickname)); diff --git a/src/main/java/coffeemeet/server/auth/dto/SignupRequest.java b/src/main/java/coffeemeet/server/user/dto/SignupRequest.java similarity index 91% rename from src/main/java/coffeemeet/server/auth/dto/SignupRequest.java rename to src/main/java/coffeemeet/server/user/dto/SignupRequest.java index 76c798e3..42f7cde8 100644 --- a/src/main/java/coffeemeet/server/auth/dto/SignupRequest.java +++ b/src/main/java/coffeemeet/server/user/dto/SignupRequest.java @@ -1,4 +1,4 @@ -package coffeemeet.server.auth.dto; +package coffeemeet.server.user.dto; import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.user.domain.OAuthProvider; diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 466508bf..6cde2672 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -2,18 +2,26 @@ import static coffeemeet.server.common.media.S3MediaService.KeyType.PROFILE_IMAGE; -import coffeemeet.server.auth.dto.OAuthInfoResponse; +import coffeemeet.server.auth.domain.AuthTokens; +import coffeemeet.server.auth.domain.AuthTokensGenerator; import coffeemeet.server.common.media.S3MediaService; import coffeemeet.server.interest.domain.Interest; import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.interest.repository.InterestRepository; import coffeemeet.server.interest.service.InterestService; +import coffeemeet.server.oauth.dto.OAuthInfoResponse; +import coffeemeet.server.oauth.service.OAuthService; import coffeemeet.server.user.domain.CompanyEmail; +import coffeemeet.server.user.domain.OAuthInfo; +import coffeemeet.server.user.domain.OAuthProvider; +import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.dto.MyProfileResponse; +import coffeemeet.server.user.dto.SignupRequest; import coffeemeet.server.user.dto.UserProfileResponse; import coffeemeet.server.user.repository.UserRepository; import java.io.File; +import java.util.ArrayList; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -26,11 +34,15 @@ public class UserService { private static final String EXISTED_COMPANY_EMAIL_ERROR = "이미 사용 중인 회사이메일입니다."; private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; + private static final String USER_NOT_REGISTERED_MESSAGE = "해당 아이디(%s)와 로그인 타입(%s)의 유저는 회원가입되지 않았습니다."; + private static final String DEFAULT_IMAGE_URL = "기본 이미지 URL"; private final S3MediaService s3MediaService; + private final InterestService interestService; + private final OAuthService oAuthService; private final UserRepository userRepository; private final InterestRepository interestRepository; - private final InterestService interestService; + private final AuthTokensGenerator authTokensGenerator; @Transactional public void updateBusinessCardUrl(Long userId, String businessCardUrl) { @@ -92,6 +104,34 @@ public void updateProfileInfo(Long userId, String nickname, String name, interestService.updateInterests(userId, interests); } + @Transactional + public AuthTokens signup(SignupRequest request) { + OAuthInfoResponse response = oAuthService.getOAuthInfo(request.oAuthProvider(), + request.authCode()); + + checkDuplicatedUser(response); + checkDuplicatedNickname(request.nickname()); + String profileImage = getProfileImageOrDefault(response.profileImage()); + + User user = new User(new OAuthInfo(response.oAuthProvider(), response.oAuthProviderId()), + Profile.builder().name(response.name()).nickname(request.nickname()).email(response.email()) + .profileImageUrl(profileImage).birth(response.birth()).build()); + + User newUser = userRepository.save(user); + saveInterests(request, newUser); + return authTokensGenerator.generate(newUser.getId()); + } + + public AuthTokens login(OAuthProvider oAuthProvider, String authCode) { + OAuthInfoResponse response = oAuthService.getOAuthInfo(oAuthProvider, authCode); + User foundUser = userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( + response.oAuthProvider(), response.oAuthProviderId()).orElseThrow( + () -> new IllegalArgumentException( + String.format(USER_NOT_REGISTERED_MESSAGE, response.oAuthProviderId(), + response.oAuthProvider()))); + return authTokensGenerator.generate(foundUser.getId()); + } + @Transactional public void deleteUser(Long userId) { interestRepository.deleteById(userId); @@ -111,6 +151,21 @@ public void checkDuplicatedUser(OAuthInfoResponse response) { } } + private String getProfileImageOrDefault(String profileImage) { + if (profileImage == null) { + profileImage = DEFAULT_IMAGE_URL; + } + return profileImage; + } + + private void saveInterests(SignupRequest request, User newUser) { + List interests = new ArrayList<>(); + for (Keyword value : request.keywords()) { + interests.add(new Interest(value, newUser)); + } + interestRepository.saveAll(interests); + } + private User getUserById(Long userId) { return userRepository.findById(userId) .orElseThrow(IllegalArgumentException::new); From 8315491118a9d756ac644ac8b9524f19698a9882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Wed, 25 Oct 2023 23:20:32 +0900 Subject: [PATCH 147/311] =?UTF-8?q?style:=20oauth=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/OAuthMemberClient.java | 4 +-- .../client/OAuthMemberClientComposite.java | 4 +-- .../oauth/controller/OAuthController.java | 30 +++++++++++++++++++ .../dto/OAuthInfoResponse.java | 2 +- .../KakaoAuthCodeRequestUrlProvider.java | 6 ++-- .../kakao/client/KakaoApiClient.java | 8 ++--- .../kakao/client/KakaoMemberClient.java | 10 +++---- .../kakao/config/KakaoConfig.java | 2 +- .../kakao/config/KakaoProperties.java | 2 +- .../kakao/dto/KakaoMemberResponse.java | 4 +-- .../kakao/dto/KakaoTokens.java | 2 +- .../server/oauth/service/OAuthService.java | 26 ++++++++++++++++ .../converter/OAuthProviderConverter.java | 2 +- 13 files changed, 79 insertions(+), 23 deletions(-) rename src/main/java/coffeemeet/server/{auth/domain => oauth}/client/OAuthMemberClient.java (63%) rename src/main/java/coffeemeet/server/{auth/domain => oauth}/client/OAuthMemberClientComposite.java (91%) create mode 100644 src/main/java/coffeemeet/server/oauth/controller/OAuthController.java rename src/main/java/coffeemeet/server/{auth => oauth}/dto/OAuthInfoResponse.java (94%) rename src/main/java/coffeemeet/server/{auth/infrastructure/oauth => oauth/infrastructure}/kakao/authcode/KakaoAuthCodeRequestUrlProvider.java (80%) rename src/main/java/coffeemeet/server/{auth/infrastructure/oauth => oauth/infrastructure}/kakao/client/KakaoApiClient.java (87%) rename src/main/java/coffeemeet/server/{auth/infrastructure/oauth => oauth/infrastructure}/kakao/client/KakaoMemberClient.java (65%) rename src/main/java/coffeemeet/server/{auth/infrastructure/oauth => oauth/infrastructure}/kakao/config/KakaoConfig.java (78%) rename src/main/java/coffeemeet/server/{auth/infrastructure/oauth => oauth/infrastructure}/kakao/config/KakaoProperties.java (84%) rename src/main/java/coffeemeet/server/{auth/infrastructure/oauth => oauth/infrastructure}/kakao/dto/KakaoMemberResponse.java (89%) rename src/main/java/coffeemeet/server/{auth/infrastructure/oauth => oauth/infrastructure}/kakao/dto/KakaoTokens.java (84%) create mode 100644 src/main/java/coffeemeet/server/oauth/service/OAuthService.java rename src/main/java/coffeemeet/server/{auth => oauth}/utils/converter/OAuthProviderConverter.java (88%) diff --git a/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClient.java b/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClient.java similarity index 63% rename from src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClient.java rename to src/main/java/coffeemeet/server/oauth/client/OAuthMemberClient.java index 28c018c0..b9773906 100644 --- a/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClient.java +++ b/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClient.java @@ -1,6 +1,6 @@ -package coffeemeet.server.auth.domain.client; +package coffeemeet.server.oauth.client; -import coffeemeet.server.auth.dto.OAuthInfoResponse; +import coffeemeet.server.oauth.dto.OAuthInfoResponse; import coffeemeet.server.user.domain.OAuthProvider; public interface OAuthMemberClient { diff --git a/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClientComposite.java b/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java similarity index 91% rename from src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClientComposite.java rename to src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java index 5ad41848..6e9cdb38 100644 --- a/src/main/java/coffeemeet/server/auth/domain/client/OAuthMemberClientComposite.java +++ b/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java @@ -1,6 +1,6 @@ -package coffeemeet.server.auth.domain.client; +package coffeemeet.server.oauth.client; -import coffeemeet.server.auth.dto.OAuthInfoResponse; +import coffeemeet.server.oauth.dto.OAuthInfoResponse; import coffeemeet.server.user.domain.OAuthProvider; import java.util.Map; import java.util.Optional; diff --git a/src/main/java/coffeemeet/server/oauth/controller/OAuthController.java b/src/main/java/coffeemeet/server/oauth/controller/OAuthController.java new file mode 100644 index 00000000..f4594705 --- /dev/null +++ b/src/main/java/coffeemeet/server/oauth/controller/OAuthController.java @@ -0,0 +1,30 @@ +package coffeemeet.server.oauth.controller; + +import coffeemeet.server.oauth.service.OAuthService; +import coffeemeet.server.user.domain.OAuthProvider; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/oauth2") +public class OAuthController { + + private final OAuthService oAuthService; + + @GetMapping("/{oAuthProvider}") + public ResponseEntity redirectAuthCodeRequestUrl(@PathVariable OAuthProvider oAuthProvider, + HttpServletResponse response) throws IOException { + String redirectUrl = oAuthService.getAuthCodeRequestUrl(oAuthProvider); + response.sendRedirect(redirectUrl); + return new ResponseEntity<>(HttpStatus.FOUND); + } + +} diff --git a/src/main/java/coffeemeet/server/auth/dto/OAuthInfoResponse.java b/src/main/java/coffeemeet/server/oauth/dto/OAuthInfoResponse.java similarity index 94% rename from src/main/java/coffeemeet/server/auth/dto/OAuthInfoResponse.java rename to src/main/java/coffeemeet/server/oauth/dto/OAuthInfoResponse.java index 679bde6e..ec974b6d 100644 --- a/src/main/java/coffeemeet/server/auth/dto/OAuthInfoResponse.java +++ b/src/main/java/coffeemeet/server/oauth/dto/OAuthInfoResponse.java @@ -1,4 +1,4 @@ -package coffeemeet.server.auth.dto; +package coffeemeet.server.oauth.dto; import coffeemeet.server.user.domain.Birth; import coffeemeet.server.user.domain.Email; diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/authcode/KakaoAuthCodeRequestUrlProvider.java b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/authcode/KakaoAuthCodeRequestUrlProvider.java similarity index 80% rename from src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/authcode/KakaoAuthCodeRequestUrlProvider.java rename to src/main/java/coffeemeet/server/oauth/infrastructure/kakao/authcode/KakaoAuthCodeRequestUrlProvider.java index 29121844..19c563e3 100644 --- a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/authcode/KakaoAuthCodeRequestUrlProvider.java +++ b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/authcode/KakaoAuthCodeRequestUrlProvider.java @@ -1,7 +1,7 @@ -package coffeemeet.server.auth.infrastructure.oauth.kakao.authcode; +package coffeemeet.server.oauth.infrastructure.kakao.authcode; -import coffeemeet.server.auth.domain.authcode.AuthCodeRequestUrlProvider; -import coffeemeet.server.auth.infrastructure.oauth.kakao.config.KakaoProperties; +import coffeemeet.server.oauth.authcode.AuthCodeRequestUrlProvider; +import coffeemeet.server.oauth.infrastructure.kakao.config.KakaoProperties; import coffeemeet.server.user.domain.OAuthProvider; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoApiClient.java b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoApiClient.java similarity index 87% rename from src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoApiClient.java rename to src/main/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoApiClient.java index a1440505..d0b3bd97 100644 --- a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoApiClient.java +++ b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoApiClient.java @@ -1,8 +1,8 @@ -package coffeemeet.server.auth.infrastructure.oauth.kakao.client; +package coffeemeet.server.oauth.infrastructure.kakao.client; -import coffeemeet.server.auth.infrastructure.oauth.kakao.config.KakaoProperties; -import coffeemeet.server.auth.infrastructure.oauth.kakao.dto.KakaoMemberResponse; -import coffeemeet.server.auth.infrastructure.oauth.kakao.dto.KakaoTokens; +import coffeemeet.server.oauth.infrastructure.kakao.config.KakaoProperties; +import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoMemberResponse; +import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoTokens; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoMemberClient.java b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClient.java similarity index 65% rename from src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoMemberClient.java rename to src/main/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClient.java index 8771e9bc..b0c13acc 100644 --- a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/client/KakaoMemberClient.java +++ b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClient.java @@ -1,9 +1,9 @@ -package coffeemeet.server.auth.infrastructure.oauth.kakao.client; +package coffeemeet.server.oauth.infrastructure.kakao.client; -import coffeemeet.server.auth.domain.client.OAuthMemberClient; -import coffeemeet.server.auth.dto.OAuthInfoResponse; -import coffeemeet.server.auth.infrastructure.oauth.kakao.dto.KakaoMemberResponse; -import coffeemeet.server.auth.infrastructure.oauth.kakao.dto.KakaoTokens; +import coffeemeet.server.oauth.client.OAuthMemberClient; +import coffeemeet.server.oauth.dto.OAuthInfoResponse; +import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoMemberResponse; +import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoTokens; import coffeemeet.server.user.domain.OAuthProvider; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/config/KakaoConfig.java b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/config/KakaoConfig.java similarity index 78% rename from src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/config/KakaoConfig.java rename to src/main/java/coffeemeet/server/oauth/infrastructure/kakao/config/KakaoConfig.java index 27524a2e..13f71437 100644 --- a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/config/KakaoConfig.java +++ b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/config/KakaoConfig.java @@ -1,4 +1,4 @@ -package coffeemeet.server.auth.infrastructure.oauth.kakao.config; +package coffeemeet.server.oauth.infrastructure.kakao.config; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/config/KakaoProperties.java b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/config/KakaoProperties.java similarity index 84% rename from src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/config/KakaoProperties.java rename to src/main/java/coffeemeet/server/oauth/infrastructure/kakao/config/KakaoProperties.java index 7f148f8b..bcce7b4e 100644 --- a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/config/KakaoProperties.java +++ b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/config/KakaoProperties.java @@ -1,4 +1,4 @@ -package coffeemeet.server.auth.infrastructure.oauth.kakao.config; +package coffeemeet.server.oauth.infrastructure.kakao.config; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoMemberResponse.java b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberResponse.java similarity index 89% rename from src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoMemberResponse.java rename to src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberResponse.java index 295da79e..29c66aa5 100644 --- a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoMemberResponse.java +++ b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberResponse.java @@ -1,6 +1,6 @@ -package coffeemeet.server.auth.infrastructure.oauth.kakao.dto; +package coffeemeet.server.oauth.infrastructure.kakao.dto; -import coffeemeet.server.auth.dto.OAuthInfoResponse; +import coffeemeet.server.oauth.dto.OAuthInfoResponse; import coffeemeet.server.user.domain.Birth; import coffeemeet.server.user.domain.Email; import coffeemeet.server.user.domain.OAuthProvider; diff --git a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoTokens.java b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoTokens.java similarity index 84% rename from src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoTokens.java rename to src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoTokens.java index 84404093..b41c22bc 100644 --- a/src/main/java/coffeemeet/server/auth/infrastructure/oauth/kakao/dto/KakaoTokens.java +++ b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoTokens.java @@ -1,4 +1,4 @@ -package coffeemeet.server.auth.infrastructure.oauth.kakao.dto; +package coffeemeet.server.oauth.infrastructure.kakao.dto; import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; import com.fasterxml.jackson.databind.annotation.JsonNaming; diff --git a/src/main/java/coffeemeet/server/oauth/service/OAuthService.java b/src/main/java/coffeemeet/server/oauth/service/OAuthService.java new file mode 100644 index 00000000..f0148f76 --- /dev/null +++ b/src/main/java/coffeemeet/server/oauth/service/OAuthService.java @@ -0,0 +1,26 @@ +package coffeemeet.server.oauth.service; + +import coffeemeet.server.oauth.authcode.AuthCodeRequestUrlProviderComposite; +import coffeemeet.server.oauth.client.OAuthMemberClientComposite; +import coffeemeet.server.oauth.dto.OAuthInfoResponse; +import coffeemeet.server.user.domain.OAuthProvider; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class OAuthService { + + private final AuthCodeRequestUrlProviderComposite authCodeRequestUrlProviderComposite; + private final OAuthMemberClientComposite oauthMemberClientComposite; + + public String getAuthCodeRequestUrl(OAuthProvider oAuthProvider) { + return authCodeRequestUrlProviderComposite.provide(oAuthProvider); + } + + public OAuthInfoResponse getOAuthInfo(OAuthProvider oAuthProvider, String authCode) { + return oauthMemberClientComposite.fetch(oAuthProvider, + authCode); + } + +} diff --git a/src/main/java/coffeemeet/server/auth/utils/converter/OAuthProviderConverter.java b/src/main/java/coffeemeet/server/oauth/utils/converter/OAuthProviderConverter.java similarity index 88% rename from src/main/java/coffeemeet/server/auth/utils/converter/OAuthProviderConverter.java rename to src/main/java/coffeemeet/server/oauth/utils/converter/OAuthProviderConverter.java index c828aad1..993c6925 100644 --- a/src/main/java/coffeemeet/server/auth/utils/converter/OAuthProviderConverter.java +++ b/src/main/java/coffeemeet/server/oauth/utils/converter/OAuthProviderConverter.java @@ -1,4 +1,4 @@ -package coffeemeet.server.auth.utils.converter; +package coffeemeet.server.oauth.utils.converter; import coffeemeet.server.user.domain.OAuthProvider; import jakarta.validation.constraints.NotNull; From 2ba8627512e91dc2afa63d8fb9f43df63cd15c1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Wed, 25 Oct 2023 23:41:34 +0900 Subject: [PATCH 148/311] =?UTF-8?q?refactor:=20=EB=B3=80=EA=B2=BD=EB=90=9C?= =?UTF-8?q?=20=EA=B5=AC=EC=A1=B0=EC=97=90=20=EB=A7=9E=EC=B6=B0=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/auth/controller/AuthControllerTest.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java b/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java index 0a539001..e9d69208 100644 --- a/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java +++ b/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java @@ -14,8 +14,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import coffeemeet.server.auth.service.AuthService; import coffeemeet.server.common.config.ControllerTestConfig; +import coffeemeet.server.oauth.controller.OAuthController; +import coffeemeet.server.oauth.service.OAuthService; import coffeemeet.server.user.domain.OAuthProvider; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -23,21 +24,21 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; -@WebMvcTest(AuthController.class) -class AuthControllerTest extends ControllerTestConfig { +@WebMvcTest(OAuthController.class) +class OAuthControllerTest extends ControllerTestConfig { @MockBean - private AuthService authService; + private OAuthService oAuthService; @DisplayName("사용자가 로그인 버튼을 누르면 해당하는 서비스의 접근 권한 url로 리다이렉트한다.") @Test void redirectAuthCodeRequestUrlTest() throws Exception { String expectedRedirectUrl = "https://example.com"; - when(authService.getAuthCodeRequestUrl(OAuthProvider.KAKAO)).thenReturn( + when(oAuthService.getAuthCodeRequestUrl(OAuthProvider.KAKAO)).thenReturn( expectedRedirectUrl); - mockMvc.perform(get("/oauth2/auth/{oAuthProvider}", OAuthProvider.KAKAO) + mockMvc.perform(get("/oauth2/{oAuthProvider}", OAuthProvider.KAKAO) .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON) ) From 8162eb4316292968e807c4ca252da069091b0dc2 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 03:44:37 +0900 Subject: [PATCH 149/311] =?UTF-8?q?refactor:=20User=20=EB=82=B4=EB=B6=80?= =?UTF-8?q?=20=EC=BB=AC=EB=9F=BC=EC=9C=BC=EB=A1=9C=20=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=ED=96=88=EB=8D=98=20=EC=9D=B8=EC=A6=9D=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EC=B6=94=EC=B6=9C=ED=95=B4=EC=84=9C=20Certification=20Table=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../certification/domain/Certification.java | 61 +++++++++++++++++++ .../domain/CompanyEmail.java | 15 +++-- .../certification/domain/Department.java | 5 ++ .../server/user/domain/Certification.java | 54 ---------------- .../coffeemeet/server/user/domain/User.java | 12 ---- 5 files changed, 75 insertions(+), 72 deletions(-) create mode 100644 src/main/java/coffeemeet/server/certification/domain/Certification.java rename src/main/java/coffeemeet/server/{user => certification}/domain/CompanyEmail.java (57%) create mode 100644 src/main/java/coffeemeet/server/certification/domain/Department.java delete mode 100644 src/main/java/coffeemeet/server/user/domain/Certification.java diff --git a/src/main/java/coffeemeet/server/certification/domain/Certification.java b/src/main/java/coffeemeet/server/certification/domain/Certification.java new file mode 100644 index 00000000..c07e0ee2 --- /dev/null +++ b/src/main/java/coffeemeet/server/certification/domain/Certification.java @@ -0,0 +1,61 @@ +package coffeemeet.server.certification.domain; + +import coffeemeet.server.common.entity.AdvancedBaseEntity; +import coffeemeet.server.user.domain.User; +import jakarta.persistence.Column; +import jakarta.persistence.Embedded; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.NonNull; + +@Entity +@Getter +@Table(name = "certifications") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Certification extends AdvancedBaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Embedded + @Column(nullable = false) + private CompanyEmail companyEmail; + + @Column(nullable = false) + private String businessCardUrl; + + @Enumerated(EnumType.STRING) + private Department department; + + @Column(nullable = false) + private boolean isCertificated; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", unique = true) + private User user; + + @Builder + private Certification( + @NonNull CompanyEmail companyEmail, @NonNull String businessCardUrl, + @NonNull Department department, @NonNull User user) { + this.companyEmail = companyEmail; + this.businessCardUrl = businessCardUrl; + this.department = department; + this.isCertificated = false; + this.user = user; + } + +} diff --git a/src/main/java/coffeemeet/server/user/domain/CompanyEmail.java b/src/main/java/coffeemeet/server/certification/domain/CompanyEmail.java similarity index 57% rename from src/main/java/coffeemeet/server/user/domain/CompanyEmail.java rename to src/main/java/coffeemeet/server/certification/domain/CompanyEmail.java index a9522bfe..f6567fc7 100644 --- a/src/main/java/coffeemeet/server/user/domain/CompanyEmail.java +++ b/src/main/java/coffeemeet/server/certification/domain/CompanyEmail.java @@ -1,20 +1,23 @@ -package coffeemeet.server.user.domain; +package coffeemeet.server.certification.domain; import coffeemeet.server.common.util.Patterns; +import jakarta.persistence.Column; import jakarta.persistence.Embeddable; +import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; @Getter @Embeddable -@NoArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class CompanyEmail { - private String companyEmail; + @Column(name = "company_email") + private String value; - public CompanyEmail(String companyEmail) { - validateCompanyEmail(companyEmail); - this.companyEmail = companyEmail; + public CompanyEmail(String value) { + validateCompanyEmail(value); + this.value = value; } private void validateCompanyEmail(String companyEmail) { diff --git a/src/main/java/coffeemeet/server/certification/domain/Department.java b/src/main/java/coffeemeet/server/certification/domain/Department.java new file mode 100644 index 00000000..36b886ae --- /dev/null +++ b/src/main/java/coffeemeet/server/certification/domain/Department.java @@ -0,0 +1,5 @@ +package coffeemeet.server.certification.domain; + +public enum Department { + IT, MANAGEMENT, SALES, DISTRIBUTION, DESIGN, MANUFACTURING, RESEARCH_AND_DEVELOPMENT, MARKETING, PLANNING +} diff --git a/src/main/java/coffeemeet/server/user/domain/Certification.java b/src/main/java/coffeemeet/server/user/domain/Certification.java deleted file mode 100644 index 0fe8be55..00000000 --- a/src/main/java/coffeemeet/server/user/domain/Certification.java +++ /dev/null @@ -1,54 +0,0 @@ -package coffeemeet.server.user.domain; - -import jakarta.persistence.Column; -import jakarta.persistence.Embeddable; -import jakarta.persistence.Embedded; -import lombok.Getter; - -@Getter -@Embeddable -public class Certification { - - private static final String DEFAULT_EMAIL = "default@default.com"; - private static final String DEFAULT = "default"; - - @Embedded - @Column(nullable = false) - private CompanyEmail companyEmail; - - @Column(nullable = false) - private String businessCardUrl; - - @Column(nullable = false) - private boolean isCertificated; - - @Column(nullable = false) - private String department; - - public Certification() { - this.companyEmail = new CompanyEmail(DEFAULT_EMAIL); - this.businessCardUrl = DEFAULT; - this.department = DEFAULT; - isCertificated = false; - } - - public void updateBusinessCardUrl(String newBusinessCardUrl) { - validateBusinessCardUrl(newBusinessCardUrl); - this.businessCardUrl = newBusinessCardUrl; - } - - private void validateBusinessCardUrl(String businessCardUrl) { - if (businessCardUrl == null) { - throw new IllegalArgumentException("잘못된 명함 URL입니다."); - } - } - - public void updateCompanyEmail(CompanyEmail newCompanyEmail) { - this.companyEmail = newCompanyEmail; - } - - public void certificate() { - isCertificated = true; - } - -} diff --git a/src/main/java/coffeemeet/server/user/domain/User.java b/src/main/java/coffeemeet/server/user/domain/User.java index f6928142..fa49d42d 100644 --- a/src/main/java/coffeemeet/server/user/domain/User.java +++ b/src/main/java/coffeemeet/server/user/domain/User.java @@ -39,9 +39,6 @@ public class User extends AdvancedBaseEntity { @JoinColumn(name = "chatting_room_id") private ChattingRoom chattingRoom; - @Embedded - private Certification certification; - @Embedded @Column(nullable = false) private ReportInfo reportInfo; @@ -55,19 +52,10 @@ public User( ) { this.oauthInfo = oauthInfo; this.profile = profile; - this.certification = new Certification(); this.reportInfo = new ReportInfo(); this.isDeleted = false; } - public void updateBusinessCardUrl(String newBusinessCardUrl) { - this.certification.updateBusinessCardUrl(newBusinessCardUrl); - } - - public void updateCompanyEmail(CompanyEmail newCompanyEmail) { - this.certification.updateCompanyEmail(newCompanyEmail); - } - public void updateProfileImageUrl(String newProfileImageUrl) { this.profile.updateProfileImageUrl(newProfileImageUrl); } From 7d72ae379e58d97750eb70e94f62e19f7a8fdefc Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 03:45:37 +0900 Subject: [PATCH 150/311] =?UTF-8?q?feat:=20CertificationRepository=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/CertificationRepository.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/main/java/coffeemeet/server/certification/repository/CertificationRepository.java diff --git a/src/main/java/coffeemeet/server/certification/repository/CertificationRepository.java b/src/main/java/coffeemeet/server/certification/repository/CertificationRepository.java new file mode 100644 index 00000000..22fc0c07 --- /dev/null +++ b/src/main/java/coffeemeet/server/certification/repository/CertificationRepository.java @@ -0,0 +1,16 @@ +package coffeemeet.server.certification.repository; + +import coffeemeet.server.certification.domain.Certification; +import coffeemeet.server.certification.domain.CompanyEmail; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CertificationRepository extends JpaRepository { + + Optional findByUserId(Long userId); + + boolean existsByCompanyEmail(CompanyEmail companyEmail); + + boolean existsByUserId(Long userId); + +} From 123c43b4ae960058b71b98e85f26f9fa8d6c1293 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 03:45:58 +0900 Subject: [PATCH 151/311] =?UTF-8?q?test:=20CertificationRepository=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CertificationRepositoryTest.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/test/java/coffeemeet/server/certification/repository/CertificationRepositoryTest.java diff --git a/src/test/java/coffeemeet/server/certification/repository/CertificationRepositoryTest.java b/src/test/java/coffeemeet/server/certification/repository/CertificationRepositoryTest.java new file mode 100644 index 00000000..599594c0 --- /dev/null +++ b/src/test/java/coffeemeet/server/certification/repository/CertificationRepositoryTest.java @@ -0,0 +1,50 @@ +package coffeemeet.server.certification.repository; + +import static coffeemeet.server.common.fixture.entity.CertificationFixture.certification; +import static coffeemeet.server.common.fixture.entity.UserFixture.user; +import static org.assertj.core.api.Assertions.assertThat; + +import coffeemeet.server.certification.domain.Certification; +import coffeemeet.server.user.domain.User; +import coffeemeet.server.user.repository.UserRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +class CertificationRepositoryTest { + + @Autowired + private CertificationRepository certificationRepository; + @Autowired + private UserRepository userRepository; + private User user; + + + @BeforeEach + void setUp() { + user = userRepository.save(user()); + } + + @Test + void findCertificationByUserIdTest() { + // given + Certification certification = certification(user); + certificationRepository.save(certification); + + // when, then + assertThat(certificationRepository.findByUserId(user.getId())).isPresent(); + } + + @Test + void existsByCompanyEmailTest() { + // given + Certification certification = certification(user); + certificationRepository.save(certification); + // when, then + assertThat( + certificationRepository.existsByCompanyEmail(certification.getCompanyEmail())).isTrue(); + } + +} From c59ae59e59629c32e8ed44ac783e44920f706786 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 03:46:27 +0900 Subject: [PATCH 152/311] =?UTF-8?q?test:=20Certification=20=ED=94=BD?= =?UTF-8?q?=EC=8A=A4=EC=B2=98=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fixture/entity/CertificationFixture.java | 31 +++++++++++++++++++ .../common/fixture/entity/UserFixture.java | 20 ++---------- 2 files changed, 34 insertions(+), 17 deletions(-) create mode 100644 src/test/java/coffeemeet/server/common/fixture/entity/CertificationFixture.java diff --git a/src/test/java/coffeemeet/server/common/fixture/entity/CertificationFixture.java b/src/test/java/coffeemeet/server/common/fixture/entity/CertificationFixture.java new file mode 100644 index 00000000..526d2e58 --- /dev/null +++ b/src/test/java/coffeemeet/server/common/fixture/entity/CertificationFixture.java @@ -0,0 +1,31 @@ +package coffeemeet.server.common.fixture.entity; + +import static org.instancio.Select.field; + +import coffeemeet.server.certification.domain.Certification; +import coffeemeet.server.certification.domain.CompanyEmail; +import coffeemeet.server.user.domain.User; +import org.instancio.Instancio; + +public class CertificationFixture { + + public static Certification certification() { + return Instancio.of(Certification.class) + .set(field(Certification::getCompanyEmail), companyEmail()) + .create(); + } + + public static Certification certification(User user) { + return Instancio.of(Certification.class) + .set(field(Certification::getCompanyEmail), companyEmail()) + .set(field(Certification::getUser), user) + .create(); + } + + private static CompanyEmail companyEmail() { + return Instancio.of(CompanyEmail.class) + .generate(field(CompanyEmail::getValue), gen -> gen.net().email()) + .create(); + } + +} diff --git a/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java b/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java index 868b1ae1..57b19be5 100644 --- a/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java @@ -3,8 +3,6 @@ import static org.instancio.Select.field; import coffeemeet.server.user.domain.Birth; -import coffeemeet.server.user.domain.Certification; -import coffeemeet.server.user.domain.CompanyEmail; import coffeemeet.server.user.domain.Email; import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; @@ -15,15 +13,15 @@ public class UserFixture { public static User user() { return Instancio.of(User.class) .set(field(User::getProfile), profile()) - .set(field(User::getCertification), certification()) .ignore(field(User::isDeleted)) + .ignore(field(User::getChattingRoom)) .create(); } private static Birth birth() { return Instancio.of(Birth.class) - .generate(field(Birth::getBirthYear), gen -> gen.ints().range(1000, 9999)) - .generate(field(Birth::getBirthDay), gen -> gen.ints().range(1000, 9999)) + .generate(field(Birth::getBirthYear), gen -> gen.ints().range(1000, 9999).asString()) + .generate(field(Birth::getBirthDay), gen -> gen.ints().range(1000, 9999).asString()) .create(); } @@ -35,22 +33,10 @@ private static Profile profile() { .create(); } - private static Certification certification() { - return Instancio.of(Certification.class) - .set(field(Certification::getCompanyEmail), companyEmail()) - .create(); - } - private static Email email() { return Instancio.of(Email.class) .generate(field(Email::getEmail), gen -> gen.net().email()) .create(); } - private static CompanyEmail companyEmail() { - return Instancio.of(CompanyEmail.class) - .generate(field(CompanyEmail::getCompanyEmail), gen -> gen.net().email()) - .create(); - } - } From 3c1e630729c94e1974abae61d576f9bc67651561 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 03:47:06 +0900 Subject: [PATCH 153/311] =?UTF-8?q?refactor:=20final=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/common/media/S3MediaService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/common/media/S3MediaService.java b/src/main/java/coffeemeet/server/common/media/S3MediaService.java index 8ed1bad1..cda107da 100644 --- a/src/main/java/coffeemeet/server/common/media/S3MediaService.java +++ b/src/main/java/coffeemeet/server/common/media/S3MediaService.java @@ -53,7 +53,7 @@ public enum KeyType { PROFILE_IMAGE("ProfileImage"), ; - private String value; + private final String value; KeyType(String value) { this.value = value; From 505a0e16a0d8dba7eef25bde1b36c1f971e7cb70 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 03:48:04 +0900 Subject: [PATCH 154/311] =?UTF-8?q?refactor:=20import=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/certification/domain/EmailVerification.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/certification/domain/EmailVerification.java b/src/main/java/coffeemeet/server/certification/domain/EmailVerification.java index f41c6c3e..d68d7e29 100644 --- a/src/main/java/coffeemeet/server/certification/domain/EmailVerification.java +++ b/src/main/java/coffeemeet/server/certification/domain/EmailVerification.java @@ -1,6 +1,5 @@ package coffeemeet.server.certification.domain; -import coffeemeet.server.user.domain.CompanyEmail; import java.time.LocalDateTime; import lombok.Getter; import org.springframework.data.annotation.Id; From d07e2b6cdc2f3a9cffe9929e155eeab646be03b4 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 03:48:48 +0900 Subject: [PATCH 155/311] =?UTF-8?q?refactor:=20=EB=B3=80=EA=B2=BD=EB=90=9C?= =?UTF-8?q?=20=ED=95=84=EB=93=9C=EB=AA=85=EC=9C=BC=EB=A1=9C=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/common/media/EmailService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/common/media/EmailService.java b/src/main/java/coffeemeet/server/common/media/EmailService.java index 3542a28f..35b0f13b 100644 --- a/src/main/java/coffeemeet/server/common/media/EmailService.java +++ b/src/main/java/coffeemeet/server/common/media/EmailService.java @@ -1,6 +1,6 @@ package coffeemeet.server.common.media; -import coffeemeet.server.user.domain.CompanyEmail; +import coffeemeet.server.certification.domain.CompanyEmail; import org.springframework.beans.factory.annotation.Value; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; @@ -21,7 +21,7 @@ public EmailService(JavaMailSender javaMailSender, public void sendVerificationCode(CompanyEmail companyMail, String verificationCode) { SimpleMailMessage mailMessage = new SimpleMailMessage(); mailMessage.setFrom(sender); - mailMessage.setTo(companyMail.getCompanyEmail()); + mailMessage.setTo(companyMail.getValue()); String subject = "[coffee-meet] 커피밋 사용을 위해 이메일 인증을 완료해주세요"; mailMessage.setSubject(subject); From efdcc230ab84343f2f80f64710d90cfba7e80f49 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 03:51:58 +0900 Subject: [PATCH 156/311] =?UTF-8?q?refactor:=20table=20=EB=B6=84=EB=A6=AC?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=ED=95=B4=20=EC=97=B0=EA=B4=80=20=EC=97=86?= =?UTF-8?q?=EC=96=B4=EC=A7=84=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/user/repository/UserRepository.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/repository/UserRepository.java b/src/main/java/coffeemeet/server/user/repository/UserRepository.java index dd44536c..6434d2fa 100644 --- a/src/main/java/coffeemeet/server/user/repository/UserRepository.java +++ b/src/main/java/coffeemeet/server/user/repository/UserRepository.java @@ -1,6 +1,5 @@ package coffeemeet.server.user.repository; -import coffeemeet.server.user.domain.CompanyEmail; import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.User; import java.util.Optional; @@ -18,6 +17,4 @@ Optional getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( Optional findUserByProfileNickname(String nickname); - boolean existsByCertification_CompanyEmail(CompanyEmail companyEmail); - } From 58c74b18a81ef3a9bcf256bc07288cfcfacb0c57 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 04:08:51 +0900 Subject: [PATCH 157/311] =?UTF-8?q?refactor:=20table=20=EB=B6=84=EB=A6=AC?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20response=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/user/dto/MyProfileResponse.java | 9 ++++----- .../coffeemeet/server/user/dto/UserProfileResponse.java | 8 +++++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java b/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java index 05318718..69db6d31 100644 --- a/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java +++ b/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java @@ -1,5 +1,6 @@ package coffeemeet.server.user.dto; +import coffeemeet.server.certification.domain.Department; import coffeemeet.server.interest.domain.Interest; import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.user.domain.User; @@ -15,12 +16,11 @@ public record MyProfileResponse( String birthDay, int reportedCount, LocalDateTime sanctionPeriod, - String companyEmail, - String department, + Department department, List interests ) { - public static MyProfileResponse of(User user, List interests) { + public static MyProfileResponse of(User user, List interests, Department department) { List keywords = interests.stream() .map(Interest::getKeyword) .toList(); @@ -34,8 +34,7 @@ public static MyProfileResponse of(User user, List interests) { user.getProfile().getBirth().getBirthDay(), user.getReportInfo().getReportedCount(), user.getReportInfo().getSanctionPeriod(), - user.getCertification().getCompanyEmail().getCompanyEmail(), - user.getCertification().getDepartment(), + department, keywords ); } diff --git a/src/main/java/coffeemeet/server/user/dto/UserProfileResponse.java b/src/main/java/coffeemeet/server/user/dto/UserProfileResponse.java index cc396249..0874366b 100644 --- a/src/main/java/coffeemeet/server/user/dto/UserProfileResponse.java +++ b/src/main/java/coffeemeet/server/user/dto/UserProfileResponse.java @@ -1,5 +1,6 @@ package coffeemeet.server.user.dto; +import coffeemeet.server.certification.domain.Department; import coffeemeet.server.interest.domain.Interest; import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.user.domain.User; @@ -8,11 +9,12 @@ public record UserProfileResponse( String nickname, String profileImageUrl, - String department, + Department department, List interests ) { - public static UserProfileResponse of(User user, List interests) { + public static UserProfileResponse of(User user, Department department, + List interests) { List keywords = interests.stream() .map(Interest::getKeyword) .toList(); @@ -20,7 +22,7 @@ public static UserProfileResponse of(User user, List interests) { return new UserProfileResponse( user.getProfile().getNickname(), user.getProfile().getProfileImageUrl(), - user.getCertification().getDepartment(), + department, keywords ); } From 1a85025d27af45ded224ca4752e21c3e45ed085a Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 04:11:16 +0900 Subject: [PATCH 158/311] =?UTF-8?q?refactor:=20=EC=88=9C=ED=99=98=EC=B0=B8?= =?UTF-8?q?=EC=A1=B0=EA=B0=80=20=EB=B0=9C=EC=83=9D=ED=95=B4=EC=84=9C=20Ser?= =?UTF-8?q?vice=EC=99=80=20Repository=20=EC=82=AC=EC=9D=B4=20Repository=20?= =?UTF-8?q?=EA=B0=80=EA=B3=B5=20Layer=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/cq/CertificationCommand.java | 36 +++++++++++++++++++ .../service/cq/CertificationQuery.java | 32 +++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java create mode 100644 src/main/java/coffeemeet/server/certification/service/cq/CertificationQuery.java diff --git a/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java b/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java new file mode 100644 index 00000000..76725505 --- /dev/null +++ b/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java @@ -0,0 +1,36 @@ +package coffeemeet.server.certification.service.cq; + +import coffeemeet.server.certification.domain.Certification; +import coffeemeet.server.certification.domain.CompanyEmail; +import coffeemeet.server.certification.domain.Department; +import coffeemeet.server.certification.repository.CertificationRepository; +import coffeemeet.server.user.domain.User; +import java.util.function.Consumer; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Transactional +@RequiredArgsConstructor +@Service +public class CertificationCommand { + + private final CertificationRepository certificationRepository; + + public void newCertification(CompanyEmail companyEmail, String businessCardUrl, + Department department, User user) { + certificationRepository.save( + Certification.builder() + .companyEmail(companyEmail) + .businessCardUrl(businessCardUrl) + .department(department) + .user(user) + .build() + ); + } + + public void applyIfCertifiedUser(Long userId, Consumer consumer) { + certificationRepository.findByUserId(userId).ifPresent(consumer); + } + +} diff --git a/src/main/java/coffeemeet/server/certification/service/cq/CertificationQuery.java b/src/main/java/coffeemeet/server/certification/service/cq/CertificationQuery.java new file mode 100644 index 00000000..fcf4cf4f --- /dev/null +++ b/src/main/java/coffeemeet/server/certification/service/cq/CertificationQuery.java @@ -0,0 +1,32 @@ +package coffeemeet.server.certification.service.cq; + +import coffeemeet.server.certification.domain.Certification; +import coffeemeet.server.certification.domain.CompanyEmail; +import coffeemeet.server.certification.repository.CertificationRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Transactional(readOnly = true) +@RequiredArgsConstructor +@Service +public class CertificationQuery { + + public static final String CERTIFICATION_NOT_FOUND = "해당 사용자의 인증정보를 찾을 수 없습니다."; + private static final String EXISTED_COMPANY_EMAIL = "이미 사용 중인 회사 이메일입니다."; + + private final CertificationRepository certificationRepository; + + public Certification getCertificationByUserId(Long userId) { + return certificationRepository.findByUserId(userId) + .orElseThrow(() -> new IllegalArgumentException(CERTIFICATION_NOT_FOUND)); + } + + public void checkDuplicatedCompanyEmail(CompanyEmail companyEmail) { + if (certificationRepository.existsByCompanyEmail(companyEmail)) { + throw new IllegalArgumentException(EXISTED_COMPANY_EMAIL); + } + } + + +} From c135bf82e1a2872ef173b9fbd02e8d655a95ed96 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 04:11:57 +0900 Subject: [PATCH 159/311] =?UTF-8?q?refactor:=20PK=EC=99=80=20FK(user=5Fid)?= =?UTF-8?q?=20=EB=8F=99=EC=9D=BC=ED=95=98=EA=B2=8C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/certification/domain/Certification.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/domain/Certification.java b/src/main/java/coffeemeet/server/certification/domain/Certification.java index c07e0ee2..ad404ddc 100644 --- a/src/main/java/coffeemeet/server/certification/domain/Certification.java +++ b/src/main/java/coffeemeet/server/certification/domain/Certification.java @@ -8,10 +8,8 @@ import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; +import jakarta.persistence.MapsId; import jakarta.persistence.OneToOne; import jakarta.persistence.Table; import lombok.AccessLevel; @@ -27,9 +25,12 @@ public class Certification extends AdvancedBaseEntity { @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @MapsId + @OneToOne(fetch = FetchType.LAZY) + private User user; + @Embedded @Column(nullable = false) private CompanyEmail companyEmail; @@ -43,10 +44,6 @@ public class Certification extends AdvancedBaseEntity { @Column(nullable = false) private boolean isCertificated; - @OneToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "user_id", unique = true) - private User user; - @Builder private Certification( @NonNull CompanyEmail companyEmail, @NonNull String businessCardUrl, From 640988995a3be98a99832cd0c7b287cb72d43239 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 04:12:28 +0900 Subject: [PATCH 160/311] =?UTF-8?q?refactor:=20=EB=8B=89=EB=84=A4=EC=9E=84?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C=20->=20=EC=95=84=EC=9D=B4=EB=94=94=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/user/controller/UserController.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index 94573aa4..bc6aa952 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -25,14 +25,14 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/user") +@RequestMapping("/users") public class UserController { private final UserService userService; - @GetMapping("/{nickname}") - public ResponseEntity findUserProfile(@PathVariable String nickname) { - return ResponseEntity.ok(userService.findUserProfile(nickname)); + @GetMapping("/{userId}") + public ResponseEntity findUserProfile(@PathVariable long userId) { + return ResponseEntity.ok(userService.findUserProfile(userId)); } @GetMapping("/me") From ff0caafeccc327b07229f62900b6044a04b3bb11 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 04:13:47 +0900 Subject: [PATCH 161/311] =?UTF-8?q?refactor:=20=EB=8B=A4=EB=A5=B8=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=EC=9D=98=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=20=EC=9D=98=EC=A1=B4=EC=9D=B4=20=EC=95=84=EB=8B=8C=20?= =?UTF-8?q?Repository=20=EA=B0=80=EA=B3=B5=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=EC=9D=98=EC=A1=B4=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CertificationService.java | 57 ++++++++++++------- .../server/user/service/UserService.java | 36 ++++-------- 2 files changed, 49 insertions(+), 44 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java index 2c44c6ae..6d12afc8 100644 --- a/src/main/java/coffeemeet/server/certification/service/CertificationService.java +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -2,63 +2,82 @@ import static coffeemeet.server.common.media.S3MediaService.KeyType.BUSINESS_CARD; +import coffeemeet.server.certification.domain.CompanyEmail; +import coffeemeet.server.certification.domain.Department; import coffeemeet.server.certification.domain.EmailVerification; import coffeemeet.server.certification.repository.VerificationVoRepository; +import coffeemeet.server.certification.service.cq.CertificationCommand; +import coffeemeet.server.certification.service.cq.CertificationQuery; import coffeemeet.server.common.media.EmailService; import coffeemeet.server.common.media.S3MediaService; import coffeemeet.server.common.util.FileUtils; -import coffeemeet.server.user.domain.CompanyEmail; +import coffeemeet.server.user.domain.User; import coffeemeet.server.user.service.UserService; import java.io.File; import java.util.random.RandomGenerator; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor public class CertificationService { - public static final String VERIFICATION_CODE_NOT_FOUND = "인증코드 기간이 만료되었거나 해당 유저가 인증 번호를 요청한 기록이 없습니다."; - public static final String WRONG_VERIFICATION_CODE = "잘못된 인증코드입니다."; + private static final String VERIFICATION_CODE_NOT_FOUND = "인증코드 기간이 만료되었거나 해당 유저가 인증 번호를 요청한 기록이 없습니다."; + private static final String WRONG_VERIFICATION_CODE = "잘못된 인증코드입니다."; private static final RandomGenerator RANDOM_GENERATOR = RandomGenerator.getDefault(); private final S3MediaService s3MediaService; - private final UserService userService; private final EmailService emailService; + private final UserService userService; private final VerificationVoRepository verificationVoRepository; + private final CertificationQuery certificationQuery; + private final CertificationCommand certificationCommand; - public void uploadBusinessCard(long userId, File file) { + @Transactional + public void registerCertification(long userId, String email, String departmentName, + File businessCardImage) { String key = s3MediaService.generateKey(BUSINESS_CARD); - s3MediaService.upload(key, file); - userService.updateBusinessCardUrl(userId, s3MediaService.getUrl(key)); + uploadBusinessCard(userId, key, businessCardImage); - FileUtils.delete(file); + CompanyEmail companyEmail = new CompanyEmail(email); + String businessCardUrl = s3MediaService.getUrl(key); + Department department = Department.valueOf(departmentName); + User user = userService.getUserById(userId); + certificationCommand.newCertification(companyEmail, businessCardUrl, department, user); } + private void uploadBusinessCard(long userId, String key, File businessCardUrl) { + certificationCommand.applyIfCertifiedUser(userId, certification -> { + String oldKey = s3MediaService.extractKey(certification.getBusinessCardUrl(), BUSINESS_CARD); + s3MediaService.delete(oldKey); + }); + + s3MediaService.upload(key, businessCardUrl); + FileUtils.delete(businessCardUrl); + } + + @Transactional public void sendVerificationMail(Long userId, String email) { CompanyEmail companyEmail = new CompanyEmail(email); - userService.validateDuplicatedCompanyEmail(companyEmail); + certificationQuery.checkDuplicatedCompanyEmail(companyEmail); String verificationCode = generateVerificationCode(); emailService.sendVerificationCode(companyEmail, verificationCode); - verificationVoRepository.save( - new EmailVerification(userId, companyEmail, verificationCode)); - } - - private String generateVerificationCode() { - return String.format("%06d", RANDOM_GENERATOR.nextInt(1000000)); + verificationVoRepository.save(new EmailVerification(userId, companyEmail, verificationCode)); } + @Transactional(readOnly = true) public void verifyEmail(Long userId, String verificationCode) { EmailVerification emailVerification = verificationVoRepository.findById(userId) - .orElseThrow( - () -> new IllegalArgumentException(VERIFICATION_CODE_NOT_FOUND)); - + .orElseThrow(() -> new IllegalArgumentException(VERIFICATION_CODE_NOT_FOUND)); if (!emailVerification.getCode().equals(verificationCode)) { throw new IllegalArgumentException(WRONG_VERIFICATION_CODE); } + } - userService.updateCompanyEmail(userId, emailVerification.getCompanyEmail()); + private String generateVerificationCode() { + return String.format("%06d", RANDOM_GENERATOR.nextInt(1000000)); } } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 466508bf..fc255315 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -3,12 +3,13 @@ import static coffeemeet.server.common.media.S3MediaService.KeyType.PROFILE_IMAGE; import coffeemeet.server.auth.dto.OAuthInfoResponse; +import coffeemeet.server.certification.domain.Certification; +import coffeemeet.server.certification.service.cq.CertificationQuery; import coffeemeet.server.common.media.S3MediaService; import coffeemeet.server.interest.domain.Interest; import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.interest.repository.InterestRepository; import coffeemeet.server.interest.service.InterestService; -import coffeemeet.server.user.domain.CompanyEmail; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.dto.MyProfileResponse; import coffeemeet.server.user.dto.UserProfileResponse; @@ -24,44 +25,29 @@ @Transactional(readOnly = true) public class UserService { - private static final String EXISTED_COMPANY_EMAIL_ERROR = "이미 사용 중인 회사이메일입니다."; private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; private final S3MediaService s3MediaService; private final UserRepository userRepository; private final InterestRepository interestRepository; private final InterestService interestService; + private final CertificationQuery certificationQuery; - @Transactional - public void updateBusinessCardUrl(Long userId, String businessCardUrl) { - User user = getUserById(userId); - user.updateBusinessCardUrl(businessCardUrl); - } - - public void validateDuplicatedCompanyEmail(CompanyEmail companyEmail) { - if (userRepository.existsByCertification_CompanyEmail(companyEmail)) { - throw new IllegalArgumentException(EXISTED_COMPANY_EMAIL_ERROR); - } - } - - public UserProfileResponse findUserProfile(String nickname) { - User user = userRepository.findUserByProfileNickname(nickname) + public UserProfileResponse findUserProfile(long userId) { + User user = userRepository.findById(userId) .orElseThrow(() -> new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); + List interests = interestRepository.findAllByUserId(userId); + Certification certification = certificationQuery.getCertificationByUserId(userId); - List interests = interestRepository.findAllByUserId(user.getId()); - return UserProfileResponse.of(user, interests); + return UserProfileResponse.of(user, certification.getDepartment(), interests); } public MyProfileResponse findMyProfile(Long userId) { User user = getUserById(userId); List interests = interestRepository.findAllByUserId(userId); - return MyProfileResponse.of(user, interests); - } + Certification certification = certificationQuery.getCertificationByUserId(userId); - @Transactional - public void updateCompanyEmail(Long userId, CompanyEmail companyEmail) { - User user = getUserById(userId); - user.updateCompanyEmail(companyEmail); + return MyProfileResponse.of(user, interests, certification.getDepartment()); } @Transactional @@ -111,7 +97,7 @@ public void checkDuplicatedUser(OAuthInfoResponse response) { } } - private User getUserById(Long userId) { + public User getUserById(Long userId) { return userRepository.findById(userId) .orElseThrow(IllegalArgumentException::new); } From f80907cfba32d803a3aa59503b3d0feeb675df52 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 04:14:29 +0900 Subject: [PATCH 162/311] =?UTF-8?q?feat:=20=ED=9A=8C=EC=82=AC=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EB=93=B1=EB=A1=9D=20api=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/CertificationController.java | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java index 5c87a263..bb6bfdd8 100644 --- a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java +++ b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java @@ -25,36 +25,30 @@ public class CertificationController { private final CertificationService certificationService; @PostMapping("/users/business-card") - public ResponseEntity uploadBusinessCard( - @Login - AuthInfo authInfo, - @NotNull - @RequestPart("businessCard") - MultipartFile businessCard + public ResponseEntity registerCompanyInfo( + @Login AuthInfo authInfo, + @RequestPart("companyEmail") @NotNull String companyEmail, + @RequestPart("department") @NotNull String department, + @RequestPart("businessCard") @NotNull MultipartFile businessCardImage ) { - certificationService.uploadBusinessCard(authInfo.userId(), - FileUtils.convertMultipartFileToFile(businessCard)); + certificationService.registerCertification(authInfo.userId(), companyEmail, department, + FileUtils.convertMultipartFileToFile(businessCardImage)); return ResponseEntity.ok().build(); } @PostMapping("/users/company-mail") public ResponseEntity sendVerificationCodeByEmail( - @Login - AuthInfo authInfo, - @Valid @RequestBody - EmailDto emailDto + @Login AuthInfo authInfo, + @Valid @RequestBody EmailDto emailDto ) { certificationService.sendVerificationMail(authInfo.userId(), emailDto.companyEmail()); return ResponseEntity.ok().build(); - } @PostMapping("/users/company-mail/verification") public ResponseEntity verifyEmail( - @Login - AuthInfo authInfo, - @Valid @RequestBody - VerificationCodeDto verificationCodeDto + @Login AuthInfo authInfo, + @Valid @RequestBody VerificationCodeDto verificationCodeDto ) { certificationService.verifyEmail(authInfo.userId(), verificationCodeDto.verificationCode()); return ResponseEntity.ok().build(); From 359b2fc04337292151bf4ff526c1df045fe74790 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 04:18:30 +0900 Subject: [PATCH 163/311] =?UTF-8?q?refactor:=20DTO=20=EC=BB=A8=EB=B2=A4?= =?UTF-8?q?=EC=85=98=EC=97=90=20=EB=A7=9E=EA=B2=8C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/CertificationController.java | 8 ++++---- .../server/certification/dto/EmailDto.java | 12 ++++++++---- .../certification/dto/VerificationCodeDto.java | 12 ++++++++---- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java index bb6bfdd8..a6f52509 100644 --- a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java +++ b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java @@ -39,18 +39,18 @@ public ResponseEntity registerCompanyInfo( @PostMapping("/users/company-mail") public ResponseEntity sendVerificationCodeByEmail( @Login AuthInfo authInfo, - @Valid @RequestBody EmailDto emailDto + @Valid @RequestBody EmailDto.Request request ) { - certificationService.sendVerificationMail(authInfo.userId(), emailDto.companyEmail()); + certificationService.sendVerificationMail(authInfo.userId(), request.companyEmail()); return ResponseEntity.ok().build(); } @PostMapping("/users/company-mail/verification") public ResponseEntity verifyEmail( @Login AuthInfo authInfo, - @Valid @RequestBody VerificationCodeDto verificationCodeDto + @Valid @RequestBody VerificationCodeDto.Request request ) { - certificationService.verifyEmail(authInfo.userId(), verificationCodeDto.verificationCode()); + certificationService.verifyEmail(authInfo.userId(), request.verificationCode()); return ResponseEntity.ok().build(); } diff --git a/src/main/java/coffeemeet/server/certification/dto/EmailDto.java b/src/main/java/coffeemeet/server/certification/dto/EmailDto.java index b86752a7..63d9fddc 100644 --- a/src/main/java/coffeemeet/server/certification/dto/EmailDto.java +++ b/src/main/java/coffeemeet/server/certification/dto/EmailDto.java @@ -3,9 +3,13 @@ import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotNull; -public record EmailDto( - @Email @NotNull - String companyEmail -) { +public sealed interface EmailDto permits EmailDto.Request { + + record Request( + @Email @NotNull + String companyEmail + ) implements EmailDto { + + } } diff --git a/src/main/java/coffeemeet/server/certification/dto/VerificationCodeDto.java b/src/main/java/coffeemeet/server/certification/dto/VerificationCodeDto.java index 2e6df7a4..11035e5c 100644 --- a/src/main/java/coffeemeet/server/certification/dto/VerificationCodeDto.java +++ b/src/main/java/coffeemeet/server/certification/dto/VerificationCodeDto.java @@ -3,9 +3,13 @@ import jakarta.validation.constraints.NotNull; import org.hibernate.validator.constraints.Length; -public record VerificationCodeDto( - @NotNull @Length(min = 6, max = 6) - String verificationCode -) { +public sealed interface VerificationCodeDto permits VerificationCodeDto.Request { + + record Request( + @NotNull @Length(min = 6, max = 6) + String verificationCode + ) implements VerificationCodeDto { + + } } From 0c88f42e7f14b10a1ee6ee13e952962940b1b48c Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 05:01:23 +0900 Subject: [PATCH 164/311] =?UTF-8?q?feat:=20repository=20=EA=B0=80=EA=B3=B5?= =?UTF-8?q?=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/cq/EmailVerificationCommand.java | 20 +++++++++++++++++ .../service/cq/EmailVerificationQuery.java | 22 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/main/java/coffeemeet/server/certification/service/cq/EmailVerificationCommand.java create mode 100644 src/main/java/coffeemeet/server/certification/service/cq/EmailVerificationQuery.java diff --git a/src/main/java/coffeemeet/server/certification/service/cq/EmailVerificationCommand.java b/src/main/java/coffeemeet/server/certification/service/cq/EmailVerificationCommand.java new file mode 100644 index 00000000..37323810 --- /dev/null +++ b/src/main/java/coffeemeet/server/certification/service/cq/EmailVerificationCommand.java @@ -0,0 +1,20 @@ +package coffeemeet.server.certification.service.cq; + +import coffeemeet.server.certification.domain.CompanyEmail; +import coffeemeet.server.certification.domain.EmailVerification; +import coffeemeet.server.certification.repository.EmailVerificationRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class EmailVerificationCommand { + + private final EmailVerificationRepository emailVerificationRepository; + + public void newEmailVerification(Long userId, CompanyEmail companyEmail, + String verificationCode) { + emailVerificationRepository.save(new EmailVerification(userId, companyEmail, verificationCode)); + } + +} diff --git a/src/main/java/coffeemeet/server/certification/service/cq/EmailVerificationQuery.java b/src/main/java/coffeemeet/server/certification/service/cq/EmailVerificationQuery.java new file mode 100644 index 00000000..8ac135bf --- /dev/null +++ b/src/main/java/coffeemeet/server/certification/service/cq/EmailVerificationQuery.java @@ -0,0 +1,22 @@ +package coffeemeet.server.certification.service.cq; + +import coffeemeet.server.certification.domain.EmailVerification; +import coffeemeet.server.certification.repository.EmailVerificationRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class EmailVerificationQuery { + + private static final String VERIFICATION_CODE_NOT_FOUND = "인증코드 기간이 만료되었거나 해당 유저가 인증 번호를 요청한 기록이 없습니다."; + + private final EmailVerificationRepository emailVerificationRepository; + + public String getCodeById(Long userId) { + EmailVerification emailVerification = emailVerificationRepository.findById(userId) + .orElseThrow(() -> new IllegalArgumentException(VERIFICATION_CODE_NOT_FOUND)); + return emailVerification.getCode(); + } + +} From d95a4642b7004176f0110eb708ddda1f79f28e1f Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 05:01:44 +0900 Subject: [PATCH 165/311] =?UTF-8?q?refactor:=20class=20=EB=AA=85=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 --- ...cationVoRepository.java => EmailVerificationRepository.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/java/coffeemeet/server/certification/repository/{VerificationVoRepository.java => EmailVerificationRepository.java} (65%) diff --git a/src/main/java/coffeemeet/server/certification/repository/VerificationVoRepository.java b/src/main/java/coffeemeet/server/certification/repository/EmailVerificationRepository.java similarity index 65% rename from src/main/java/coffeemeet/server/certification/repository/VerificationVoRepository.java rename to src/main/java/coffeemeet/server/certification/repository/EmailVerificationRepository.java index 423bbde0..d3290459 100644 --- a/src/main/java/coffeemeet/server/certification/repository/VerificationVoRepository.java +++ b/src/main/java/coffeemeet/server/certification/repository/EmailVerificationRepository.java @@ -3,6 +3,6 @@ import coffeemeet.server.certification.domain.EmailVerification; import org.springframework.data.repository.CrudRepository; -public interface VerificationVoRepository extends CrudRepository { +public interface EmailVerificationRepository extends CrudRepository { } From 1abc25d586e9a80180dfe269cbb9a3e0342d6325 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 05:03:25 +0900 Subject: [PATCH 166/311] =?UTF-8?q?refactor:=20=EB=A0=88=ED=8F=AC=EC=A7=80?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EA=B0=80=EA=B3=B5=20=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=20=ED=95=84=EB=93=9C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/CertificationController.java | 2 +- .../service/CertificationService.java | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java index a6f52509..7c84cd9a 100644 --- a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java +++ b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java @@ -50,7 +50,7 @@ public ResponseEntity verifyEmail( @Login AuthInfo authInfo, @Valid @RequestBody VerificationCodeDto.Request request ) { - certificationService.verifyEmail(authInfo.userId(), request.verificationCode()); + certificationService.compareCode(authInfo.userId(), request.verificationCode()); return ResponseEntity.ok().build(); } diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java index 6d12afc8..dd33cdb5 100644 --- a/src/main/java/coffeemeet/server/certification/service/CertificationService.java +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -4,10 +4,10 @@ import coffeemeet.server.certification.domain.CompanyEmail; import coffeemeet.server.certification.domain.Department; -import coffeemeet.server.certification.domain.EmailVerification; -import coffeemeet.server.certification.repository.VerificationVoRepository; import coffeemeet.server.certification.service.cq.CertificationCommand; import coffeemeet.server.certification.service.cq.CertificationQuery; +import coffeemeet.server.certification.service.cq.EmailVerificationCommand; +import coffeemeet.server.certification.service.cq.EmailVerificationQuery; import coffeemeet.server.common.media.EmailService; import coffeemeet.server.common.media.S3MediaService; import coffeemeet.server.common.util.FileUtils; @@ -30,9 +30,11 @@ public class CertificationService { private final S3MediaService s3MediaService; private final EmailService emailService; private final UserService userService; - private final VerificationVoRepository verificationVoRepository; - private final CertificationQuery certificationQuery; private final CertificationCommand certificationCommand; + private final CertificationQuery certificationQuery; + private final EmailVerificationCommand emailVerificationCommand; + private final EmailVerificationQuery emailVerificationQuery; + @Transactional public void registerCertification(long userId, String email, String departmentName, @@ -64,14 +66,12 @@ public void sendVerificationMail(Long userId, String email) { String verificationCode = generateVerificationCode(); emailService.sendVerificationCode(companyEmail, verificationCode); - verificationVoRepository.save(new EmailVerification(userId, companyEmail, verificationCode)); + emailVerificationCommand.newEmailVerification(userId, companyEmail, verificationCode); } - @Transactional(readOnly = true) - public void verifyEmail(Long userId, String verificationCode) { - EmailVerification emailVerification = verificationVoRepository.findById(userId) - .orElseThrow(() -> new IllegalArgumentException(VERIFICATION_CODE_NOT_FOUND)); - if (!emailVerification.getCode().equals(verificationCode)) { + public void compareCode(Long userId, String verificationCode) { + String correctCode = emailVerificationQuery.getCodeById(userId); + if (!correctCode.equals(verificationCode)) { throw new IllegalArgumentException(WRONG_VERIFICATION_CODE); } } From 69c41df8ad7692844cd010420be6aaf45ef9e6c0 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 05:14:06 +0900 Subject: [PATCH 167/311] =?UTF-8?q?refactor:=20Transactional(readOnly=20?= =?UTF-8?q?=3D=20true)=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/certification/service/cq/CertificationCommand.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java b/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java index 76725505..773c110f 100644 --- a/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java +++ b/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java @@ -29,6 +29,7 @@ public void newCertification(CompanyEmail companyEmail, String businessCardUrl, ); } + @Transactional(readOnly = true) public void applyIfCertifiedUser(Long userId, Consumer consumer) { certificationRepository.findByUserId(userId).ifPresent(consumer); } From b059c933c2b969b0f7149fdc4326c97b9c87d9fe Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 05:14:38 +0900 Subject: [PATCH 168/311] =?UTF-8?q?refactor:=20=EC=83=81=EC=88=98=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/certification/service/CertificationService.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java index dd33cdb5..37f75988 100644 --- a/src/main/java/coffeemeet/server/certification/service/CertificationService.java +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -23,7 +23,6 @@ @RequiredArgsConstructor public class CertificationService { - private static final String VERIFICATION_CODE_NOT_FOUND = "인증코드 기간이 만료되었거나 해당 유저가 인증 번호를 요청한 기록이 없습니다."; private static final String WRONG_VERIFICATION_CODE = "잘못된 인증코드입니다."; private static final RandomGenerator RANDOM_GENERATOR = RandomGenerator.getDefault(); @@ -35,7 +34,6 @@ public class CertificationService { private final EmailVerificationCommand emailVerificationCommand; private final EmailVerificationQuery emailVerificationQuery; - @Transactional public void registerCertification(long userId, String email, String departmentName, File businessCardImage) { From 0d54dee55b2561ecf0084bdefbac2482a54d6b15 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 05:47:29 +0900 Subject: [PATCH 169/311] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20Transactional=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/certification/service/CertificationService.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java index 37f75988..69e32864 100644 --- a/src/main/java/coffeemeet/server/certification/service/CertificationService.java +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -17,7 +17,6 @@ import java.util.random.RandomGenerator; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor @@ -34,7 +33,6 @@ public class CertificationService { private final EmailVerificationCommand emailVerificationCommand; private final EmailVerificationQuery emailVerificationQuery; - @Transactional public void registerCertification(long userId, String email, String departmentName, File businessCardImage) { String key = s3MediaService.generateKey(BUSINESS_CARD); @@ -57,7 +55,6 @@ private void uploadBusinessCard(long userId, String key, File businessCardUrl) { FileUtils.delete(businessCardUrl); } - @Transactional public void sendVerificationMail(Long userId, String email) { CompanyEmail companyEmail = new CompanyEmail(email); certificationQuery.checkDuplicatedCompanyEmail(companyEmail); From 257ef54b4c3c10873132f911bc2ff7e0008cedab Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 14:22:56 +0900 Subject: [PATCH 170/311] =?UTF-8?q?fix:=20merge=20conflict=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/controller/UserController.java | 2 +- .../coffeemeet/server/user/service/UserService.java | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index 816d1f3d..52167566 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -37,7 +37,7 @@ public class UserController { public ResponseEntity findUserProfile(@PathVariable long userId) { return ResponseEntity.ok(userService.findUserProfile(userId)); } - + @PostMapping("/sign-up") public ResponseEntity signup(@Valid @RequestBody SignupRequest request) { return ResponseEntity.ok(userService.signup(request)); diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index d97dc096..2405fcca 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -2,11 +2,10 @@ import static coffeemeet.server.common.media.S3MediaService.KeyType.PROFILE_IMAGE; -import coffeemeet.server.auth.dto.OAuthInfoResponse; -import coffeemeet.server.certification.domain.Certification; -import coffeemeet.server.certification.service.cq.CertificationQuery; import coffeemeet.server.auth.domain.AuthTokens; import coffeemeet.server.auth.domain.AuthTokensGenerator; +import coffeemeet.server.certification.domain.Certification; +import coffeemeet.server.certification.service.cq.CertificationQuery; import coffeemeet.server.common.media.S3MediaService; import coffeemeet.server.interest.domain.Interest; import coffeemeet.server.interest.domain.Keyword; @@ -14,7 +13,6 @@ import coffeemeet.server.interest.service.InterestService; import coffeemeet.server.oauth.dto.OAuthInfoResponse; import coffeemeet.server.oauth.service.OAuthService; -import coffeemeet.server.user.domain.CompanyEmail; import coffeemeet.server.user.domain.OAuthInfo; import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.Profile; @@ -44,7 +42,6 @@ public class UserService { private final OAuthService oAuthService; private final UserRepository userRepository; private final InterestRepository interestRepository; - private final InterestService interestService; private final CertificationQuery certificationQuery; private final AuthTokensGenerator authTokensGenerator; @@ -141,10 +138,10 @@ public void checkDuplicatedUser(OAuthInfoResponse response) { } public User getUserById(Long userId) { - return userRepository.findById(userId) + return userRepository.findById(userId) .orElseThrow(IllegalArgumentException::new); } - + private String getProfileImageOrDefault(String profileImage) { if (profileImage == null) { profileImage = DEFAULT_IMAGE_URL; From a4982e7d6c656c6c25deeeab98e48e27e9e83ade Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 14:24:01 +0900 Subject: [PATCH 171/311] =?UTF-8?q?refactor:=20applyIfCertifiedUser=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=20command=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../certification/service/CertificationService.java | 2 +- .../certification/service/cq/CertificationCommand.java | 8 +------- .../certification/service/cq/CertificationQuery.java | 8 ++++++-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java index 69e32864..0149fc2b 100644 --- a/src/main/java/coffeemeet/server/certification/service/CertificationService.java +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -46,7 +46,7 @@ public void registerCertification(long userId, String email, String departmentNa } private void uploadBusinessCard(long userId, String key, File businessCardUrl) { - certificationCommand.applyIfCertifiedUser(userId, certification -> { + certificationQuery.applyIfCertifiedUser(userId, certification -> { String oldKey = s3MediaService.extractKey(certification.getBusinessCardUrl(), BUSINESS_CARD); s3MediaService.delete(oldKey); }); diff --git a/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java b/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java index 773c110f..9403de83 100644 --- a/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java +++ b/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java @@ -5,14 +5,13 @@ import coffeemeet.server.certification.domain.Department; import coffeemeet.server.certification.repository.CertificationRepository; import coffeemeet.server.user.domain.User; -import java.util.function.Consumer; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +@Service @Transactional @RequiredArgsConstructor -@Service public class CertificationCommand { private final CertificationRepository certificationRepository; @@ -29,9 +28,4 @@ public void newCertification(CompanyEmail companyEmail, String businessCardUrl, ); } - @Transactional(readOnly = true) - public void applyIfCertifiedUser(Long userId, Consumer consumer) { - certificationRepository.findByUserId(userId).ifPresent(consumer); - } - } diff --git a/src/main/java/coffeemeet/server/certification/service/cq/CertificationQuery.java b/src/main/java/coffeemeet/server/certification/service/cq/CertificationQuery.java index fcf4cf4f..5a647b54 100644 --- a/src/main/java/coffeemeet/server/certification/service/cq/CertificationQuery.java +++ b/src/main/java/coffeemeet/server/certification/service/cq/CertificationQuery.java @@ -3,13 +3,14 @@ import coffeemeet.server.certification.domain.Certification; import coffeemeet.server.certification.domain.CompanyEmail; import coffeemeet.server.certification.repository.CertificationRepository; +import java.util.function.Consumer; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -@Transactional(readOnly = true) -@RequiredArgsConstructor @Service +@RequiredArgsConstructor +@Transactional(readOnly = true) public class CertificationQuery { public static final String CERTIFICATION_NOT_FOUND = "해당 사용자의 인증정보를 찾을 수 없습니다."; @@ -28,5 +29,8 @@ public void checkDuplicatedCompanyEmail(CompanyEmail companyEmail) { } } + public void applyIfCertifiedUser(Long userId, Consumer consumer) { + certificationRepository.findByUserId(userId).ifPresent(consumer); + } } From 948910f6565fb3c7712d9cc0f91477e5cd4a8142 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 14:26:00 +0900 Subject: [PATCH 172/311] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../certification/repository/CertificationRepository.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/repository/CertificationRepository.java b/src/main/java/coffeemeet/server/certification/repository/CertificationRepository.java index 22fc0c07..2ee7ca0a 100644 --- a/src/main/java/coffeemeet/server/certification/repository/CertificationRepository.java +++ b/src/main/java/coffeemeet/server/certification/repository/CertificationRepository.java @@ -11,6 +11,4 @@ public interface CertificationRepository extends JpaRepository Date: Thu, 26 Oct 2023 15:55:12 +0900 Subject: [PATCH 173/311] =?UTF-8?q?refactor:=20oauth=202.0=20redirect=20AP?= =?UTF-8?q?I=20URI=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/oauth/controller/OAuthController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/oauth/controller/OAuthController.java b/src/main/java/coffeemeet/server/oauth/controller/OAuthController.java index f4594705..e30e06bf 100644 --- a/src/main/java/coffeemeet/server/oauth/controller/OAuthController.java +++ b/src/main/java/coffeemeet/server/oauth/controller/OAuthController.java @@ -14,7 +14,7 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/oauth2") +@RequestMapping("/api/v1/oauth2.0") public class OAuthController { private final OAuthService oAuthService; From a70b4adf1e3d1b5d94f3b5f35176a7ac7520aac6 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 15:55:52 +0900 Subject: [PATCH 174/311] =?UTF-8?q?refactor:=20OAuthControllerTest=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{AuthControllerTest.java => OAuthControllerTest.java} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/test/java/coffeemeet/server/auth/controller/{AuthControllerTest.java => OAuthControllerTest.java} (100%) diff --git a/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java b/src/test/java/coffeemeet/server/auth/controller/OAuthControllerTest.java similarity index 100% rename from src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java rename to src/test/java/coffeemeet/server/auth/controller/OAuthControllerTest.java From 44c9cd2de18f6ff7a5e1fee86f0ad37a6d21f927 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 15:56:21 +0900 Subject: [PATCH 175/311] =?UTF-8?q?test:=20provideTest=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 --- ...thCodeRequestUrlProviderCompositeTest.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/test/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderCompositeTest.java diff --git a/src/test/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderCompositeTest.java b/src/test/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderCompositeTest.java new file mode 100644 index 00000000..f26b8c5d --- /dev/null +++ b/src/test/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderCompositeTest.java @@ -0,0 +1,46 @@ +package coffeemeet.server.oauth.authcode; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +import coffeemeet.server.user.domain.OAuthProvider; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class AuthCodeRequestUrlProviderCompositeTest { + + @Mock + private AuthCodeRequestUrlProvider provider; + + @Mock + private Set providers; + + @InjectMocks + private AuthCodeRequestUrlProviderComposite composite; + + @Test + void provideTest() { + // given + OAuthProvider oAuthProvider = OAuthProvider.KAKAO; + String resultUrl = "https://kakao.com/login/oauth/authorize?client_id=testClientId&redirect_uri=https://testClientId/redirect"; + + // when + when(provider.oAuthProvider()).thenReturn(OAuthProvider.KAKAO); + when(provider.provide()).thenReturn(resultUrl); + + // then + providers = new HashSet<>(Collections.singletonList(provider)); + composite = new AuthCodeRequestUrlProviderComposite(providers); + + String expectedUrl = composite.provide(oAuthProvider); + assertThat(resultUrl).isEqualTo(expectedUrl); + } + +} From fdead852d356278ae9fefc9d2b9ebaab2fe1e2be Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 16:16:57 +0900 Subject: [PATCH 176/311] =?UTF-8?q?refactor:=20=EC=A0=91=EA=B7=BC=20?= =?UTF-8?q?=EC=A0=9C=EC=96=B4=EC=9E=90=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/oauth/client/OAuthMemberClientComposite.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java b/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java index 6e9cdb38..33ac6e71 100644 --- a/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java +++ b/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java @@ -25,7 +25,7 @@ public OAuthInfoResponse fetch(OAuthProvider oAuthProvider, String authCode) { return getClient(oAuthProvider).fetch(authCode); } - public OAuthMemberClient getClient(OAuthProvider oAuthProvider) { + private OAuthMemberClient getClient(OAuthProvider oAuthProvider) { return Optional.ofNullable(mapping.get(oAuthProvider)) .orElseThrow(() -> new IllegalArgumentException( String.format(INVALID_LOGIN_TYPE_MESSAGE, oAuthProvider)) From 2b17a0c4609c0be87b96819247f9178557b4354f Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 16:17:09 +0900 Subject: [PATCH 177/311] =?UTF-8?q?test:=20OAuthInfoResponseFixture=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fixture/dto/OAuthInfoResponseFixture.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java new file mode 100644 index 00000000..98ff5b00 --- /dev/null +++ b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java @@ -0,0 +1,13 @@ +package coffeemeet.server.common.fixture.dto; + +import coffeemeet.server.oauth.dto.OAuthInfoResponse; +import org.instancio.Instancio; + +public class OAuthInfoResponseFixture { + + public static OAuthInfoResponse oAuthInfoResponse() { + return Instancio.of(OAuthInfoResponse.class) + .create(); + } + +} From 725efedbd19263039188e13e13ad2c0441aac31f Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 16:17:21 +0900 Subject: [PATCH 178/311] =?UTF-8?q?test:=20OAuthMemberClientCompositeTest?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OAuthMemberClientCompositeTest.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java diff --git a/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java new file mode 100644 index 00000000..95b0b8ff --- /dev/null +++ b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java @@ -0,0 +1,49 @@ +package coffeemeet.server.oauth.client; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +import coffeemeet.server.common.fixture.dto.OAuthInfoResponseFixture; +import coffeemeet.server.oauth.dto.OAuthInfoResponse; +import coffeemeet.server.user.domain.OAuthProvider; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class OAuthMemberClientCompositeTest { + + @Mock + private OAuthMemberClient client; + + @Mock + private Set clients; + + @InjectMocks + private OAuthMemberClientComposite composite; + + @Test + void fetchTest() { + // given + String authCode = "authCode"; + OAuthProvider oAuthProvider = OAuthProvider.KAKAO; + OAuthInfoResponse response = OAuthInfoResponseFixture.oAuthInfoResponse(); + + // when + when(client.oAuthProvider()).thenReturn(OAuthProvider.KAKAO); + when(client.fetch(authCode)).thenReturn(response); + + clients = new HashSet<>(Collections.singletonList(client)); + composite = new OAuthMemberClientComposite(clients); + + // then + OAuthInfoResponse expectedResponse = composite.fetch(oAuthProvider, authCode); + assertThat(response).isEqualTo(expectedResponse); + } + +} From 0a3b942a334bfe9cdabd2d4a00daa82923cb2ebd Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 16:37:13 +0900 Subject: [PATCH 179/311] =?UTF-8?q?test:=20OAuthControllerTest=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 --- .../oauth/controller/OAuthControllerTest.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/test/java/coffeemeet/server/oauth/controller/OAuthControllerTest.java diff --git a/src/test/java/coffeemeet/server/oauth/controller/OAuthControllerTest.java b/src/test/java/coffeemeet/server/oauth/controller/OAuthControllerTest.java new file mode 100644 index 00000000..e91518f7 --- /dev/null +++ b/src/test/java/coffeemeet/server/oauth/controller/OAuthControllerTest.java @@ -0,0 +1,63 @@ +package coffeemeet.server.oauth.controller; + +import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; +import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.resourceDetails; +import static org.mockito.Mockito.when; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import coffeemeet.server.common.config.ControllerTestConfig; +import coffeemeet.server.oauth.service.OAuthService; +import coffeemeet.server.user.domain.OAuthProvider; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; + +@WebMvcTest(OAuthController.class) +class OAuthControllerTest extends ControllerTestConfig { + + @MockBean + private OAuthService oAuthService; + + @DisplayName("sns 접근 권한 url로 redirect 할 수 있다.") + @Test + void redirectAuthCodeRequestUrlTest() throws Exception { + // given + String expectedRedirectUrl = "https://example.com"; + + // when + when(oAuthService.getAuthCodeRequestUrl(OAuthProvider.KAKAO)).thenReturn( + expectedRedirectUrl); + + // then + mockMvc.perform(get("/api/v1/oauth2.0/{oAuthProvider}", OAuthProvider.KAKAO) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + ) + .andDo(document("oauth-redirect", + resourceDetails().tag("인증").description("접근 권한 url 리다이렉트"), + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + pathParameters( + parameterWithName("oAuthProvider").description("OAuth 로그인 타입") + ), + responseHeaders( + headerWithName("Location").description("리다이렉션 대상 URL") + ) + ) + ) + .andExpect(status().is3xxRedirection()) + .andExpect(redirectedUrl(expectedRedirectUrl)); + } + +} From 9987b0a1f31b4cf0ba326ca2ad1d9d7b8674107c Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 16:47:58 +0900 Subject: [PATCH 180/311] =?UTF-8?q?test:=20KakaoAuthCodeRequestUrlProvider?= =?UTF-8?q?Test=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../KakaoAuthCodeRequestUrlProviderTest.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/test/java/coffeemeet/server/oauth/infrastructure/kakao/authcode/KakaoAuthCodeRequestUrlProviderTest.java diff --git a/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/authcode/KakaoAuthCodeRequestUrlProviderTest.java b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/authcode/KakaoAuthCodeRequestUrlProviderTest.java new file mode 100644 index 00000000..6ad7dc55 --- /dev/null +++ b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/authcode/KakaoAuthCodeRequestUrlProviderTest.java @@ -0,0 +1,46 @@ +package coffeemeet.server.oauth.infrastructure.kakao.authcode; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +import coffeemeet.server.oauth.infrastructure.kakao.config.KakaoProperties; +import coffeemeet.server.user.domain.OAuthProvider; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class KakaoAuthCodeRequestUrlProviderTest { + + @Mock + private KakaoProperties kakaoProperties; + + @InjectMocks + private KakaoAuthCodeRequestUrlProvider provider; + + @Test + void oAuthProviderTest() { + // given + OAuthProvider oAuthProvider = provider.oAuthProvider(); + + // when, then + assertThat(oAuthProvider).isEqualTo(OAuthProvider.KAKAO); + } + + @Test + void provideTest() { + // given + String resultUrl = "https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=testClientId&redirect_uri=https://testClientId/redirect"; + + // when + when(kakaoProperties.getClientId()).thenReturn("testClientId"); + when(kakaoProperties.getRedirectUrl()).thenReturn("https://testClientId/redirect"); + + // then + String expectedUrl = provider.provide(); + assertThat(resultUrl).isEqualTo(expectedUrl); + } + +} From 11644d12e696aee91a82672b6f35e2fc77280d0d Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 17:29:13 +0900 Subject: [PATCH 181/311] =?UTF-8?q?test:=20KakaoMemberResponseFixture=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fixture/dto/KakaoMemberResponseFixture.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/test/java/coffeemeet/server/common/fixture/dto/KakaoMemberResponseFixture.java diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/KakaoMemberResponseFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/KakaoMemberResponseFixture.java new file mode 100644 index 00000000..e28e0168 --- /dev/null +++ b/src/test/java/coffeemeet/server/common/fixture/dto/KakaoMemberResponseFixture.java @@ -0,0 +1,13 @@ +package coffeemeet.server.common.fixture.dto; + +import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoMemberResponse; +import org.instancio.Instancio; + +public class KakaoMemberResponseFixture { + + public static KakaoMemberResponse kakaoMemberResponse() { + return Instancio.of(KakaoMemberResponse.class) + .create(); + } + +} From c1b65140004a565925f3c8bbc32f86a780faa135 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 17:29:44 +0900 Subject: [PATCH 182/311] =?UTF-8?q?test:=20KakaoTokensFixture=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 --- .../common/fixture/dto/KakaoTokensFixture.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/test/java/coffeemeet/server/common/fixture/dto/KakaoTokensFixture.java diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/KakaoTokensFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/KakaoTokensFixture.java new file mode 100644 index 00000000..8f1e5216 --- /dev/null +++ b/src/test/java/coffeemeet/server/common/fixture/dto/KakaoTokensFixture.java @@ -0,0 +1,13 @@ +package coffeemeet.server.common.fixture.dto; + +import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoTokens; +import org.instancio.Instancio; + +public class KakaoTokensFixture { + + public static KakaoTokens kakaoTokens() { + return Instancio.of(KakaoTokens.class) + .create(); + } + +} From fd67f47bdc13b7836d5e42d86070772e254a1d08 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 17:29:58 +0900 Subject: [PATCH 183/311] =?UTF-8?q?test:=20KakaoApiClientTest=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 --- .../kakao/client/KakaoApiClientTest.java | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoApiClientTest.java diff --git a/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoApiClientTest.java b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoApiClientTest.java new file mode 100644 index 00000000..a5fac71a --- /dev/null +++ b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoApiClientTest.java @@ -0,0 +1,85 @@ +package coffeemeet.server.oauth.infrastructure.kakao.client; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +import coffeemeet.server.common.fixture.dto.KakaoMemberResponseFixture; +import coffeemeet.server.common.fixture.dto.KakaoTokensFixture; +import coffeemeet.server.oauth.infrastructure.kakao.config.KakaoProperties; +import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoMemberResponse; +import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoTokens; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; + +@ExtendWith(MockitoExtension.class) +class KakaoApiClientTest { + + @Mock + private RestTemplate restTemplate; + + @Mock + private KakaoProperties kakaoProperties; + + @InjectMocks + private KakaoApiClient kakaoApiClient; + + @Test + void fetchTokenTest() { + // given + String authCode = "authCode"; + KakaoTokens kakaoTokens = KakaoTokensFixture.kakaoTokens(); + + // when + when(kakaoProperties.getClientId()).thenReturn("testClientId"); + when(kakaoProperties.getRedirectUrl()).thenReturn("testRedirectUrl"); + when(kakaoProperties.getClientSecret()).thenReturn("testClientSecret"); + when(restTemplate.postForObject( + anyString(), + any(HttpEntity.class), + eq(KakaoTokens.class))) + .thenReturn(kakaoTokens); + + // then + KakaoTokens expectedTokens = kakaoApiClient.fetchToken(authCode); + assertAll( + () -> assertThat(expectedTokens).isNotNull(), + () -> assertThat(expectedTokens.accessToken()).isEqualTo(kakaoTokens.accessToken()), + () -> assertThat(expectedTokens.refreshToken()).isEqualTo(kakaoTokens.refreshToken()), + () -> assertThat(expectedTokens.tokenType()).isEqualTo(kakaoTokens.tokenType()), + () -> assertThat(expectedTokens.expiresIn()).isEqualTo(kakaoTokens.expiresIn()), + () -> assertThat(expectedTokens.refreshTokenExpiresIn()).isEqualTo( + kakaoTokens.refreshTokenExpiresIn()) + ); + } + + @Test + void fetchMemberTest() { + // given + KakaoMemberResponse response = KakaoMemberResponseFixture.kakaoMemberResponse(); + ResponseEntity mockResponse = ResponseEntity.ok(response); + + // when + when(restTemplate.exchange( + anyString(), + any(HttpMethod.class), + any(HttpEntity.class), + eq(KakaoMemberResponse.class))) + .thenReturn(mockResponse); + + // then + KakaoMemberResponse result = kakaoApiClient.fetchMember("accessToken"); + assertThat(result).isNotNull(); + } + +} From 482aa3297bc59dbe97876f4c7c015de245da0dcc Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 18:11:26 +0900 Subject: [PATCH 184/311] =?UTF-8?q?refactor:=20KakaoMemberResponse=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 - 도메인 반환 x --- .../server/oauth/dto/OAuthInfoResponse.java | 15 ++++++++------- .../kakao/dto/KakaoMemberResponse.java | 7 +++---- .../server/user/service/UserService.java | 8 ++++++-- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/main/java/coffeemeet/server/oauth/dto/OAuthInfoResponse.java b/src/main/java/coffeemeet/server/oauth/dto/OAuthInfoResponse.java index ec974b6d..df92e221 100644 --- a/src/main/java/coffeemeet/server/oauth/dto/OAuthInfoResponse.java +++ b/src/main/java/coffeemeet/server/oauth/dto/OAuthInfoResponse.java @@ -1,14 +1,13 @@ package coffeemeet.server.oauth.dto; -import coffeemeet.server.user.domain.Birth; -import coffeemeet.server.user.domain.Email; import coffeemeet.server.user.domain.OAuthProvider; public record OAuthInfoResponse( String name, String profileImage, - Birth birth, - Email email, + String birthYear, + String birthDay, + String email, OAuthProvider oAuthProvider, String oAuthProviderId ) { @@ -16,15 +15,17 @@ public record OAuthInfoResponse( public static OAuthInfoResponse of( String name, String profileImage, - Birth birth, - Email email, + String birthYear, + String birthDay, + String email, OAuthProvider oAuthProvider, String oAuthProviderId ) { return new OAuthInfoResponse( name, profileImage, - birth, + birthYear, + birthDay, email, oAuthProvider, oAuthProviderId diff --git a/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberResponse.java b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberResponse.java index 29c66aa5..5ddaca2a 100644 --- a/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberResponse.java +++ b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberResponse.java @@ -1,8 +1,6 @@ package coffeemeet.server.oauth.infrastructure.kakao.dto; import coffeemeet.server.oauth.dto.OAuthInfoResponse; -import coffeemeet.server.user.domain.Birth; -import coffeemeet.server.user.domain.Email; import coffeemeet.server.user.domain.OAuthProvider; import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; import com.fasterxml.jackson.databind.annotation.JsonNaming; @@ -17,8 +15,9 @@ public OAuthInfoResponse toOAuthInfoResponse() { return OAuthInfoResponse.of( kakaoAccount.name, kakaoAccount.profile.profileImageUrl, - new Birth(kakaoAccount.birthyear, kakaoAccount.birthday), - new Email(kakaoAccount.email), + kakaoAccount.birthyear, + kakaoAccount.birthday, + kakaoAccount.email, OAuthProvider.KAKAO, String.valueOf(id) ); diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 2405fcca..f493d380 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -13,6 +13,8 @@ import coffeemeet.server.interest.service.InterestService; import coffeemeet.server.oauth.dto.OAuthInfoResponse; import coffeemeet.server.oauth.service.OAuthService; +import coffeemeet.server.user.domain.Birth; +import coffeemeet.server.user.domain.Email; import coffeemeet.server.user.domain.OAuthInfo; import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.Profile; @@ -100,8 +102,10 @@ public AuthTokens signup(SignupRequest request) { String profileImage = getProfileImageOrDefault(response.profileImage()); User user = new User(new OAuthInfo(response.oAuthProvider(), response.oAuthProviderId()), - Profile.builder().name(response.name()).nickname(request.nickname()).email(response.email()) - .profileImageUrl(profileImage).birth(response.birth()).build()); + Profile.builder().name(response.name()).nickname(request.nickname()) + .email(new Email(response.email())) + .profileImageUrl(profileImage) + .birth(new Birth(response.birthYear(), response.birthDay())).build()); User newUser = userRepository.save(user); saveInterests(request, newUser); From 99dd868a2b95ac541ff327d438f47582f90add61 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 18:11:42 +0900 Subject: [PATCH 185/311] =?UTF-8?q?test:=20KakaoMemberClientTest=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 --- .../kakao/client/KakaoMemberClientTest.java | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClientTest.java diff --git a/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClientTest.java b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClientTest.java new file mode 100644 index 00000000..455af895 --- /dev/null +++ b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClientTest.java @@ -0,0 +1,52 @@ +package coffeemeet.server.oauth.infrastructure.kakao.client; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import coffeemeet.server.common.fixture.dto.KakaoMemberResponseFixture; +import coffeemeet.server.common.fixture.dto.KakaoTokensFixture; +import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoMemberResponse; +import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoTokens; +import coffeemeet.server.user.domain.OAuthProvider; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class KakaoMemberClientTest { + + @InjectMocks + KakaoMemberClient kakaoMemberClient; + + @Mock + KakaoApiClient kakaoApiClient; + + @DisplayName("카카오 프로바이더를 가져올 수 있다.") + @Test + void oAuthProvider() { + // given, when, then + assertThat(kakaoMemberClient.oAuthProvider()).isEqualTo(OAuthProvider.KAKAO); + } + + @DisplayName("카카오로부터 사용자 정보를 가져올 수 있다.") + @Test + void fetch() { + // given + String authCode = "authCode"; + + KakaoTokens kakaoTokens = KakaoTokensFixture.kakaoTokens(); + KakaoMemberResponse response = KakaoMemberResponseFixture.kakaoMemberResponse(); + + // when + when(kakaoApiClient.fetchToken(any())).thenReturn(kakaoTokens); + when(kakaoApiClient.fetchMember(any())).thenReturn(response); + + // then + assertThat(kakaoMemberClient.fetch(authCode)).isNotNull(); + } + +} From 62dc92b2a398ef80a7998ebec6b9f1b44598e0f5 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 18:22:34 +0900 Subject: [PATCH 186/311] =?UTF-8?q?test:=20AuthCodeRequestUrlProviderCompo?= =?UTF-8?q?siteTest=20=EC=84=A4=EB=AA=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oauth/authcode/AuthCodeRequestUrlProviderCompositeTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderCompositeTest.java b/src/test/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderCompositeTest.java index f26b8c5d..6b74a2fe 100644 --- a/src/test/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderCompositeTest.java +++ b/src/test/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderCompositeTest.java @@ -7,6 +7,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.Set; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -25,6 +26,7 @@ class AuthCodeRequestUrlProviderCompositeTest { @InjectMocks private AuthCodeRequestUrlProviderComposite composite; + @DisplayName("sns 의 redirect url 을 제공할 수 있다.") @Test void provideTest() { // given From 0bfd32c3534a14e3803be2b456a4d6c7c8291e50 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 18:22:50 +0900 Subject: [PATCH 187/311] =?UTF-8?q?test:=20KakaoApiClientTest=20=EC=84=A4?= =?UTF-8?q?=EB=AA=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oauth/infrastructure/kakao/client/KakaoApiClientTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoApiClientTest.java b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoApiClientTest.java index a5fac71a..a07e642b 100644 --- a/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoApiClientTest.java +++ b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoApiClientTest.java @@ -12,6 +12,7 @@ import coffeemeet.server.oauth.infrastructure.kakao.config.KakaoProperties; import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoMemberResponse; import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoTokens; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -34,6 +35,7 @@ class KakaoApiClientTest { @InjectMocks private KakaoApiClient kakaoApiClient; + @DisplayName("카카오로부터 인증 토큰을 받을 수 있다.") @Test void fetchTokenTest() { // given @@ -63,6 +65,7 @@ void fetchTokenTest() { ); } + @DisplayName("카카오로부터 사용자 정보를 가져올 수 있다.") @Test void fetchMemberTest() { // given From 8ad301cf8a03ace4bc1a6f16e7e6f4f6cb078868 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 18:23:01 +0900 Subject: [PATCH 188/311] =?UTF-8?q?test:=20KakaoAuthCodeRequestUrlProvider?= =?UTF-8?q?Test=20=EC=84=A4=EB=AA=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kakao/authcode/KakaoAuthCodeRequestUrlProviderTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/authcode/KakaoAuthCodeRequestUrlProviderTest.java b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/authcode/KakaoAuthCodeRequestUrlProviderTest.java index 6ad7dc55..b85719e8 100644 --- a/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/authcode/KakaoAuthCodeRequestUrlProviderTest.java +++ b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/authcode/KakaoAuthCodeRequestUrlProviderTest.java @@ -5,6 +5,7 @@ import coffeemeet.server.oauth.infrastructure.kakao.config.KakaoProperties; import coffeemeet.server.user.domain.OAuthProvider; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -20,6 +21,7 @@ class KakaoAuthCodeRequestUrlProviderTest { @InjectMocks private KakaoAuthCodeRequestUrlProvider provider; + @DisplayName("카카오 프로바이더를 제공할 수 있다.") @Test void oAuthProviderTest() { // given @@ -29,6 +31,7 @@ void oAuthProviderTest() { assertThat(oAuthProvider).isEqualTo(OAuthProvider.KAKAO); } + @DisplayName("카카오의 redirect url 을 제공할 수 있다.") @Test void provideTest() { // given From 93e0c492fa59127eb722e9bbb7c038fab8d3d823 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 18:23:12 +0900 Subject: [PATCH 189/311] =?UTF-8?q?test:=20OAuthMemberClientCompositeTest?= =?UTF-8?q?=20=EC=84=A4=EB=AA=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/oauth/client/OAuthMemberClientCompositeTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java index 95b0b8ff..de8ea34a 100644 --- a/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java +++ b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java @@ -9,6 +9,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.Set; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -27,6 +28,7 @@ class OAuthMemberClientCompositeTest { @InjectMocks private OAuthMemberClientComposite composite; + @DisplayName("sns 로부터 사용자 정보를 가져올 수 있다.") @Test void fetchTest() { // given From 4d7b61ffa787e708e5eca6ec963305761b9d4508 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 23:08:55 +0900 Subject: [PATCH 190/311] =?UTF-8?q?test:=20OAuthServiceTest=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 --- .../oauth/service/OAuthServiceTest.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java diff --git a/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java b/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java new file mode 100644 index 00000000..6b68adf4 --- /dev/null +++ b/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java @@ -0,0 +1,59 @@ +package coffeemeet.server.oauth.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +import coffeemeet.server.common.fixture.dto.OAuthInfoResponseFixture; +import coffeemeet.server.oauth.authcode.AuthCodeRequestUrlProviderComposite; +import coffeemeet.server.oauth.client.OAuthMemberClientComposite; +import coffeemeet.server.oauth.dto.OAuthInfoResponse; +import coffeemeet.server.user.domain.OAuthProvider; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class OAuthServiceTest { + + @InjectMocks + private OAuthService oAuthService; + + @Mock + private AuthCodeRequestUrlProviderComposite authCodeRequestUrlProviderComposite; + + @Mock + private OAuthMemberClientComposite oAuthMemberClientComposite; + + @DisplayName("로그인 타입에 맞는 redirect url 을 생성할 수 있다.") + @Test + void getAuthCodeRequestUrlTest() { + // given + String expectedUrl = "https://example.com"; + + // when + when(authCodeRequestUrlProviderComposite.provide(OAuthProvider.KAKAO)).thenReturn(expectedUrl); + + // then + String result = oAuthService.getAuthCodeRequestUrl(OAuthProvider.KAKAO); + assertThat(result).isEqualTo(expectedUrl); + } + + @DisplayName("로그인 타입에 맞는 redirect url 을 생성할 수 있다.") + @Test + void getOAuthInfoTest() { + // given + OAuthProvider oAuthProvider = OAuthProvider.KAKAO; + String authCode = "authCode"; + OAuthInfoResponse oAuthInfoResponse = OAuthInfoResponseFixture.oAuthInfoResponse(); + + // when + when(oAuthMemberClientComposite.fetch(oAuthProvider, authCode)).thenReturn(oAuthInfoResponse); + + // then + assertThat(oAuthService.getOAuthInfo(oAuthProvider, authCode)).isEqualTo(oAuthInfoResponse); + } + +} From a0e69a130ef2b9c2ceb2ca16baf9dfff7243af0b Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 23:28:53 +0900 Subject: [PATCH 191/311] =?UTF-8?q?test:=20OAuthProviderConverterTest=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 --- .../converter/OAuthProviderConverterTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/test/java/coffeemeet/server/oauth/utils/converter/OAuthProviderConverterTest.java diff --git a/src/test/java/coffeemeet/server/oauth/utils/converter/OAuthProviderConverterTest.java b/src/test/java/coffeemeet/server/oauth/utils/converter/OAuthProviderConverterTest.java new file mode 100644 index 00000000..1f4a981d --- /dev/null +++ b/src/test/java/coffeemeet/server/oauth/utils/converter/OAuthProviderConverterTest.java @@ -0,0 +1,27 @@ +package coffeemeet.server.oauth.utils.converter; + +import static org.assertj.core.api.Assertions.assertThat; + +import coffeemeet.server.user.domain.OAuthProvider; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + + +class OAuthProviderConverterTest { + + private OAuthProviderConverter oAuthProviderConverter = new OAuthProviderConverter(); + + @DisplayName("입력된 sns provider 이름을 항상 대문자로 변환 시킬 수 있다.") + @Test + void convert() { + // given + String provider = "kakao"; + + // when + OAuthProvider oAuthProvider = oAuthProviderConverter.convert(provider); + + // then + assertThat(oAuthProvider).isEqualTo(OAuthProvider.KAKAO); + } + +} From c1b6c68317486cab5ada1a0774ae696d2be077f9 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 23:32:26 +0900 Subject: [PATCH 192/311] =?UTF-8?q?refactor:=20=EC=A4=91=EB=B3=B5=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/controller/OAuthControllerTest.java | 61 ------------------- 1 file changed, 61 deletions(-) delete mode 100644 src/test/java/coffeemeet/server/auth/controller/OAuthControllerTest.java diff --git a/src/test/java/coffeemeet/server/auth/controller/OAuthControllerTest.java b/src/test/java/coffeemeet/server/auth/controller/OAuthControllerTest.java deleted file mode 100644 index e9d69208..00000000 --- a/src/test/java/coffeemeet/server/auth/controller/OAuthControllerTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package coffeemeet.server.auth.controller; - -import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; -import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.resourceDetails; -import static org.mockito.Mockito.when; -import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; -import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; -import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; -import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; -import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import coffeemeet.server.common.config.ControllerTestConfig; -import coffeemeet.server.oauth.controller.OAuthController; -import coffeemeet.server.oauth.service.OAuthService; -import coffeemeet.server.user.domain.OAuthProvider; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; - -@WebMvcTest(OAuthController.class) -class OAuthControllerTest extends ControllerTestConfig { - - @MockBean - private OAuthService oAuthService; - - @DisplayName("사용자가 로그인 버튼을 누르면 해당하는 서비스의 접근 권한 url로 리다이렉트한다.") - @Test - void redirectAuthCodeRequestUrlTest() throws Exception { - String expectedRedirectUrl = "https://example.com"; - - when(oAuthService.getAuthCodeRequestUrl(OAuthProvider.KAKAO)).thenReturn( - expectedRedirectUrl); - - mockMvc.perform(get("/oauth2/{oAuthProvider}", OAuthProvider.KAKAO) - .accept(MediaType.APPLICATION_JSON) - .contentType(MediaType.APPLICATION_JSON) - ) - .andDo(document("auth-redirect", - resourceDetails().tag("Auth").description("접근 권한 url 리다이렉트"), - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint()), - pathParameters( - parameterWithName("oAuthProvider").description("OAuth 로그인 타입") - ), - responseHeaders( - headerWithName("Location").description("리다이렉션 대상 URL") - ) - ) - ) - .andExpect(status().is3xxRedirection()) - .andExpect(redirectedUrl(expectedRedirectUrl)); - } - -} From f4eaaea0734c5e0b264ed64b11d53538e87a6919 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Thu, 26 Oct 2023 23:50:50 +0900 Subject: [PATCH 193/311] =?UTF-8?q?refactor:=20Mockito=20=EB=8C=80?= =?UTF-8?q?=EC=8B=A0,=20BDDMockito=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...thCodeRequestUrlProviderCompositeTest.java | 11 ++++---- .../OAuthMemberClientCompositeTest.java | 11 ++++---- .../oauth/controller/OAuthControllerTest.java | 7 +++-- .../KakaoAuthCodeRequestUrlProviderTest.java | 13 +++++----- .../kakao/client/KakaoApiClientTest.java | 26 ++++++++++--------- .../kakao/client/KakaoMemberClientTest.java | 12 ++++----- .../oauth/service/OAuthServiceTest.java | 12 ++++----- 7 files changed, 47 insertions(+), 45 deletions(-) diff --git a/src/test/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderCompositeTest.java b/src/test/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderCompositeTest.java index 6b74a2fe..86ca825b 100644 --- a/src/test/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderCompositeTest.java +++ b/src/test/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderCompositeTest.java @@ -1,7 +1,7 @@ package coffeemeet.server.oauth.authcode; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; +import static org.mockito.BDDMockito.given; import coffeemeet.server.user.domain.OAuthProvider; import java.util.Collections; @@ -33,15 +33,16 @@ void provideTest() { OAuthProvider oAuthProvider = OAuthProvider.KAKAO; String resultUrl = "https://kakao.com/login/oauth/authorize?client_id=testClientId&redirect_uri=https://testClientId/redirect"; - // when - when(provider.oAuthProvider()).thenReturn(OAuthProvider.KAKAO); - when(provider.provide()).thenReturn(resultUrl); + given(provider.oAuthProvider()).willReturn(OAuthProvider.KAKAO); + given(provider.provide()).willReturn(resultUrl); - // then providers = new HashSet<>(Collections.singletonList(provider)); composite = new AuthCodeRequestUrlProviderComposite(providers); + // when String expectedUrl = composite.provide(oAuthProvider); + + // then assertThat(resultUrl).isEqualTo(expectedUrl); } diff --git a/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java index de8ea34a..fdf66136 100644 --- a/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java +++ b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java @@ -1,7 +1,7 @@ package coffeemeet.server.oauth.client; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; +import static org.mockito.BDDMockito.given; import coffeemeet.server.common.fixture.dto.OAuthInfoResponseFixture; import coffeemeet.server.oauth.dto.OAuthInfoResponse; @@ -36,15 +36,16 @@ void fetchTest() { OAuthProvider oAuthProvider = OAuthProvider.KAKAO; OAuthInfoResponse response = OAuthInfoResponseFixture.oAuthInfoResponse(); - // when - when(client.oAuthProvider()).thenReturn(OAuthProvider.KAKAO); - when(client.fetch(authCode)).thenReturn(response); + given(client.oAuthProvider()).willReturn(OAuthProvider.KAKAO); + given(client.fetch(authCode)).willReturn(response); clients = new HashSet<>(Collections.singletonList(client)); composite = new OAuthMemberClientComposite(clients); - // then + // when OAuthInfoResponse expectedResponse = composite.fetch(oAuthProvider, authCode); + + // then assertThat(response).isEqualTo(expectedResponse); } diff --git a/src/test/java/coffeemeet/server/oauth/controller/OAuthControllerTest.java b/src/test/java/coffeemeet/server/oauth/controller/OAuthControllerTest.java index e91518f7..ef1b7980 100644 --- a/src/test/java/coffeemeet/server/oauth/controller/OAuthControllerTest.java +++ b/src/test/java/coffeemeet/server/oauth/controller/OAuthControllerTest.java @@ -2,7 +2,7 @@ import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.resourceDetails; -import static org.mockito.Mockito.when; +import static org.mockito.BDDMockito.given; import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; @@ -35,11 +35,10 @@ void redirectAuthCodeRequestUrlTest() throws Exception { // given String expectedRedirectUrl = "https://example.com"; - // when - when(oAuthService.getAuthCodeRequestUrl(OAuthProvider.KAKAO)).thenReturn( + given(oAuthService.getAuthCodeRequestUrl(OAuthProvider.KAKAO)).willReturn( expectedRedirectUrl); - // then + // when, then mockMvc.perform(get("/api/v1/oauth2.0/{oAuthProvider}", OAuthProvider.KAKAO) .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON) diff --git a/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/authcode/KakaoAuthCodeRequestUrlProviderTest.java b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/authcode/KakaoAuthCodeRequestUrlProviderTest.java index b85719e8..2bdb2fd4 100644 --- a/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/authcode/KakaoAuthCodeRequestUrlProviderTest.java +++ b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/authcode/KakaoAuthCodeRequestUrlProviderTest.java @@ -1,7 +1,7 @@ package coffeemeet.server.oauth.infrastructure.kakao.authcode; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; +import static org.mockito.BDDMockito.given; import coffeemeet.server.oauth.infrastructure.kakao.config.KakaoProperties; import coffeemeet.server.user.domain.OAuthProvider; @@ -24,10 +24,10 @@ class KakaoAuthCodeRequestUrlProviderTest { @DisplayName("카카오 프로바이더를 제공할 수 있다.") @Test void oAuthProviderTest() { - // given + // when OAuthProvider oAuthProvider = provider.oAuthProvider(); - // when, then + // then assertThat(oAuthProvider).isEqualTo(OAuthProvider.KAKAO); } @@ -37,12 +37,13 @@ void provideTest() { // given String resultUrl = "https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=testClientId&redirect_uri=https://testClientId/redirect"; + given(kakaoProperties.getClientId()).willReturn("testClientId"); + given(kakaoProperties.getRedirectUrl()).willReturn("https://testClientId/redirect"); + // when - when(kakaoProperties.getClientId()).thenReturn("testClientId"); - when(kakaoProperties.getRedirectUrl()).thenReturn("https://testClientId/redirect"); + String expectedUrl = provider.provide(); // then - String expectedUrl = provider.provide(); assertThat(resultUrl).isEqualTo(expectedUrl); } diff --git a/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoApiClientTest.java b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoApiClientTest.java index a07e642b..50a774fe 100644 --- a/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoApiClientTest.java +++ b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoApiClientTest.java @@ -5,7 +5,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.when; +import static org.mockito.BDDMockito.given; import coffeemeet.server.common.fixture.dto.KakaoMemberResponseFixture; import coffeemeet.server.common.fixture.dto.KakaoTokensFixture; @@ -42,18 +42,19 @@ void fetchTokenTest() { String authCode = "authCode"; KakaoTokens kakaoTokens = KakaoTokensFixture.kakaoTokens(); - // when - when(kakaoProperties.getClientId()).thenReturn("testClientId"); - when(kakaoProperties.getRedirectUrl()).thenReturn("testRedirectUrl"); - when(kakaoProperties.getClientSecret()).thenReturn("testClientSecret"); - when(restTemplate.postForObject( + given(kakaoProperties.getClientId()).willReturn("testClientId"); + given(kakaoProperties.getRedirectUrl()).willReturn("testRedirectUrl"); + given(kakaoProperties.getClientSecret()).willReturn("testClientSecret"); + given(restTemplate.postForObject( anyString(), any(HttpEntity.class), eq(KakaoTokens.class))) - .thenReturn(kakaoTokens); + .willReturn(kakaoTokens); - // then + // when KakaoTokens expectedTokens = kakaoApiClient.fetchToken(authCode); + + // then assertAll( () -> assertThat(expectedTokens).isNotNull(), () -> assertThat(expectedTokens.accessToken()).isEqualTo(kakaoTokens.accessToken()), @@ -72,16 +73,17 @@ void fetchMemberTest() { KakaoMemberResponse response = KakaoMemberResponseFixture.kakaoMemberResponse(); ResponseEntity mockResponse = ResponseEntity.ok(response); - // when - when(restTemplate.exchange( + given(restTemplate.exchange( anyString(), any(HttpMethod.class), any(HttpEntity.class), eq(KakaoMemberResponse.class))) - .thenReturn(mockResponse); + .willReturn(mockResponse); - // then + // when KakaoMemberResponse result = kakaoApiClient.fetchMember("accessToken"); + + // then assertThat(result).isNotNull(); } diff --git a/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClientTest.java b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClientTest.java index 455af895..20410236 100644 --- a/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClientTest.java +++ b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClientTest.java @@ -2,7 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; +import static org.mockito.BDDMockito.given; import coffeemeet.server.common.fixture.dto.KakaoMemberResponseFixture; import coffeemeet.server.common.fixture.dto.KakaoTokensFixture; @@ -28,7 +28,7 @@ class KakaoMemberClientTest { @DisplayName("카카오 프로바이더를 가져올 수 있다.") @Test void oAuthProvider() { - // given, when, then + // when, then assertThat(kakaoMemberClient.oAuthProvider()).isEqualTo(OAuthProvider.KAKAO); } @@ -37,15 +37,13 @@ void oAuthProvider() { void fetch() { // given String authCode = "authCode"; - KakaoTokens kakaoTokens = KakaoTokensFixture.kakaoTokens(); KakaoMemberResponse response = KakaoMemberResponseFixture.kakaoMemberResponse(); - // when - when(kakaoApiClient.fetchToken(any())).thenReturn(kakaoTokens); - when(kakaoApiClient.fetchMember(any())).thenReturn(response); + given(kakaoApiClient.fetchToken(any())).willReturn(kakaoTokens); + given(kakaoApiClient.fetchMember(any())).willReturn(response); - // then + // when, then assertThat(kakaoMemberClient.fetch(authCode)).isNotNull(); } diff --git a/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java b/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java index 6b68adf4..df36a011 100644 --- a/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java +++ b/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java @@ -1,7 +1,7 @@ package coffeemeet.server.oauth.service; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; +import static org.mockito.BDDMockito.given; import coffeemeet.server.common.fixture.dto.OAuthInfoResponseFixture; import coffeemeet.server.oauth.authcode.AuthCodeRequestUrlProviderComposite; @@ -33,11 +33,12 @@ void getAuthCodeRequestUrlTest() { // given String expectedUrl = "https://example.com"; + given(authCodeRequestUrlProviderComposite.provide(OAuthProvider.KAKAO)).willReturn(expectedUrl); + // when - when(authCodeRequestUrlProviderComposite.provide(OAuthProvider.KAKAO)).thenReturn(expectedUrl); + String result = oAuthService.getAuthCodeRequestUrl(OAuthProvider.KAKAO); // then - String result = oAuthService.getAuthCodeRequestUrl(OAuthProvider.KAKAO); assertThat(result).isEqualTo(expectedUrl); } @@ -49,10 +50,9 @@ void getOAuthInfoTest() { String authCode = "authCode"; OAuthInfoResponse oAuthInfoResponse = OAuthInfoResponseFixture.oAuthInfoResponse(); - // when - when(oAuthMemberClientComposite.fetch(oAuthProvider, authCode)).thenReturn(oAuthInfoResponse); + given(oAuthMemberClientComposite.fetch(oAuthProvider, authCode)).willReturn(oAuthInfoResponse); - // then + // when, then assertThat(oAuthService.getOAuthInfo(oAuthProvider, authCode)).isEqualTo(oAuthInfoResponse); } From 2fe406d71977ee5e882c869f1ffe343d0b426d7f Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 00:09:57 +0900 Subject: [PATCH 194/311] =?UTF-8?q?refactor:=20OAuthInfoResponse=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/oauth/dto/OAuthInfoResponse.java | 35 ------------------- 1 file changed, 35 deletions(-) delete mode 100644 src/main/java/coffeemeet/server/oauth/dto/OAuthInfoResponse.java diff --git a/src/main/java/coffeemeet/server/oauth/dto/OAuthInfoResponse.java b/src/main/java/coffeemeet/server/oauth/dto/OAuthInfoResponse.java deleted file mode 100644 index df92e221..00000000 --- a/src/main/java/coffeemeet/server/oauth/dto/OAuthInfoResponse.java +++ /dev/null @@ -1,35 +0,0 @@ -package coffeemeet.server.oauth.dto; - -import coffeemeet.server.user.domain.OAuthProvider; - -public record OAuthInfoResponse( - String name, - String profileImage, - String birthYear, - String birthDay, - String email, - OAuthProvider oAuthProvider, - String oAuthProviderId -) { - - public static OAuthInfoResponse of( - String name, - String profileImage, - String birthYear, - String birthDay, - String email, - OAuthProvider oAuthProvider, - String oAuthProviderId - ) { - return new OAuthInfoResponse( - name, - profileImage, - birthYear, - birthDay, - email, - oAuthProvider, - oAuthProviderId - ); - } - -} From 9fb6d8d6d3d7e39f55338e16f891e771cfd54567 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 00:10:42 +0900 Subject: [PATCH 195/311] =?UTF-8?q?feat:=20OAuthInfoDto=20interface=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 - sealed 적용 - Response 추가 --- .../server/oauth/dto/OAuthInfoDto.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/main/java/coffeemeet/server/oauth/dto/OAuthInfoDto.java diff --git a/src/main/java/coffeemeet/server/oauth/dto/OAuthInfoDto.java b/src/main/java/coffeemeet/server/oauth/dto/OAuthInfoDto.java new file mode 100644 index 00000000..9442fd87 --- /dev/null +++ b/src/main/java/coffeemeet/server/oauth/dto/OAuthInfoDto.java @@ -0,0 +1,38 @@ +package coffeemeet.server.oauth.dto; + +import coffeemeet.server.user.domain.OAuthProvider; + +public sealed interface OAuthInfoDto permits OAuthInfoDto.Response { + + record Response( + String name, + String profileImage, + String birthYear, + String birthDay, + String email, + OAuthProvider oAuthProvider, + String oAuthProviderId + ) implements OAuthInfoDto { + + public static OAuthInfoDto.Response of( + String name, + String profileImage, + String birthYear, + String birthDay, + String email, + OAuthProvider oAuthProvider, + String oAuthProviderId + ) { + return new OAuthInfoDto.Response( + name, + profileImage, + birthYear, + birthDay, + email, + oAuthProvider, + oAuthProviderId + ); + } + } + +} From f042e535d08dcfbcd2ec9f3ccfb4e838d7896e94 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 00:11:04 +0900 Subject: [PATCH 196/311] =?UTF-8?q?refactor:=20OAuthInfoDto=20interface=20?= =?UTF-8?q?=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/oauth/client/OAuthMemberClient.java | 4 ++-- .../server/oauth/client/OAuthMemberClientComposite.java | 4 ++-- .../infrastructure/kakao/client/KakaoMemberClient.java | 4 ++-- .../infrastructure/kakao/dto/KakaoMemberResponse.java | 6 +++--- .../coffeemeet/server/oauth/service/OAuthService.java | 4 ++-- .../java/coffeemeet/server/user/service/UserService.java | 8 ++++---- .../common/fixture/dto/OAuthInfoResponseFixture.java | 6 +++--- .../oauth/client/OAuthMemberClientCompositeTest.java | 6 +++--- .../coffeemeet/server/oauth/service/OAuthServiceTest.java | 4 ++-- 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClient.java b/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClient.java index b9773906..a3f81b1f 100644 --- a/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClient.java +++ b/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClient.java @@ -1,12 +1,12 @@ package coffeemeet.server.oauth.client; -import coffeemeet.server.oauth.dto.OAuthInfoResponse; +import coffeemeet.server.oauth.dto.OAuthInfoDto; import coffeemeet.server.user.domain.OAuthProvider; public interface OAuthMemberClient { OAuthProvider oAuthProvider(); - OAuthInfoResponse fetch(String authCode); + OAuthInfoDto.Response fetch(String authCode); } diff --git a/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java b/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java index 33ac6e71..71796d74 100644 --- a/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java +++ b/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java @@ -1,6 +1,6 @@ package coffeemeet.server.oauth.client; -import coffeemeet.server.oauth.dto.OAuthInfoResponse; +import coffeemeet.server.oauth.dto.OAuthInfoDto; import coffeemeet.server.user.domain.OAuthProvider; import java.util.Map; import java.util.Optional; @@ -21,7 +21,7 @@ public OAuthMemberClientComposite(Set clients) { ); } - public OAuthInfoResponse fetch(OAuthProvider oAuthProvider, String authCode) { + public OAuthInfoDto.Response fetch(OAuthProvider oAuthProvider, String authCode) { return getClient(oAuthProvider).fetch(authCode); } diff --git a/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClient.java b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClient.java index b0c13acc..1cc51007 100644 --- a/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClient.java +++ b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClient.java @@ -1,7 +1,7 @@ package coffeemeet.server.oauth.infrastructure.kakao.client; import coffeemeet.server.oauth.client.OAuthMemberClient; -import coffeemeet.server.oauth.dto.OAuthInfoResponse; +import coffeemeet.server.oauth.dto.OAuthInfoDto; import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoMemberResponse; import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoTokens; import coffeemeet.server.user.domain.OAuthProvider; @@ -20,7 +20,7 @@ public OAuthProvider oAuthProvider() { } @Override - public OAuthInfoResponse fetch(String authCode) { + public OAuthInfoDto.Response fetch(String authCode) { KakaoTokens tokenInfo = kakaoApiClient.fetchToken(authCode); KakaoMemberResponse response = kakaoApiClient.fetchMember(tokenInfo.accessToken()); diff --git a/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberResponse.java b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberResponse.java index 5ddaca2a..0863930e 100644 --- a/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberResponse.java +++ b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberResponse.java @@ -1,6 +1,6 @@ package coffeemeet.server.oauth.infrastructure.kakao.dto; -import coffeemeet.server.oauth.dto.OAuthInfoResponse; +import coffeemeet.server.oauth.dto.OAuthInfoDto; import coffeemeet.server.user.domain.OAuthProvider; import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; import com.fasterxml.jackson.databind.annotation.JsonNaming; @@ -11,8 +11,8 @@ public record KakaoMemberResponse( KakaoAccount kakaoAccount ) { - public OAuthInfoResponse toOAuthInfoResponse() { - return OAuthInfoResponse.of( + public OAuthInfoDto.Response toOAuthInfoResponse() { + return OAuthInfoDto.Response.of( kakaoAccount.name, kakaoAccount.profile.profileImageUrl, kakaoAccount.birthyear, diff --git a/src/main/java/coffeemeet/server/oauth/service/OAuthService.java b/src/main/java/coffeemeet/server/oauth/service/OAuthService.java index f0148f76..29aac986 100644 --- a/src/main/java/coffeemeet/server/oauth/service/OAuthService.java +++ b/src/main/java/coffeemeet/server/oauth/service/OAuthService.java @@ -2,7 +2,7 @@ import coffeemeet.server.oauth.authcode.AuthCodeRequestUrlProviderComposite; import coffeemeet.server.oauth.client.OAuthMemberClientComposite; -import coffeemeet.server.oauth.dto.OAuthInfoResponse; +import coffeemeet.server.oauth.dto.OAuthInfoDto; import coffeemeet.server.user.domain.OAuthProvider; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -18,7 +18,7 @@ public String getAuthCodeRequestUrl(OAuthProvider oAuthProvider) { return authCodeRequestUrlProviderComposite.provide(oAuthProvider); } - public OAuthInfoResponse getOAuthInfo(OAuthProvider oAuthProvider, String authCode) { + public OAuthInfoDto.Response getOAuthInfo(OAuthProvider oAuthProvider, String authCode) { return oauthMemberClientComposite.fetch(oAuthProvider, authCode); } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index f493d380..ae0130be 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -11,7 +11,7 @@ import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.interest.repository.InterestRepository; import coffeemeet.server.interest.service.InterestService; -import coffeemeet.server.oauth.dto.OAuthInfoResponse; +import coffeemeet.server.oauth.dto.OAuthInfoDto; import coffeemeet.server.oauth.service.OAuthService; import coffeemeet.server.user.domain.Birth; import coffeemeet.server.user.domain.Email; @@ -94,7 +94,7 @@ public void updateProfileInfo(Long userId, String nickname, String name, @Transactional public AuthTokens signup(SignupRequest request) { - OAuthInfoResponse response = oAuthService.getOAuthInfo(request.oAuthProvider(), + OAuthInfoDto.Response response = oAuthService.getOAuthInfo(request.oAuthProvider(), request.authCode()); checkDuplicatedUser(response); @@ -113,7 +113,7 @@ public AuthTokens signup(SignupRequest request) { } public AuthTokens login(OAuthProvider oAuthProvider, String authCode) { - OAuthInfoResponse response = oAuthService.getOAuthInfo(oAuthProvider, authCode); + OAuthInfoDto.Response response = oAuthService.getOAuthInfo(oAuthProvider, authCode); User foundUser = userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( response.oAuthProvider(), response.oAuthProviderId()).orElseThrow( () -> new IllegalArgumentException( @@ -134,7 +134,7 @@ public void checkDuplicatedNickname(String nickname) { } } - public void checkDuplicatedUser(OAuthInfoResponse response) { + public void checkDuplicatedUser(OAuthInfoDto.Response response) { if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( response.oAuthProvider(), response.oAuthProviderId())) { throw new IllegalArgumentException(ALREADY_REGISTERED_MESSAGE); diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java index 98ff5b00..a9e3f15f 100644 --- a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java @@ -1,12 +1,12 @@ package coffeemeet.server.common.fixture.dto; -import coffeemeet.server.oauth.dto.OAuthInfoResponse; +import coffeemeet.server.oauth.dto.OAuthInfoDto; import org.instancio.Instancio; public class OAuthInfoResponseFixture { - public static OAuthInfoResponse oAuthInfoResponse() { - return Instancio.of(OAuthInfoResponse.class) + public static OAuthInfoDto.Response oAuthInfoResponse() { + return Instancio.of(OAuthInfoDto.Response.class) .create(); } diff --git a/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java index fdf66136..324dc45d 100644 --- a/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java +++ b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java @@ -4,7 +4,7 @@ import static org.mockito.BDDMockito.given; import coffeemeet.server.common.fixture.dto.OAuthInfoResponseFixture; -import coffeemeet.server.oauth.dto.OAuthInfoResponse; +import coffeemeet.server.oauth.dto.OAuthInfoDto; import coffeemeet.server.user.domain.OAuthProvider; import java.util.Collections; import java.util.HashSet; @@ -34,7 +34,7 @@ void fetchTest() { // given String authCode = "authCode"; OAuthProvider oAuthProvider = OAuthProvider.KAKAO; - OAuthInfoResponse response = OAuthInfoResponseFixture.oAuthInfoResponse(); + OAuthInfoDto.Response response = OAuthInfoResponseFixture.oAuthInfoResponse(); given(client.oAuthProvider()).willReturn(OAuthProvider.KAKAO); given(client.fetch(authCode)).willReturn(response); @@ -43,7 +43,7 @@ void fetchTest() { composite = new OAuthMemberClientComposite(clients); // when - OAuthInfoResponse expectedResponse = composite.fetch(oAuthProvider, authCode); + OAuthInfoDto.Response expectedResponse = composite.fetch(oAuthProvider, authCode); // then assertThat(response).isEqualTo(expectedResponse); diff --git a/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java b/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java index df36a011..96d368f5 100644 --- a/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java +++ b/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java @@ -6,7 +6,7 @@ import coffeemeet.server.common.fixture.dto.OAuthInfoResponseFixture; import coffeemeet.server.oauth.authcode.AuthCodeRequestUrlProviderComposite; import coffeemeet.server.oauth.client.OAuthMemberClientComposite; -import coffeemeet.server.oauth.dto.OAuthInfoResponse; +import coffeemeet.server.oauth.dto.OAuthInfoDto; import coffeemeet.server.user.domain.OAuthProvider; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -48,7 +48,7 @@ void getOAuthInfoTest() { // given OAuthProvider oAuthProvider = OAuthProvider.KAKAO; String authCode = "authCode"; - OAuthInfoResponse oAuthInfoResponse = OAuthInfoResponseFixture.oAuthInfoResponse(); + OAuthInfoDto.Response oAuthInfoResponse = OAuthInfoResponseFixture.oAuthInfoResponse(); given(oAuthMemberClientComposite.fetch(oAuthProvider, authCode)).willReturn(oAuthInfoResponse); From 17fc6d738c9ff681d91a23fa09a6352a6af17667 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 13:51:25 +0900 Subject: [PATCH 197/311] =?UTF-8?q?feat:=20TestContainerConfig=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/config/TestContainerConfig.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/test/java/coffeemeet/server/common/config/TestContainerConfig.java diff --git a/src/test/java/coffeemeet/server/common/config/TestContainerConfig.java b/src/test/java/coffeemeet/server/common/config/TestContainerConfig.java new file mode 100644 index 00000000..eeba396f --- /dev/null +++ b/src/test/java/coffeemeet/server/common/config/TestContainerConfig.java @@ -0,0 +1,29 @@ +package coffeemeet.server.common.config; + +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.junit.jupiter.Testcontainers; + +@Testcontainers +public class TestContainerConfig { + + private static final String REDIS_IMAGE = "redis:7.0.8-alpine"; + private static final int REDIS_PORT = 6379; + private static final GenericContainer redis; + + static { + redis = new GenericContainer(REDIS_IMAGE) + .withExposedPorts(REDIS_PORT) + .withReuse(true); + redis.start(); + } + + @DynamicPropertySource + private static void registerRedisProperties(DynamicPropertyRegistry registry) { + registry.add("spring.data.redis.host", redis::getHost); + registry.add("spring.data.redis.port", () -> redis.getMappedPort(REDIS_PORT) + .toString()); + } + +} From 34d648a1ef29d6e0008528edfae67d6008830794 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 14:36:15 +0900 Subject: [PATCH 198/311] =?UTF-8?q?style:=20OAuthInfoDtoFixture=20?= =?UTF-8?q?=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...OAuthInfoResponseFixture.java => OAuthInfoDtoFixture.java} | 4 ++-- .../server/oauth/client/OAuthMemberClientCompositeTest.java | 4 ++-- .../coffeemeet/server/oauth/service/OAuthServiceTest.java | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename src/test/java/coffeemeet/server/common/fixture/dto/{OAuthInfoResponseFixture.java => OAuthInfoDtoFixture.java} (67%) diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoDtoFixture.java similarity index 67% rename from src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java rename to src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoDtoFixture.java index a9e3f15f..c09d143a 100644 --- a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoDtoFixture.java @@ -3,9 +3,9 @@ import coffeemeet.server.oauth.dto.OAuthInfoDto; import org.instancio.Instancio; -public class OAuthInfoResponseFixture { +public class OAuthInfoDtoFixture { - public static OAuthInfoDto.Response oAuthInfoResponse() { + public static OAuthInfoDto.Response response() { return Instancio.of(OAuthInfoDto.Response.class) .create(); } diff --git a/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java index 324dc45d..fcf9b179 100644 --- a/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java +++ b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; -import coffeemeet.server.common.fixture.dto.OAuthInfoResponseFixture; +import coffeemeet.server.common.fixture.dto.OAuthInfoDtoFixture; import coffeemeet.server.oauth.dto.OAuthInfoDto; import coffeemeet.server.user.domain.OAuthProvider; import java.util.Collections; @@ -34,7 +34,7 @@ void fetchTest() { // given String authCode = "authCode"; OAuthProvider oAuthProvider = OAuthProvider.KAKAO; - OAuthInfoDto.Response response = OAuthInfoResponseFixture.oAuthInfoResponse(); + OAuthInfoDto.Response response = OAuthInfoDtoFixture.response(); given(client.oAuthProvider()).willReturn(OAuthProvider.KAKAO); given(client.fetch(authCode)).willReturn(response); diff --git a/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java b/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java index 96d368f5..ea79dd99 100644 --- a/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java +++ b/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; -import coffeemeet.server.common.fixture.dto.OAuthInfoResponseFixture; +import coffeemeet.server.common.fixture.dto.OAuthInfoDtoFixture; import coffeemeet.server.oauth.authcode.AuthCodeRequestUrlProviderComposite; import coffeemeet.server.oauth.client.OAuthMemberClientComposite; import coffeemeet.server.oauth.dto.OAuthInfoDto; @@ -48,7 +48,7 @@ void getOAuthInfoTest() { // given OAuthProvider oAuthProvider = OAuthProvider.KAKAO; String authCode = "authCode"; - OAuthInfoDto.Response oAuthInfoResponse = OAuthInfoResponseFixture.oAuthInfoResponse(); + OAuthInfoDto.Response oAuthInfoResponse = OAuthInfoDtoFixture.response(); given(oAuthMemberClientComposite.fetch(oAuthProvider, authCode)).willReturn(oAuthInfoResponse); From dc72a7c0972de4c8af57aec50d3cf70e562b2434 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 15:37:41 +0900 Subject: [PATCH 199/311] =?UTF-8?q?feat:=20RefreshTokenFixture=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 --- .../common/fixture/dto/RefreshTokenFixture.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/test/java/coffeemeet/server/common/fixture/dto/RefreshTokenFixture.java diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/RefreshTokenFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/RefreshTokenFixture.java new file mode 100644 index 00000000..9140ba1a --- /dev/null +++ b/src/test/java/coffeemeet/server/common/fixture/dto/RefreshTokenFixture.java @@ -0,0 +1,13 @@ +package coffeemeet.server.common.fixture.dto; + +import coffeemeet.server.auth.domain.RefreshToken; +import org.instancio.Instancio; + +public class RefreshTokenFixture { + + public static RefreshToken refreshToken() { + return Instancio.of(RefreshToken.class) + .create(); + } + +} From 09334bd998d960b1fc4707c58c62ae2cb9c208da Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 15:37:50 +0900 Subject: [PATCH 200/311] =?UTF-8?q?feat:=20AuthTokensFixture=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 --- .../common/fixture/dto/AuthTokensFixture.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/test/java/coffeemeet/server/common/fixture/dto/AuthTokensFixture.java diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/AuthTokensFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/AuthTokensFixture.java new file mode 100644 index 00000000..ce0be0e2 --- /dev/null +++ b/src/test/java/coffeemeet/server/common/fixture/dto/AuthTokensFixture.java @@ -0,0 +1,13 @@ +package coffeemeet.server.common.fixture.dto; + +import coffeemeet.server.auth.domain.AuthTokens; +import org.instancio.Instancio; + +public class AuthTokensFixture { + + public static AuthTokens authTokens() { + return Instancio.of(AuthTokens.class) + .create(); + } + +} From bf6e8df4ce0bd39e9614677dbd34a54bc6e706de Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 15:38:27 +0900 Subject: [PATCH 201/311] =?UTF-8?q?refactor:=20@RequestMapping("/api/v1/au?= =?UTF-8?q?th")=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/auth/controller/AuthController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/auth/controller/AuthController.java b/src/main/java/coffeemeet/server/auth/controller/AuthController.java index 5ba14558..d2549563 100644 --- a/src/main/java/coffeemeet/server/auth/controller/AuthController.java +++ b/src/main/java/coffeemeet/server/auth/controller/AuthController.java @@ -12,7 +12,7 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/auth") +@RequestMapping("/api/v1/auth") public class AuthController { private final AuthService authService; From 76dbd4cb096202b44597b1658c430aa46717c5bb Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 15:40:05 +0900 Subject: [PATCH 202/311] =?UTF-8?q?test:=20renewTest=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/controller/AuthControllerTest.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java diff --git a/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java b/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java new file mode 100644 index 00000000..e72ff4a8 --- /dev/null +++ b/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java @@ -0,0 +1,76 @@ +package coffeemeet.server.auth.controller; + +import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; +import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.resourceDetails; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.BDDMockito.given; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import coffeemeet.server.auth.domain.AuthTokens; +import coffeemeet.server.auth.domain.RefreshToken; +import coffeemeet.server.auth.service.AuthService; +import coffeemeet.server.common.config.ControllerTestConfig; +import coffeemeet.server.common.fixture.dto.AuthTokensFixture; +import coffeemeet.server.common.fixture.dto.RefreshTokenFixture; +import com.epages.restdocs.apispec.Schema; +import java.util.Optional; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.restdocs.payload.JsonFieldType; + +@WebMvcTest(AuthController.class) +class AuthControllerTest extends ControllerTestConfig { + + @MockBean + private AuthService authService; + + @DisplayName("refresh token 을 통해 access token 을 갱신할 수 있다.") + @Test + void renewTest() throws Exception { + // given + AuthTokens authTokens = AuthTokensFixture.authTokens(); + RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); + given(authService.renew(anyLong(), any())).willReturn(authTokens); + given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + + // when, then + mockMvc.perform(post("/api/v1/auth/renew-token") + .header("Authorization", TOKEN) + .contentType(MediaType.APPLICATION_JSON) + ) + .andDo(document("renew-token", + resourceDetails().tag("인증").description("토큰 갱신") + .responseSchema(Schema.schema("AuthTokens")), + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + responseFields( + fieldWithPath("accessToken").type(JsonFieldType.STRING).description("액세스 토큰"), + fieldWithPath("refreshToken").type(JsonFieldType.STRING).description("리프레시 토큰") + ) + ) + ) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.accessToken").value(authTokens.accessToken())) + .andExpect(jsonPath("$.refreshToken").value(authTokens.refreshToken())); + } + + @Test + void logoutTest() { + } + + @Test + void deleteTest() { + } + +} From 798c760f83f112acbc646ae15fc256971e29ded5 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 16:16:01 +0900 Subject: [PATCH 203/311] =?UTF-8?q?test:=20logoutTest=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/controller/AuthControllerTest.java | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java b/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java index e72ff4a8..99e755bb 100644 --- a/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java +++ b/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java @@ -5,6 +5,9 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doNothing; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest; import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; @@ -41,6 +44,7 @@ void renewTest() throws Exception { // given AuthTokens authTokens = AuthTokensFixture.authTokens(); RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); + given(authService.renew(anyLong(), any())).willReturn(authTokens); given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); @@ -49,11 +53,14 @@ void renewTest() throws Exception { .header("Authorization", TOKEN) .contentType(MediaType.APPLICATION_JSON) ) - .andDo(document("renew-token", + .andDo(document("auth-renew", resourceDetails().tag("인증").description("토큰 갱신") .responseSchema(Schema.schema("AuthTokens")), preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()), + requestHeaders( + headerWithName("Authorization").description("토큰") + ), responseFields( fieldWithPath("accessToken").type(JsonFieldType.STRING).description("액세스 토큰"), fieldWithPath("refreshToken").type(JsonFieldType.STRING).description("리프레시 토큰") @@ -65,8 +72,31 @@ void renewTest() throws Exception { .andExpect(jsonPath("$.refreshToken").value(authTokens.refreshToken())); } + @DisplayName("사용자는 로그아웃 할 수 있다.") @Test - void logoutTest() { + void logoutTest() throws Exception { + // given + AuthTokens authTokens = AuthTokensFixture.authTokens(); + RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); + + doNothing().when(authService).logout(anyLong()); + given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + + // when, then + mockMvc.perform(post("/api/v1/auth/logout") + .header("Authorization", TOKEN) + .contentType(MediaType.APPLICATION_JSON) + ) + .andDo(document("auth-logout", + resourceDetails().tag("인증").description("로그아웃"), + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + requestHeaders( + headerWithName("Authorization").description("토큰") + ) + ) + ) + .andExpect(status().isOk()); } @Test From a79d935217bb8d1f7fe9ce864dc5c7824b0446c9 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 16:22:38 +0900 Subject: [PATCH 204/311] =?UTF-8?q?test:=20deleteTest=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/controller/AuthControllerTest.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java b/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java index 99e755bb..d9c03a48 100644 --- a/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java +++ b/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java @@ -76,7 +76,6 @@ void renewTest() throws Exception { @Test void logoutTest() throws Exception { // given - AuthTokens authTokens = AuthTokensFixture.authTokens(); RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); doNothing().when(authService).logout(anyLong()); @@ -99,8 +98,30 @@ void logoutTest() throws Exception { .andExpect(status().isOk()); } + @DisplayName("사용자는 회원탈퇴 할 수 있다.") @Test - void deleteTest() { + void deleteTest() throws Exception { + // given + RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); + + doNothing().when(authService).delete(anyLong()); + given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + + // when, then + mockMvc.perform(post("/api/v1/auth/delete") + .header("Authorization", TOKEN) + .contentType(MediaType.APPLICATION_JSON) + ) + .andDo(document("auth-delete", + resourceDetails().tag("인증").description("회원탈퇴"), + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + requestHeaders( + headerWithName("Authorization").description("토큰") + ) + ) + ) + .andExpect(status().isOk()); } } From c1ad650574a37dc98c10489b95e71318a45599df Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 16:48:04 +0900 Subject: [PATCH 205/311] =?UTF-8?q?test:=20generateTest=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 --- .../auth/domain/AuthTokensGeneratorTest.java | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java diff --git a/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java b/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java new file mode 100644 index 00000000..94567f12 --- /dev/null +++ b/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java @@ -0,0 +1,52 @@ +package coffeemeet.server.auth.domain; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; + +import coffeemeet.server.auth.repository.RefreshTokenRepository; +import java.util.Date; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class AuthTokensGeneratorTest { + + private static final Long accessTokenExpireTime = 1800L; + private static final Long refreshTokenExpireTime = 3600L; + private static final String BEARER_TYPE = "Bearer "; + private static final String ACCESS_TOKEN = "accessToken"; + private static final String REFRESH_TOKEN = "refreshToken"; + + @InjectMocks + private AuthTokensGenerator authTokensGenerator; + + @Mock + private JwtTokenProvider jwtTokenProvider; + + @Mock + private RefreshTokenRepository refreshTokenRepository; + + @BeforeEach + public void init() { + authTokensGenerator = new AuthTokensGenerator(jwtTokenProvider, accessTokenExpireTime, + refreshTokenExpireTime, refreshTokenRepository); + } + + @Test + void generateTest() { + // given + when(jwtTokenProvider.generate(anyString(), any(Date.class))).thenReturn(ACCESS_TOKEN, + REFRESH_TOKEN); + AuthTokens authTokens = authTokensGenerator.generate((long) Math.random()); + + assertThat(authTokens.accessToken()).isEqualTo(BEARER_TYPE + ACCESS_TOKEN); + assertThat(authTokens.refreshToken()).isEqualTo(BEARER_TYPE + REFRESH_TOKEN); + } + +} From 152fd565db9a4d3532c826e9e055bfc164dc0b71 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 16:51:00 +0900 Subject: [PATCH 206/311] =?UTF-8?q?test:=20refreshJwtTokenTest=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 --- .../auth/domain/AuthTokensGeneratorTest.java | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java b/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java index 94567f12..68654d39 100644 --- a/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java +++ b/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java @@ -1,6 +1,7 @@ package coffeemeet.server.auth.domain; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; @@ -43,10 +44,32 @@ void generateTest() { // given when(jwtTokenProvider.generate(anyString(), any(Date.class))).thenReturn(ACCESS_TOKEN, REFRESH_TOKEN); + + // when AuthTokens authTokens = authTokensGenerator.generate((long) Math.random()); - assertThat(authTokens.accessToken()).isEqualTo(BEARER_TYPE + ACCESS_TOKEN); - assertThat(authTokens.refreshToken()).isEqualTo(BEARER_TYPE + REFRESH_TOKEN); + // then + assertAll( + () -> assertThat(authTokens.accessToken()).isEqualTo(BEARER_TYPE + ACCESS_TOKEN), + () -> assertThat(authTokens.refreshToken()).isEqualTo(BEARER_TYPE + REFRESH_TOKEN) + ); + } + + @Test + void refreshJwtTokenTest() { + // given + when(jwtTokenProvider.generate(anyString(), any(Date.class))).thenReturn(ACCESS_TOKEN, + REFRESH_TOKEN); + + // when + AuthTokens authTokens = authTokensGenerator.reissueAccessToken((long) Math.random(), + REFRESH_TOKEN); + + // then + assertAll( + () -> assertThat(authTokens.accessToken()).isEqualTo(BEARER_TYPE + ACCESS_TOKEN), + () -> assertThat(authTokens.refreshToken()).isEqualTo(BEARER_TYPE + REFRESH_TOKEN) + ); } } From 7b994d724dd28a2a7ee15424668c2880156ed6c4 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 17:28:10 +0900 Subject: [PATCH 207/311] =?UTF-8?q?test:=20AuthTokensGeneratorTest=20?= =?UTF-8?q?=EC=84=A4=EB=AA=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/auth/domain/AuthTokensGeneratorTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java b/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java index 68654d39..9f380338 100644 --- a/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java +++ b/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java @@ -9,6 +9,7 @@ import coffeemeet.server.auth.repository.RefreshTokenRepository; import java.util.Date; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -39,6 +40,7 @@ public void init() { refreshTokenExpireTime, refreshTokenRepository); } + @DisplayName("access token & refresh token 발급할 수 있다.") @Test void generateTest() { // given @@ -55,8 +57,9 @@ void generateTest() { ); } + @DisplayName("access token 을 갱신 할 수 있다.") @Test - void refreshJwtTokenTest() { + void reissueAccessTokenTest() { // given when(jwtTokenProvider.generate(anyString(), any(Date.class))).thenReturn(ACCESS_TOKEN, REFRESH_TOKEN); From 7dc2e5600d5b649377ad45a3d902e0b8dbaa1be9 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 17:46:53 +0900 Subject: [PATCH 208/311] =?UTF-8?q?test:=20JwtTokenProviderTest=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 --- .../auth/domain/JwtTokenProviderTest.java | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/test/java/coffeemeet/server/auth/domain/JwtTokenProviderTest.java diff --git a/src/test/java/coffeemeet/server/auth/domain/JwtTokenProviderTest.java b/src/test/java/coffeemeet/server/auth/domain/JwtTokenProviderTest.java new file mode 100644 index 00000000..2b22d811 --- /dev/null +++ b/src/test/java/coffeemeet/server/auth/domain/JwtTokenProviderTest.java @@ -0,0 +1,64 @@ +package coffeemeet.server.auth.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; +import java.util.Base64; +import java.util.Date; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class JwtTokenProviderTest { + + private static final String SUBJECT = "123"; + private static final int ACCESS_TOKEN_EXPIRE_TIME = 3600000; + + private final String secretKey = Base64.getEncoder() + .encodeToString(Keys.secretKeyFor(SignatureAlgorithm.HS512).getEncoded()); + + private JwtTokenProvider jwtTokenProvider = new JwtTokenProvider(secretKey); + + @DisplayName("jwt 를 생성할 수 있다.") + @Test + void generate() { + // given + Date date = new Date(System.currentTimeMillis() + ACCESS_TOKEN_EXPIRE_TIME); + + // when + String result = jwtTokenProvider.generate(SUBJECT, date); + + // then + assertThat(result).isNotNull(); + } + + @DisplayName("jwt 로부터 userId 를 가져올 수 있다.") + @Test + void extractUserId() { + // given + Date date = new Date(System.currentTimeMillis() + ACCESS_TOKEN_EXPIRE_TIME); + + // when + String token = jwtTokenProvider.generate(SUBJECT, date); + Long result = jwtTokenProvider.extractUserId(token); + + // then + assertThat(result).isEqualTo(Long.parseLong(SUBJECT)); + } + + @DisplayName("jwt(refresh token) 로부터 토큰이 만료되었는지 확인할 수 있다.") + @Test + void isExpiredRefreshToken() { + // given + Date date = new Date(System.currentTimeMillis() + ACCESS_TOKEN_EXPIRE_TIME); + + String token = jwtTokenProvider.generate(SUBJECT, date); + + // when, then + assertThat(jwtTokenProvider.isExpiredRefreshToken(token)).isFalse(); + } + +} From 07109a2319894bc1d119cc4835d0340142f1b3da Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 18:29:23 +0900 Subject: [PATCH 209/311] test: add authTokens fixture --- .../server/common/fixture/dto/AuthTokensFixture.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/AuthTokensFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/AuthTokensFixture.java index ce0be0e2..3d657555 100644 --- a/src/test/java/coffeemeet/server/common/fixture/dto/AuthTokensFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/dto/AuthTokensFixture.java @@ -1,5 +1,7 @@ package coffeemeet.server.common.fixture.dto; +import static org.instancio.Select.field; + import coffeemeet.server.auth.domain.AuthTokens; import org.instancio.Instancio; @@ -10,4 +12,10 @@ public static AuthTokens authTokens() { .create(); } + public static AuthTokens authTokens(String refreshToken) { + return Instancio.of(AuthTokens.class) + .set(field(AuthTokens::refreshToken), refreshToken) + .create(); + } + } From 29119f97363143548e554092c7cb04d7c20e57bf Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 18:36:07 +0900 Subject: [PATCH 210/311] =?UTF-8?q?test:=20AuthServiceTest=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 --- .../server/auth/service/AuthServiceTest.java | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/test/java/coffeemeet/server/auth/service/AuthServiceTest.java diff --git a/src/test/java/coffeemeet/server/auth/service/AuthServiceTest.java b/src/test/java/coffeemeet/server/auth/service/AuthServiceTest.java new file mode 100644 index 00000000..614b0538 --- /dev/null +++ b/src/test/java/coffeemeet/server/auth/service/AuthServiceTest.java @@ -0,0 +1,90 @@ +package coffeemeet.server.auth.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.mockito.BDDMockito.any; +import static org.mockito.BDDMockito.anyLong; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.willDoNothing; + +import coffeemeet.server.auth.domain.AuthTokens; +import coffeemeet.server.auth.domain.AuthTokensGenerator; +import coffeemeet.server.auth.domain.JwtTokenProvider; +import coffeemeet.server.auth.repository.RefreshTokenRepository; +import coffeemeet.server.common.fixture.dto.AuthTokensFixture; +import coffeemeet.server.user.service.UserService; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class AuthServiceTest { + + public static final String REFRESH_TOKEN = "Bearer aaaaaaaa.bbbbbbb.ccccccc"; + @InjectMocks + private AuthService authService; + + @Mock + private UserService userService; + + @Mock + private AuthTokensGenerator authTokensGenerator; + + @Mock + private JwtTokenProvider jwtTokenProvider; + + @Mock + private RefreshTokenRepository refreshTokenRepository; + + @DisplayName("access token 을 갱신할 수 있다.") + @Test + void renew() { + // given + AuthTokens authTokens = AuthTokensFixture.authTokens(); + AuthTokens newAuthTokens = AuthTokensFixture.authTokens(REFRESH_TOKEN); + + given(jwtTokenProvider.isExpiredRefreshToken(REFRESH_TOKEN)).willReturn(false); + given(authTokensGenerator.reissueAccessToken(anyLong(), any(String.class))).willReturn( + newAuthTokens); + + // when + AuthTokens renewedAuthTokens = authService.renew((long) Math.random(), REFRESH_TOKEN); + + // then + assertAll( + () -> assertThat(renewedAuthTokens.accessToken()).isNotEqualTo(authTokens.accessToken()), + () -> assertThat(renewedAuthTokens.refreshToken()).isEqualTo(REFRESH_TOKEN) + ); + } + + @DisplayName("로그아웃 시킬 수 있다.") + @Test + void logout() { + // given + willDoNothing().given(refreshTokenRepository).deleteById(anyLong()); + + // when + authService.logout((long) Math.random()); + + // then + assertThat(true).isTrue(); + } + + @DisplayName("회원 탈퇴 시킬 수 있다.") + @Test + void delete() { + // given + willDoNothing().given(refreshTokenRepository).deleteById(anyLong()); + willDoNothing().given(userService).deleteUser(anyLong()); + + // when + authService.delete((long) Math.random()); + + // then + assertThat(true).isTrue(); + } + +} From b4d7e03b3c8de9a069d5cbdd264fa967e46164be Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 18:38:53 +0900 Subject: [PATCH 211/311] =?UTF-8?q?test:=20BDDMockito=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=EB=9F=AC=EB=A6=AC=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/auth/controller/AuthControllerTest.java | 8 +++----- .../server/auth/domain/AuthTokensGeneratorTest.java | 6 +++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java b/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java index d9c03a48..4387a1f6 100644 --- a/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java +++ b/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java @@ -5,7 +5,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.doNothing; +import static org.mockito.BDDMockito.willDoNothing; import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; @@ -77,8 +77,7 @@ void renewTest() throws Exception { void logoutTest() throws Exception { // given RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); - - doNothing().when(authService).logout(anyLong()); + willDoNothing().given(authService).logout(anyLong()); given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); // when, then @@ -103,8 +102,7 @@ void logoutTest() throws Exception { void deleteTest() throws Exception { // given RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); - - doNothing().when(authService).delete(anyLong()); + willDoNothing().given(authService).delete(anyLong()); given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); // when, then diff --git a/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java b/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java index 9f380338..09de8058 100644 --- a/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java +++ b/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java @@ -4,7 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertAll; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.when; +import static org.mockito.BDDMockito.given; import coffeemeet.server.auth.repository.RefreshTokenRepository; import java.util.Date; @@ -44,7 +44,7 @@ public void init() { @Test void generateTest() { // given - when(jwtTokenProvider.generate(anyString(), any(Date.class))).thenReturn(ACCESS_TOKEN, + given(jwtTokenProvider.generate(anyString(), any(Date.class))).willReturn(ACCESS_TOKEN, REFRESH_TOKEN); // when @@ -61,7 +61,7 @@ void generateTest() { @Test void reissueAccessTokenTest() { // given - when(jwtTokenProvider.generate(anyString(), any(Date.class))).thenReturn(ACCESS_TOKEN, + given(jwtTokenProvider.generate(anyString(), any(Date.class))).willReturn(ACCESS_TOKEN, REFRESH_TOKEN); // when From 816f2be962975302d684f5354f7c6c092736ea50 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 18:45:37 +0900 Subject: [PATCH 212/311] =?UTF-8?q?refactor:=20OAuthUserInfoDto=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/oauth/client/OAuthMemberClient.java | 4 ++-- .../server/oauth/client/OAuthMemberClientComposite.java | 4 ++-- .../dto/{OAuthInfoDto.java => OAuthUserInfoDto.java} | 8 ++++---- .../infrastructure/kakao/client/KakaoMemberClient.java | 4 ++-- .../infrastructure/kakao/dto/KakaoMemberResponse.java | 6 +++--- .../coffeemeet/server/oauth/service/OAuthService.java | 4 ++-- .../java/coffeemeet/server/user/service/UserService.java | 8 ++++---- .../server/common/fixture/dto/OAuthInfoDtoFixture.java | 6 +++--- .../oauth/client/OAuthMemberClientCompositeTest.java | 6 +++--- .../coffeemeet/server/oauth/service/OAuthServiceTest.java | 4 ++-- 10 files changed, 27 insertions(+), 27 deletions(-) rename src/main/java/coffeemeet/server/oauth/dto/{OAuthInfoDto.java => OAuthUserInfoDto.java} (76%) diff --git a/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClient.java b/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClient.java index a3f81b1f..7a13eeea 100644 --- a/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClient.java +++ b/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClient.java @@ -1,12 +1,12 @@ package coffeemeet.server.oauth.client; -import coffeemeet.server.oauth.dto.OAuthInfoDto; +import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import coffeemeet.server.user.domain.OAuthProvider; public interface OAuthMemberClient { OAuthProvider oAuthProvider(); - OAuthInfoDto.Response fetch(String authCode); + OAuthUserInfoDto.Response fetch(String authCode); } diff --git a/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java b/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java index 71796d74..b240569b 100644 --- a/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java +++ b/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java @@ -1,6 +1,6 @@ package coffeemeet.server.oauth.client; -import coffeemeet.server.oauth.dto.OAuthInfoDto; +import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import coffeemeet.server.user.domain.OAuthProvider; import java.util.Map; import java.util.Optional; @@ -21,7 +21,7 @@ public OAuthMemberClientComposite(Set clients) { ); } - public OAuthInfoDto.Response fetch(OAuthProvider oAuthProvider, String authCode) { + public OAuthUserInfoDto.Response fetch(OAuthProvider oAuthProvider, String authCode) { return getClient(oAuthProvider).fetch(authCode); } diff --git a/src/main/java/coffeemeet/server/oauth/dto/OAuthInfoDto.java b/src/main/java/coffeemeet/server/oauth/dto/OAuthUserInfoDto.java similarity index 76% rename from src/main/java/coffeemeet/server/oauth/dto/OAuthInfoDto.java rename to src/main/java/coffeemeet/server/oauth/dto/OAuthUserInfoDto.java index 9442fd87..0a1c1782 100644 --- a/src/main/java/coffeemeet/server/oauth/dto/OAuthInfoDto.java +++ b/src/main/java/coffeemeet/server/oauth/dto/OAuthUserInfoDto.java @@ -2,7 +2,7 @@ import coffeemeet.server.user.domain.OAuthProvider; -public sealed interface OAuthInfoDto permits OAuthInfoDto.Response { +public sealed interface OAuthUserInfoDto permits OAuthUserInfoDto.Response { record Response( String name, @@ -12,9 +12,9 @@ record Response( String email, OAuthProvider oAuthProvider, String oAuthProviderId - ) implements OAuthInfoDto { + ) implements OAuthUserInfoDto { - public static OAuthInfoDto.Response of( + public static OAuthUserInfoDto.Response of( String name, String profileImage, String birthYear, @@ -23,7 +23,7 @@ public static OAuthInfoDto.Response of( OAuthProvider oAuthProvider, String oAuthProviderId ) { - return new OAuthInfoDto.Response( + return new OAuthUserInfoDto.Response( name, profileImage, birthYear, diff --git a/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClient.java b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClient.java index 1cc51007..d9343906 100644 --- a/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClient.java +++ b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClient.java @@ -1,7 +1,7 @@ package coffeemeet.server.oauth.infrastructure.kakao.client; import coffeemeet.server.oauth.client.OAuthMemberClient; -import coffeemeet.server.oauth.dto.OAuthInfoDto; +import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoMemberResponse; import coffeemeet.server.oauth.infrastructure.kakao.dto.KakaoTokens; import coffeemeet.server.user.domain.OAuthProvider; @@ -20,7 +20,7 @@ public OAuthProvider oAuthProvider() { } @Override - public OAuthInfoDto.Response fetch(String authCode) { + public OAuthUserInfoDto.Response fetch(String authCode) { KakaoTokens tokenInfo = kakaoApiClient.fetchToken(authCode); KakaoMemberResponse response = kakaoApiClient.fetchMember(tokenInfo.accessToken()); diff --git a/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberResponse.java b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberResponse.java index 0863930e..12acbdea 100644 --- a/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberResponse.java +++ b/src/main/java/coffeemeet/server/oauth/infrastructure/kakao/dto/KakaoMemberResponse.java @@ -1,6 +1,6 @@ package coffeemeet.server.oauth.infrastructure.kakao.dto; -import coffeemeet.server.oauth.dto.OAuthInfoDto; +import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import coffeemeet.server.user.domain.OAuthProvider; import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; import com.fasterxml.jackson.databind.annotation.JsonNaming; @@ -11,8 +11,8 @@ public record KakaoMemberResponse( KakaoAccount kakaoAccount ) { - public OAuthInfoDto.Response toOAuthInfoResponse() { - return OAuthInfoDto.Response.of( + public OAuthUserInfoDto.Response toOAuthInfoResponse() { + return OAuthUserInfoDto.Response.of( kakaoAccount.name, kakaoAccount.profile.profileImageUrl, kakaoAccount.birthyear, diff --git a/src/main/java/coffeemeet/server/oauth/service/OAuthService.java b/src/main/java/coffeemeet/server/oauth/service/OAuthService.java index 29aac986..07b7b1c4 100644 --- a/src/main/java/coffeemeet/server/oauth/service/OAuthService.java +++ b/src/main/java/coffeemeet/server/oauth/service/OAuthService.java @@ -2,7 +2,7 @@ import coffeemeet.server.oauth.authcode.AuthCodeRequestUrlProviderComposite; import coffeemeet.server.oauth.client.OAuthMemberClientComposite; -import coffeemeet.server.oauth.dto.OAuthInfoDto; +import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import coffeemeet.server.user.domain.OAuthProvider; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -18,7 +18,7 @@ public String getAuthCodeRequestUrl(OAuthProvider oAuthProvider) { return authCodeRequestUrlProviderComposite.provide(oAuthProvider); } - public OAuthInfoDto.Response getOAuthInfo(OAuthProvider oAuthProvider, String authCode) { + public OAuthUserInfoDto.Response getOAuthInfo(OAuthProvider oAuthProvider, String authCode) { return oauthMemberClientComposite.fetch(oAuthProvider, authCode); } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index ae0130be..9cf0c36d 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -11,7 +11,7 @@ import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.interest.repository.InterestRepository; import coffeemeet.server.interest.service.InterestService; -import coffeemeet.server.oauth.dto.OAuthInfoDto; +import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import coffeemeet.server.oauth.service.OAuthService; import coffeemeet.server.user.domain.Birth; import coffeemeet.server.user.domain.Email; @@ -94,7 +94,7 @@ public void updateProfileInfo(Long userId, String nickname, String name, @Transactional public AuthTokens signup(SignupRequest request) { - OAuthInfoDto.Response response = oAuthService.getOAuthInfo(request.oAuthProvider(), + OAuthUserInfoDto.Response response = oAuthService.getOAuthInfo(request.oAuthProvider(), request.authCode()); checkDuplicatedUser(response); @@ -113,7 +113,7 @@ public AuthTokens signup(SignupRequest request) { } public AuthTokens login(OAuthProvider oAuthProvider, String authCode) { - OAuthInfoDto.Response response = oAuthService.getOAuthInfo(oAuthProvider, authCode); + OAuthUserInfoDto.Response response = oAuthService.getOAuthInfo(oAuthProvider, authCode); User foundUser = userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( response.oAuthProvider(), response.oAuthProviderId()).orElseThrow( () -> new IllegalArgumentException( @@ -134,7 +134,7 @@ public void checkDuplicatedNickname(String nickname) { } } - public void checkDuplicatedUser(OAuthInfoDto.Response response) { + public void checkDuplicatedUser(OAuthUserInfoDto.Response response) { if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( response.oAuthProvider(), response.oAuthProviderId())) { throw new IllegalArgumentException(ALREADY_REGISTERED_MESSAGE); diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoDtoFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoDtoFixture.java index c09d143a..f2177a86 100644 --- a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoDtoFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoDtoFixture.java @@ -1,12 +1,12 @@ package coffeemeet.server.common.fixture.dto; -import coffeemeet.server.oauth.dto.OAuthInfoDto; +import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import org.instancio.Instancio; public class OAuthInfoDtoFixture { - public static OAuthInfoDto.Response response() { - return Instancio.of(OAuthInfoDto.Response.class) + public static OAuthUserInfoDto.Response response() { + return Instancio.of(OAuthUserInfoDto.Response.class) .create(); } diff --git a/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java index fcf9b179..7ec0762a 100644 --- a/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java +++ b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java @@ -4,7 +4,7 @@ import static org.mockito.BDDMockito.given; import coffeemeet.server.common.fixture.dto.OAuthInfoDtoFixture; -import coffeemeet.server.oauth.dto.OAuthInfoDto; +import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import coffeemeet.server.user.domain.OAuthProvider; import java.util.Collections; import java.util.HashSet; @@ -34,7 +34,7 @@ void fetchTest() { // given String authCode = "authCode"; OAuthProvider oAuthProvider = OAuthProvider.KAKAO; - OAuthInfoDto.Response response = OAuthInfoDtoFixture.response(); + OAuthUserInfoDto.Response response = OAuthInfoDtoFixture.response(); given(client.oAuthProvider()).willReturn(OAuthProvider.KAKAO); given(client.fetch(authCode)).willReturn(response); @@ -43,7 +43,7 @@ void fetchTest() { composite = new OAuthMemberClientComposite(clients); // when - OAuthInfoDto.Response expectedResponse = composite.fetch(oAuthProvider, authCode); + OAuthUserInfoDto.Response expectedResponse = composite.fetch(oAuthProvider, authCode); // then assertThat(response).isEqualTo(expectedResponse); diff --git a/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java b/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java index ea79dd99..e40c8ec2 100644 --- a/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java +++ b/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java @@ -6,7 +6,7 @@ import coffeemeet.server.common.fixture.dto.OAuthInfoDtoFixture; import coffeemeet.server.oauth.authcode.AuthCodeRequestUrlProviderComposite; import coffeemeet.server.oauth.client.OAuthMemberClientComposite; -import coffeemeet.server.oauth.dto.OAuthInfoDto; +import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import coffeemeet.server.user.domain.OAuthProvider; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -48,7 +48,7 @@ void getOAuthInfoTest() { // given OAuthProvider oAuthProvider = OAuthProvider.KAKAO; String authCode = "authCode"; - OAuthInfoDto.Response oAuthInfoResponse = OAuthInfoDtoFixture.response(); + OAuthUserInfoDto.Response oAuthInfoResponse = OAuthInfoDtoFixture.response(); given(oAuthMemberClientComposite.fetch(oAuthProvider, authCode)).willReturn(oAuthInfoResponse); From a46ab5928e5636185bfa45dccc73a368a09cff25 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 18:47:01 +0900 Subject: [PATCH 213/311] =?UTF-8?q?refactor:=20OAuthUserInfoDtoFixture=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...{OAuthInfoDtoFixture.java => OAuthUserInfoDtoFixture.java} | 2 +- .../server/oauth/client/OAuthMemberClientCompositeTest.java | 4 ++-- .../coffeemeet/server/oauth/service/OAuthServiceTest.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename src/test/java/coffeemeet/server/common/fixture/dto/{OAuthInfoDtoFixture.java => OAuthUserInfoDtoFixture.java} (87%) diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoDtoFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthUserInfoDtoFixture.java similarity index 87% rename from src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoDtoFixture.java rename to src/test/java/coffeemeet/server/common/fixture/dto/OAuthUserInfoDtoFixture.java index f2177a86..4ddb409f 100644 --- a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoDtoFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthUserInfoDtoFixture.java @@ -3,7 +3,7 @@ import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import org.instancio.Instancio; -public class OAuthInfoDtoFixture { +public class OAuthUserInfoDtoFixture { public static OAuthUserInfoDto.Response response() { return Instancio.of(OAuthUserInfoDto.Response.class) diff --git a/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java index 7ec0762a..96952a18 100644 --- a/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java +++ b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; -import coffeemeet.server.common.fixture.dto.OAuthInfoDtoFixture; +import coffeemeet.server.common.fixture.dto.OAuthUserInfoDtoFixture; import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import coffeemeet.server.user.domain.OAuthProvider; import java.util.Collections; @@ -34,7 +34,7 @@ void fetchTest() { // given String authCode = "authCode"; OAuthProvider oAuthProvider = OAuthProvider.KAKAO; - OAuthUserInfoDto.Response response = OAuthInfoDtoFixture.response(); + OAuthUserInfoDto.Response response = OAuthUserInfoDtoFixture.response(); given(client.oAuthProvider()).willReturn(OAuthProvider.KAKAO); given(client.fetch(authCode)).willReturn(response); diff --git a/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java b/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java index e40c8ec2..66176595 100644 --- a/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java +++ b/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; -import coffeemeet.server.common.fixture.dto.OAuthInfoDtoFixture; +import coffeemeet.server.common.fixture.dto.OAuthUserInfoDtoFixture; import coffeemeet.server.oauth.authcode.AuthCodeRequestUrlProviderComposite; import coffeemeet.server.oauth.client.OAuthMemberClientComposite; import coffeemeet.server.oauth.dto.OAuthUserInfoDto; @@ -48,7 +48,7 @@ void getOAuthInfoTest() { // given OAuthProvider oAuthProvider = OAuthProvider.KAKAO; String authCode = "authCode"; - OAuthUserInfoDto.Response oAuthInfoResponse = OAuthInfoDtoFixture.response(); + OAuthUserInfoDto.Response oAuthInfoResponse = OAuthUserInfoDtoFixture.response(); given(oAuthMemberClientComposite.fetch(oAuthProvider, authCode)).willReturn(oAuthInfoResponse); From 702120bbb9da4bf7a5be0b55e698c636fa97e749 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Fri, 27 Oct 2023 21:52:35 +0900 Subject: [PATCH 214/311] test: update test method name --- .../coffeemeet/server/auth/domain/JwtTokenProviderTest.java | 6 +++--- .../coffeemeet/server/auth/service/AuthServiceTest.java | 6 +++--- .../infrastructure/kakao/client/KakaoMemberClientTest.java | 4 ++-- .../oauth/utils/converter/OAuthProviderConverterTest.java | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test/java/coffeemeet/server/auth/domain/JwtTokenProviderTest.java b/src/test/java/coffeemeet/server/auth/domain/JwtTokenProviderTest.java index 2b22d811..aae466cb 100644 --- a/src/test/java/coffeemeet/server/auth/domain/JwtTokenProviderTest.java +++ b/src/test/java/coffeemeet/server/auth/domain/JwtTokenProviderTest.java @@ -24,7 +24,7 @@ class JwtTokenProviderTest { @DisplayName("jwt 를 생성할 수 있다.") @Test - void generate() { + void generateTest() { // given Date date = new Date(System.currentTimeMillis() + ACCESS_TOKEN_EXPIRE_TIME); @@ -37,7 +37,7 @@ void generate() { @DisplayName("jwt 로부터 userId 를 가져올 수 있다.") @Test - void extractUserId() { + void extractUserIdTest() { // given Date date = new Date(System.currentTimeMillis() + ACCESS_TOKEN_EXPIRE_TIME); @@ -51,7 +51,7 @@ void extractUserId() { @DisplayName("jwt(refresh token) 로부터 토큰이 만료되었는지 확인할 수 있다.") @Test - void isExpiredRefreshToken() { + void isExpiredRefreshTokenTest() { // given Date date = new Date(System.currentTimeMillis() + ACCESS_TOKEN_EXPIRE_TIME); diff --git a/src/test/java/coffeemeet/server/auth/service/AuthServiceTest.java b/src/test/java/coffeemeet/server/auth/service/AuthServiceTest.java index 614b0538..d02f6298 100644 --- a/src/test/java/coffeemeet/server/auth/service/AuthServiceTest.java +++ b/src/test/java/coffeemeet/server/auth/service/AuthServiceTest.java @@ -41,7 +41,7 @@ class AuthServiceTest { @DisplayName("access token 을 갱신할 수 있다.") @Test - void renew() { + void renewTest() { // given AuthTokens authTokens = AuthTokensFixture.authTokens(); AuthTokens newAuthTokens = AuthTokensFixture.authTokens(REFRESH_TOKEN); @@ -62,7 +62,7 @@ void renew() { @DisplayName("로그아웃 시킬 수 있다.") @Test - void logout() { + void logoutTest() { // given willDoNothing().given(refreshTokenRepository).deleteById(anyLong()); @@ -75,7 +75,7 @@ void logout() { @DisplayName("회원 탈퇴 시킬 수 있다.") @Test - void delete() { + void deleteTest() { // given willDoNothing().given(refreshTokenRepository).deleteById(anyLong()); willDoNothing().given(userService).deleteUser(anyLong()); diff --git a/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClientTest.java b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClientTest.java index 20410236..a6ddf6d2 100644 --- a/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClientTest.java +++ b/src/test/java/coffeemeet/server/oauth/infrastructure/kakao/client/KakaoMemberClientTest.java @@ -27,14 +27,14 @@ class KakaoMemberClientTest { @DisplayName("카카오 프로바이더를 가져올 수 있다.") @Test - void oAuthProvider() { + void oAuthProviderTest() { // when, then assertThat(kakaoMemberClient.oAuthProvider()).isEqualTo(OAuthProvider.KAKAO); } @DisplayName("카카오로부터 사용자 정보를 가져올 수 있다.") @Test - void fetch() { + void fetchTest() { // given String authCode = "authCode"; KakaoTokens kakaoTokens = KakaoTokensFixture.kakaoTokens(); diff --git a/src/test/java/coffeemeet/server/oauth/utils/converter/OAuthProviderConverterTest.java b/src/test/java/coffeemeet/server/oauth/utils/converter/OAuthProviderConverterTest.java index 1f4a981d..fb891af1 100644 --- a/src/test/java/coffeemeet/server/oauth/utils/converter/OAuthProviderConverterTest.java +++ b/src/test/java/coffeemeet/server/oauth/utils/converter/OAuthProviderConverterTest.java @@ -13,7 +13,7 @@ class OAuthProviderConverterTest { @DisplayName("입력된 sns provider 이름을 항상 대문자로 변환 시킬 수 있다.") @Test - void convert() { + void convertTest() { // given String provider = "kakao"; From b379dfdaf22b2636242ecdf16596779a4ebaba9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Fri, 27 Oct 2023 23:49:11 +0900 Subject: [PATCH 215/311] =?UTF-8?q?refactor:=20User=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=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 --- .../coffeemeet/server/user/domain/Birth.java | 8 ++-- .../server/user/domain/OAuthInfo.java | 11 +---- .../server/user/domain/Profile.java | 41 ++++--------------- 3 files changed, 15 insertions(+), 45 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/Birth.java b/src/main/java/coffeemeet/server/user/domain/Birth.java index b987b586..2b61ee9e 100644 --- a/src/main/java/coffeemeet/server/user/domain/Birth.java +++ b/src/main/java/coffeemeet/server/user/domain/Birth.java @@ -5,7 +5,7 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -import org.springframework.util.StringUtils; +import lombok.NonNull; @Getter @Embeddable @@ -20,7 +20,7 @@ public class Birth { @Column(nullable = false, length = BIRTH_LENGTH) String birthDay; - public Birth(String birthYear, String birthDay) { + public Birth(@NonNull String birthYear, @NonNull String birthDay) { validateYear(birthYear); validateDay(birthDay); this.birthYear = birthYear; @@ -28,13 +28,13 @@ public Birth(String birthYear, String birthDay) { } private void validateYear(String birthYear) { - if (!StringUtils.hasText(birthYear) || birthYear.length() != BIRTH_LENGTH) { + if (birthYear.length() != BIRTH_LENGTH) { throw new IllegalArgumentException("올바르지 않은 연도 형식입니다."); } } private void validateDay(String birthDay) { - if (!StringUtils.hasText(birthDay) || birthDay.length() != BIRTH_LENGTH) { + if (birthDay.length() != BIRTH_LENGTH) { throw new IllegalArgumentException("올바르지 않은 날짜 형식입니다."); } } diff --git a/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java b/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java index 16055bbe..a1f4d704 100644 --- a/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java +++ b/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java @@ -6,7 +6,7 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -import org.springframework.util.StringUtils; +import lombok.NonNull; @Getter @Embeddable @@ -18,16 +18,9 @@ public class OAuthInfo { private String oauthProviderId; - public OAuthInfo(OAuthProvider oauthProvider, String oauthProviderId) { - validateOAuthProviderId(oauthProviderId); + public OAuthInfo(OAuthProvider oauthProvider, @NonNull String oauthProviderId) { this.oauthProvider = oauthProvider; this.oauthProviderId = oauthProviderId; } - private void validateOAuthProviderId(String oauthProviderId) { - if (!StringUtils.hasText(oauthProviderId)) { - throw new IllegalArgumentException("올바르지 않은 로그인 아이디입니다."); - } - } - } diff --git a/src/main/java/coffeemeet/server/user/domain/Profile.java b/src/main/java/coffeemeet/server/user/domain/Profile.java index 0c12e34c..b4552cd0 100644 --- a/src/main/java/coffeemeet/server/user/domain/Profile.java +++ b/src/main/java/coffeemeet/server/user/domain/Profile.java @@ -3,11 +3,12 @@ import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import jakarta.persistence.Embedded; +import jakarta.validation.constraints.NotNull; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import org.springframework.util.StringUtils; +import lombok.NonNull; @Getter @Embeddable @@ -35,15 +36,13 @@ public class Profile { @Builder private Profile( - String name, - String nickname, + @NonNull String name, + @NotNull String nickname, Email email, - String profileImageUrl, + @NonNull String profileImageUrl, Birth birth ) { - validateName(name); validateNickname(nickname); - validateProfileImage(profileImageUrl); this.name = name; this.nickname = nickname; this.email = email; @@ -51,41 +50,19 @@ private Profile( this.birth = birth; } - private void validateName(String name) { - if (!StringUtils.hasText(name)) { - throw new IllegalArgumentException("올바르지 않은 이름입니다."); - } - } - - private void validateNickname(String nickname) { - if (!StringUtils.hasText(nickname) || nickname.length() > NICKNAME_MAX_LENGTH) { - throw new IllegalArgumentException("올바르지 않은 닉네임입니다."); - } - } - - private void validateProfileImage(String profileImageUrl) { - if (!StringUtils.hasText(profileImageUrl)) { - throw new IllegalArgumentException("올바르지 않은 프로필 사진 url입니다."); - } - } - public void updateNickname(String newNickname) { validateNickname(nickname); this.nickname = newNickname; } public void updateProfileImageUrl(String newProfileImageUrl) { - validateProfileImage(profileImageUrl); this.profileImageUrl = newProfileImageUrl; } - public void updateEmail(String newEmail) { - this.email = new Email(newEmail); - } - - public void updateName(String newName) { - validateName(newName); - this.name = newName; + private void validateNickname(String nickname) { + if (nickname.length() > NICKNAME_MAX_LENGTH) { + throw new IllegalArgumentException("올바르지 않은 닉네임입니다."); + } } } From 8b75e76a2176b1c8586f5c6a36653bbe4d75e625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Fri, 27 Oct 2023 23:50:57 +0900 Subject: [PATCH 216/311] =?UTF-8?q?refactor:=20UserController=20url=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/user/controller/UserController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index 52167566..80448776 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -28,7 +28,7 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/users") +@RequestMapping("/api/v1/users") public class UserController { private final UserService userService; From de6739579665b0cf6087ef02ea5dc5a03de66715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Fri, 27 Oct 2023 23:52:15 +0900 Subject: [PATCH 217/311] =?UTF-8?q?refactor:=20UserService=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/repository/UserRepository.java | 2 + .../server/user/service/UserService.java | 160 +++++++----------- .../server/user/service/cq/UserCommand.java | 57 +++++++ .../server/user/service/cq/UserQuery.java | 57 +++++++ 4 files changed, 178 insertions(+), 98 deletions(-) create mode 100644 src/main/java/coffeemeet/server/user/service/cq/UserCommand.java create mode 100644 src/main/java/coffeemeet/server/user/service/cq/UserQuery.java diff --git a/src/main/java/coffeemeet/server/user/repository/UserRepository.java b/src/main/java/coffeemeet/server/user/repository/UserRepository.java index 6434d2fa..36d996eb 100644 --- a/src/main/java/coffeemeet/server/user/repository/UserRepository.java +++ b/src/main/java/coffeemeet/server/user/repository/UserRepository.java @@ -17,4 +17,6 @@ Optional getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( Optional findUserByProfileNickname(String nickname); + boolean existsUserByProfile_Nickname(String nickname); + } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 9cf0c36d..97c32c01 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -7,24 +7,22 @@ import coffeemeet.server.certification.domain.Certification; import coffeemeet.server.certification.service.cq.CertificationQuery; import coffeemeet.server.common.media.S3MediaService; -import coffeemeet.server.interest.domain.Interest; import coffeemeet.server.interest.domain.Keyword; -import coffeemeet.server.interest.repository.InterestRepository; -import coffeemeet.server.interest.service.InterestService; -import coffeemeet.server.oauth.dto.OAuthUserInfoDto; +import coffeemeet.server.interest.service.cq.InterestCommand; +import coffeemeet.server.interest.service.cq.InterestQuery; import coffeemeet.server.oauth.service.OAuthService; import coffeemeet.server.user.domain.Birth; import coffeemeet.server.user.domain.Email; -import coffeemeet.server.user.domain.OAuthInfo; import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; -import coffeemeet.server.user.dto.MyProfileResponse; -import coffeemeet.server.user.dto.SignupRequest; -import coffeemeet.server.user.dto.UserProfileResponse; -import coffeemeet.server.user.repository.UserRepository; +import coffeemeet.server.user.dto.MyProfileDto; +import coffeemeet.server.user.dto.OAuthUserInfo; +import coffeemeet.server.user.dto.SignupDto; +import coffeemeet.server.user.dto.UserProfileDto; +import coffeemeet.server.user.service.cq.UserCommand; +import coffeemeet.server.user.service.cq.UserQuery; import java.io.File; -import java.util.ArrayList; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -35,115 +33,83 @@ @Transactional(readOnly = true) public class UserService { - private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; - private static final String USER_NOT_REGISTERED_MESSAGE = "해당 아이디(%s)와 로그인 타입(%s)의 유저는 회원가입되지 않았습니다."; private static final String DEFAULT_IMAGE_URL = "기본 이미지 URL"; private final S3MediaService s3MediaService; - private final InterestService interestService; private final OAuthService oAuthService; - private final UserRepository userRepository; - private final InterestRepository interestRepository; + private final CertificationQuery certificationQuery; private final AuthTokensGenerator authTokensGenerator; - public UserProfileResponse findUserProfile(long userId) { - User user = userRepository.findById(userId) - .orElseThrow(() -> new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); - List interests = interestRepository.findAllByUserId(userId); - Certification certification = certificationQuery.getCertificationByUserId(userId); + private final InterestQuery interestQuery; + private final InterestCommand interestCommand; + private final UserQuery userQuery; + private final UserCommand userCommand; + + public AuthTokens signup(SignupDto.Request request) { + OAuthUserInfo oAuthUserInfo = oAuthService.getOAuthUserInfo(request.oAuthProvider(), + request.authCode()); + + userCommand.checkDuplicatedUser(oAuthUserInfo.oAuthProvider(), oAuthUserInfo.oAuthProviderId()); + userCommand.checkDuplicatedNickname(request.nickname()); + String profileImage = getProfileImageOrDefault(oAuthUserInfo.profileImage()); + + User user = new User(new coffeemeet.server.user.domain.OAuthInfo(oAuthUserInfo.oAuthProvider(), + oAuthUserInfo.oAuthProviderId()), + Profile.builder().name(oAuthUserInfo.name()).nickname(request.nickname()) + .email(new Email(oAuthUserInfo.email())) + .profileImageUrl(profileImage) + .birth(new Birth(oAuthUserInfo.birthYear(), oAuthUserInfo.birthDay())).build()); + + User newUser = userCommand.saveUser(user); + interestCommand.saveInterests(request, newUser); + return authTokensGenerator.generate(newUser.getId()); + } - return UserProfileResponse.of(user, certification.getDepartment(), interests); + public AuthTokens login(OAuthProvider oAuthProvider, String authCode) { + OAuthUserInfo oAuthUserInfo = oAuthService.getOAuthUserInfo(oAuthProvider, authCode); + User user = userCommand.getUserByOAuthInfo(oAuthProvider, oAuthUserInfo.oAuthProviderId()); + return authTokensGenerator.generate(user.getId()); } - public MyProfileResponse findMyProfile(Long userId) { - User user = getUserById(userId); - List interests = interestRepository.findAllByUserId(userId); + public UserProfileDto.Response findUserProfile(long userId) { + User user = userQuery.getUserById(userId); + List keywords = interestQuery.getKeywordsByUserId(userId); Certification certification = certificationQuery.getCertificationByUserId(userId); + return UserProfileDto.Response.of(user, certification.getDepartment(), keywords); + } - return MyProfileResponse.of(user, interests, certification.getDepartment()); + public MyProfileDto.Response findMyProfile(Long userId) { + User user = userQuery.getUserById(userId); + List keywords = interestQuery.getKeywordsByUserId(userId); + Certification certification = certificationQuery.getCertificationByUserId(userId); + return MyProfileDto.Response.of(user, keywords, certification.getDepartment()); } - @Transactional public void updateProfileImage(Long userId, File file) { - User user = getUserById(userId); - deleteCurrentProfileImage(user); + User user = userQuery.getUserById(userId); + deleteCurrentProfileImage(user.getProfile().getProfileImageUrl()); String key = s3MediaService.generateKey(PROFILE_IMAGE); s3MediaService.upload(key, file); user.updateProfileImageUrl(s3MediaService.getUrl(key)); + userCommand.updateUser(user); } - private void deleteCurrentProfileImage(User user) { - String currentKey = s3MediaService.extractKey(user.getProfile().getProfileImageUrl(), - PROFILE_IMAGE); - s3MediaService.delete(currentKey); - } - - @Transactional - public void updateProfileInfo(Long userId, String nickname, String name, - List interests) { - User user = getUserById(userId); - - checkDuplicatedNickname(nickname); - + public void updateProfileInfo(Long userId, String nickname, + List keywords) { + User user = userQuery.getUserById(userId); + userQuery.checkDuplicatedNickname(nickname); user.updateNickname(nickname); - user.updateName(name); - - interestService.updateInterests(userId, interests); + interestCommand.updateInterests(userQuery.getUserById(userId), keywords); } - @Transactional - public AuthTokens signup(SignupRequest request) { - OAuthUserInfoDto.Response response = oAuthService.getOAuthInfo(request.oAuthProvider(), - request.authCode()); - - checkDuplicatedUser(response); - checkDuplicatedNickname(request.nickname()); - String profileImage = getProfileImageOrDefault(response.profileImage()); - - User user = new User(new OAuthInfo(response.oAuthProvider(), response.oAuthProviderId()), - Profile.builder().name(response.name()).nickname(request.nickname()) - .email(new Email(response.email())) - .profileImageUrl(profileImage) - .birth(new Birth(response.birthYear(), response.birthDay())).build()); - - User newUser = userRepository.save(user); - saveInterests(request, newUser); - return authTokensGenerator.generate(newUser.getId()); - } - - public AuthTokens login(OAuthProvider oAuthProvider, String authCode) { - OAuthUserInfoDto.Response response = oAuthService.getOAuthInfo(oAuthProvider, authCode); - User foundUser = userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( - response.oAuthProvider(), response.oAuthProviderId()).orElseThrow( - () -> new IllegalArgumentException( - String.format(USER_NOT_REGISTERED_MESSAGE, response.oAuthProviderId(), - response.oAuthProvider()))); - return authTokensGenerator.generate(foundUser.getId()); + public void checkDuplicatedNickname(String nickname) { + userCommand.checkDuplicatedNickname(nickname); } @Transactional public void deleteUser(Long userId) { - interestRepository.deleteById(userId); - userRepository.deleteById(userId); - } - - public void checkDuplicatedNickname(String nickname) { - if (userRepository.findUserByProfileNickname(nickname).isPresent()) { - throw new IllegalArgumentException("이미 존재하는 닉네임입니다."); - } - } - - public void checkDuplicatedUser(OAuthUserInfoDto.Response response) { - if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( - response.oAuthProvider(), response.oAuthProviderId())) { - throw new IllegalArgumentException(ALREADY_REGISTERED_MESSAGE); - } - } - - public User getUserById(Long userId) { - return userRepository.findById(userId) - .orElseThrow(IllegalArgumentException::new); + userCommand.deleteUser(userId); } private String getProfileImageOrDefault(String profileImage) { @@ -153,12 +119,10 @@ private String getProfileImageOrDefault(String profileImage) { return profileImage; } - private void saveInterests(SignupRequest request, User newUser) { - List interests = new ArrayList<>(); - for (Keyword value : request.keywords()) { - interests.add(new Interest(value, newUser)); - } - interestRepository.saveAll(interests); + private void deleteCurrentProfileImage(String profileImageUrl) { + String currentKey = s3MediaService.extractKey(profileImageUrl, + PROFILE_IMAGE); + s3MediaService.delete(currentKey); } } diff --git a/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java b/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java new file mode 100644 index 00000000..767de48f --- /dev/null +++ b/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java @@ -0,0 +1,57 @@ +package coffeemeet.server.user.service.cq; + +import coffeemeet.server.interest.repository.InterestRepository; +import coffeemeet.server.user.domain.OAuthProvider; +import coffeemeet.server.user.domain.User; +import coffeemeet.server.user.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +public class UserCommand { + + private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; + private static final String USER_NOT_REGISTERED_MESSAGE = "해당 아이디(%s)와 로그인 타입(%s)의 유저는 회원가입되지 않았습니다."; + + private final UserRepository userRepository; + private final InterestRepository interestRepository; + + public User saveUser(User user) { + return userRepository.save(user); + } + + public void updateUser(User user) { + userRepository.save(user); + } + + public User getUserByOAuthInfo(OAuthProvider oAuthProvider, String oAuthProviderId) { + return userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( + oAuthProvider, oAuthProviderId).orElseThrow( + () -> new IllegalArgumentException( + String.format(USER_NOT_REGISTERED_MESSAGE, oAuthProviderId, + oAuthProvider))); + } + + @Transactional + public void deleteUser(Long userId) { + interestRepository.deleteById(userId); + userRepository.deleteById(userId); + } + + public void checkDuplicatedNickname(String nickname) { + if (userRepository.existsUserByProfile_Nickname(nickname)) { + throw new IllegalArgumentException("이미 존재하는 닉네임입니다."); + } + } + + public void checkDuplicatedUser(OAuthProvider oAuthProvider, String oAuthProviderId) { + if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( + oAuthProvider, oAuthProviderId)) { + throw new IllegalArgumentException(ALREADY_REGISTERED_MESSAGE); + } + } + +} diff --git a/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java b/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java new file mode 100644 index 00000000..017ac62c --- /dev/null +++ b/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java @@ -0,0 +1,57 @@ +package coffeemeet.server.user.service.cq; + +import coffeemeet.server.certification.domain.Certification; +import coffeemeet.server.certification.service.cq.CertificationQuery; +import coffeemeet.server.interest.domain.Interest; +import coffeemeet.server.interest.domain.Keyword; +import coffeemeet.server.interest.repository.InterestRepository; +import coffeemeet.server.user.domain.User; +import coffeemeet.server.user.dto.MyProfileDto; +import coffeemeet.server.user.dto.MyProfileDto.Response; +import coffeemeet.server.user.dto.UserProfileDto; +import coffeemeet.server.user.repository.UserRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class UserQuery { + + private final UserRepository userRepository; + private final InterestRepository interestRepository; + private final CertificationQuery certificationQuery; + + public UserProfileDto.Response findUserProfile(Long userId) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); + List interests = interestRepository.findAllByUserId(userId); + List keywords = interests.stream().map(Interest::getKeyword).toList(); + Certification certification = certificationQuery.getCertificationByUserId(userId); + + return UserProfileDto.Response.of(user, certification.getDepartment(), keywords); + } + + public Response findMyProfile(Long userId) { + User user = getUserById(userId); + List interests = interestRepository.findAllByUserId(userId); + List keywords = interests.stream().map(Interest::getKeyword).toList(); + Certification certification = certificationQuery.getCertificationByUserId(userId); + + return MyProfileDto.Response.of(user, keywords, certification.getDepartment()); + } + + public User getUserById(Long userId) { + return userRepository.findById(userId) + .orElseThrow(IllegalArgumentException::new); + } + + public void checkDuplicatedNickname(String nickname) { + if (userRepository.findUserByProfileNickname(nickname).isPresent()) { + throw new IllegalArgumentException("이미 존재하는 닉네임입니다."); + } + } + +} From c5fdd55653c2c5ca42dd4a680db698ef98393f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 28 Oct 2023 22:44:23 +0900 Subject: [PATCH 218/311] =?UTF-8?q?refactor:=20InterestService=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interest/service/InterestService.java | 43 ------------------- .../interest/service/cq/InterestCommand.java | 39 +++++++++++++++++ .../interest/service/cq/InterestQuery.java | 24 +++++++++++ 3 files changed, 63 insertions(+), 43 deletions(-) delete mode 100644 src/main/java/coffeemeet/server/interest/service/InterestService.java create mode 100644 src/main/java/coffeemeet/server/interest/service/cq/InterestCommand.java create mode 100644 src/main/java/coffeemeet/server/interest/service/cq/InterestQuery.java diff --git a/src/main/java/coffeemeet/server/interest/service/InterestService.java b/src/main/java/coffeemeet/server/interest/service/InterestService.java deleted file mode 100644 index a9906ed2..00000000 --- a/src/main/java/coffeemeet/server/interest/service/InterestService.java +++ /dev/null @@ -1,43 +0,0 @@ -package coffeemeet.server.interest.service; - -import coffeemeet.server.interest.domain.Interest; -import coffeemeet.server.interest.domain.Keyword; -import coffeemeet.server.interest.repository.InterestRepository; -import coffeemeet.server.user.domain.User; -import coffeemeet.server.user.repository.UserRepository; -import java.util.List; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -@RequiredArgsConstructor -public class InterestService { - - private final InterestRepository interestRepository; - private final UserRepository userRepository; - - @Transactional - public void updateInterests(Long userId, List interests) { - - for (Keyword interest : interests) { - try { - Keyword.valueOf(interest.name()); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("유효한 관심사가 아닙니다."); - } - } - - User user = userRepository.findById(userId) - .orElseThrow(() -> new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); - - List currentInterests = interestRepository.findAllByUserId(userId); - interestRepository.deleteAll(currentInterests); - - for (Keyword keyword : interests) { - Interest newInterest = new Interest(keyword, user); - interestRepository.save(newInterest); - } - } - -} diff --git a/src/main/java/coffeemeet/server/interest/service/cq/InterestCommand.java b/src/main/java/coffeemeet/server/interest/service/cq/InterestCommand.java new file mode 100644 index 00000000..c79dd483 --- /dev/null +++ b/src/main/java/coffeemeet/server/interest/service/cq/InterestCommand.java @@ -0,0 +1,39 @@ +package coffeemeet.server.interest.service.cq; + +import coffeemeet.server.interest.domain.Interest; +import coffeemeet.server.interest.domain.Keyword; +import coffeemeet.server.interest.repository.InterestRepository; +import coffeemeet.server.user.domain.User; +import coffeemeet.server.user.dto.SignupDto; +import java.util.ArrayList; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +public class InterestCommand { + + private final InterestRepository interestRepository; + + public void saveInterests(SignupDto.Request request, User newUser) { + List interests = new ArrayList<>(); + for (Keyword value : request.keywords()) { + interests.add(new Interest(value, newUser)); + } + interestRepository.saveAll(interests); + } + + public void updateInterests(User user, List keywords) { + List currentInterests = interestRepository.findAllByUserId(user.getId()); + interestRepository.deleteAllInBatch(currentInterests); + + List interests = keywords.stream() + .map(keyword -> new Interest(keyword, user)) + .toList(); + interestRepository.saveAll(interests); + } + +} diff --git a/src/main/java/coffeemeet/server/interest/service/cq/InterestQuery.java b/src/main/java/coffeemeet/server/interest/service/cq/InterestQuery.java new file mode 100644 index 00000000..eb326652 --- /dev/null +++ b/src/main/java/coffeemeet/server/interest/service/cq/InterestQuery.java @@ -0,0 +1,24 @@ +package coffeemeet.server.interest.service.cq; + +import coffeemeet.server.interest.domain.Interest; +import coffeemeet.server.interest.domain.Keyword; +import coffeemeet.server.interest.repository.InterestRepository; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class InterestQuery { + + private final InterestRepository interestRepository; + + public List getKeywordsByUserId(Long userId) { + return interestRepository.findAllByUserId(userId).stream() + .map(Interest::getKeyword) + .toList(); + } + +} From 72e4a19d3721f681f7b34272212d41d7a2c61944 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 28 Oct 2023 22:45:04 +0900 Subject: [PATCH 219/311] =?UTF-8?q?refactor:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/coffeemeet/server/user/domain/User.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/User.java b/src/main/java/coffeemeet/server/user/domain/User.java index fa49d42d..85a38c7c 100644 --- a/src/main/java/coffeemeet/server/user/domain/User.java +++ b/src/main/java/coffeemeet/server/user/domain/User.java @@ -64,8 +64,4 @@ public void updateNickname(String newNickname) { this.profile.updateNickname(newNickname); } - public void updateName(String newName) { - this.profile.updateName(newName); - } - } From a8d39bf0786c24be243016ed580fd3e59230c709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 28 Oct 2023 22:50:18 +0900 Subject: [PATCH 220/311] =?UTF-8?q?refactor:=20=EC=9C=A0=EC=A0=80=20DTO?= =?UTF-8?q?=EB=A5=BC=20sealed=20class=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/controller/UserController.java | 27 ++++++------ .../server/user/dto/MyProfileDto.java | 41 ++++++++++++++++++ .../server/user/dto/MyProfileResponse.java | 42 ------------------- .../coffeemeet/server/user/dto/SignupDto.java | 23 ++++++++++ .../server/user/dto/SignupRequest.java | 19 --------- ...fileRequest.java => UpdateProfileDto.java} | 11 +++-- .../dto/UpdateProfileImageUrlRequest.java | 7 ---- .../server/user/dto/UserProfileDto.java | 29 +++++++++++++ .../server/user/dto/UserProfileResponse.java | 30 ------------- 9 files changed, 114 insertions(+), 115 deletions(-) create mode 100644 src/main/java/coffeemeet/server/user/dto/MyProfileDto.java delete mode 100644 src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java create mode 100644 src/main/java/coffeemeet/server/user/dto/SignupDto.java delete mode 100644 src/main/java/coffeemeet/server/user/dto/SignupRequest.java rename src/main/java/coffeemeet/server/user/dto/{UpdateProfileRequest.java => UpdateProfileDto.java} (52%) delete mode 100644 src/main/java/coffeemeet/server/user/dto/UpdateProfileImageUrlRequest.java create mode 100644 src/main/java/coffeemeet/server/user/dto/UserProfileDto.java delete mode 100644 src/main/java/coffeemeet/server/user/dto/UserProfileResponse.java diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index 80448776..87adc3ee 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -5,10 +5,10 @@ import coffeemeet.server.common.util.FileUtils; import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.dto.AuthInfo; -import coffeemeet.server.user.dto.MyProfileResponse; -import coffeemeet.server.user.dto.SignupRequest; -import coffeemeet.server.user.dto.UpdateProfileRequest; -import coffeemeet.server.user.dto.UserProfileResponse; +import coffeemeet.server.user.dto.MyProfileDto; +import coffeemeet.server.user.dto.SignupDto; +import coffeemeet.server.user.dto.UpdateProfileDto; +import coffeemeet.server.user.dto.UserProfileDto; import coffeemeet.server.user.service.UserService; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; @@ -33,13 +33,8 @@ public class UserController { private final UserService userService; - @GetMapping("/{userId}") - public ResponseEntity findUserProfile(@PathVariable long userId) { - return ResponseEntity.ok(userService.findUserProfile(userId)); - } - @PostMapping("/sign-up") - public ResponseEntity signup(@Valid @RequestBody SignupRequest request) { + public ResponseEntity signup(@Valid @RequestBody SignupDto.Request request) { return ResponseEntity.ok(userService.signup(request)); } @@ -49,8 +44,13 @@ public ResponseEntity login(@PathVariable OAuthProvider oAuthProvide return ResponseEntity.ok(userService.login(oAuthProvider, authCode)); } + @GetMapping("/{userId}") + public ResponseEntity findUserProfile(@PathVariable long userId) { + return ResponseEntity.ok(userService.findUserProfile(userId)); + } + @GetMapping("/me") - public ResponseEntity findMyProfile(@Login AuthInfo authInfo) { + public ResponseEntity findMyProfile(@Login AuthInfo authInfo) { return ResponseEntity.ok(userService.findMyProfile(authInfo.userId())); } @@ -67,9 +67,8 @@ public ResponseEntity updateProfileImage( @PatchMapping("/me") public ResponseEntity updateProfileInfo(@Login AuthInfo authInfo, - @Valid @RequestBody UpdateProfileRequest request) { - userService.updateProfileInfo(authInfo.userId(), request.nickname(), request.name(), - request.interests()); + @Valid @RequestBody UpdateProfileDto.Request request) { + userService.updateProfileInfo(authInfo.userId(), request.nickname(), request.interests()); return ResponseEntity.ok().build(); } diff --git a/src/main/java/coffeemeet/server/user/dto/MyProfileDto.java b/src/main/java/coffeemeet/server/user/dto/MyProfileDto.java new file mode 100644 index 00000000..d2f918cc --- /dev/null +++ b/src/main/java/coffeemeet/server/user/dto/MyProfileDto.java @@ -0,0 +1,41 @@ +package coffeemeet.server.user.dto; + +import coffeemeet.server.certification.domain.Department; +import coffeemeet.server.interest.domain.Keyword; +import coffeemeet.server.user.domain.User; +import java.time.LocalDateTime; +import java.util.List; + +public sealed interface MyProfileDto permits MyProfileDto.Response { + + record Response( + String name, + String nickname, + String email, + String profileImageUrl, + String birthYear, + String birthDay, + int reportedCount, + LocalDateTime sanctionPeriod, + Department department, + List interests + ) implements MyProfileDto { + + public static Response of(User user, List interests, Department department) { + + return new Response( + user.getProfile().getName(), + user.getProfile().getNickname(), + user.getProfile().getEmail().getEmail(), + user.getProfile().getProfileImageUrl(), + user.getProfile().getBirth().getBirthYear(), + user.getProfile().getBirth().getBirthDay(), + user.getReportInfo().getReportedCount(), + user.getReportInfo().getSanctionPeriod(), + department, + interests + ); + } + } + +} diff --git a/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java b/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java deleted file mode 100644 index 69db6d31..00000000 --- a/src/main/java/coffeemeet/server/user/dto/MyProfileResponse.java +++ /dev/null @@ -1,42 +0,0 @@ -package coffeemeet.server.user.dto; - -import coffeemeet.server.certification.domain.Department; -import coffeemeet.server.interest.domain.Interest; -import coffeemeet.server.interest.domain.Keyword; -import coffeemeet.server.user.domain.User; -import java.time.LocalDateTime; -import java.util.List; - -public record MyProfileResponse( - String name, - String nickname, - String email, - String profileImageUrl, - String birthYear, - String birthDay, - int reportedCount, - LocalDateTime sanctionPeriod, - Department department, - List interests -) { - - public static MyProfileResponse of(User user, List interests, Department department) { - List keywords = interests.stream() - .map(Interest::getKeyword) - .toList(); - - return new MyProfileResponse( - user.getProfile().getName(), - user.getProfile().getNickname(), - user.getProfile().getEmail().getEmail(), - user.getProfile().getProfileImageUrl(), - user.getProfile().getBirth().getBirthYear(), - user.getProfile().getBirth().getBirthDay(), - user.getReportInfo().getReportedCount(), - user.getReportInfo().getSanctionPeriod(), - department, - keywords - ); - } - -} diff --git a/src/main/java/coffeemeet/server/user/dto/SignupDto.java b/src/main/java/coffeemeet/server/user/dto/SignupDto.java new file mode 100644 index 00000000..2a64dfd7 --- /dev/null +++ b/src/main/java/coffeemeet/server/user/dto/SignupDto.java @@ -0,0 +1,23 @@ +package coffeemeet.server.user.dto; + +import coffeemeet.server.interest.domain.Keyword; +import coffeemeet.server.user.domain.OAuthProvider; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import java.util.List; + +public sealed interface SignupDto permits SignupDto.Request { + + record Request( + @NotBlank + String nickname, + @NotNull + List keywords, + @NotBlank + String authCode, + OAuthProvider oAuthProvider + ) implements SignupDto { + + } + +} diff --git a/src/main/java/coffeemeet/server/user/dto/SignupRequest.java b/src/main/java/coffeemeet/server/user/dto/SignupRequest.java deleted file mode 100644 index 42f7cde8..00000000 --- a/src/main/java/coffeemeet/server/user/dto/SignupRequest.java +++ /dev/null @@ -1,19 +0,0 @@ -package coffeemeet.server.user.dto; - -import coffeemeet.server.interest.domain.Keyword; -import coffeemeet.server.user.domain.OAuthProvider; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import java.util.List; - -public record SignupRequest( - @NotBlank - String nickname, - @NotNull - List keywords, - @NotBlank - String authCode, - OAuthProvider oAuthProvider -) { - -} diff --git a/src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java b/src/main/java/coffeemeet/server/user/dto/UpdateProfileDto.java similarity index 52% rename from src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java rename to src/main/java/coffeemeet/server/user/dto/UpdateProfileDto.java index 8a8c7e1d..2c4e8d61 100644 --- a/src/main/java/coffeemeet/server/user/dto/UpdateProfileRequest.java +++ b/src/main/java/coffeemeet/server/user/dto/UpdateProfileDto.java @@ -6,8 +6,13 @@ import jakarta.validation.constraints.Size; import java.util.List; -public record UpdateProfileRequest(@NotBlank String nickname, - @NotBlank String name, - @NotNull @Size(min = 1, max = 3) List interests) { +public sealed interface UpdateProfileDto permits UpdateProfileDto.Request { + + record Request( + @NotBlank String nickname, + @NotNull @Size(min = 1, max = 3) List interests + ) implements UpdateProfileDto { + + } } diff --git a/src/main/java/coffeemeet/server/user/dto/UpdateProfileImageUrlRequest.java b/src/main/java/coffeemeet/server/user/dto/UpdateProfileImageUrlRequest.java deleted file mode 100644 index 7f1c54ca..00000000 --- a/src/main/java/coffeemeet/server/user/dto/UpdateProfileImageUrlRequest.java +++ /dev/null @@ -1,7 +0,0 @@ -package coffeemeet.server.user.dto; - -import jakarta.validation.constraints.NotBlank; - -public record UpdateProfileImageUrlRequest(@NotBlank String profileImageUrl) { - -} diff --git a/src/main/java/coffeemeet/server/user/dto/UserProfileDto.java b/src/main/java/coffeemeet/server/user/dto/UserProfileDto.java new file mode 100644 index 00000000..9ff20391 --- /dev/null +++ b/src/main/java/coffeemeet/server/user/dto/UserProfileDto.java @@ -0,0 +1,29 @@ +package coffeemeet.server.user.dto; + +import coffeemeet.server.certification.domain.Department; +import coffeemeet.server.interest.domain.Keyword; +import coffeemeet.server.user.domain.User; +import java.util.List; + +public sealed interface UserProfileDto permits UserProfileDto.Response { + + record Response( + String nickname, + String profileImageUrl, + Department department, + List interests + ) implements UserProfileDto { + + public static Response of(User user, Department department, + List interests) { + + return new Response( + user.getProfile().getNickname(), + user.getProfile().getProfileImageUrl(), + department, + interests + ); + } + } + +} diff --git a/src/main/java/coffeemeet/server/user/dto/UserProfileResponse.java b/src/main/java/coffeemeet/server/user/dto/UserProfileResponse.java deleted file mode 100644 index 0874366b..00000000 --- a/src/main/java/coffeemeet/server/user/dto/UserProfileResponse.java +++ /dev/null @@ -1,30 +0,0 @@ -package coffeemeet.server.user.dto; - -import coffeemeet.server.certification.domain.Department; -import coffeemeet.server.interest.domain.Interest; -import coffeemeet.server.interest.domain.Keyword; -import coffeemeet.server.user.domain.User; -import java.util.List; - -public record UserProfileResponse( - String nickname, - String profileImageUrl, - Department department, - List interests -) { - - public static UserProfileResponse of(User user, Department department, - List interests) { - List keywords = interests.stream() - .map(Interest::getKeyword) - .toList(); - - return new UserProfileResponse( - user.getProfile().getNickname(), - user.getProfile().getProfileImageUrl(), - department, - keywords - ); - } - -} From 33abbe5e653db095da118bfdea3e72bb4e415f72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 28 Oct 2023 22:51:58 +0900 Subject: [PATCH 221/311] =?UTF-8?q?refactor:=20=EA=B3=84=EC=B8=B5=20?= =?UTF-8?q?=EA=B0=84=20DTO=20=EB=B6=84=EB=A6=AC=EB=A5=BC=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20OAuthUserInfo=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/dto/OAuthUserInfo.java | 28 +++++++++++++++++++ .../fixture/dto/OAuthInfoResponseFixture.java | 13 +++++++++ .../OAuthMemberClientCompositeTest.java | 4 +-- 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 src/main/java/coffeemeet/server/user/dto/OAuthUserInfo.java create mode 100644 src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java diff --git a/src/main/java/coffeemeet/server/user/dto/OAuthUserInfo.java b/src/main/java/coffeemeet/server/user/dto/OAuthUserInfo.java new file mode 100644 index 00000000..b60760c6 --- /dev/null +++ b/src/main/java/coffeemeet/server/user/dto/OAuthUserInfo.java @@ -0,0 +1,28 @@ +package coffeemeet.server.user.dto; + +import coffeemeet.server.oauth.dto.OAuthUserInfoDto; +import coffeemeet.server.user.domain.OAuthProvider; + +public record OAuthUserInfo( + String name, + String profileImage, + String birthYear, + String birthDay, + String email, + OAuthProvider oAuthProvider, + String oAuthProviderId +) { + + public static OAuthUserInfo from(OAuthUserInfoDto.Response response) { + return new OAuthUserInfo( + response.name(), + response.profileImage(), + response.birthYear(), + response.birthDay(), + response.email(), + response.oAuthProvider(), + response.oAuthProviderId() + ); + } + +} diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java new file mode 100644 index 00000000..d4a771cf --- /dev/null +++ b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java @@ -0,0 +1,13 @@ +package coffeemeet.server.common.fixture.dto; + +import coffeemeet.server.oauth.dto.OAuthUserInfoDto; +import org.instancio.Instancio; + +public class OAuthInfoResponseFixture { + + public static OAuthUserInfoDto.Response oAuthInfoResponse() { + return Instancio.of(OAuthUserInfoDto.Response.class) + .create(); + } + +} diff --git a/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java index 96952a18..1fea992b 100644 --- a/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java +++ b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; -import coffeemeet.server.common.fixture.dto.OAuthUserInfoDtoFixture; +import coffeemeet.server.common.fixture.dto.OAuthInfoResponseFixture; import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import coffeemeet.server.user.domain.OAuthProvider; import java.util.Collections; @@ -34,7 +34,7 @@ void fetchTest() { // given String authCode = "authCode"; OAuthProvider oAuthProvider = OAuthProvider.KAKAO; - OAuthUserInfoDto.Response response = OAuthUserInfoDtoFixture.response(); + OAuthUserInfoDto.Response response = OAuthInfoResponseFixture.oAuthInfoResponse(); given(client.oAuthProvider()).willReturn(OAuthProvider.KAKAO); given(client.fetch(authCode)).willReturn(response); From 8b0a9cc588410bd8ba1e1e1749fbb5648627cb8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 28 Oct 2023 23:09:19 +0900 Subject: [PATCH 222/311] =?UTF-8?q?refactor:=20CertificationService?= =?UTF-8?q?=EA=B0=80=20UserQuery=EB=A5=BC=20=EC=9D=98=EC=A1=B4=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/certification/service/CertificationService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java index 0149fc2b..77230bf6 100644 --- a/src/main/java/coffeemeet/server/certification/service/CertificationService.java +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -12,7 +12,7 @@ import coffeemeet.server.common.media.S3MediaService; import coffeemeet.server.common.util.FileUtils; import coffeemeet.server.user.domain.User; -import coffeemeet.server.user.service.UserService; +import coffeemeet.server.user.service.cq.UserQuery; import java.io.File; import java.util.random.RandomGenerator; import lombok.RequiredArgsConstructor; @@ -27,7 +27,7 @@ public class CertificationService { private final S3MediaService s3MediaService; private final EmailService emailService; - private final UserService userService; + private final UserQuery userQuery; private final CertificationCommand certificationCommand; private final CertificationQuery certificationQuery; private final EmailVerificationCommand emailVerificationCommand; @@ -41,7 +41,7 @@ public void registerCertification(long userId, String email, String departmentNa CompanyEmail companyEmail = new CompanyEmail(email); String businessCardUrl = s3MediaService.getUrl(key); Department department = Department.valueOf(departmentName); - User user = userService.getUserById(userId); + User user = userQuery.getUserById(userId); certificationCommand.newCertification(companyEmail, businessCardUrl, department, user); } From e289142c6754a5155877bcf473fec2ffec71db4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sat, 28 Oct 2023 23:25:18 +0900 Subject: [PATCH 223/311] =?UTF-8?q?fix:=20=EB=A6=AC=EB=B2=A0=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=8B=9C=20=EC=B6=A9=EB=8F=8C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/oauth/service/OAuthService.java | 2 +- .../server/user/service/UserService.java | 22 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/coffeemeet/server/oauth/service/OAuthService.java b/src/main/java/coffeemeet/server/oauth/service/OAuthService.java index 07b7b1c4..23240129 100644 --- a/src/main/java/coffeemeet/server/oauth/service/OAuthService.java +++ b/src/main/java/coffeemeet/server/oauth/service/OAuthService.java @@ -18,7 +18,7 @@ public String getAuthCodeRequestUrl(OAuthProvider oAuthProvider) { return authCodeRequestUrlProviderComposite.provide(oAuthProvider); } - public OAuthUserInfoDto.Response getOAuthInfo(OAuthProvider oAuthProvider, String authCode) { + public OAuthUserInfoDto.Response getOAuthUserInfo(OAuthProvider oAuthProvider, String authCode) { return oauthMemberClientComposite.fetch(oAuthProvider, authCode); } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 97c32c01..db4b3f2c 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -10,6 +10,7 @@ import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.interest.service.cq.InterestCommand; import coffeemeet.server.interest.service.cq.InterestQuery; +import coffeemeet.server.oauth.dto.OAuthUserInfoDto.Response; import coffeemeet.server.oauth.service.OAuthService; import coffeemeet.server.user.domain.Birth; import coffeemeet.server.user.domain.Email; @@ -17,7 +18,6 @@ import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.dto.MyProfileDto; -import coffeemeet.server.user.dto.OAuthUserInfo; import coffeemeet.server.user.dto.SignupDto; import coffeemeet.server.user.dto.UserProfileDto; import coffeemeet.server.user.service.cq.UserCommand; @@ -47,19 +47,19 @@ public class UserService { private final UserCommand userCommand; public AuthTokens signup(SignupDto.Request request) { - OAuthUserInfo oAuthUserInfo = oAuthService.getOAuthUserInfo(request.oAuthProvider(), + Response response = oAuthService.getOAuthUserInfo(request.oAuthProvider(), request.authCode()); - userCommand.checkDuplicatedUser(oAuthUserInfo.oAuthProvider(), oAuthUserInfo.oAuthProviderId()); + userCommand.checkDuplicatedUser(response.oAuthProvider(), response.oAuthProviderId()); userCommand.checkDuplicatedNickname(request.nickname()); - String profileImage = getProfileImageOrDefault(oAuthUserInfo.profileImage()); + String profileImage = getProfileImageOrDefault(response.profileImage()); - User user = new User(new coffeemeet.server.user.domain.OAuthInfo(oAuthUserInfo.oAuthProvider(), - oAuthUserInfo.oAuthProviderId()), - Profile.builder().name(oAuthUserInfo.name()).nickname(request.nickname()) - .email(new Email(oAuthUserInfo.email())) + User user = new User(new coffeemeet.server.user.domain.OAuthInfo(response.oAuthProvider(), + response.oAuthProviderId()), + Profile.builder().name(response.name()).nickname(request.nickname()) + .email(new Email(response.email())) .profileImageUrl(profileImage) - .birth(new Birth(oAuthUserInfo.birthYear(), oAuthUserInfo.birthDay())).build()); + .birth(new Birth(response.birthYear(), response.birthDay())).build()); User newUser = userCommand.saveUser(user); interestCommand.saveInterests(request, newUser); @@ -67,8 +67,8 @@ public AuthTokens signup(SignupDto.Request request) { } public AuthTokens login(OAuthProvider oAuthProvider, String authCode) { - OAuthUserInfo oAuthUserInfo = oAuthService.getOAuthUserInfo(oAuthProvider, authCode); - User user = userCommand.getUserByOAuthInfo(oAuthProvider, oAuthUserInfo.oAuthProviderId()); + Response response = oAuthService.getOAuthUserInfo(oAuthProvider, authCode); + User user = userCommand.getUserByOAuthInfo(oAuthProvider, response.oAuthProviderId()); return authTokensGenerator.generate(user.getId()); } From ba55e23feac316f30cd026eab70201e3ff8df13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sun, 29 Oct 2023 01:23:20 +0900 Subject: [PATCH 224/311] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/service/UserService.java | 13 ++--- .../server/user/service/cq/UserCommand.java | 26 --------- .../server/user/service/cq/UserQuery.java | 53 ++++++++----------- 3 files changed, 26 insertions(+), 66 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index db4b3f2c..52096117 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -26,11 +26,9 @@ import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor -@Transactional(readOnly = true) public class UserService { private static final String DEFAULT_IMAGE_URL = "기본 이미지 URL"; @@ -50,8 +48,8 @@ public AuthTokens signup(SignupDto.Request request) { Response response = oAuthService.getOAuthUserInfo(request.oAuthProvider(), request.authCode()); - userCommand.checkDuplicatedUser(response.oAuthProvider(), response.oAuthProviderId()); - userCommand.checkDuplicatedNickname(request.nickname()); + userQuery.hasDuplicatedUser(response.oAuthProvider(), response.oAuthProviderId()); + userQuery.hasDuplicatedNickname(request.nickname()); String profileImage = getProfileImageOrDefault(response.profileImage()); User user = new User(new coffeemeet.server.user.domain.OAuthInfo(response.oAuthProvider(), @@ -68,7 +66,7 @@ public AuthTokens signup(SignupDto.Request request) { public AuthTokens login(OAuthProvider oAuthProvider, String authCode) { Response response = oAuthService.getOAuthUserInfo(oAuthProvider, authCode); - User user = userCommand.getUserByOAuthInfo(oAuthProvider, response.oAuthProviderId()); + User user = userQuery.getUserByOAuthInfo(oAuthProvider, response.oAuthProviderId()); return authTokensGenerator.generate(user.getId()); } @@ -98,16 +96,15 @@ public void updateProfileImage(Long userId, File file) { public void updateProfileInfo(Long userId, String nickname, List keywords) { User user = userQuery.getUserById(userId); - userQuery.checkDuplicatedNickname(nickname); + userQuery.hasDuplicatedNickname(nickname); user.updateNickname(nickname); interestCommand.updateInterests(userQuery.getUserById(userId), keywords); } public void checkDuplicatedNickname(String nickname) { - userCommand.checkDuplicatedNickname(nickname); + userQuery.hasDuplicatedNickname(nickname); } - @Transactional public void deleteUser(Long userId) { userCommand.deleteUser(userId); } diff --git a/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java b/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java index 767de48f..b575bac1 100644 --- a/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java +++ b/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java @@ -1,7 +1,6 @@ package coffeemeet.server.user.service.cq; import coffeemeet.server.interest.repository.InterestRepository; -import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.repository.UserRepository; import lombok.RequiredArgsConstructor; @@ -13,9 +12,6 @@ @RequiredArgsConstructor public class UserCommand { - private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; - private static final String USER_NOT_REGISTERED_MESSAGE = "해당 아이디(%s)와 로그인 타입(%s)의 유저는 회원가입되지 않았습니다."; - private final UserRepository userRepository; private final InterestRepository interestRepository; @@ -27,31 +23,9 @@ public void updateUser(User user) { userRepository.save(user); } - public User getUserByOAuthInfo(OAuthProvider oAuthProvider, String oAuthProviderId) { - return userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( - oAuthProvider, oAuthProviderId).orElseThrow( - () -> new IllegalArgumentException( - String.format(USER_NOT_REGISTERED_MESSAGE, oAuthProviderId, - oAuthProvider))); - } - - @Transactional public void deleteUser(Long userId) { interestRepository.deleteById(userId); userRepository.deleteById(userId); } - public void checkDuplicatedNickname(String nickname) { - if (userRepository.existsUserByProfile_Nickname(nickname)) { - throw new IllegalArgumentException("이미 존재하는 닉네임입니다."); - } - } - - public void checkDuplicatedUser(OAuthProvider oAuthProvider, String oAuthProviderId) { - if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( - oAuthProvider, oAuthProviderId)) { - throw new IllegalArgumentException(ALREADY_REGISTERED_MESSAGE); - } - } - } diff --git a/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java b/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java index 017ac62c..32cc7301 100644 --- a/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java +++ b/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java @@ -1,16 +1,8 @@ package coffeemeet.server.user.service.cq; -import coffeemeet.server.certification.domain.Certification; -import coffeemeet.server.certification.service.cq.CertificationQuery; -import coffeemeet.server.interest.domain.Interest; -import coffeemeet.server.interest.domain.Keyword; -import coffeemeet.server.interest.repository.InterestRepository; +import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.User; -import coffeemeet.server.user.dto.MyProfileDto; -import coffeemeet.server.user.dto.MyProfileDto.Response; -import coffeemeet.server.user.dto.UserProfileDto; import coffeemeet.server.user.repository.UserRepository; -import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -20,38 +12,35 @@ @Transactional(readOnly = true) public class UserQuery { - private final UserRepository userRepository; - private final InterestRepository interestRepository; - private final CertificationQuery certificationQuery; - - public UserProfileDto.Response findUserProfile(Long userId) { - User user = userRepository.findById(userId) - .orElseThrow(() -> new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); - List interests = interestRepository.findAllByUserId(userId); - List keywords = interests.stream().map(Interest::getKeyword).toList(); - Certification certification = certificationQuery.getCertificationByUserId(userId); - - return UserProfileDto.Response.of(user, certification.getDepartment(), keywords); - } - - public Response findMyProfile(Long userId) { - User user = getUserById(userId); - List interests = interestRepository.findAllByUserId(userId); - List keywords = interests.stream().map(Interest::getKeyword).toList(); - Certification certification = certificationQuery.getCertificationByUserId(userId); + private static final String USER_NOT_REGISTERED_MESSAGE = "해당 아이디(%s)와 로그인 타입(%s)의 유저는 회원가입되지 않았습니다."; + private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; - return MyProfileDto.Response.of(user, keywords, certification.getDepartment()); - } + private final UserRepository userRepository; public User getUserById(Long userId) { return userRepository.findById(userId) .orElseThrow(IllegalArgumentException::new); } - public void checkDuplicatedNickname(String nickname) { - if (userRepository.findUserByProfileNickname(nickname).isPresent()) { + public User getUserByOAuthInfo(OAuthProvider oAuthProvider, String oAuthProviderId) { + return userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( + oAuthProvider, oAuthProviderId).orElseThrow( + () -> new IllegalArgumentException( + String.format(USER_NOT_REGISTERED_MESSAGE, oAuthProviderId, + oAuthProvider))); + } + + public void hasDuplicatedNickname(String nickname) { + if (userRepository.existsUserByProfile_Nickname(nickname)) { throw new IllegalArgumentException("이미 존재하는 닉네임입니다."); } } + public void hasDuplicatedUser(OAuthProvider oAuthProvider, String oAuthProviderId) { + if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( + oAuthProvider, oAuthProviderId)) { + throw new IllegalArgumentException(ALREADY_REGISTERED_MESSAGE); + } + } + } From c64540dff3330426944b8856b554deb09457afd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sun, 29 Oct 2023 11:10:22 +0900 Subject: [PATCH 225/311] =?UTF-8?q?refactor:=20UserCommand=20=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=20=EC=A0=80=EC=9E=A5=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EC=9D=98=20=EB=B0=98=ED=99=98=ED=83=80=EC=9E=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/user/service/UserService.java | 9 ++++++--- .../coffeemeet/server/user/service/cq/UserCommand.java | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 52096117..3b8ff737 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -14,6 +14,7 @@ import coffeemeet.server.oauth.service.OAuthService; import coffeemeet.server.user.domain.Birth; import coffeemeet.server.user.domain.Email; +import coffeemeet.server.user.domain.OAuthInfo; import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; @@ -52,14 +53,15 @@ public AuthTokens signup(SignupDto.Request request) { userQuery.hasDuplicatedNickname(request.nickname()); String profileImage = getProfileImageOrDefault(response.profileImage()); - User user = new User(new coffeemeet.server.user.domain.OAuthInfo(response.oAuthProvider(), + User user = new User(new OAuthInfo(response.oAuthProvider(), response.oAuthProviderId()), Profile.builder().name(response.name()).nickname(request.nickname()) .email(new Email(response.email())) .profileImageUrl(profileImage) .birth(new Birth(response.birthYear(), response.birthDay())).build()); - User newUser = userCommand.saveUser(user); + Long userId = userCommand.saveUser(user); + User newUser = userQuery.getUserById(userId); interestCommand.saveInterests(request, newUser); return authTokensGenerator.generate(newUser.getId()); } @@ -81,12 +83,13 @@ public MyProfileDto.Response findMyProfile(Long userId) { User user = userQuery.getUserById(userId); List keywords = interestQuery.getKeywordsByUserId(userId); Certification certification = certificationQuery.getCertificationByUserId(userId); - return MyProfileDto.Response.of(user, keywords, certification.getDepartment()); + return MyProfileDto.Response.of(user, certification.getDepartment(), keywords); } public void updateProfileImage(Long userId, File file) { User user = userQuery.getUserById(userId); deleteCurrentProfileImage(user.getProfile().getProfileImageUrl()); + String key = s3MediaService.generateKey(PROFILE_IMAGE); s3MediaService.upload(key, file); user.updateProfileImageUrl(s3MediaService.getUrl(key)); diff --git a/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java b/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java index b575bac1..f41736b9 100644 --- a/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java +++ b/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java @@ -15,8 +15,8 @@ public class UserCommand { private final UserRepository userRepository; private final InterestRepository interestRepository; - public User saveUser(User user) { - return userRepository.save(user); + public Long saveUser(User user) { + return userRepository.save(user).getId(); } public void updateUser(User user) { From 2abf270e21feb9ab873854f6be3b9ec937d19ccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sun, 29 Oct 2023 11:19:14 +0900 Subject: [PATCH 226/311] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=A0=9C=EA=B1=B0=20?= =?UTF-8?q?=EB=B0=8F=20=EC=9E=98=EB=AA=BB=EB=90=9C=20=ED=8C=8C=EB=9D=BC?= =?UTF-8?q?=EB=AF=B8=ED=84=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/user/repository/UserRepository.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/repository/UserRepository.java b/src/main/java/coffeemeet/server/user/repository/UserRepository.java index 36d996eb..166c0cb9 100644 --- a/src/main/java/coffeemeet/server/user/repository/UserRepository.java +++ b/src/main/java/coffeemeet/server/user/repository/UserRepository.java @@ -12,10 +12,8 @@ boolean existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( String oauthProviderId); Optional getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( - OAuthProvider oAuthProvider, - String authCode); - - Optional findUserByProfileNickname(String nickname); + OAuthProvider oauthProvider, + String oauthProviderId); boolean existsUserByProfile_Nickname(String nickname); From 4d65471df49a510ed3ce9f189f3103ed62b67d77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sun, 29 Oct 2023 11:46:44 +0900 Subject: [PATCH 227/311] =?UTF-8?q?refactor:=20=EA=B4=80=EC=8B=AC=EC=82=AC?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interest/service/cq/InterestCommand.java | 19 +++++++------------ .../server/user/service/UserService.java | 14 +++++++++++--- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/main/java/coffeemeet/server/interest/service/cq/InterestCommand.java b/src/main/java/coffeemeet/server/interest/service/cq/InterestCommand.java index c79dd483..ae544fd4 100644 --- a/src/main/java/coffeemeet/server/interest/service/cq/InterestCommand.java +++ b/src/main/java/coffeemeet/server/interest/service/cq/InterestCommand.java @@ -4,8 +4,6 @@ import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.interest.repository.InterestRepository; import coffeemeet.server.user.domain.User; -import coffeemeet.server.user.dto.SignupDto; -import java.util.ArrayList; import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -18,22 +16,19 @@ public class InterestCommand { private final InterestRepository interestRepository; - public void saveInterests(SignupDto.Request request, User newUser) { - List interests = new ArrayList<>(); - for (Keyword value : request.keywords()) { - interests.add(new Interest(value, newUser)); - } - interestRepository.saveAll(interests); + public List findAllByUserId(long userId) { + return interestRepository.findAllByUserId(userId); } - public void updateInterests(User user, List keywords) { - List currentInterests = interestRepository.findAllByUserId(user.getId()); - interestRepository.deleteAllInBatch(currentInterests); - + public void saveAll(List keywords, User user) { List interests = keywords.stream() .map(keyword -> new Interest(keyword, user)) .toList(); interestRepository.saveAll(interests); } + public void deleteAll(List interests) { + interestRepository.deleteAllInBatch(interests); + } + } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 3b8ff737..532d130c 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -7,6 +7,7 @@ import coffeemeet.server.certification.domain.Certification; import coffeemeet.server.certification.service.cq.CertificationQuery; import coffeemeet.server.common.media.S3MediaService; +import coffeemeet.server.interest.domain.Interest; import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.interest.service.cq.InterestCommand; import coffeemeet.server.interest.service.cq.InterestQuery; @@ -62,7 +63,8 @@ public AuthTokens signup(SignupDto.Request request) { Long userId = userCommand.saveUser(user); User newUser = userQuery.getUserById(userId); - interestCommand.saveInterests(request, newUser); + + interestCommand.saveAll(request.keywords(), newUser); return authTokensGenerator.generate(newUser.getId()); } @@ -83,7 +85,7 @@ public MyProfileDto.Response findMyProfile(Long userId) { User user = userQuery.getUserById(userId); List keywords = interestQuery.getKeywordsByUserId(userId); Certification certification = certificationQuery.getCertificationByUserId(userId); - return MyProfileDto.Response.of(user, certification.getDepartment(), keywords); + return MyProfileDto.Response.of(user, keywords, certification.getDepartment()); } public void updateProfileImage(Long userId, File file) { @@ -101,7 +103,7 @@ public void updateProfileInfo(Long userId, String nickname, User user = userQuery.getUserById(userId); userQuery.hasDuplicatedNickname(nickname); user.updateNickname(nickname); - interestCommand.updateInterests(userQuery.getUserById(userId), keywords); + updateInterests(user, keywords); } public void checkDuplicatedNickname(String nickname) { @@ -125,4 +127,10 @@ private void deleteCurrentProfileImage(String profileImageUrl) { s3MediaService.delete(currentKey); } + private void updateInterests(User user, List keywords) { + List currentInterests = interestCommand.findAllByUserId(user.getId()); + interestCommand.deleteAll(currentInterests); + interestCommand.saveAll(keywords, user); + } + } From f8feab2950c1dec59119d89ce9eedf77d64a2bfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Sun, 29 Oct 2023 12:07:47 +0900 Subject: [PATCH 228/311] =?UTF-8?q?refactor:=20=EB=B3=80=EA=B2=BD=EB=90=9C?= =?UTF-8?q?=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=AA=85=EC=97=90=20=EB=94=B0?= =?UTF-8?q?=EB=9D=BC=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EC=BD=94=EB=93=9C=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 --- .../java/coffeemeet/server/oauth/service/OAuthServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java b/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java index 66176595..91953ce6 100644 --- a/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java +++ b/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java @@ -53,7 +53,7 @@ void getOAuthInfoTest() { given(oAuthMemberClientComposite.fetch(oAuthProvider, authCode)).willReturn(oAuthInfoResponse); // when, then - assertThat(oAuthService.getOAuthInfo(oAuthProvider, authCode)).isEqualTo(oAuthInfoResponse); + assertThat(oAuthService.getOAuthUserInfo(oAuthProvider, authCode)).isEqualTo(oAuthInfoResponse); } } From 5ba3fc44a0c9b8bbdfdceec85b444d58584d838c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 30 Oct 2023 01:26:26 +0900 Subject: [PATCH 229/311] =?UTF-8?q?refactor:=20=EB=88=84=EB=9D=BD=EB=90=9C?= =?UTF-8?q?=20`@NonNull`=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/user/domain/Email.java | 3 ++- .../coffeemeet/server/user/domain/OAuthInfo.java | 2 +- .../java/coffeemeet/server/user/domain/Profile.java | 12 ++++++++---- .../java/coffeemeet/server/user/domain/User.java | 5 +++-- .../java/coffeemeet/server/user/dto/SignupDto.java | 2 ++ 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/Email.java b/src/main/java/coffeemeet/server/user/domain/Email.java index e52f12d3..5af94843 100644 --- a/src/main/java/coffeemeet/server/user/domain/Email.java +++ b/src/main/java/coffeemeet/server/user/domain/Email.java @@ -5,6 +5,7 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.NonNull; @Getter @Embeddable @@ -13,7 +14,7 @@ public class Email { private String email; - public Email(String email) { + public Email(@NonNull String email) { validateEmail(email); this.email = email; } diff --git a/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java b/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java index a1f4d704..9b566182 100644 --- a/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java +++ b/src/main/java/coffeemeet/server/user/domain/OAuthInfo.java @@ -18,7 +18,7 @@ public class OAuthInfo { private String oauthProviderId; - public OAuthInfo(OAuthProvider oauthProvider, @NonNull String oauthProviderId) { + public OAuthInfo(@NonNull OAuthProvider oauthProvider, @NonNull String oauthProviderId) { this.oauthProvider = oauthProvider; this.oauthProviderId = oauthProviderId; } diff --git a/src/main/java/coffeemeet/server/user/domain/Profile.java b/src/main/java/coffeemeet/server/user/domain/Profile.java index b4552cd0..b0bc1196 100644 --- a/src/main/java/coffeemeet/server/user/domain/Profile.java +++ b/src/main/java/coffeemeet/server/user/domain/Profile.java @@ -3,7 +3,6 @@ import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import jakarta.persistence.Embedded; -import jakarta.validation.constraints.NotNull; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -36,10 +35,15 @@ public class Profile { @Builder private Profile( - @NonNull String name, - @NotNull String nickname, + @NonNull + String name, + @NonNull + String nickname, + @NonNull Email email, - @NonNull String profileImageUrl, + @NonNull + String profileImageUrl, + @NonNull Birth birth ) { validateNickname(nickname); diff --git a/src/main/java/coffeemeet/server/user/domain/User.java b/src/main/java/coffeemeet/server/user/domain/User.java index 85a38c7c..08ddcb10 100644 --- a/src/main/java/coffeemeet/server/user/domain/User.java +++ b/src/main/java/coffeemeet/server/user/domain/User.java @@ -14,6 +14,7 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.NonNull; import org.hibernate.annotations.Where; @Entity @@ -47,8 +48,8 @@ public class User extends AdvancedBaseEntity { private boolean isDeleted; public User( - OAuthInfo oauthInfo, - Profile profile + @NonNull OAuthInfo oauthInfo, + @NonNull Profile profile ) { this.oauthInfo = oauthInfo; this.profile = profile; diff --git a/src/main/java/coffeemeet/server/user/dto/SignupDto.java b/src/main/java/coffeemeet/server/user/dto/SignupDto.java index 2a64dfd7..911a8b3a 100644 --- a/src/main/java/coffeemeet/server/user/dto/SignupDto.java +++ b/src/main/java/coffeemeet/server/user/dto/SignupDto.java @@ -5,6 +5,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import java.util.List; +import lombok.NonNull; public sealed interface SignupDto permits SignupDto.Request { @@ -15,6 +16,7 @@ record Request( List keywords, @NotBlank String authCode, + @NonNull OAuthProvider oAuthProvider ) implements SignupDto { From b639277b559f0cae175e76b182536c743d1e145a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Mon, 30 Oct 2023 16:03:57 +0900 Subject: [PATCH 230/311] =?UTF-8?q?refactor:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interest/service/cq/InterestCommand.java | 6 ++++++ .../server/user/service/UserService.java | 14 ++++---------- .../server/user/service/cq/UserCommand.java | 7 +++++++ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/main/java/coffeemeet/server/interest/service/cq/InterestCommand.java b/src/main/java/coffeemeet/server/interest/service/cq/InterestCommand.java index ae544fd4..404f4b6a 100644 --- a/src/main/java/coffeemeet/server/interest/service/cq/InterestCommand.java +++ b/src/main/java/coffeemeet/server/interest/service/cq/InterestCommand.java @@ -27,6 +27,12 @@ public void saveAll(List keywords, User user) { interestRepository.saveAll(interests); } + public void updateInterests(User user, List keywords) { + List currentInterests = findAllByUserId(user.getId()); + deleteAll(currentInterests); + saveAll(keywords, user); + } + public void deleteAll(List interests) { interestRepository.deleteAllInBatch(interests); } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 532d130c..15544f3a 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -7,7 +7,6 @@ import coffeemeet.server.certification.domain.Certification; import coffeemeet.server.certification.service.cq.CertificationQuery; import coffeemeet.server.common.media.S3MediaService; -import coffeemeet.server.interest.domain.Interest; import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.interest.service.cq.InterestCommand; import coffeemeet.server.interest.service.cq.InterestQuery; @@ -28,6 +27,7 @@ import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor @@ -98,12 +98,12 @@ public void updateProfileImage(Long userId, File file) { userCommand.updateUser(user); } + @Transactional public void updateProfileInfo(Long userId, String nickname, List keywords) { + userCommand.updateUserInfo(userId, nickname); User user = userQuery.getUserById(userId); - userQuery.hasDuplicatedNickname(nickname); - user.updateNickname(nickname); - updateInterests(user, keywords); + interestCommand.updateInterests(user, keywords); } public void checkDuplicatedNickname(String nickname) { @@ -127,10 +127,4 @@ private void deleteCurrentProfileImage(String profileImageUrl) { s3MediaService.delete(currentKey); } - private void updateInterests(User user, List keywords) { - List currentInterests = interestCommand.findAllByUserId(user.getId()); - interestCommand.deleteAll(currentInterests); - interestCommand.saveAll(keywords, user); - } - } diff --git a/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java b/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java index f41736b9..c458d9ba 100644 --- a/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java +++ b/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java @@ -13,6 +13,7 @@ public class UserCommand { private final UserRepository userRepository; + private final UserQuery userQuery; private final InterestRepository interestRepository; public Long saveUser(User user) { @@ -28,4 +29,10 @@ public void deleteUser(Long userId) { userRepository.deleteById(userId); } + public void updateUserInfo(Long userId, String nickname) { + User user = userQuery.getUserById(userId); + userQuery.hasDuplicatedNickname(nickname); + user.updateNickname(nickname); + } + } From 52cad1254f6a7d1d90e8a0054f2f0aa9f2579101 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 16:00:25 +0900 Subject: [PATCH 231/311] =?UTF-8?q?refactor:=20NonNull=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/certification/domain/CompanyEmail.java | 11 ++--------- .../certification/domain/EmailVerification.java | 4 +++- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/domain/CompanyEmail.java b/src/main/java/coffeemeet/server/certification/domain/CompanyEmail.java index f6567fc7..38486a64 100644 --- a/src/main/java/coffeemeet/server/certification/domain/CompanyEmail.java +++ b/src/main/java/coffeemeet/server/certification/domain/CompanyEmail.java @@ -1,11 +1,11 @@ package coffeemeet.server.certification.domain; -import coffeemeet.server.common.util.Patterns; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.NonNull; @Getter @Embeddable @@ -15,15 +15,8 @@ public class CompanyEmail { @Column(name = "company_email") private String value; - public CompanyEmail(String value) { - validateCompanyEmail(value); + public CompanyEmail(@NonNull String value) { this.value = value; } - private void validateCompanyEmail(String companyEmail) { - if (!Patterns.EMAIL_PATTERN.matcher(companyEmail).matches()) { - throw new IllegalArgumentException("올바르지 않은 이메일입니다."); - } - } - } diff --git a/src/main/java/coffeemeet/server/certification/domain/EmailVerification.java b/src/main/java/coffeemeet/server/certification/domain/EmailVerification.java index d68d7e29..25e6350f 100644 --- a/src/main/java/coffeemeet/server/certification/domain/EmailVerification.java +++ b/src/main/java/coffeemeet/server/certification/domain/EmailVerification.java @@ -2,6 +2,7 @@ import java.time.LocalDateTime; import lombok.Getter; +import lombok.NonNull; import org.springframework.data.annotation.Id; import org.springframework.data.redis.core.RedisHash; @@ -15,7 +16,8 @@ public class EmailVerification { private String code; private LocalDateTime createdAt; - public EmailVerification(Long userId, CompanyEmail companyEmail, String code) { + public EmailVerification(@NonNull Long userId, @NonNull CompanyEmail companyEmail, + @NonNull String code) { this.userId = userId; this.companyEmail = companyEmail; this.code = code; From a286e5fdad3919f48087f42c9a987b25acdec8d6 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 16:01:10 +0900 Subject: [PATCH 232/311] =?UTF-8?q?test:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../certification/repository/CertificationRepositoryTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/coffeemeet/server/certification/repository/CertificationRepositoryTest.java b/src/test/java/coffeemeet/server/certification/repository/CertificationRepositoryTest.java index 599594c0..21e87b6a 100644 --- a/src/test/java/coffeemeet/server/certification/repository/CertificationRepositoryTest.java +++ b/src/test/java/coffeemeet/server/certification/repository/CertificationRepositoryTest.java @@ -28,7 +28,7 @@ void setUp() { } @Test - void findCertificationByUserIdTest() { + void findByUserIdTest() { // given Certification certification = certification(user); certificationRepository.save(certification); From be979543c165e0ae99d2f8599add77b9636d84ad Mon Sep 17 00:00:00 2001 From: sangminnim Date: Thu, 26 Oct 2023 16:01:58 +0900 Subject: [PATCH 233/311] =?UTF-8?q?fix:=20api=20uri=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../certification/controller/CertificationController.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java index 7c84cd9a..a544ffb5 100644 --- a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java +++ b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java @@ -19,12 +19,12 @@ @RestController @RequiredArgsConstructor -@RequestMapping("/certification") +@RequestMapping("/api/v1/certification") public class CertificationController { private final CertificationService certificationService; - @PostMapping("/users/business-card") + @PostMapping("/users/me/company-info") public ResponseEntity registerCompanyInfo( @Login AuthInfo authInfo, @RequestPart("companyEmail") @NotNull String companyEmail, @@ -36,7 +36,7 @@ public ResponseEntity registerCompanyInfo( return ResponseEntity.ok().build(); } - @PostMapping("/users/company-mail") + @PostMapping("/users/me/company-mail") public ResponseEntity sendVerificationCodeByEmail( @Login AuthInfo authInfo, @Valid @RequestBody EmailDto.Request request @@ -45,7 +45,7 @@ public ResponseEntity sendVerificationCodeByEmail( return ResponseEntity.ok().build(); } - @PostMapping("/users/company-mail/verification") + @PostMapping("/users/me/company-mail/verification") public ResponseEntity verifyEmail( @Login AuthInfo authInfo, @Valid @RequestBody VerificationCodeDto.Request request From 97e51d3111ae4826b678ae28eebd97bd44b4e272 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 30 Oct 2023 06:23:49 +0900 Subject: [PATCH 234/311] =?UTF-8?q?refactor:=20query=EC=97=90=EC=84=9C=20c?= =?UTF-8?q?ommand=EB=A1=9C=20=EC=9D=BC=EB=B6=80=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=98=AE=EA=B9=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/CertificationService.java | 4 ++-- .../service/cq/CertificationCommand.java | 13 +++++++++++++ .../service/cq/CertificationQuery.java | 15 +-------------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java index 77230bf6..eed3a600 100644 --- a/src/main/java/coffeemeet/server/certification/service/CertificationService.java +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -46,7 +46,7 @@ public void registerCertification(long userId, String email, String departmentNa } private void uploadBusinessCard(long userId, String key, File businessCardUrl) { - certificationQuery.applyIfCertifiedUser(userId, certification -> { + certificationCommand.applyIfCertifiedUser(userId, certification -> { String oldKey = s3MediaService.extractKey(certification.getBusinessCardUrl(), BUSINESS_CARD); s3MediaService.delete(oldKey); }); @@ -57,7 +57,7 @@ private void uploadBusinessCard(long userId, String key, File businessCardUrl) { public void sendVerificationMail(Long userId, String email) { CompanyEmail companyEmail = new CompanyEmail(email); - certificationQuery.checkDuplicatedCompanyEmail(companyEmail); + certificationCommand.hasDuplicatedCompanyEmail(companyEmail); String verificationCode = generateVerificationCode(); emailService.sendVerificationCode(companyEmail, verificationCode); diff --git a/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java b/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java index 9403de83..2767d1f4 100644 --- a/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java +++ b/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java @@ -5,6 +5,7 @@ import coffeemeet.server.certification.domain.Department; import coffeemeet.server.certification.repository.CertificationRepository; import coffeemeet.server.user.domain.User; +import java.util.function.Consumer; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -14,6 +15,8 @@ @RequiredArgsConstructor public class CertificationCommand { + private static final String EXISTED_COMPANY_EMAIL = "이미 사용 중인 회사 이메일입니다."; + private final CertificationRepository certificationRepository; public void newCertification(CompanyEmail companyEmail, String businessCardUrl, @@ -28,4 +31,14 @@ public void newCertification(CompanyEmail companyEmail, String businessCardUrl, ); } + public void hasDuplicatedCompanyEmail(CompanyEmail companyEmail) { + if (certificationRepository.existsByCompanyEmail(companyEmail)) { + throw new IllegalArgumentException(EXISTED_COMPANY_EMAIL); + } + } + + public void applyIfCertifiedUser(Long userId, Consumer consumer) { + certificationRepository.findByUserId(userId).ifPresent(consumer); + } + } diff --git a/src/main/java/coffeemeet/server/certification/service/cq/CertificationQuery.java b/src/main/java/coffeemeet/server/certification/service/cq/CertificationQuery.java index 5a647b54..31061050 100644 --- a/src/main/java/coffeemeet/server/certification/service/cq/CertificationQuery.java +++ b/src/main/java/coffeemeet/server/certification/service/cq/CertificationQuery.java @@ -1,9 +1,7 @@ package coffeemeet.server.certification.service.cq; import coffeemeet.server.certification.domain.Certification; -import coffeemeet.server.certification.domain.CompanyEmail; import coffeemeet.server.certification.repository.CertificationRepository; -import java.util.function.Consumer; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -13,8 +11,7 @@ @Transactional(readOnly = true) public class CertificationQuery { - public static final String CERTIFICATION_NOT_FOUND = "해당 사용자의 인증정보를 찾을 수 없습니다."; - private static final String EXISTED_COMPANY_EMAIL = "이미 사용 중인 회사 이메일입니다."; + private static final String CERTIFICATION_NOT_FOUND = "해당 사용자의 인증정보를 찾을 수 없습니다."; private final CertificationRepository certificationRepository; @@ -23,14 +20,4 @@ public Certification getCertificationByUserId(Long userId) { .orElseThrow(() -> new IllegalArgumentException(CERTIFICATION_NOT_FOUND)); } - public void checkDuplicatedCompanyEmail(CompanyEmail companyEmail) { - if (certificationRepository.existsByCompanyEmail(companyEmail)) { - throw new IllegalArgumentException(EXISTED_COMPANY_EMAIL); - } - } - - public void applyIfCertifiedUser(Long userId, Consumer consumer) { - certificationRepository.findByUserId(userId).ifPresent(consumer); - } - } From 525d1e847062c7a4157c302b0af04396d5e30dea Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 30 Oct 2023 06:24:44 +0900 Subject: [PATCH 235/311] test: CertificationQuery Test --- .../service/cq/CertificationQueryTest.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/test/java/coffeemeet/server/certification/service/cq/CertificationQueryTest.java diff --git a/src/test/java/coffeemeet/server/certification/service/cq/CertificationQueryTest.java b/src/test/java/coffeemeet/server/certification/service/cq/CertificationQueryTest.java new file mode 100644 index 00000000..7c6b1118 --- /dev/null +++ b/src/test/java/coffeemeet/server/certification/service/cq/CertificationQueryTest.java @@ -0,0 +1,44 @@ +package coffeemeet.server.certification.service.cq; + +import static coffeemeet.server.common.fixture.entity.CertificationFixture.certification; +import static coffeemeet.server.common.fixture.entity.UserFixture.user; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; + +import coffeemeet.server.certification.domain.Certification; +import coffeemeet.server.certification.repository.CertificationRepository; +import coffeemeet.server.user.domain.User; +import java.util.Optional; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class CertificationQueryTest { + + @InjectMocks + private CertificationQuery certificationQuery; + @Mock + private CertificationRepository certificationRepository; + + @Test + @DisplayName("유저 아이디로 인증 정보를 가져올 수 있다.") + void getCertificationByUserIdTest() { + // given + User user = user(); + Long userId = user.getId(); + Certification certification = certification(user); + + given(certificationRepository.findByUserId(userId)).willReturn(Optional.of(certification)); + + // when + Certification foundCertification = certificationQuery.getCertificationByUserId(userId); + + // then + assertThat(foundCertification).isEqualTo(certification); + } + +} From 454721f481fdc0abf86a099775d576aafd126f45 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 30 Oct 2023 06:31:05 +0900 Subject: [PATCH 236/311] test: CertificationService Test --- .../service/CertificationServiceTest.java | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java diff --git a/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java b/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java new file mode 100644 index 00000000..8f55ca59 --- /dev/null +++ b/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java @@ -0,0 +1,112 @@ +package coffeemeet.server.certification.service; + +import static coffeemeet.server.common.fixture.entity.CertificationFixture.businessCardUrl; +import static coffeemeet.server.common.fixture.entity.CertificationFixture.department; +import static coffeemeet.server.common.fixture.entity.CertificationFixture.email; +import static coffeemeet.server.common.fixture.entity.CertificationFixture.verificationCode; +import static coffeemeet.server.common.fixture.entity.UserFixture.user; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.only; + +import coffeemeet.server.certification.service.cq.CertificationCommand; +import coffeemeet.server.certification.service.cq.CertificationQuery; +import coffeemeet.server.certification.service.cq.EmailVerificationCommand; +import coffeemeet.server.certification.service.cq.EmailVerificationQuery; +import coffeemeet.server.common.media.EmailService; +import coffeemeet.server.common.media.S3MediaService; +import coffeemeet.server.common.util.FileUtils; +import coffeemeet.server.user.domain.User; +import coffeemeet.server.user.service.UserService; +import java.io.File; +import org.instancio.Instancio; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class CertificationServiceTest { + + @InjectMocks + private CertificationService certificationService; + @Mock + private S3MediaService s3MediaService; + @Mock + private EmailService emailService; + @Mock + private UserService userService; + @Mock + private CertificationCommand certificationCommand; + @Mock + private CertificationQuery certificationQuery; + @Mock + private EmailVerificationCommand emailVerificationCommand; + @Mock + private EmailVerificationQuery emailVerificationQuery; + + @Test + void registerCertificationTest() { + // given + User user = user(); + Long userId = user.getId(); + String email = email(); + String departmentName = department().name(); + File file = mock(); + String businessCardUrl = businessCardUrl(); + + MockedStatic fileUtils = mockStatic(FileUtils.class); + fileUtils.when(() -> FileUtils.delete(file)).then(invocation -> null); + given(s3MediaService.generateKey(any())).willReturn("someKey"); + given(s3MediaService.getUrl(any())).willReturn(businessCardUrl); + given(userService.getUserById(userId)).willReturn(user); + + // when + certificationService.registerCertification(userId, email, departmentName, file); + + // then + then(s3MediaService).should().generateKey(any()); + then(s3MediaService).should().upload(any(), any(File.class)); + then(certificationCommand).should().newCertification(any(), any(), any(), any()); + + fileUtils.close(); + } + + @Test + void sendVerificationMailTest() { + // given + String email = email(); + User user = user(); + Long userId = user.getId(); + + // when + certificationService.sendVerificationMail(userId, email); + + // then + then(certificationCommand).should(only()).hasDuplicatedCompanyEmail(any()); + then(emailService).should(only()).sendVerificationCode(any(), anyString()); + then(emailVerificationCommand).should(only()) + .newEmailVerification(anyLong(), any(), anyString()); + } + + @Test + void compareCodeTest() { + // given + Long userId = Instancio.create(Long.class); + String verificationCode = verificationCode(); + given(emailVerificationQuery.getCodeById(userId)).willReturn(verificationCode); + + // when, then + assertThatCode(() -> certificationService.compareCode(userId, verificationCode)) + .doesNotThrowAnyException(); + } + +} From e67bbdf2a727d4e567f21f6f1566645a6ace6f80 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 30 Oct 2023 06:43:38 +0900 Subject: [PATCH 237/311] test: CertificationCommand Test --- .../service/cq/CertificationCommandTest.java | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/test/java/coffeemeet/server/certification/service/cq/CertificationCommandTest.java diff --git a/src/test/java/coffeemeet/server/certification/service/cq/CertificationCommandTest.java b/src/test/java/coffeemeet/server/certification/service/cq/CertificationCommandTest.java new file mode 100644 index 00000000..2d243bdf --- /dev/null +++ b/src/test/java/coffeemeet/server/certification/service/cq/CertificationCommandTest.java @@ -0,0 +1,85 @@ +package coffeemeet.server.certification.service.cq; + +import static coffeemeet.server.common.fixture.entity.CertificationFixture.businessCardUrl; +import static coffeemeet.server.common.fixture.entity.CertificationFixture.certification; +import static coffeemeet.server.common.fixture.entity.CertificationFixture.companyEmail; +import static coffeemeet.server.common.fixture.entity.CertificationFixture.department; +import static coffeemeet.server.common.fixture.entity.UserFixture.user; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.only; + +import coffeemeet.server.certification.domain.Certification; +import coffeemeet.server.certification.domain.CompanyEmail; +import coffeemeet.server.certification.domain.Department; +import coffeemeet.server.certification.repository.CertificationRepository; +import coffeemeet.server.user.domain.User; +import java.util.Optional; +import java.util.function.Consumer; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class CertificationCommandTest { + + @Mock + Consumer consumer; + @InjectMocks + private CertificationCommand certificationCommand; + @Mock + private CertificationRepository certificationRepository; + + @Test + @DisplayName("새로운 Certification 객체를 저장할 수 있다.") + void newCertificationTest() { + // given + CompanyEmail companyEmail = companyEmail(); + String businessCardUrl = businessCardUrl(); + Department department = department(); + User user = user(); + + // when + certificationCommand.newCertification(companyEmail, businessCardUrl, department, user); + + // then + then(certificationRepository).should(only()).save(any(Certification.class)); + } + + @Test + @DisplayName("중복된 회사 이메일이 있을 경우 예외가 발생한다.") + void checkDuplicatedCompanyEmailTest() { + // given + CompanyEmail companyEmail = companyEmail(); + given(certificationRepository.existsByCompanyEmail(companyEmail)).willReturn(true); + + // when, then + assertThatThrownBy( + () -> certificationCommand.hasDuplicatedCompanyEmail(companyEmail)).isInstanceOf( + IllegalArgumentException.class) + .hasMessage("이미 사용 중인 회사 이메일입니다."); // todo 에러메세지 public으로 두는게 어떨까요? + } + + @Test + @DisplayName("만약 인증이 완료된 사용자면 Consumer를 실행할 수 있다.") + void applyIfCertifiedUserTest() { + // given + User user = user(); + Long userId = user.getId(); + Certification certification = certification(user()); + + given(certificationRepository.findByUserId(userId)).willReturn(Optional.of(certification)); + + // when + certificationCommand.applyIfCertifiedUser(userId, consumer); + + // then + then(consumer).should(only()).accept(certification); + } + +} From 4ba576ef81916b309f8ac6cb8df230c0ad0c233d Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 30 Oct 2023 06:44:15 +0900 Subject: [PATCH 238/311] test: CertificationController Test --- .../CertificationControllerTest.java | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 src/test/java/coffeemeet/server/certification/controller/CertificationControllerTest.java diff --git a/src/test/java/coffeemeet/server/certification/controller/CertificationControllerTest.java b/src/test/java/coffeemeet/server/certification/controller/CertificationControllerTest.java new file mode 100644 index 00000000..2c5ee084 --- /dev/null +++ b/src/test/java/coffeemeet/server/certification/controller/CertificationControllerTest.java @@ -0,0 +1,145 @@ +package coffeemeet.server.certification.controller; + +import static coffeemeet.server.common.fixture.dto.RefreshTokenFixture.refreshToken; +import static coffeemeet.server.common.fixture.entity.CertificationFixture.department; +import static coffeemeet.server.common.fixture.entity.CertificationFixture.email; +import static coffeemeet.server.common.fixture.entity.CertificationFixture.emailDtoRequest; +import static coffeemeet.server.common.fixture.entity.CertificationFixture.verificationCodeDtoRequest; +import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; +import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.resourceDetails; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.BDDMockito.given; +import static org.springframework.http.HttpHeaders.AUTHORIZATION; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.http.MediaType.MULTIPART_FORM_DATA; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.multipart; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; +import static org.springframework.restdocs.request.RequestDocumentation.partWithName; +import static org.springframework.restdocs.request.RequestDocumentation.requestParts; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import coffeemeet.server.auth.domain.RefreshToken; +import coffeemeet.server.auth.service.AuthService; +import coffeemeet.server.certification.service.CertificationService; +import coffeemeet.server.common.config.ControllerTestConfig; +import coffeemeet.server.oauth.service.OAuthService; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.mock.web.MockPart; + +class CertificationControllerTest extends ControllerTestConfig { + + @MockBean + protected AuthService authService; + @MockBean + protected OAuthService oAuthService; // TODO: 2023/10/30 authService, oAuthService Controller 테스트에서 전부 중복이라서 Config에 두는게 좋을 듯 + @MockBean + private CertificationService certificationService; + private RefreshToken refreshToken; + + @BeforeEach + void setUp() { + RefreshToken refreshToken = refreshToken(); + given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + } + + @Test + void registerCompanyInfoTest() throws Exception { + // given + String sBusinessCard = "businessCard"; + String sCompanyEmail = "companyEmail"; + String sDepartment = "department"; + MockMultipartFile businessCardImage = new MockMultipartFile( + sBusinessCard, + "business_card.jpg", + "image/jpeg", + sBusinessCard.getBytes() + ); + + MockPart companyEmail = new MockPart(sCompanyEmail, email().getBytes()); + MockPart department = new MockPart(sDepartment, department().name().getBytes()); + + // when, then + mockMvc.perform(multipart("/api/v1/certification/users/me/company-info") + .file("businessCard", businessCardImage.getBytes()) + .part(companyEmail) + .part(department) + .header(AUTHORIZATION, TOKEN) + .contentType(MULTIPART_FORM_DATA) + ) + .andExpect(status().isOk()) + .andDo(document("certification-register", + resourceDetails().tag("회사 인증").description("회사 정보 등록"), + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + requestHeaders( + headerWithName(AUTHORIZATION).description("토큰") + ), + requestParts( + partWithName(sBusinessCard).description("회사 명함 이미지"), + partWithName(sCompanyEmail).description("회사 이메일"), + partWithName(sDepartment).description("회사 부서명") + ) + )); + } + + @Test + void sendVerificationCodeByEmailTest() throws Exception { + // given + String emailDtoRequest = objectMapper.writeValueAsString(emailDtoRequest()); + + // when, then + mockMvc.perform(post("/api/v1/certification/users/me/company-mail") + .header(AUTHORIZATION, TOKEN) + .contentType(APPLICATION_JSON) + .content(emailDtoRequest)) + .andDo(document("certification-sendVerificationCode", + resourceDetails().tag("회사 인증").description("회사 이메일 인증을 위한 메일 전송"), + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + requestHeaders( + headerWithName(AUTHORIZATION).description("토큰") + ), + requestFields( + fieldWithPath("companyEmail").description("회사 이메일") + ) + ) + ) + .andExpect(status().isOk()); + } + + @Test + void verifyEmailTest() throws Exception { + String verificationCodeDtoRequest = objectMapper.writeValueAsString( + verificationCodeDtoRequest()); + + mockMvc.perform(post("/api/v1/certification/users/me/company-mail/verification") + .header(AUTHORIZATION, TOKEN) + .contentType(APPLICATION_JSON) + .content(verificationCodeDtoRequest)) + .andDo(document("certification-verifyEmail", + resourceDetails().tag("회사 인증").description("회사 이메일 인증을 위한 코드 검증"), + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + requestHeaders( + headerWithName(AUTHORIZATION).description("토큰") + ), + requestFields( + fieldWithPath("verificationCode").description("인증 코드") + ) + ) + ) + .andExpect(status().isOk()); + } + +} From f41885c048f65233191443c362473fa505ab75e4 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 30 Oct 2023 06:44:28 +0900 Subject: [PATCH 239/311] test: EmailVerificationCommand Test --- .../cq/EmailVerificationCommandTest.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/test/java/coffeemeet/server/certification/service/cq/EmailVerificationCommandTest.java diff --git a/src/test/java/coffeemeet/server/certification/service/cq/EmailVerificationCommandTest.java b/src/test/java/coffeemeet/server/certification/service/cq/EmailVerificationCommandTest.java new file mode 100644 index 00000000..d2e60dcc --- /dev/null +++ b/src/test/java/coffeemeet/server/certification/service/cq/EmailVerificationCommandTest.java @@ -0,0 +1,42 @@ +package coffeemeet.server.certification.service.cq; + +import static coffeemeet.server.common.fixture.entity.CertificationFixture.emailVerification; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.only; + +import coffeemeet.server.certification.domain.EmailVerification; +import coffeemeet.server.certification.repository.EmailVerificationRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class EmailVerificationCommandTest { + + @InjectMocks + private EmailVerificationCommand emailVerificationCommand; + @Mock + private EmailVerificationRepository emailVerificationRepository; + + @Test + @DisplayName("새로운 EmailVerification 객체를 저장할 수 있다.") + void newEmailVerificationTest() { + // given + EmailVerification emailVerification = emailVerification(); + given(emailVerificationRepository.save(any(EmailVerification.class))).willReturn( + emailVerification); + + // when + emailVerificationCommand.newEmailVerification(emailVerification.getUserId(), + emailVerification.getCompanyEmail(), emailVerification.getCode()); + + // then + then(emailVerificationRepository).should(only()).save(any(EmailVerification.class)); + } + +} From adec00ea38f90f866d0b458e6c4005d5ee87c956 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 30 Oct 2023 06:44:33 +0900 Subject: [PATCH 240/311] test: EmailVerificationQuery Test --- .../cq/EmailVerificationQueryTest.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/test/java/coffeemeet/server/certification/service/cq/EmailVerificationQueryTest.java diff --git a/src/test/java/coffeemeet/server/certification/service/cq/EmailVerificationQueryTest.java b/src/test/java/coffeemeet/server/certification/service/cq/EmailVerificationQueryTest.java new file mode 100644 index 00000000..fd850641 --- /dev/null +++ b/src/test/java/coffeemeet/server/certification/service/cq/EmailVerificationQueryTest.java @@ -0,0 +1,39 @@ +package coffeemeet.server.certification.service.cq; + +import static coffeemeet.server.common.fixture.entity.CertificationFixture.emailVerification; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; + +import coffeemeet.server.certification.domain.EmailVerification; +import coffeemeet.server.certification.repository.EmailVerificationRepository; +import java.util.Optional; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class EmailVerificationQueryTest { + + @InjectMocks + private EmailVerificationQuery emailVerificationQuery; + @Mock + private EmailVerificationRepository emailVerificationRepository; + + @Test + void getCodeByIdTest() { + // given + EmailVerification emailVerification = emailVerification(); + + given(emailVerificationRepository.findById(emailVerification.getUserId())).willReturn( + Optional.of(emailVerification)); + + // when + String code = emailVerificationQuery.getCodeById(emailVerification.getUserId()); + + // then + assertThat(code).isEqualTo(emailVerification.getCode()); + } + +} From 3ed896cc7b7d4e05dcdc8c5b6976752d18542f3f Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 30 Oct 2023 06:46:04 +0900 Subject: [PATCH 241/311] =?UTF-8?q?test:=20ControllerTestConfig=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/common/config/ControllerTestConfig.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java index f7c773d8..595f9c78 100644 --- a/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java +++ b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java @@ -5,9 +5,11 @@ import coffeemeet.server.auth.domain.JwtTokenProvider; import coffeemeet.server.auth.repository.RefreshTokenRepository; +import coffeemeet.server.user.service.UserService; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.restdocs.RestDocumentationContextProvider; import org.springframework.restdocs.RestDocumentationExtension; @@ -16,10 +18,11 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.filter.CharacterEncodingFilter; +@WebMvcTest @ExtendWith({RestDocumentationExtension.class}) public abstract class ControllerTestConfig { - protected static final String TOKEN = "Bearer aaaaaaaa.bbbbbbb.ccccccc"; + protected static final String TOKEN = "Bearer aaaaaaaa.bbbbbbb.ccccccc"; // todo "Bearer header.payload.signature" 얘가 좀 더 의미 있는 듯 protected ObjectMapper objectMapper = new ObjectMapper(); @@ -31,6 +34,9 @@ public abstract class ControllerTestConfig { @MockBean protected RefreshTokenRepository refreshTokenRepository; + @MockBean + protected UserService userService; // TODO: 2023/10/30 AuthService 때문에 얘가 있어야 되는데 이거 바꿔야 될 듯? + @BeforeEach void setUp(WebApplicationContext ctx, RestDocumentationContextProvider restDocumentation) { mockMvc = MockMvcBuilders.webAppContextSetup(ctx) From de39ef4fa016b40518cf495bf9699f7c90f6e783 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Mon, 30 Oct 2023 06:46:58 +0900 Subject: [PATCH 242/311] =?UTF-8?q?test:=20CertificationFixture=20?= =?UTF-8?q?=ED=94=BD=EC=8A=A4=EC=B3=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fixture/entity/CertificationFixture.java | 61 +++++++++++++++++-- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/src/test/java/coffeemeet/server/common/fixture/entity/CertificationFixture.java b/src/test/java/coffeemeet/server/common/fixture/entity/CertificationFixture.java index 526d2e58..02118b08 100644 --- a/src/test/java/coffeemeet/server/common/fixture/entity/CertificationFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/entity/CertificationFixture.java @@ -4,28 +4,77 @@ import coffeemeet.server.certification.domain.Certification; import coffeemeet.server.certification.domain.CompanyEmail; +import coffeemeet.server.certification.domain.Department; +import coffeemeet.server.certification.domain.EmailVerification; +import coffeemeet.server.certification.dto.EmailDto; +import coffeemeet.server.certification.dto.VerificationCodeDto; import coffeemeet.server.user.domain.User; import org.instancio.Instancio; +import org.instancio.internal.generator.domain.internet.EmailGenerator; +import org.instancio.internal.generator.lang.IntegerGenerator; +import org.instancio.internal.generator.net.URLGenerator; public class CertificationFixture { public static Certification certification() { return Instancio.of(Certification.class) - .set(field(Certification::getCompanyEmail), companyEmail()) + .generate(field(Certification::getBusinessCardUrl), gen -> gen.net().url().asString()) + .set(field(Certification::getCompanyEmail), new CompanyEmail(new EmailGenerator().get())) .create(); } public static Certification certification(User user) { return Instancio.of(Certification.class) - .set(field(Certification::getCompanyEmail), companyEmail()) - .set(field(Certification::getUser), user) + .generate(field(Certification::getBusinessCardUrl), gen -> gen.net().url().asString()) + .set(field(Certification::getCompanyEmail), new CompanyEmail(new EmailGenerator().get())) + .set(field(Certification::getId), user.getId()).set(field(Certification::getUser), user) .create(); } - private static CompanyEmail companyEmail() { - return Instancio.of(CompanyEmail.class) - .generate(field(CompanyEmail::getValue), gen -> gen.net().email()) + public static EmailVerification emailVerification() { + return Instancio.of(EmailVerification.class) + .set(field(EmailVerification::getCompanyEmail), + new CompanyEmail(new EmailGenerator().get())) .create(); } + public static EmailVerification emailVerification(Long userId) { + return Instancio.of(EmailVerification.class).set(field(EmailVerification::getUserId), userId) + .set(field(EmailVerification::getCompanyEmail), + new CompanyEmail(new EmailGenerator().get())) + .create(); + } + + public static CompanyEmail companyEmail() { + return Instancio.of(CompanyEmail.class) + .generate(field(CompanyEmail::getValue), gen -> gen.net().email()).create(); + } + + public static String verificationCode() { + return String.format("%06d", new IntegerGenerator().range(0, 999999).get()); + } + + public static String businessCardUrl() { + return String.valueOf(new URLGenerator().get()); + } + + public static String email() { + return new EmailGenerator().get(); + } + + public static Department department() { + return Instancio.create(Department.class); + } + + public static EmailDto.Request emailDtoRequest() { + return Instancio.of(EmailDto.Request.class) + .generate(field(EmailDto.Request::companyEmail), gen -> gen.net().email()).create(); + } + + public static VerificationCodeDto.Request verificationCodeDtoRequest() { + return Instancio.of(VerificationCodeDto.Request.class) + .set(field(VerificationCodeDto.Request::verificationCode), + String.format("%06d", new IntegerGenerator().range(0, 999999).get())).create(); + } + } From 23fd289f6e170e663bbbc75f4a0432e3fe568d70 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 30 Oct 2023 18:22:09 +0900 Subject: [PATCH 243/311] =?UTF-8?q?feat:=20CoffeeMeetException=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 --- .../common/execption/exception/CoffeeMeetException.java | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/execption/exception/CoffeeMeetException.java diff --git a/src/main/java/coffeemeet/server/common/execption/exception/CoffeeMeetException.java b/src/main/java/coffeemeet/server/common/execption/exception/CoffeeMeetException.java new file mode 100644 index 00000000..6d2ce5ff --- /dev/null +++ b/src/main/java/coffeemeet/server/common/execption/exception/CoffeeMeetException.java @@ -0,0 +1,9 @@ +package coffeemeet.server.common.execption.exception; + +public class CoffeeMeetException extends RuntimeException { + + public CoffeeMeetException(String message) { + super(message); + } + +} From f817d000549e291b3c41ce8b27c31fa9696f9ec8 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 30 Oct 2023 18:22:27 +0900 Subject: [PATCH 244/311] =?UTF-8?q?feat:=20DataLengthExceededException=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 --- .../exception/DataLengthExceededException.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/execption/exception/DataLengthExceededException.java diff --git a/src/main/java/coffeemeet/server/common/execption/exception/DataLengthExceededException.java b/src/main/java/coffeemeet/server/common/execption/exception/DataLengthExceededException.java new file mode 100644 index 00000000..1dfd5401 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/execption/exception/DataLengthExceededException.java @@ -0,0 +1,15 @@ +package coffeemeet.server.common.execption.exception; + +import lombok.Getter; + +@Getter +public class DataLengthExceededException extends CoffeeMeetException { + + private final ErrorCode errorCode; + + public DataLengthExceededException(ErrorCode errorCode, String message) { + super(message); + this.errorCode = errorCode; + } + +} From 07f4217f498363712ef5891ff1ab4b044426c948 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 30 Oct 2023 18:22:57 +0900 Subject: [PATCH 245/311] =?UTF-8?q?feat:=20NotFoundException=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 --- .../execption/exception/NotFoundException.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/execption/exception/NotFoundException.java diff --git a/src/main/java/coffeemeet/server/common/execption/exception/NotFoundException.java b/src/main/java/coffeemeet/server/common/execption/exception/NotFoundException.java new file mode 100644 index 00000000..aed8e0e1 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/execption/exception/NotFoundException.java @@ -0,0 +1,15 @@ +package coffeemeet.server.common.execption.exception; + +import lombok.Getter; + +@Getter +public class NotFoundException extends CoffeeMeetException { + + private final ErrorCode errorCode; + + public NotFoundException(ErrorCode errorCode, String message) { + super(message); + this.errorCode = errorCode; + } + +} From c8b9215652b3f2188aa6d3cf130c4b2a7030f6ed Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 30 Oct 2023 18:23:13 +0900 Subject: [PATCH 246/311] =?UTF-8?q?feat:=20MissMatchException=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 --- .../execption/exception/MissMatchException.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/execption/exception/MissMatchException.java diff --git a/src/main/java/coffeemeet/server/common/execption/exception/MissMatchException.java b/src/main/java/coffeemeet/server/common/execption/exception/MissMatchException.java new file mode 100644 index 00000000..32ef0a2f --- /dev/null +++ b/src/main/java/coffeemeet/server/common/execption/exception/MissMatchException.java @@ -0,0 +1,15 @@ +package coffeemeet.server.common.execption.exception; + +import lombok.Getter; + +@Getter +public class MissMatchException extends CoffeeMeetException { + + private final ErrorCode errorCode; + + public MissMatchException(ErrorCode errorCode, String message) { + super(message); + this.errorCode = errorCode; + } + +} From dddd64d8e2744060e2336f3bc1eeb55e200efa64 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 30 Oct 2023 18:23:28 +0900 Subject: [PATCH 247/311] =?UTF-8?q?feat:=20InvalidAuthException=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 --- .../execption/exception/InvalidAuthException.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/execption/exception/InvalidAuthException.java diff --git a/src/main/java/coffeemeet/server/common/execption/exception/InvalidAuthException.java b/src/main/java/coffeemeet/server/common/execption/exception/InvalidAuthException.java new file mode 100644 index 00000000..ac31293c --- /dev/null +++ b/src/main/java/coffeemeet/server/common/execption/exception/InvalidAuthException.java @@ -0,0 +1,15 @@ +package coffeemeet.server.common.execption.exception; + +import lombok.Getter; + +@Getter +public class InvalidAuthException extends CoffeeMeetException { + + private final ErrorCode errorCode; + + public InvalidAuthException(ErrorCode errorCode, String message) { + super(message); + this.errorCode = errorCode; + } + +} From 158c0b4a690b9f9864c16174700dff1f97799359 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 30 Oct 2023 18:24:01 +0900 Subject: [PATCH 248/311] =?UTF-8?q?feat:=20ErrorCode=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - code, message 작성 --- .../server/common/execption/exception/ErrorCode.java | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/execption/exception/ErrorCode.java diff --git a/src/main/java/coffeemeet/server/common/execption/exception/ErrorCode.java b/src/main/java/coffeemeet/server/common/execption/exception/ErrorCode.java new file mode 100644 index 00000000..da9d05b1 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/execption/exception/ErrorCode.java @@ -0,0 +1,9 @@ +package coffeemeet.server.common.execption.exception; + +public interface ErrorCode { + + String code(); + + String message(); + +} From 7a4e40ea092bf182b839d2f48ed0fc3d9b004574 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 30 Oct 2023 18:24:19 +0900 Subject: [PATCH 249/311] =?UTF-8?q?feat:=20GlobalErrorCode=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 --- .../execption/exception/GlobalErrorCode.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/execption/exception/GlobalErrorCode.java diff --git a/src/main/java/coffeemeet/server/common/execption/exception/GlobalErrorCode.java b/src/main/java/coffeemeet/server/common/execption/exception/GlobalErrorCode.java new file mode 100644 index 00000000..7d485dc0 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/execption/exception/GlobalErrorCode.java @@ -0,0 +1,26 @@ +package coffeemeet.server.common.execption.exception; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum GlobalErrorCode implements ErrorCode { + + VALIDATION_ERROR("G000", "유효하지 않은 입력입니다."), + INTERNAL_SERVER_ERROR("G050", "예상치 못한 오류입니다."); + + private final String code; + private final String message; + + @Override + public String code() { + return this.code; + } + + @Override + public String message() { + return this.message; + } + +} From e79b8ad1f2b04736ea6548d026598f20c648cd12 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 30 Oct 2023 18:24:32 +0900 Subject: [PATCH 250/311] =?UTF-8?q?feat:=20ErrorResponse=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 --- .../common/advice/advice/ErrorResponse.java | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/advice/advice/ErrorResponse.java diff --git a/src/main/java/coffeemeet/server/common/advice/advice/ErrorResponse.java b/src/main/java/coffeemeet/server/common/advice/advice/ErrorResponse.java new file mode 100644 index 00000000..516159a9 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/advice/advice/ErrorResponse.java @@ -0,0 +1,85 @@ +package coffeemeet.server.common.advice.advice; + +import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; + +import coffeemeet.server.common.execption.exception.ErrorCode; +import coffeemeet.server.common.execption.exception.GlobalErrorCode; +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.ArrayList; +import java.util.List; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.validation.BindingResult; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; + +@Getter +@JsonInclude(NON_NULL) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ErrorResponse { + + private String code; + private String message; + private List errors; + + private ErrorResponse(final ErrorCode code, List errors) { + this.code = code.code(); + this.message = code.message(); + this.errors = errors; + } + + private ErrorResponse(final ErrorCode code) { + this.message = code.message(); + this.code = code.code(); + } + + public static ErrorResponse of(final ErrorCode code, final BindingResult bindingResult) { + return new ErrorResponse(code, FieldError.of(bindingResult)); + } + + public static ErrorResponse of(final ErrorCode code) { + return new ErrorResponse(code); + } + + public static ErrorResponse of(final ErrorCode code, final List errors) { + return new ErrorResponse(code, errors); + } + + public static ErrorResponse of(MethodArgumentTypeMismatchException e) { + final String value = e.getValue() == null ? "" : String.valueOf(e.getValue()); + final List errors = FieldError.of(e.getName(), value, e.getErrorCode()); + return new ErrorResponse(GlobalErrorCode.VALIDATION_ERROR, errors); + } + + @Getter + @NoArgsConstructor(access = AccessLevel.PROTECTED) + static class FieldError { + + private String field; + private String value; + private String reason; + + private FieldError(final String field, final String value, final String reason) { + this.field = field; + this.value = value; + this.reason = reason; + } + + public static List of(final String field, final String value, final String reason) { + List fieldErrors = new ArrayList<>(); + fieldErrors.add(new FieldError(field, value, reason)); + return fieldErrors; + } + + private static List of(final BindingResult bindingResult) { + final List fieldErrors = bindingResult.getFieldErrors(); + return fieldErrors.stream() + .map(error -> new FieldError( + error.getField(), + error.getRejectedValue() == null ? "" : error.getRejectedValue().toString(), + error.getDefaultMessage())) + .toList(); + } + } + +} From 2117e2140443993ec99c8ba8bc95d247ed90014c Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 30 Oct 2023 18:24:44 +0900 Subject: [PATCH 251/311] =?UTF-8?q?feat:=20GlobalExceptionHandler=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 --- .../advice/advice/GlobalExceptionHandler.java | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/advice/advice/GlobalExceptionHandler.java diff --git a/src/main/java/coffeemeet/server/common/advice/advice/GlobalExceptionHandler.java b/src/main/java/coffeemeet/server/common/advice/advice/GlobalExceptionHandler.java new file mode 100644 index 00000000..54c0ed73 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/advice/advice/GlobalExceptionHandler.java @@ -0,0 +1,89 @@ +package coffeemeet.server.common.advice.advice; + +import coffeemeet.server.common.execption.exception.DataLengthExceededException; +import coffeemeet.server.common.execption.exception.GlobalErrorCode; +import coffeemeet.server.common.execption.exception.InvalidAuthException; +import coffeemeet.server.common.execption.exception.MissMatchException; +import coffeemeet.server.common.execption.exception.NotFoundException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.UnsatisfiedServletRequestParameterException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; + +@Slf4j +@RestControllerAdvice +@RequiredArgsConstructor +public class GlobalExceptionHandler { + + @ExceptionHandler(RuntimeException.class) + public ResponseEntity handleException(RuntimeException exception) { + log.info(exception.getMessage(), exception); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(ErrorResponse.of(GlobalErrorCode.INTERNAL_SERVER_ERROR)); + } + + @ExceptionHandler(DataLengthExceededException.class) + public ResponseEntity handleException(DataLengthExceededException exception) { + log.info(exception.getMessage(), exception); + return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY) + .body(ErrorResponse.of(exception.getErrorCode())); + } + + @ExceptionHandler(InvalidAuthException.class) + public ResponseEntity handleException(InvalidAuthException exception) { + log.info(exception.getMessage(), exception); + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body(ErrorResponse.of(exception.getErrorCode())); + } + + @ExceptionHandler(MissMatchException.class) + public ResponseEntity handleException(MissMatchException exception) { + log.info(exception.getMessage(), exception); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ErrorResponse.of(exception.getErrorCode())); + } + + @ExceptionHandler(NotFoundException.class) + public ResponseEntity handleException(NotFoundException exception) { + log.info(exception.getMessage(), exception); + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(ErrorResponse.of(exception.getErrorCode())); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity handleException(MethodArgumentNotValidException exception) { + log.info(exception.getMessage(), exception); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ErrorResponse.of(GlobalErrorCode.VALIDATION_ERROR, exception.getBindingResult())); + } + + @ExceptionHandler(UnsatisfiedServletRequestParameterException.class) + public ResponseEntity handleException( + UnsatisfiedServletRequestParameterException exception) { + log.info(exception.getMessage(), exception); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ErrorResponse.of(GlobalErrorCode.VALIDATION_ERROR)); + } + + @ExceptionHandler(MethodArgumentTypeMismatchException.class) + public ResponseEntity handleException( + MethodArgumentTypeMismatchException exception) { + log.info(exception.getMessage(), exception); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ErrorResponse.of(exception)); + } + + @ExceptionHandler(HttpMessageNotReadableException.class) + public ResponseEntity handleException(HttpMessageNotReadableException exception) { + log.info(exception.getMessage(), exception); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(ErrorResponse.of(GlobalErrorCode.VALIDATION_ERROR)); + } + +} From 828523bb3d0cc9e00d4aa2f52260a2a42e3ddf6f Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 30 Oct 2023 18:25:15 +0900 Subject: [PATCH 252/311] fix: merge conflict --- .../certification/service/CertificationServiceTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java b/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java index 8f55ca59..7ccfc544 100644 --- a/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java +++ b/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java @@ -24,6 +24,7 @@ import coffeemeet.server.common.util.FileUtils; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.service.UserService; +import coffeemeet.server.user.service.cq.UserQuery; import java.io.File; import org.instancio.Instancio; import org.junit.jupiter.api.Test; @@ -45,6 +46,8 @@ class CertificationServiceTest { @Mock private UserService userService; @Mock + private UserQuery userQuery; + @Mock private CertificationCommand certificationCommand; @Mock private CertificationQuery certificationQuery; @@ -67,7 +70,7 @@ void registerCertificationTest() { fileUtils.when(() -> FileUtils.delete(file)).then(invocation -> null); given(s3MediaService.generateKey(any())).willReturn("someKey"); given(s3MediaService.getUrl(any())).willReturn(businessCardUrl); - given(userService.getUserById(userId)).willReturn(user); + given(userQuery.getUserById(userId)).willReturn(user); // when certificationService.registerCertification(userId, email, departmentName, file); From 856cb6b3295b04d8d39bde513074c9420125f983 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Mon, 30 Oct 2023 18:33:18 +0900 Subject: [PATCH 253/311] =?UTF-8?q?style:=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/advice/{advice => }/ErrorResponse.java | 6 +++--- .../advice/{advice => }/GlobalExceptionHandler.java | 12 ++++++------ .../{exception => }/CoffeeMeetException.java | 2 +- .../{exception => }/DataLengthExceededException.java | 2 +- .../common/execption/{exception => }/ErrorCode.java | 2 +- .../execption/{exception => }/GlobalErrorCode.java | 2 +- .../{exception => }/InvalidAuthException.java | 2 +- .../{exception => }/MissMatchException.java | 2 +- .../execption/{exception => }/NotFoundException.java | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) rename src/main/java/coffeemeet/server/common/advice/{advice => }/ErrorResponse.java (93%) rename src/main/java/coffeemeet/server/common/advice/{advice => }/GlobalExceptionHandler.java (90%) rename src/main/java/coffeemeet/server/common/execption/{exception => }/CoffeeMeetException.java (71%) rename src/main/java/coffeemeet/server/common/execption/{exception => }/DataLengthExceededException.java (83%) rename src/main/java/coffeemeet/server/common/execption/{exception => }/ErrorCode.java (57%) rename src/main/java/coffeemeet/server/common/execption/{exception => }/GlobalErrorCode.java (89%) rename src/main/java/coffeemeet/server/common/execption/{exception => }/InvalidAuthException.java (82%) rename src/main/java/coffeemeet/server/common/execption/{exception => }/MissMatchException.java (82%) rename src/main/java/coffeemeet/server/common/execption/{exception => }/NotFoundException.java (82%) diff --git a/src/main/java/coffeemeet/server/common/advice/advice/ErrorResponse.java b/src/main/java/coffeemeet/server/common/advice/ErrorResponse.java similarity index 93% rename from src/main/java/coffeemeet/server/common/advice/advice/ErrorResponse.java rename to src/main/java/coffeemeet/server/common/advice/ErrorResponse.java index 516159a9..6981dd9a 100644 --- a/src/main/java/coffeemeet/server/common/advice/advice/ErrorResponse.java +++ b/src/main/java/coffeemeet/server/common/advice/ErrorResponse.java @@ -1,9 +1,9 @@ -package coffeemeet.server.common.advice.advice; +package coffeemeet.server.common.advice; import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL; -import coffeemeet.server.common.execption.exception.ErrorCode; -import coffeemeet.server.common.execption.exception.GlobalErrorCode; +import coffeemeet.server.common.execption.ErrorCode; +import coffeemeet.server.common.execption.GlobalErrorCode; import com.fasterxml.jackson.annotation.JsonInclude; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/coffeemeet/server/common/advice/advice/GlobalExceptionHandler.java b/src/main/java/coffeemeet/server/common/advice/GlobalExceptionHandler.java similarity index 90% rename from src/main/java/coffeemeet/server/common/advice/advice/GlobalExceptionHandler.java rename to src/main/java/coffeemeet/server/common/advice/GlobalExceptionHandler.java index 54c0ed73..e7e3bb19 100644 --- a/src/main/java/coffeemeet/server/common/advice/advice/GlobalExceptionHandler.java +++ b/src/main/java/coffeemeet/server/common/advice/GlobalExceptionHandler.java @@ -1,10 +1,10 @@ -package coffeemeet.server.common.advice.advice; +package coffeemeet.server.common.advice; -import coffeemeet.server.common.execption.exception.DataLengthExceededException; -import coffeemeet.server.common.execption.exception.GlobalErrorCode; -import coffeemeet.server.common.execption.exception.InvalidAuthException; -import coffeemeet.server.common.execption.exception.MissMatchException; -import coffeemeet.server.common.execption.exception.NotFoundException; +import coffeemeet.server.common.execption.DataLengthExceededException; +import coffeemeet.server.common.execption.GlobalErrorCode; +import coffeemeet.server.common.execption.InvalidAuthException; +import coffeemeet.server.common.execption.MissMatchException; +import coffeemeet.server.common.execption.NotFoundException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; diff --git a/src/main/java/coffeemeet/server/common/execption/exception/CoffeeMeetException.java b/src/main/java/coffeemeet/server/common/execption/CoffeeMeetException.java similarity index 71% rename from src/main/java/coffeemeet/server/common/execption/exception/CoffeeMeetException.java rename to src/main/java/coffeemeet/server/common/execption/CoffeeMeetException.java index 6d2ce5ff..c03c47bb 100644 --- a/src/main/java/coffeemeet/server/common/execption/exception/CoffeeMeetException.java +++ b/src/main/java/coffeemeet/server/common/execption/CoffeeMeetException.java @@ -1,4 +1,4 @@ -package coffeemeet.server.common.execption.exception; +package coffeemeet.server.common.execption; public class CoffeeMeetException extends RuntimeException { diff --git a/src/main/java/coffeemeet/server/common/execption/exception/DataLengthExceededException.java b/src/main/java/coffeemeet/server/common/execption/DataLengthExceededException.java similarity index 83% rename from src/main/java/coffeemeet/server/common/execption/exception/DataLengthExceededException.java rename to src/main/java/coffeemeet/server/common/execption/DataLengthExceededException.java index 1dfd5401..4319991d 100644 --- a/src/main/java/coffeemeet/server/common/execption/exception/DataLengthExceededException.java +++ b/src/main/java/coffeemeet/server/common/execption/DataLengthExceededException.java @@ -1,4 +1,4 @@ -package coffeemeet.server.common.execption.exception; +package coffeemeet.server.common.execption; import lombok.Getter; diff --git a/src/main/java/coffeemeet/server/common/execption/exception/ErrorCode.java b/src/main/java/coffeemeet/server/common/execption/ErrorCode.java similarity index 57% rename from src/main/java/coffeemeet/server/common/execption/exception/ErrorCode.java rename to src/main/java/coffeemeet/server/common/execption/ErrorCode.java index da9d05b1..c42b5088 100644 --- a/src/main/java/coffeemeet/server/common/execption/exception/ErrorCode.java +++ b/src/main/java/coffeemeet/server/common/execption/ErrorCode.java @@ -1,4 +1,4 @@ -package coffeemeet.server.common.execption.exception; +package coffeemeet.server.common.execption; public interface ErrorCode { diff --git a/src/main/java/coffeemeet/server/common/execption/exception/GlobalErrorCode.java b/src/main/java/coffeemeet/server/common/execption/GlobalErrorCode.java similarity index 89% rename from src/main/java/coffeemeet/server/common/execption/exception/GlobalErrorCode.java rename to src/main/java/coffeemeet/server/common/execption/GlobalErrorCode.java index 7d485dc0..99c002da 100644 --- a/src/main/java/coffeemeet/server/common/execption/exception/GlobalErrorCode.java +++ b/src/main/java/coffeemeet/server/common/execption/GlobalErrorCode.java @@ -1,4 +1,4 @@ -package coffeemeet.server.common.execption.exception; +package coffeemeet.server.common.execption; import lombok.Getter; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/coffeemeet/server/common/execption/exception/InvalidAuthException.java b/src/main/java/coffeemeet/server/common/execption/InvalidAuthException.java similarity index 82% rename from src/main/java/coffeemeet/server/common/execption/exception/InvalidAuthException.java rename to src/main/java/coffeemeet/server/common/execption/InvalidAuthException.java index ac31293c..ffcfac34 100644 --- a/src/main/java/coffeemeet/server/common/execption/exception/InvalidAuthException.java +++ b/src/main/java/coffeemeet/server/common/execption/InvalidAuthException.java @@ -1,4 +1,4 @@ -package coffeemeet.server.common.execption.exception; +package coffeemeet.server.common.execption; import lombok.Getter; diff --git a/src/main/java/coffeemeet/server/common/execption/exception/MissMatchException.java b/src/main/java/coffeemeet/server/common/execption/MissMatchException.java similarity index 82% rename from src/main/java/coffeemeet/server/common/execption/exception/MissMatchException.java rename to src/main/java/coffeemeet/server/common/execption/MissMatchException.java index 32ef0a2f..abb03290 100644 --- a/src/main/java/coffeemeet/server/common/execption/exception/MissMatchException.java +++ b/src/main/java/coffeemeet/server/common/execption/MissMatchException.java @@ -1,4 +1,4 @@ -package coffeemeet.server.common.execption.exception; +package coffeemeet.server.common.execption; import lombok.Getter; diff --git a/src/main/java/coffeemeet/server/common/execption/exception/NotFoundException.java b/src/main/java/coffeemeet/server/common/execption/NotFoundException.java similarity index 82% rename from src/main/java/coffeemeet/server/common/execption/exception/NotFoundException.java rename to src/main/java/coffeemeet/server/common/execption/NotFoundException.java index aed8e0e1..36fdcd92 100644 --- a/src/main/java/coffeemeet/server/common/execption/exception/NotFoundException.java +++ b/src/main/java/coffeemeet/server/common/execption/NotFoundException.java @@ -1,4 +1,4 @@ -package coffeemeet.server.common.execption.exception; +package coffeemeet.server.common.execption; import lombok.Getter; From bb86915affcecd35e36c8df1e6e1773a90acbbbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 09:53:51 +0900 Subject: [PATCH 254/311] =?UTF-8?q?refactor:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A0=95=EB=B3=B4=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EB=A1=9C=EC=A7=81=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 --- .../interest/service/cq/InterestCommand.java | 17 ++++++++++------- .../interest/service/cq/InterestQuery.java | 4 ++++ .../server/user/dto/UpdateProfileDto.java | 6 ++---- .../server/user/service/UserService.java | 8 ++++++-- .../server/user/service/cq/UserCommand.java | 3 +-- 5 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/main/java/coffeemeet/server/interest/service/cq/InterestCommand.java b/src/main/java/coffeemeet/server/interest/service/cq/InterestCommand.java index 404f4b6a..f41e7fb0 100644 --- a/src/main/java/coffeemeet/server/interest/service/cq/InterestCommand.java +++ b/src/main/java/coffeemeet/server/interest/service/cq/InterestCommand.java @@ -15,10 +15,7 @@ public class InterestCommand { private final InterestRepository interestRepository; - - public List findAllByUserId(long userId) { - return interestRepository.findAllByUserId(userId); - } + private final InterestQuery interestQuery; public void saveAll(List keywords, User user) { List interests = keywords.stream() @@ -28,9 +25,15 @@ public void saveAll(List keywords, User user) { } public void updateInterests(User user, List keywords) { - List currentInterests = findAllByUserId(user.getId()); - deleteAll(currentInterests); - saveAll(keywords, user); + List currentInterests = interestQuery.findAllByUserId(user.getId()); + List currentKeywords = currentInterests.stream() + .map(Interest::getKeyword) + .toList(); + + if (!currentKeywords.equals(keywords)) { + deleteAll(currentInterests); + saveAll(keywords, user); + } } public void deleteAll(List interests) { diff --git a/src/main/java/coffeemeet/server/interest/service/cq/InterestQuery.java b/src/main/java/coffeemeet/server/interest/service/cq/InterestQuery.java index eb326652..1abe126f 100644 --- a/src/main/java/coffeemeet/server/interest/service/cq/InterestQuery.java +++ b/src/main/java/coffeemeet/server/interest/service/cq/InterestQuery.java @@ -21,4 +21,8 @@ public List getKeywordsByUserId(Long userId) { .toList(); } + public List findAllByUserId(long userId) { + return interestRepository.findAllByUserId(userId); + } + } diff --git a/src/main/java/coffeemeet/server/user/dto/UpdateProfileDto.java b/src/main/java/coffeemeet/server/user/dto/UpdateProfileDto.java index 2c4e8d61..b7392232 100644 --- a/src/main/java/coffeemeet/server/user/dto/UpdateProfileDto.java +++ b/src/main/java/coffeemeet/server/user/dto/UpdateProfileDto.java @@ -1,16 +1,14 @@ package coffeemeet.server.user.dto; import coffeemeet.server.interest.domain.Keyword; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import java.util.List; public sealed interface UpdateProfileDto permits UpdateProfileDto.Request { record Request( - @NotBlank String nickname, - @NotNull @Size(min = 1, max = 3) List interests + String nickname, + @Size(min = 1, max = 3) List interests ) implements UpdateProfileDto { } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 15544f3a..7cb35fc8 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -101,9 +101,13 @@ public void updateProfileImage(Long userId, File file) { @Transactional public void updateProfileInfo(Long userId, String nickname, List keywords) { - userCommand.updateUserInfo(userId, nickname); User user = userQuery.getUserById(userId); - interestCommand.updateInterests(user, keywords); + if (nickname != null) { + userCommand.updateUserInfo(user, nickname); + } + if (keywords != null && !keywords.isEmpty()) { + interestCommand.updateInterests(user, keywords); + } } public void checkDuplicatedNickname(String nickname) { diff --git a/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java b/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java index c458d9ba..cc8ffc85 100644 --- a/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java +++ b/src/main/java/coffeemeet/server/user/service/cq/UserCommand.java @@ -29,8 +29,7 @@ public void deleteUser(Long userId) { userRepository.deleteById(userId); } - public void updateUserInfo(Long userId, String nickname) { - User user = userQuery.getUserById(userId); + public void updateUserInfo(User user, String nickname) { userQuery.hasDuplicatedNickname(nickname); user.updateNickname(nickname); } From 42d0062b4fb67ed347838377ee3ee330af33bbb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 09:55:20 +0900 Subject: [PATCH 255/311] =?UTF-8?q?test:=20=EC=9C=A0=EC=A0=80=20DTO=20Fixt?= =?UTF-8?q?ure=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fixture/dto/MyProfileDtoFixture.java | 28 +++++++++++++++++++ .../fixture/dto/OAuthUserInfoDtoFixture.java | 5 ++++ .../common/fixture/dto/SignupDtoFixture.java | 25 +++++++++++++++++ .../fixture/dto/UpdateProfileDtoFixture.java | 24 ++++++++++++++++ .../fixture/dto/UserProfileDtoFixture.java | 13 +++++++++ 5 files changed, 95 insertions(+) create mode 100644 src/test/java/coffeemeet/server/common/fixture/dto/MyProfileDtoFixture.java create mode 100644 src/test/java/coffeemeet/server/common/fixture/dto/SignupDtoFixture.java create mode 100644 src/test/java/coffeemeet/server/common/fixture/dto/UpdateProfileDtoFixture.java create mode 100644 src/test/java/coffeemeet/server/common/fixture/dto/UserProfileDtoFixture.java diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/MyProfileDtoFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/MyProfileDtoFixture.java new file mode 100644 index 00000000..3d54e37e --- /dev/null +++ b/src/test/java/coffeemeet/server/common/fixture/dto/MyProfileDtoFixture.java @@ -0,0 +1,28 @@ +package coffeemeet.server.common.fixture.dto; + +import static org.instancio.Select.field; + +import coffeemeet.server.interest.domain.Keyword; +import coffeemeet.server.user.dto.MyProfileDto; +import coffeemeet.server.user.dto.MyProfileDto.Response; +import java.util.List; +import org.instancio.Instancio; + +public class MyProfileDtoFixture { + + public static MyProfileDto.Response myProfileDtoResponse() { + return Instancio.of(MyProfileDto.Response.class) + .generate(field("birthYear"), gen -> gen.ints().range(1000, 9999).asString()) + .generate(field("birthDay"), gen -> gen.ints().range(1000, 9999).asString()) + .set(field(Response::interests), keywords()) + .set(field("email"), "test123@gmail.com") + .create(); + } + + public static List keywords() { + return Instancio.ofList(Keyword.class) + .size(3) + .create(); + } + +} diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthUserInfoDtoFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthUserInfoDtoFixture.java index 4ddb409f..2b111ca6 100644 --- a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthUserInfoDtoFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthUserInfoDtoFixture.java @@ -1,5 +1,7 @@ package coffeemeet.server.common.fixture.dto; +import static org.instancio.Select.field; + import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import org.instancio.Instancio; @@ -7,6 +9,9 @@ public class OAuthUserInfoDtoFixture { public static OAuthUserInfoDto.Response response() { return Instancio.of(OAuthUserInfoDto.Response.class) + .generate(field("birthYear"), gen -> gen.ints().range(1000, 9999).asString()) + .generate(field("birthDay"), gen -> gen.ints().range(1000, 9999).asString()) + .set(field("email"),"test123@gmail.com") .create(); } diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/SignupDtoFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/SignupDtoFixture.java new file mode 100644 index 00000000..c03e4e93 --- /dev/null +++ b/src/test/java/coffeemeet/server/common/fixture/dto/SignupDtoFixture.java @@ -0,0 +1,25 @@ +package coffeemeet.server.common.fixture.dto; + +import static org.instancio.Select.field; + +import coffeemeet.server.interest.domain.Keyword; +import coffeemeet.server.user.dto.SignupDto; +import coffeemeet.server.user.dto.SignupDto.Request; +import java.util.List; +import org.instancio.Instancio; + +public class SignupDtoFixture { + + public static SignupDto.Request signupDto() { + return Instancio.of(SignupDto.Request.class) + .set(field(Request::keywords), keywords()) + .create(); + } + + public static List keywords() { + return Instancio.ofList(Keyword.class) + .size(3) + .create(); + } + +} diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/UpdateProfileDtoFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/UpdateProfileDtoFixture.java new file mode 100644 index 00000000..ca72e591 --- /dev/null +++ b/src/test/java/coffeemeet/server/common/fixture/dto/UpdateProfileDtoFixture.java @@ -0,0 +1,24 @@ +package coffeemeet.server.common.fixture.dto; + +import static org.instancio.Select.field; + +import coffeemeet.server.interest.domain.Keyword; +import coffeemeet.server.user.dto.UpdateProfileDto; +import java.util.List; +import org.instancio.Instancio; + +public class UpdateProfileDtoFixture { + + public static UpdateProfileDto.Request updateProfileDtoRequest() { + return Instancio.of(UpdateProfileDto.Request.class) + .set(field(UpdateProfileDto.Request::interests), keywords()) + .create(); + } + + public static List keywords() { + return Instancio.ofList(Keyword.class) + .size(3) + .create(); + } + +} diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/UserProfileDtoFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/UserProfileDtoFixture.java new file mode 100644 index 00000000..ae79681a --- /dev/null +++ b/src/test/java/coffeemeet/server/common/fixture/dto/UserProfileDtoFixture.java @@ -0,0 +1,13 @@ +package coffeemeet.server.common.fixture.dto; + +import coffeemeet.server.user.dto.UserProfileDto; +import org.instancio.Instancio; + +public class UserProfileDtoFixture { + + public static UserProfileDto.Response userProfileDtoResponse() { + return Instancio.of(UserProfileDto.Response.class) + .create(); + } + +} From 3cad9ae526bc6d7eb65e071b02fac4636a82a7ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 09:55:47 +0900 Subject: [PATCH 256/311] =?UTF-8?q?test:=20UserFixture=EC=9D=98=20email=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 --- .../server/common/fixture/entity/UserFixture.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java b/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java index 57b19be5..d3ccada6 100644 --- a/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/entity/UserFixture.java @@ -28,15 +28,9 @@ private static Birth birth() { private static Profile profile() { return Instancio.of(Profile.class) .set(field(Profile::getBirth), birth()) - .set(field(Profile::getEmail), email()) + .set(field(Profile::getEmail), new Email("test123@gmail.com")) .generate(field(Profile::getNickname), gen -> gen.string().maxLength(20)) .create(); } - private static Email email() { - return Instancio.of(Email.class) - .generate(field(Email::getEmail), gen -> gen.net().email()) - .create(); - } - } From 894bc3728a8a13fde3cd05e9210092415805e358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 09:56:00 +0900 Subject: [PATCH 257/311] =?UTF-8?q?test:=20UserController=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 --- .../common/config/ControllerTestConfig.java | 2 +- .../user/controller/UserControllerTest.java | 296 ++++++++++++++++++ 2 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 src/test/java/coffeemeet/server/user/controller/UserControllerTest.java diff --git a/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java index 595f9c78..d5ea3328 100644 --- a/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java +++ b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java @@ -35,7 +35,7 @@ public abstract class ControllerTestConfig { protected RefreshTokenRepository refreshTokenRepository; @MockBean - protected UserService userService; // TODO: 2023/10/30 AuthService 때문에 얘가 있어야 되는데 이거 바꿔야 될 듯? + protected UserService userService; @BeforeEach void setUp(WebApplicationContext ctx, RestDocumentationContextProvider restDocumentation) { diff --git a/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java new file mode 100644 index 00000000..3b71887f --- /dev/null +++ b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java @@ -0,0 +1,296 @@ +package coffeemeet.server.user.controller; + +import static coffeemeet.server.common.fixture.entity.UserFixture.user; +import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; +import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.resourceDetails; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.willDoNothing; +import static org.mockito.Mockito.when; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.multipart; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.partWithName; +import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; +import static org.springframework.restdocs.request.RequestDocumentation.queryParameters; +import static org.springframework.restdocs.request.RequestDocumentation.requestParts; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import coffeemeet.server.auth.domain.AuthTokens; +import coffeemeet.server.auth.domain.RefreshToken; +import coffeemeet.server.common.config.ControllerTestConfig; +import coffeemeet.server.common.fixture.dto.MyProfileDtoFixture; +import coffeemeet.server.common.fixture.dto.RefreshTokenFixture; +import coffeemeet.server.common.fixture.dto.SignupDtoFixture; +import coffeemeet.server.common.fixture.dto.UpdateProfileDtoFixture; +import coffeemeet.server.common.fixture.dto.UserProfileDtoFixture; +import coffeemeet.server.user.domain.OAuthProvider; +import coffeemeet.server.user.domain.User; +import coffeemeet.server.user.dto.MyProfileDto.Response; +import coffeemeet.server.user.dto.SignupDto; +import coffeemeet.server.user.dto.UpdateProfileDto.Request; +import coffeemeet.server.user.dto.UserProfileDto; +import com.epages.restdocs.apispec.Schema; +import java.util.Optional; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.http.MediaType; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.restdocs.payload.JsonFieldType; + +@WebMvcTest(UserController.class) +class UserControllerTest extends ControllerTestConfig { + + @Test + @DisplayName("회원가입을 할 수 있다.") + void signupTest() throws Exception { + SignupDto.Request request = SignupDtoFixture.signupDto(); + AuthTokens authTokens = new AuthTokens("accessToken", "refreshToken"); + + given(userService.signup(any())).willReturn(authTokens); + + mockMvc.perform(post("/api/v1/users/sign-up") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andDo(document("user-signup", + resourceDetails().tag("사용자").description("회원가입") + .requestSchema(Schema.schema("SignupDto.Request")) + .responseSchema(Schema.schema("AuthTokens")), + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + requestFields( + fieldWithPath("nickname").type(JsonFieldType.STRING).description("닉네임"), + fieldWithPath("keywords").type(JsonFieldType.ARRAY).description("관심사"), + fieldWithPath("authCode").type(JsonFieldType.STRING).description("인증 코드"), + fieldWithPath("oAuthProvider").type(JsonFieldType.STRING).description("OAuth 제공자") + ), + responseFields( + fieldWithPath("accessToken").type(JsonFieldType.STRING).description("액세스 토큰"), + fieldWithPath("refreshToken").type(JsonFieldType.STRING).description("리프레시 토큰") + ) + )) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.accessToken").value("accessToken")) + .andExpect(jsonPath("$.refreshToken").value("refreshToken")); + } + + @Test + @DisplayName("로그인을 할 수 있다.") + void loginTest() throws Exception { + AuthTokens authTokens = new AuthTokens("accessToken", "refreshToken"); + + given(userService.login(any(), any())).willReturn(authTokens); + + mockMvc.perform(get("/api/v1/users/login/{oAuthProvider}", OAuthProvider.KAKAO) + .contentType(MediaType.APPLICATION_JSON) + .param("authCode", "authCode")) + .andDo(document("user-login", + resourceDetails().tag("사용자").description("로그인") + .responseSchema(Schema.schema("AuthTokens")), + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + pathParameters( + parameterWithName("oAuthProvider").description("OAuth 제공자") + ), + queryParameters( + parameterWithName("authCode").description("인증 코드") + ), + responseFields( + fieldWithPath("accessToken").type(JsonFieldType.STRING).description("액세스 토큰"), + fieldWithPath("refreshToken").type(JsonFieldType.STRING).description("리프레시 토큰") + ) + )) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.accessToken").value("accessToken")) + .andExpect(jsonPath("$.refreshToken").value("refreshToken")); + } + + @Test + @DisplayName("사용자 프로필을 조회할 수 있다.") + void findUserProfileTest() throws Exception { + long id = 1L; + UserProfileDto.Response response = UserProfileDtoFixture.userProfileDtoResponse(); + + given(userService.findUserProfile(id)).willReturn(response); + + mockMvc.perform(get("/api/v1/users/{id}", id) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + ) + .andDo(document("user-profile", + resourceDetails().tag("사용자").description("사용자 프로필 조회") + .responseSchema(Schema.schema("UserProfileDto.Response")), + pathParameters( + parameterWithName("id").description("유저 아이디") + ), + responseFields( + fieldWithPath("nickname").type(JsonFieldType.STRING).description("닉네임"), + fieldWithPath("profileImageUrl").type(JsonFieldType.STRING) + .description("프로필 사진 url"), + fieldWithPath("department").type(JsonFieldType.STRING).description("부서"), + fieldWithPath("interests").type(JsonFieldType.ARRAY).description("관심사") + ) + ) + ) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.nickname").value(response.nickname())) + .andExpect(jsonPath("$.profileImageUrl").value(response.profileImageUrl())) + .andExpect(jsonPath("$.department").value(String.valueOf(response.department()))) + .andExpect(jsonPath("$.interests[0]").value(response.interests().get(0).name())); + } + + @Test + @DisplayName("마이페이지를 조회할 수 있다.") + void findMyProfileTest() throws Exception { + User user = user(); + Long userId = user.getId(); + RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); + + given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + Response response = MyProfileDtoFixture.myProfileDtoResponse(); + + when(jwtTokenProvider.extractUserId(TOKEN)).thenReturn(userId); + when(userService.findMyProfile(anyLong())).thenReturn(response); + + mockMvc.perform(get("/api/v1/users/me") + .header("Authorization", TOKEN) + .contentType(MediaType.APPLICATION_JSON) + ) + .andDo(document("my-profile", + resourceDetails().tag("사용자").description("마이페이지 조회") + .responseSchema(Schema.schema("MyProfileDto.Response")), + requestHeaders( + headerWithName("Authorization").description("토큰") + ), + responseFields( + fieldWithPath("name").type(JsonFieldType.STRING).description("이름"), + fieldWithPath("nickname").type(JsonFieldType.STRING).description("닉네임"), + fieldWithPath("email").type(JsonFieldType.STRING).description("이메일"), + fieldWithPath("profileImageUrl").type(JsonFieldType.STRING) + .description("프로필 사진 url"), + fieldWithPath("birthYear").type(JsonFieldType.STRING).description("생일년도"), + fieldWithPath("birthDay").type(JsonFieldType.STRING).description("생일월일"), + fieldWithPath("reportedCount").type(JsonFieldType.NUMBER).description("신고 횟수"), + fieldWithPath("sanctionPeriod").type(JsonFieldType.STRING).description("제재 기간"), + fieldWithPath("department").type(JsonFieldType.STRING).description("부서"), + fieldWithPath("interests").type(JsonFieldType.ARRAY).description("관심사") + ) + ) + ) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.name").value(response.name())) + .andExpect(jsonPath("$.nickname").value(response.nickname())) + .andExpect(jsonPath("$.email").value(response.email())) + .andExpect(jsonPath("$.profileImageUrl").value(response.profileImageUrl())) + .andExpect(jsonPath("$.birthYear").value(response.birthYear())) + .andExpect(jsonPath("$.birthDay").value(response.birthDay())) + .andExpect(jsonPath("$.reportedCount").value(response.reportedCount())) + .andExpect(jsonPath("$.sanctionPeriod").value(String.valueOf(response.sanctionPeriod()))) + .andExpect(jsonPath("$.department").value(String.valueOf(response.department()))) + .andExpect(jsonPath("$.interests[0]").value(response.interests().get(0).name())); + } + + @Test + @DisplayName("본인 프로필 사진을 수정할 수 있다.") + void updateProfileImageTest() throws Exception { + User user = user(); + Long userId = user.getId(); + RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); + + given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + given(jwtTokenProvider.extractUserId(TOKEN)).willReturn(userId); + + MockMultipartFile file = new MockMultipartFile("image", + "test.png", + "image/png", + "testImage".getBytes()); + + mockMvc.perform((multipart("/api/v1/users/me/profile-image") + .file("profileImage", file.getBytes()) + .header("Authorization", TOKEN) + .contentType(MediaType.MULTIPART_FORM_DATA) + )) + .andDo(document("update-profile-image", + resourceDetails().tag("사용자").description("본인 프로필 사진 수정") + .requestSchema(Schema.schema("MultipartFile")), + requestHeaders( + headerWithName("Authorization").description("토큰") + ), + requestParts( + partWithName("profileImage").description("새 프로필 사진") + ) + ) + ) + .andExpect(status().isOk()); + } + + @Test + @DisplayName("본인 프로필 정보를 수정할 수 있다.") + void updateProfileInfoTest() throws Exception { + User user = user(); + Long userId = user.getId(); + Request request = UpdateProfileDtoFixture.updateProfileDtoRequest(); + RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); + + given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + given(jwtTokenProvider.extractUserId(TOKEN)).willReturn(userId); + willDoNothing().given( + userService).updateProfileInfo(any(), any(), any()); + + mockMvc.perform(patch("/api/v1/users/me") + .header("Authorization", TOKEN) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request)) + ) + .andDo(document("update-my-profile", + resourceDetails().tag("사용자").description("본인 프로필 정보 수정") + .requestSchema(Schema.schema("UpdateProfileDto.Request")), + requestHeaders( + headerWithName("Authorization").description("토큰") + ), + requestFields( + fieldWithPath("nickname").type(JsonFieldType.STRING).description("닉네임"), + fieldWithPath("interests").type(JsonFieldType.ARRAY).description("관심사") + ) + ) + ) + .andExpect(status().isOk() + ); + } + + @Test + @DisplayName("닉네임 중복을 확인할 수 있다.") + void checkNicknameDuplicationTest() throws Exception { + User user = user(); + String nickname = user.getProfile().getNickname(); + RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); + + given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + + mockMvc.perform(get("/api/v1/users/duplicate") + .param("nickname", nickname) + ) + .andDo(document("check-nickname", + resourceDetails().tag("사용자").description("닉네임 중복 확인"), + queryParameters( + parameterWithName("nickname").description("닉네임") + ) + )) + .andExpect(status().isOk() + ); + } + +} From 49765a4a729586ee5efb2fea28e95f25ba54dd75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 10:00:46 +0900 Subject: [PATCH 258/311] =?UTF-8?q?test:=20UserService=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 --- .../server/user/service/UserServiceTest.java | 291 ++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 src/test/java/coffeemeet/server/user/service/UserServiceTest.java diff --git a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java new file mode 100644 index 00000000..f4f95ed1 --- /dev/null +++ b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java @@ -0,0 +1,291 @@ +package coffeemeet.server.user.service; + +import static coffeemeet.server.certification.domain.Department.IT; +import static coffeemeet.server.common.fixture.entity.UserFixture.user; +import static coffeemeet.server.common.media.S3MediaService.KeyType.PROFILE_IMAGE; +import static coffeemeet.server.interest.domain.Keyword.COOK; +import static coffeemeet.server.interest.domain.Keyword.GAME; +import static coffeemeet.server.user.domain.OAuthProvider.KAKAO; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; + +import coffeemeet.server.auth.domain.AuthTokens; +import coffeemeet.server.auth.domain.AuthTokensGenerator; +import coffeemeet.server.certification.domain.Certification; +import coffeemeet.server.certification.domain.CompanyEmail; +import coffeemeet.server.certification.service.cq.CertificationQuery; +import coffeemeet.server.common.fixture.dto.AuthTokensFixture; +import coffeemeet.server.common.fixture.dto.OAuthUserInfoDtoFixture; +import coffeemeet.server.common.fixture.dto.SignupDtoFixture; +import coffeemeet.server.common.fixture.entity.CertificationFixture; +import coffeemeet.server.common.media.S3MediaService; +import coffeemeet.server.interest.domain.Keyword; +import coffeemeet.server.interest.service.cq.InterestCommand; +import coffeemeet.server.interest.service.cq.InterestQuery; +import coffeemeet.server.oauth.dto.OAuthUserInfoDto; +import coffeemeet.server.oauth.service.OAuthService; +import coffeemeet.server.user.domain.Birth; +import coffeemeet.server.user.domain.Email; +import coffeemeet.server.user.domain.OAuthInfo; +import coffeemeet.server.user.domain.Profile; +import coffeemeet.server.user.domain.User; +import coffeemeet.server.user.dto.MyProfileDto; +import coffeemeet.server.user.dto.SignupDto.Request; +import coffeemeet.server.user.dto.UserProfileDto.Response; +import coffeemeet.server.user.service.cq.UserCommand; +import coffeemeet.server.user.service.cq.UserQuery; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +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.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.transaction.annotation.Transactional; + +@ExtendWith(MockitoExtension.class) +class UserServiceTest { + + @InjectMocks + private UserService userService; + + @Mock + private S3MediaService s3MediaService; + + @Mock + private OAuthService oAuthService; + + @Mock + private AuthTokensGenerator authTokensGenerator; + + @Mock + private InterestQuery interestQuery; + + @Mock + private InterestCommand interestCommand; + + @Mock + private UserQuery userQuery; + + @Mock + private UserCommand userCommand; + + @Mock + private CertificationQuery certificationQuery; + + @DisplayName("회원가입을 할 수 있다.") + @Test + void signupTest() { + // given + Request request = SignupDtoFixture.signupDto(); + AuthTokens authTokens = AuthTokensFixture.authTokens(); + OAuthUserInfoDto.Response response = OAuthUserInfoDtoFixture.response(); + User user = user(); + + given(oAuthService.getOAuthUserInfo(any(), any())).willReturn(response); + given(userCommand.saveUser(any(User.class))).willReturn(user.getId()); + given(userQuery.getUserById(user.getId())).willReturn(user); + doNothing().when(interestCommand).saveAll(any(), any()); + given(authTokensGenerator.generate(user.getId())).willReturn(authTokens); + + // when + AuthTokens result = userService.signup(request); + + // then + assertThat(result.accessToken()).isEqualTo(authTokens.accessToken()); + assertThat(result.refreshToken()).isEqualTo(authTokens.refreshToken()); + } + + @DisplayName("로그인을 할 수 있다.") + @Test + void loginTest() { + // given + User user = user(); + String authCode = "authCode"; + AuthTokens authTokens = AuthTokensFixture.authTokens(); + + OAuthUserInfoDto.Response response = OAuthUserInfoDtoFixture.response(); + + given(oAuthService.getOAuthUserInfo(any(), any())).willReturn(response); + given(userQuery.getUserByOAuthInfo(any(), any())).willReturn(user); + given(authTokensGenerator.generate(anyLong())).willReturn(authTokens); + + // when + AuthTokens result = userService.login(KAKAO, authCode); + + // then + assertThat(result.accessToken()).isEqualTo(authTokens.accessToken()); + assertThat(result.refreshToken()).isEqualTo(authTokens.refreshToken()); + } + + @DisplayName("사용자의 프로필을 조회할 수 있다.") + @Test + void findUserProfileTest() { + // given + User user = user(); + Certification certification = CertificationFixture.certification(); + List keywords = new ArrayList<>(Arrays.asList(COOK, GAME)); + Response response = Response.of(user, certification.getDepartment(), keywords); + + given(userQuery.getUserById(anyLong())).willReturn(user); + given(interestQuery.getKeywordsByUserId(user.getId())).willReturn(keywords); + given(certificationQuery.getCertificationByUserId(anyLong())).willReturn(certification); + + // when + Response result = userService.findUserProfile(user.getId()); + + // then + assertAll( + () -> assertThat(result.nickname()).isEqualTo(response.nickname()), + () -> assertThat(result.department()).isEqualTo(response.department()), + () -> assertThat(result.profileImageUrl()).isEqualTo(response.profileImageUrl()), + () -> assertThat(result.interests()).isEqualTo(response.interests()) + ); + } + + @DisplayName("본인의 프로필을 조회할 수 있다.") + @Test + void findMyProfileTest() { + // given + User user = user(); + List keywords = new ArrayList<>(List.of(COOK)); + MyProfileDto.Response response = MyProfileDto.Response.of(user, keywords, IT); + Certification certification = Certification.builder() + .department(response.department()) + .user(user) + .companyEmail(new CompanyEmail("company123@gmail.com")) + .businessCardUrl("businessCard") + .build(); + + given(userQuery.getUserById(anyLong())).willReturn(user); + given(interestQuery.getKeywordsByUserId(anyLong())).willReturn(response.interests()); + given(certificationQuery.getCertificationByUserId(anyLong())).willReturn(certification); + + // when + MyProfileDto.Response result = userService.findMyProfile(user.getId()); + + // then + assertAll( + () -> assertThat(result.name()).isEqualTo(response.name()), + () -> assertThat(result.nickname()).isEqualTo(response.nickname()), + () -> assertThat(result.email()).isEqualTo(response.email()), + () -> assertThat(result.profileImageUrl()).isEqualTo(response.profileImageUrl()), + () -> assertThat(result.birthYear()).isEqualTo(response.birthYear()), + () -> assertThat(result.birthDay()).isEqualTo(response.birthDay()), + () -> assertThat(result.department()).isEqualTo(response.department()), + () -> assertThat(result.interests()).isEqualTo(response.interests()) + ); + } + + @DisplayName("아이디로 사용자를 조회할 수 있다.") + @Test + void getUserById() { + // given + User user = user(); + Long userId = user.getId(); + + given(userQuery.getUserById(userId)).willReturn(user); + + // when + User foundUser = userQuery.getUserById(userId); + + // then + assertAll( + () -> assertThat(foundUser.getId()).isEqualTo(user.getId()), + () -> assertThat(foundUser.getOauthInfo().getOauthProvider()).isEqualTo( + user.getOauthInfo().getOauthProvider()), + () -> assertThat(foundUser.getOauthInfo().getOauthProviderId()).isEqualTo( + user.getOauthInfo().getOauthProviderId()), + () -> assertThat(foundUser.getProfile()).isEqualTo(user.getProfile()) + ); + } + + @DisplayName("프로필 사진을 수정할 수 있다.") + @Test + void updateProfileImage() throws IOException { + // given + User user = user(); + Long userId = user.getId(); + File file = File.createTempFile("temp", "png"); + + given(userQuery.getUserById(userId)).willReturn(user); + given(s3MediaService.generateKey(PROFILE_IMAGE)).willReturn("key"); + given(s3MediaService.getUrl(anyString())).willReturn("newImageUrl"); + + // when + userService.updateProfileImage(userId, file); + + // then + assertThat(user.getProfile().getProfileImageUrl()).isEqualTo("newImageUrl"); + } + + @DisplayName("프로필 정보를 수정할 수 있다.") + @Transactional + @Test + void updateProfileInfo() { + // given + User user = new User(new OAuthInfo(KAKAO, "123"), Profile.builder() + .nickname("닉네임") + .name("이름") + .birth(new Birth("2001", "1018")) + .profileImageUrl("http://imageUrl") + .email(new Email("test123@gmail.com")) + .build()); + + String newNickname = "새닉네임"; + ArrayList newKeywords = new ArrayList<>(Arrays.asList(COOK, GAME)); + + given(userQuery.getUserById(any())).willReturn(user); + + // when + userService.updateProfileInfo(user.getId(), newNickname, newKeywords); + + // then + assertThat(user.getProfile().getNickname()).isEqualTo(newNickname); + } + + @DisplayName("탈퇴할 수 있다.") + @Test + void deleteUser() { + // given + User user = user(); + + doNothing().when(userCommand).deleteUser(user.getId()); + given(userQuery.getUserById(user.getId())).willThrow( + new IllegalArgumentException()); + + // when + userService.deleteUser(user.getId()); + + // then + assertThatThrownBy(() -> userQuery.getUserById(user.getId())).isInstanceOf( + IllegalArgumentException.class); + + } + + @DisplayName("닉네임 중복을 검사할 수 있다.") + @Test + void checkDuplicatedNickname() { + // given + User user = user(); + String nickname = user.getProfile().getNickname(); + + doThrow(new IllegalArgumentException()).when(userQuery).hasDuplicatedNickname(nickname); + + // when + assertThatThrownBy(() -> userService.checkDuplicatedNickname(nickname)) + .isInstanceOf(IllegalArgumentException.class); + } + +} From 98417291489c27172c78c2b96c160fd3ab693499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 10:01:16 +0900 Subject: [PATCH 259/311] =?UTF-8?q?test:=20=EB=B3=80=EA=B2=BD=EB=90=9C=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=EC=97=90=20=EB=A7=9E=EA=B2=8C=20Certificatio?= =?UTF-8?q?nService=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=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 --- .../certification/service/CertificationServiceTest.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java b/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java index 7ccfc544..c92fbd06 100644 --- a/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java +++ b/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java @@ -16,14 +16,12 @@ import static org.mockito.Mockito.only; import coffeemeet.server.certification.service.cq.CertificationCommand; -import coffeemeet.server.certification.service.cq.CertificationQuery; import coffeemeet.server.certification.service.cq.EmailVerificationCommand; import coffeemeet.server.certification.service.cq.EmailVerificationQuery; import coffeemeet.server.common.media.EmailService; import coffeemeet.server.common.media.S3MediaService; import coffeemeet.server.common.util.FileUtils; import coffeemeet.server.user.domain.User; -import coffeemeet.server.user.service.UserService; import coffeemeet.server.user.service.cq.UserQuery; import java.io.File; import org.instancio.Instancio; @@ -44,14 +42,10 @@ class CertificationServiceTest { @Mock private EmailService emailService; @Mock - private UserService userService; - @Mock private UserQuery userQuery; @Mock private CertificationCommand certificationCommand; @Mock - private CertificationQuery certificationQuery; - @Mock private EmailVerificationCommand emailVerificationCommand; @Mock private EmailVerificationQuery emailVerificationQuery; From c09cd502d3c1e58df3c569bc16e12fab7c9319da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 10:27:21 +0900 Subject: [PATCH 260/311] =?UTF-8?q?refactor:=20Controller=EC=99=80=20Servi?= =?UTF-8?q?ce=20DTO=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/controller/UserController.java | 14 ++++--- .../user/controller/dto/MyProfileHttpDto.java | 40 +++++++++++++++++++ .../controller/dto/UserProfileHttpDto.java | 27 +++++++++++++ .../server/user/dto/MyProfileDto.java | 1 - .../server/user/dto/UserProfileDto.java | 1 - 5 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 src/main/java/coffeemeet/server/user/controller/dto/MyProfileHttpDto.java create mode 100644 src/main/java/coffeemeet/server/user/controller/dto/UserProfileHttpDto.java diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index 87adc3ee..a027f03e 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -3,12 +3,14 @@ import coffeemeet.server.auth.domain.AuthTokens; import coffeemeet.server.common.annotation.Login; import coffeemeet.server.common.util.FileUtils; +import coffeemeet.server.user.controller.dto.MyProfileHttpDto; +import coffeemeet.server.user.controller.dto.UserProfileHttpDto; import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.dto.AuthInfo; import coffeemeet.server.user.dto.MyProfileDto; import coffeemeet.server.user.dto.SignupDto; import coffeemeet.server.user.dto.UpdateProfileDto; -import coffeemeet.server.user.dto.UserProfileDto; +import coffeemeet.server.user.dto.UserProfileDto.Response; import coffeemeet.server.user.service.UserService; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; @@ -45,13 +47,15 @@ public ResponseEntity login(@PathVariable OAuthProvider oAuthProvide } @GetMapping("/{userId}") - public ResponseEntity findUserProfile(@PathVariable long userId) { - return ResponseEntity.ok(userService.findUserProfile(userId)); + public ResponseEntity findUserProfile(@PathVariable long userId) { + Response response = userService.findUserProfile(userId); + return ResponseEntity.ok(UserProfileHttpDto.Response.of(response)); } @GetMapping("/me") - public ResponseEntity findMyProfile(@Login AuthInfo authInfo) { - return ResponseEntity.ok(userService.findMyProfile(authInfo.userId())); + public ResponseEntity findMyProfile(@Login AuthInfo authInfo) { + MyProfileDto.Response response = userService.findMyProfile(authInfo.userId()); + return ResponseEntity.ok(MyProfileHttpDto.Response.of(response)); } @PostMapping("/me/profile-image") diff --git a/src/main/java/coffeemeet/server/user/controller/dto/MyProfileHttpDto.java b/src/main/java/coffeemeet/server/user/controller/dto/MyProfileHttpDto.java new file mode 100644 index 00000000..fad12706 --- /dev/null +++ b/src/main/java/coffeemeet/server/user/controller/dto/MyProfileHttpDto.java @@ -0,0 +1,40 @@ +package coffeemeet.server.user.controller.dto; + +import coffeemeet.server.certification.domain.Department; +import coffeemeet.server.interest.domain.Keyword; +import coffeemeet.server.user.dto.MyProfileDto; +import java.time.LocalDateTime; +import java.util.List; + +public sealed interface MyProfileHttpDto permits MyProfileHttpDto.Response { + + record Response( + String name, + String nickname, + String email, + String profileImageUrl, + String birthYear, + String birthDay, + int reportedCount, + LocalDateTime sanctionPeriod, + Department department, + List interests + ) implements MyProfileHttpDto { + + public static Response of(MyProfileDto.Response response) { + return new Response( + response.name(), + response.nickname(), + response.email(), + response.profileImageUrl(), + response.birthYear(), + response.birthDay(), + response.reportedCount(), + response.sanctionPeriod(), + response.department(), + response.interests() + ); + } + } + +} diff --git a/src/main/java/coffeemeet/server/user/controller/dto/UserProfileHttpDto.java b/src/main/java/coffeemeet/server/user/controller/dto/UserProfileHttpDto.java new file mode 100644 index 00000000..36c3a3a5 --- /dev/null +++ b/src/main/java/coffeemeet/server/user/controller/dto/UserProfileHttpDto.java @@ -0,0 +1,27 @@ +package coffeemeet.server.user.controller.dto; + +import coffeemeet.server.certification.domain.Department; +import coffeemeet.server.interest.domain.Keyword; +import coffeemeet.server.user.dto.UserProfileDto; +import java.util.List; + +public sealed interface UserProfileHttpDto permits UserProfileHttpDto.Response { + + record Response( + String nickname, + String profileImageUrl, + Department department, + List interests + ) implements UserProfileHttpDto { + + public static Response of(UserProfileDto.Response response) { + return new Response( + response.nickname(), + response.profileImageUrl(), + response.department(), + response.interests() + ); + } + } + +} diff --git a/src/main/java/coffeemeet/server/user/dto/MyProfileDto.java b/src/main/java/coffeemeet/server/user/dto/MyProfileDto.java index d2f918cc..83496d80 100644 --- a/src/main/java/coffeemeet/server/user/dto/MyProfileDto.java +++ b/src/main/java/coffeemeet/server/user/dto/MyProfileDto.java @@ -22,7 +22,6 @@ record Response( ) implements MyProfileDto { public static Response of(User user, List interests, Department department) { - return new Response( user.getProfile().getName(), user.getProfile().getNickname(), diff --git a/src/main/java/coffeemeet/server/user/dto/UserProfileDto.java b/src/main/java/coffeemeet/server/user/dto/UserProfileDto.java index 9ff20391..4bf52c5b 100644 --- a/src/main/java/coffeemeet/server/user/dto/UserProfileDto.java +++ b/src/main/java/coffeemeet/server/user/dto/UserProfileDto.java @@ -16,7 +16,6 @@ record Response( public static Response of(User user, Department department, List interests) { - return new Response( user.getProfile().getNickname(), user.getProfile().getProfileImageUrl(), From 1ec388a229e0a80228689c8b294bdd4672a3f604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 10:34:01 +0900 Subject: [PATCH 261/311] =?UTF-8?q?refactor:=20=EC=9C=A0=EC=A0=80=20Dto=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/auth/controller/AuthController.java | 2 +- .../controller/CertificationController.java | 2 +- .../coffeemeet/server/common/UserArgumentResolver.java | 2 +- .../server/user/controller/UserController.java | 10 +++++----- .../server/user/{ => controller}/dto/AuthInfo.java | 2 +- .../dto/UpdateProfileHttpDto.java} | 6 +++--- .../user/dto/{SignupDto.java => SignupHttpDto.java} | 4 ++-- .../coffeemeet/server/user/service/UserService.java | 4 ++-- .../server/common/fixture/dto/SignupDtoFixture.java | 8 ++++---- .../common/fixture/dto/UpdateProfileDtoFixture.java | 8 ++++---- .../server/user/controller/UserControllerTest.java | 6 +++--- .../server/user/service/UserServiceTest.java | 2 +- 12 files changed, 28 insertions(+), 28 deletions(-) rename src/main/java/coffeemeet/server/user/{ => controller}/dto/AuthInfo.java (57%) rename src/main/java/coffeemeet/server/user/{dto/UpdateProfileDto.java => controller/dto/UpdateProfileHttpDto.java} (56%) rename src/main/java/coffeemeet/server/user/dto/{SignupDto.java => SignupHttpDto.java} (82%) diff --git a/src/main/java/coffeemeet/server/auth/controller/AuthController.java b/src/main/java/coffeemeet/server/auth/controller/AuthController.java index d2549563..75d7ce9c 100644 --- a/src/main/java/coffeemeet/server/auth/controller/AuthController.java +++ b/src/main/java/coffeemeet/server/auth/controller/AuthController.java @@ -3,7 +3,7 @@ import coffeemeet.server.auth.domain.AuthTokens; import coffeemeet.server.auth.service.AuthService; import coffeemeet.server.common.annotation.Login; -import coffeemeet.server.user.dto.AuthInfo; +import coffeemeet.server.user.controller.dto.AuthInfo; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; diff --git a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java index a544ffb5..197b8c61 100644 --- a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java +++ b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java @@ -5,7 +5,7 @@ import coffeemeet.server.certification.service.CertificationService; import coffeemeet.server.common.annotation.Login; import coffeemeet.server.common.util.FileUtils; -import coffeemeet.server.user.dto.AuthInfo; +import coffeemeet.server.user.controller.dto.AuthInfo; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java index 8a97a0a0..ca373a6a 100644 --- a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java +++ b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java @@ -4,7 +4,7 @@ import coffeemeet.server.auth.domain.RefreshToken; import coffeemeet.server.auth.repository.RefreshTokenRepository; import coffeemeet.server.common.annotation.Login; -import coffeemeet.server.user.dto.AuthInfo; +import coffeemeet.server.user.controller.dto.AuthInfo; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.core.MethodParameter; diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index a027f03e..a2aa01fe 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -6,10 +6,10 @@ import coffeemeet.server.user.controller.dto.MyProfileHttpDto; import coffeemeet.server.user.controller.dto.UserProfileHttpDto; import coffeemeet.server.user.domain.OAuthProvider; -import coffeemeet.server.user.dto.AuthInfo; +import coffeemeet.server.user.controller.dto.AuthInfo; import coffeemeet.server.user.dto.MyProfileDto; -import coffeemeet.server.user.dto.SignupDto; -import coffeemeet.server.user.dto.UpdateProfileDto; +import coffeemeet.server.user.dto.SignupHttpDto; +import coffeemeet.server.user.controller.dto.UpdateProfileHttpDto; import coffeemeet.server.user.dto.UserProfileDto.Response; import coffeemeet.server.user.service.UserService; import jakarta.validation.Valid; @@ -36,7 +36,7 @@ public class UserController { private final UserService userService; @PostMapping("/sign-up") - public ResponseEntity signup(@Valid @RequestBody SignupDto.Request request) { + public ResponseEntity signup(@Valid @RequestBody SignupHttpDto.Request request) { return ResponseEntity.ok(userService.signup(request)); } @@ -71,7 +71,7 @@ public ResponseEntity updateProfileImage( @PatchMapping("/me") public ResponseEntity updateProfileInfo(@Login AuthInfo authInfo, - @Valid @RequestBody UpdateProfileDto.Request request) { + @Valid @RequestBody UpdateProfileHttpDto.Request request) { userService.updateProfileInfo(authInfo.userId(), request.nickname(), request.interests()); return ResponseEntity.ok().build(); } diff --git a/src/main/java/coffeemeet/server/user/dto/AuthInfo.java b/src/main/java/coffeemeet/server/user/controller/dto/AuthInfo.java similarity index 57% rename from src/main/java/coffeemeet/server/user/dto/AuthInfo.java rename to src/main/java/coffeemeet/server/user/controller/dto/AuthInfo.java index fac09343..b1bbaa20 100644 --- a/src/main/java/coffeemeet/server/user/dto/AuthInfo.java +++ b/src/main/java/coffeemeet/server/user/controller/dto/AuthInfo.java @@ -1,4 +1,4 @@ -package coffeemeet.server.user.dto; +package coffeemeet.server.user.controller.dto; public record AuthInfo(Long userId, String refreshToken) { diff --git a/src/main/java/coffeemeet/server/user/dto/UpdateProfileDto.java b/src/main/java/coffeemeet/server/user/controller/dto/UpdateProfileHttpDto.java similarity index 56% rename from src/main/java/coffeemeet/server/user/dto/UpdateProfileDto.java rename to src/main/java/coffeemeet/server/user/controller/dto/UpdateProfileHttpDto.java index b7392232..e84ce0e1 100644 --- a/src/main/java/coffeemeet/server/user/dto/UpdateProfileDto.java +++ b/src/main/java/coffeemeet/server/user/controller/dto/UpdateProfileHttpDto.java @@ -1,15 +1,15 @@ -package coffeemeet.server.user.dto; +package coffeemeet.server.user.controller.dto; import coffeemeet.server.interest.domain.Keyword; import jakarta.validation.constraints.Size; import java.util.List; -public sealed interface UpdateProfileDto permits UpdateProfileDto.Request { +public sealed interface UpdateProfileHttpDto permits UpdateProfileHttpDto.Request { record Request( String nickname, @Size(min = 1, max = 3) List interests - ) implements UpdateProfileDto { + ) implements UpdateProfileHttpDto { } diff --git a/src/main/java/coffeemeet/server/user/dto/SignupDto.java b/src/main/java/coffeemeet/server/user/dto/SignupHttpDto.java similarity index 82% rename from src/main/java/coffeemeet/server/user/dto/SignupDto.java rename to src/main/java/coffeemeet/server/user/dto/SignupHttpDto.java index 911a8b3a..caf432b9 100644 --- a/src/main/java/coffeemeet/server/user/dto/SignupDto.java +++ b/src/main/java/coffeemeet/server/user/dto/SignupHttpDto.java @@ -7,7 +7,7 @@ import java.util.List; import lombok.NonNull; -public sealed interface SignupDto permits SignupDto.Request { +public sealed interface SignupHttpDto permits SignupHttpDto.Request { record Request( @NotBlank @@ -18,7 +18,7 @@ record Request( String authCode, @NonNull OAuthProvider oAuthProvider - ) implements SignupDto { + ) implements SignupHttpDto { } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 7cb35fc8..7b997b09 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -19,7 +19,7 @@ import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.dto.MyProfileDto; -import coffeemeet.server.user.dto.SignupDto; +import coffeemeet.server.user.dto.SignupHttpDto; import coffeemeet.server.user.dto.UserProfileDto; import coffeemeet.server.user.service.cq.UserCommand; import coffeemeet.server.user.service.cq.UserQuery; @@ -46,7 +46,7 @@ public class UserService { private final UserQuery userQuery; private final UserCommand userCommand; - public AuthTokens signup(SignupDto.Request request) { + public AuthTokens signup(SignupHttpDto.Request request) { Response response = oAuthService.getOAuthUserInfo(request.oAuthProvider(), request.authCode()); diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/SignupDtoFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/SignupDtoFixture.java index c03e4e93..30993a54 100644 --- a/src/test/java/coffeemeet/server/common/fixture/dto/SignupDtoFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/dto/SignupDtoFixture.java @@ -3,15 +3,15 @@ import static org.instancio.Select.field; import coffeemeet.server.interest.domain.Keyword; -import coffeemeet.server.user.dto.SignupDto; -import coffeemeet.server.user.dto.SignupDto.Request; +import coffeemeet.server.user.dto.SignupHttpDto; +import coffeemeet.server.user.dto.SignupHttpDto.Request; import java.util.List; import org.instancio.Instancio; public class SignupDtoFixture { - public static SignupDto.Request signupDto() { - return Instancio.of(SignupDto.Request.class) + public static SignupHttpDto.Request signupDto() { + return Instancio.of(SignupHttpDto.Request.class) .set(field(Request::keywords), keywords()) .create(); } diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/UpdateProfileDtoFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/UpdateProfileDtoFixture.java index ca72e591..a045adf8 100644 --- a/src/test/java/coffeemeet/server/common/fixture/dto/UpdateProfileDtoFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/dto/UpdateProfileDtoFixture.java @@ -3,15 +3,15 @@ import static org.instancio.Select.field; import coffeemeet.server.interest.domain.Keyword; -import coffeemeet.server.user.dto.UpdateProfileDto; +import coffeemeet.server.user.controller.dto.UpdateProfileHttpDto; import java.util.List; import org.instancio.Instancio; public class UpdateProfileDtoFixture { - public static UpdateProfileDto.Request updateProfileDtoRequest() { - return Instancio.of(UpdateProfileDto.Request.class) - .set(field(UpdateProfileDto.Request::interests), keywords()) + public static UpdateProfileHttpDto.Request updateProfileDtoRequest() { + return Instancio.of(UpdateProfileHttpDto.Request.class) + .set(field(UpdateProfileHttpDto.Request::interests), keywords()) .create(); } diff --git a/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java index 3b71887f..1d377d27 100644 --- a/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java +++ b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java @@ -39,8 +39,8 @@ import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.dto.MyProfileDto.Response; -import coffeemeet.server.user.dto.SignupDto; -import coffeemeet.server.user.dto.UpdateProfileDto.Request; +import coffeemeet.server.user.dto.SignupHttpDto; +import coffeemeet.server.user.controller.dto.UpdateProfileHttpDto.Request; import coffeemeet.server.user.dto.UserProfileDto; import com.epages.restdocs.apispec.Schema; import java.util.Optional; @@ -57,7 +57,7 @@ class UserControllerTest extends ControllerTestConfig { @Test @DisplayName("회원가입을 할 수 있다.") void signupTest() throws Exception { - SignupDto.Request request = SignupDtoFixture.signupDto(); + SignupHttpDto.Request request = SignupDtoFixture.signupDto(); AuthTokens authTokens = new AuthTokens("accessToken", "refreshToken"); given(userService.signup(any())).willReturn(authTokens); diff --git a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java index f4f95ed1..a2fc16ec 100644 --- a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java +++ b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java @@ -37,7 +37,7 @@ import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.dto.MyProfileDto; -import coffeemeet.server.user.dto.SignupDto.Request; +import coffeemeet.server.user.dto.SignupHttpDto.Request; import coffeemeet.server.user.dto.UserProfileDto.Response; import coffeemeet.server.user.service.cq.UserCommand; import coffeemeet.server.user.service.cq.UserQuery; From deaf24d215d81541331edbc5e6e34b98e55e9886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 14:10:29 +0900 Subject: [PATCH 262/311] =?UTF-8?q?test:=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/user/service/UserServiceTest.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java index a2fc16ec..47cd90a8 100644 --- a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java +++ b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java @@ -10,11 +10,13 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.verify; import coffeemeet.server.auth.domain.AuthTokens; import coffeemeet.server.auth.domain.AuthTokensGenerator; @@ -166,7 +168,7 @@ void findMyProfileTest() { .user(user) .companyEmail(new CompanyEmail("company123@gmail.com")) .businessCardUrl("businessCard") - .build(); + .build(); given(userQuery.getUserById(anyLong())).willReturn(user); given(interestQuery.getKeywordsByUserId(anyLong())).willReturn(response.interests()); @@ -247,12 +249,15 @@ void updateProfileInfo() { ArrayList newKeywords = new ArrayList<>(Arrays.asList(COOK, GAME)); given(userQuery.getUserById(any())).willReturn(user); + doNothing().when(userCommand).updateUserInfo(any(), any()); + doNothing().when(interestCommand).updateInterests(any(), any()); // when userService.updateProfileInfo(user.getId(), newNickname, newKeywords); // then - assertThat(user.getProfile().getNickname()).isEqualTo(newNickname); + verify(userCommand).updateUserInfo(any(User.class), anyString()); + verify(interestCommand).updateInterests(any(User.class), anyList()); } @DisplayName("탈퇴할 수 있다.") From 4766c7373673e4cadbd086b80d061d9fea4274ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 14:30:14 +0900 Subject: [PATCH 263/311] =?UTF-8?q?refactor:=20=EB=88=84=EB=9D=BD=EB=90=9C?= =?UTF-8?q?=20=EC=9C=A0=EC=A0=80=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/user/domain/Birth.java | 5 +-- .../coffeemeet/server/user/domain/Email.java | 7 ++-- .../server/user/domain/Profile.java | 33 ++++++++++++------- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/Birth.java b/src/main/java/coffeemeet/server/user/domain/Birth.java index 2b61ee9e..fafbbc8d 100644 --- a/src/main/java/coffeemeet/server/user/domain/Birth.java +++ b/src/main/java/coffeemeet/server/user/domain/Birth.java @@ -6,6 +6,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.NonNull; +import org.springframework.util.StringUtils; @Getter @Embeddable @@ -28,13 +29,13 @@ public Birth(@NonNull String birthYear, @NonNull String birthDay) { } private void validateYear(String birthYear) { - if (birthYear.length() != BIRTH_LENGTH) { + if (!StringUtils.hasText(birthYear) || birthYear.length() != BIRTH_LENGTH) { throw new IllegalArgumentException("올바르지 않은 연도 형식입니다."); } } private void validateDay(String birthDay) { - if (birthDay.length() != BIRTH_LENGTH) { + if (!StringUtils.hasText(birthDay) || birthDay.length() != BIRTH_LENGTH) { throw new IllegalArgumentException("올바르지 않은 날짜 형식입니다."); } } diff --git a/src/main/java/coffeemeet/server/user/domain/Email.java b/src/main/java/coffeemeet/server/user/domain/Email.java index 5af94843..8fdb719b 100644 --- a/src/main/java/coffeemeet/server/user/domain/Email.java +++ b/src/main/java/coffeemeet/server/user/domain/Email.java @@ -6,21 +6,22 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.NonNull; +import org.springframework.util.StringUtils; @Getter @Embeddable @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Email { - private String email; + private String value; public Email(@NonNull String email) { validateEmail(email); - this.email = email; + this.value = email; } private void validateEmail(String email) { - if (!Patterns.EMAIL_PATTERN.matcher(email).matches()) { + if (!StringUtils.hasText(email) || !Patterns.EMAIL_PATTERN.matcher(email).matches()) { throw new IllegalArgumentException("올바르지 않은 이메일입니다."); } } diff --git a/src/main/java/coffeemeet/server/user/domain/Profile.java b/src/main/java/coffeemeet/server/user/domain/Profile.java index b0bc1196..cccc45a0 100644 --- a/src/main/java/coffeemeet/server/user/domain/Profile.java +++ b/src/main/java/coffeemeet/server/user/domain/Profile.java @@ -8,6 +8,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.NonNull; +import org.springframework.util.StringUtils; @Getter @Embeddable @@ -35,18 +36,15 @@ public class Profile { @Builder private Profile( - @NonNull - String name, - @NonNull - String nickname, - @NonNull - Email email, - @NonNull - String profileImageUrl, - @NonNull - Birth birth + @NonNull String name, + @NonNull String nickname, + @NonNull Email email, + @NonNull String profileImageUrl, + @NonNull Birth birth ) { validateNickname(nickname); + validateName(name); + validateProfileImageUrl(profileImageUrl); this.name = name; this.nickname = nickname; this.email = email; @@ -60,13 +58,26 @@ public void updateNickname(String newNickname) { } public void updateProfileImageUrl(String newProfileImageUrl) { + validateProfileImageUrl(newProfileImageUrl); this.profileImageUrl = newProfileImageUrl; } private void validateNickname(String nickname) { - if (nickname.length() > NICKNAME_MAX_LENGTH) { + if (!StringUtils.hasText(nickname) || nickname.length() > NICKNAME_MAX_LENGTH) { throw new IllegalArgumentException("올바르지 않은 닉네임입니다."); } } + private void validateName(String name) { + if (!StringUtils.hasText(name)) { + throw new IllegalArgumentException("올바르지 않은 이름입니다."); + } + } + + private void validateProfileImageUrl(String profileImageUrl) { + if (!StringUtils.hasText(profileImageUrl)) { + throw new IllegalArgumentException("올바르지 않은 프로필 이미지 url입니다."); + } + } + } From bcbaa0b969f1933ccc815cbc7bf7994da77c560d Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 14:32:10 +0900 Subject: [PATCH 264/311] =?UTF-8?q?feat:=20InvalidInputException=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 - 유효하지 않은 입력값에 대한 커스텀 예외 --- .../common/execption/InvalidInputException.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/main/java/coffeemeet/server/common/execption/InvalidInputException.java diff --git a/src/main/java/coffeemeet/server/common/execption/InvalidInputException.java b/src/main/java/coffeemeet/server/common/execption/InvalidInputException.java new file mode 100644 index 00000000..67fadc15 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/execption/InvalidInputException.java @@ -0,0 +1,15 @@ +package coffeemeet.server.common.execption; + +import lombok.Getter; + +@Getter +public class InvalidInputException extends CoffeeMeetException { + + private final ErrorCode errorCode; + + public InvalidInputException(ErrorCode errorCode, String message) { + super(message); + this.errorCode = errorCode; + } + +} From 44b7be9d348ee832509b7ce2edac02f6b16f2861 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 14:32:50 +0900 Subject: [PATCH 265/311] =?UTF-8?q?feat:=20MessageErrorCode=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 --- .../message/exception/MessageErrorCode.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/main/java/coffeemeet/server/chatting/message/exception/MessageErrorCode.java diff --git a/src/main/java/coffeemeet/server/chatting/message/exception/MessageErrorCode.java b/src/main/java/coffeemeet/server/chatting/message/exception/MessageErrorCode.java new file mode 100644 index 00000000..70587f3b --- /dev/null +++ b/src/main/java/coffeemeet/server/chatting/message/exception/MessageErrorCode.java @@ -0,0 +1,26 @@ +package coffeemeet.server.chatting.message.exception; + +import coffeemeet.server.common.execption.ErrorCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum MessageErrorCode implements ErrorCode { + INVALID_MESSAGE("CM000", "유효하지 않은 메세지 형식입니다."), + ; + + private final String errorCode; + private final String message; + + @Override + public String code() { + return errorCode; + } + + @Override + public String message() { + return message; + } + +} From 1276b98372d7ab5e1d664eaffff8e97dec5e0e55 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 14:34:10 +0900 Subject: [PATCH 266/311] =?UTF-8?q?style:=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EA=B2=BD=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../message}/domain/ChattingMessage.java | 4 ++-- .../message}/domain/ChattingMessageHistory.java | 15 +++++++++++---- .../room}/domain/ChattingRoom.java | 2 +- .../room}/domain/ChattingRoomHistory.java | 2 +- .../java/coffeemeet/server/user/domain/User.java | 2 +- .../domain/UserChattingHistory.java | 2 +- 6 files changed, 17 insertions(+), 10 deletions(-) rename src/main/java/coffeemeet/server/{chatting_message => chatting/message}/domain/ChattingMessage.java (92%) rename src/main/java/coffeemeet/server/{chatting_message_history => chatting/message}/domain/ChattingMessageHistory.java (63%) rename src/main/java/coffeemeet/server/{chatting_room => chatting/room}/domain/ChattingRoom.java (91%) rename src/main/java/coffeemeet/server/{chatting_room_history => chatting/room}/domain/ChattingRoomHistory.java (90%) diff --git a/src/main/java/coffeemeet/server/chatting_message/domain/ChattingMessage.java b/src/main/java/coffeemeet/server/chatting/message/domain/ChattingMessage.java similarity index 92% rename from src/main/java/coffeemeet/server/chatting_message/domain/ChattingMessage.java rename to src/main/java/coffeemeet/server/chatting/message/domain/ChattingMessage.java index db6ca4f2..a8201c49 100644 --- a/src/main/java/coffeemeet/server/chatting_message/domain/ChattingMessage.java +++ b/src/main/java/coffeemeet/server/chatting/message/domain/ChattingMessage.java @@ -1,6 +1,6 @@ -package coffeemeet.server.chatting_message.domain; +package coffeemeet.server.chatting.message.domain; -import coffeemeet.server.chatting_room.domain.ChattingRoom; +import coffeemeet.server.chatting.room.domain.ChattingRoom; import coffeemeet.server.common.entity.BaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; diff --git a/src/main/java/coffeemeet/server/chatting_message_history/domain/ChattingMessageHistory.java b/src/main/java/coffeemeet/server/chatting/message/domain/ChattingMessageHistory.java similarity index 63% rename from src/main/java/coffeemeet/server/chatting_message_history/domain/ChattingMessageHistory.java rename to src/main/java/coffeemeet/server/chatting/message/domain/ChattingMessageHistory.java index 7bcf098b..440325b2 100644 --- a/src/main/java/coffeemeet/server/chatting_message_history/domain/ChattingMessageHistory.java +++ b/src/main/java/coffeemeet/server/chatting/message/domain/ChattingMessageHistory.java @@ -1,7 +1,10 @@ -package coffeemeet.server.chatting_message_history.domain; +package coffeemeet.server.chatting.message.domain; -import coffeemeet.server.chatting_room_history.domain.ChattingRoomHistory; +import static coffeemeet.server.chatting.message.exception.MessageErrorCode.INVALID_MESSAGE; + +import coffeemeet.server.chatting.room.domain.ChattingRoomHistory; import coffeemeet.server.common.entity.BaseEntity; +import coffeemeet.server.common.execption.InvalidInputException; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -13,6 +16,7 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.NonNull; import org.springframework.util.StringUtils; @Entity @@ -21,6 +25,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ChattingMessageHistory extends BaseEntity { + public static final String INVALID_CHATTING_MESSAGE = "입력된 (%s)는 올바르지 않은 메시지입니다."; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -32,7 +37,8 @@ public class ChattingMessageHistory extends BaseEntity { @JoinColumn(name = "chatting_room_history_id", nullable = false) private ChattingRoomHistory chattingRoomHistory; - public ChattingMessageHistory(String message, ChattingRoomHistory chattingRoomHistory) { + public ChattingMessageHistory(@NonNull String message, + @NonNull ChattingRoomHistory chattingRoomHistory) { validateMessage(message); this.message = message; this.chattingRoomHistory = chattingRoomHistory; @@ -40,7 +46,8 @@ public ChattingMessageHistory(String message, ChattingRoomHistory chattingRoomHi private void validateMessage(String message) { if (!StringUtils.hasText(message)) { - throw new IllegalArgumentException("올바르지 않은 메시지입니다."); + throw new InvalidInputException(INVALID_MESSAGE, + String.format(INVALID_CHATTING_MESSAGE, message)); } } diff --git a/src/main/java/coffeemeet/server/chatting_room/domain/ChattingRoom.java b/src/main/java/coffeemeet/server/chatting/room/domain/ChattingRoom.java similarity index 91% rename from src/main/java/coffeemeet/server/chatting_room/domain/ChattingRoom.java rename to src/main/java/coffeemeet/server/chatting/room/domain/ChattingRoom.java index 64586482..ee0a12ca 100644 --- a/src/main/java/coffeemeet/server/chatting_room/domain/ChattingRoom.java +++ b/src/main/java/coffeemeet/server/chatting/room/domain/ChattingRoom.java @@ -1,4 +1,4 @@ -package coffeemeet.server.chatting_room.domain; +package coffeemeet.server.chatting.room.domain; import coffeemeet.server.common.entity.BaseEntity; import jakarta.persistence.Entity; diff --git a/src/main/java/coffeemeet/server/chatting_room_history/domain/ChattingRoomHistory.java b/src/main/java/coffeemeet/server/chatting/room/domain/ChattingRoomHistory.java similarity index 90% rename from src/main/java/coffeemeet/server/chatting_room_history/domain/ChattingRoomHistory.java rename to src/main/java/coffeemeet/server/chatting/room/domain/ChattingRoomHistory.java index edadac32..cb49b645 100644 --- a/src/main/java/coffeemeet/server/chatting_room_history/domain/ChattingRoomHistory.java +++ b/src/main/java/coffeemeet/server/chatting/room/domain/ChattingRoomHistory.java @@ -1,4 +1,4 @@ -package coffeemeet.server.chatting_room_history.domain; +package coffeemeet.server.chatting.room.domain; import coffeemeet.server.common.entity.BaseEntity; import jakarta.persistence.Entity; diff --git a/src/main/java/coffeemeet/server/user/domain/User.java b/src/main/java/coffeemeet/server/user/domain/User.java index 08ddcb10..a156d0a8 100644 --- a/src/main/java/coffeemeet/server/user/domain/User.java +++ b/src/main/java/coffeemeet/server/user/domain/User.java @@ -1,6 +1,6 @@ package coffeemeet.server.user.domain; -import coffeemeet.server.chatting_room.domain.ChattingRoom; +import coffeemeet.server.chatting.room.domain.ChattingRoom; import coffeemeet.server.common.entity.AdvancedBaseEntity; import jakarta.persistence.Column; import jakarta.persistence.Embedded; diff --git a/src/main/java/coffeemeet/server/user_chatting_history/domain/UserChattingHistory.java b/src/main/java/coffeemeet/server/user_chatting_history/domain/UserChattingHistory.java index c968c9c0..ca81c79b 100644 --- a/src/main/java/coffeemeet/server/user_chatting_history/domain/UserChattingHistory.java +++ b/src/main/java/coffeemeet/server/user_chatting_history/domain/UserChattingHistory.java @@ -1,6 +1,6 @@ package coffeemeet.server.user_chatting_history.domain; -import coffeemeet.server.chatting_room_history.domain.ChattingRoomHistory; +import coffeemeet.server.chatting.room.domain.ChattingRoomHistory; import coffeemeet.server.common.entity.BaseEntity; import coffeemeet.server.user.domain.User; import jakarta.persistence.Entity; From 8aa83f2228ae9d27c59884c966769993e719e3e6 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 14:35:31 +0900 Subject: [PATCH 267/311] =?UTF-8?q?feat:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chatting/message/domain/ChattingMessage.java | 11 +++++++++-- .../message/domain/ChattingMessageHistory.java | 3 ++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/coffeemeet/server/chatting/message/domain/ChattingMessage.java b/src/main/java/coffeemeet/server/chatting/message/domain/ChattingMessage.java index a8201c49..d93b98ed 100644 --- a/src/main/java/coffeemeet/server/chatting/message/domain/ChattingMessage.java +++ b/src/main/java/coffeemeet/server/chatting/message/domain/ChattingMessage.java @@ -1,7 +1,10 @@ package coffeemeet.server.chatting.message.domain; +import static coffeemeet.server.chatting.message.exception.MessageErrorCode.INVALID_MESSAGE; + import coffeemeet.server.chatting.room.domain.ChattingRoom; import coffeemeet.server.common.entity.BaseEntity; +import coffeemeet.server.common.execption.InvalidInputException; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -14,6 +17,7 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.NonNull; import org.springframework.util.StringUtils; @Entity @@ -22,6 +26,8 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ChattingMessage extends BaseEntity { + private static final String INVALID_CHATTING_MESSAGE = "입력된 (%s)는 올바르지 않은 메시지입니다."; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -33,7 +39,7 @@ public class ChattingMessage extends BaseEntity { @JoinColumn(name = "chatting_room_id", nullable = false) private ChattingRoom chattingRoom; - public ChattingMessage(String message, ChattingRoom chattingRoom) { + public ChattingMessage(@NonNull String message, @NonNull ChattingRoom chattingRoom) { validateMessage(message); this.message = message; this.chattingRoom = chattingRoom; @@ -41,7 +47,8 @@ public ChattingMessage(String message, ChattingRoom chattingRoom) { private void validateMessage(String message) { if (!StringUtils.hasText(message)) { - throw new IllegalArgumentException("올바르지 않은 메시지입니다."); + throw new InvalidInputException(INVALID_MESSAGE, + String.format(INVALID_CHATTING_MESSAGE, message)); } } diff --git a/src/main/java/coffeemeet/server/chatting/message/domain/ChattingMessageHistory.java b/src/main/java/coffeemeet/server/chatting/message/domain/ChattingMessageHistory.java index 440325b2..8ac78084 100644 --- a/src/main/java/coffeemeet/server/chatting/message/domain/ChattingMessageHistory.java +++ b/src/main/java/coffeemeet/server/chatting/message/domain/ChattingMessageHistory.java @@ -25,7 +25,8 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ChattingMessageHistory extends BaseEntity { - public static final String INVALID_CHATTING_MESSAGE = "입력된 (%s)는 올바르지 않은 메시지입니다."; + private static final String INVALID_CHATTING_MESSAGE = "입력된 (%s)는 올바르지 않은 메시지입니다."; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; From 1ab06dda85987c57238537ee3b125131cec1be5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 14:31:35 +0900 Subject: [PATCH 268/311] =?UTF-8?q?refactor:=20=EC=9C=A0=EC=A0=80=20DTO=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=9D=B4=EB=8F=99=20=EB=B0=8F=20?= =?UTF-8?q?=EC=A0=84=EB=8B=AC=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/controller/UserController.java | 6 ++++-- .../user/{ => controller}/dto/SignupHttpDto.java | 2 +- .../java/coffeemeet/server/user/domain/Email.java | 4 ++-- .../server/user/service/UserService.java | 14 +++++++------- .../common/fixture/dto/SignupDtoFixture.java | 4 ++-- .../server/user/controller/UserControllerTest.java | 4 ++-- .../server/user/service/UserServiceTest.java | 5 +++-- 7 files changed, 21 insertions(+), 18 deletions(-) rename src/main/java/coffeemeet/server/user/{ => controller}/dto/SignupHttpDto.java (92%) diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index a2aa01fe..3f083200 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -8,7 +8,7 @@ import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.controller.dto.AuthInfo; import coffeemeet.server.user.dto.MyProfileDto; -import coffeemeet.server.user.dto.SignupHttpDto; +import coffeemeet.server.user.controller.dto.SignupHttpDto; import coffeemeet.server.user.controller.dto.UpdateProfileHttpDto; import coffeemeet.server.user.dto.UserProfileDto.Response; import coffeemeet.server.user.service.UserService; @@ -37,7 +37,9 @@ public class UserController { @PostMapping("/sign-up") public ResponseEntity signup(@Valid @RequestBody SignupHttpDto.Request request) { - return ResponseEntity.ok(userService.signup(request)); + return ResponseEntity.ok( + userService.signup(request.nickname(), request.keywords(), request.authCode(), + request.oAuthProvider())); } @GetMapping("/login/{oAuthProvider}") diff --git a/src/main/java/coffeemeet/server/user/dto/SignupHttpDto.java b/src/main/java/coffeemeet/server/user/controller/dto/SignupHttpDto.java similarity index 92% rename from src/main/java/coffeemeet/server/user/dto/SignupHttpDto.java rename to src/main/java/coffeemeet/server/user/controller/dto/SignupHttpDto.java index caf432b9..27c5fe4b 100644 --- a/src/main/java/coffeemeet/server/user/dto/SignupHttpDto.java +++ b/src/main/java/coffeemeet/server/user/controller/dto/SignupHttpDto.java @@ -1,4 +1,4 @@ -package coffeemeet.server.user.dto; +package coffeemeet.server.user.controller.dto; import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.user.domain.OAuthProvider; diff --git a/src/main/java/coffeemeet/server/user/domain/Email.java b/src/main/java/coffeemeet/server/user/domain/Email.java index 8fdb719b..2db64cdb 100644 --- a/src/main/java/coffeemeet/server/user/domain/Email.java +++ b/src/main/java/coffeemeet/server/user/domain/Email.java @@ -13,11 +13,11 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Email { - private String value; + private String email; public Email(@NonNull String email) { validateEmail(email); - this.value = email; + this.email = email; } private void validateEmail(String email) { diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 7b997b09..4936220c 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -19,7 +19,6 @@ import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.dto.MyProfileDto; -import coffeemeet.server.user.dto.SignupHttpDto; import coffeemeet.server.user.dto.UserProfileDto; import coffeemeet.server.user.service.cq.UserCommand; import coffeemeet.server.user.service.cq.UserQuery; @@ -46,17 +45,18 @@ public class UserService { private final UserQuery userQuery; private final UserCommand userCommand; - public AuthTokens signup(SignupHttpDto.Request request) { - Response response = oAuthService.getOAuthUserInfo(request.oAuthProvider(), - request.authCode()); + public AuthTokens signup(String nickname, List keywords, String authCode, + OAuthProvider oAuthProvider) { + Response response = oAuthService.getOAuthUserInfo(oAuthProvider, + authCode); userQuery.hasDuplicatedUser(response.oAuthProvider(), response.oAuthProviderId()); - userQuery.hasDuplicatedNickname(request.nickname()); + userQuery.hasDuplicatedNickname(nickname); String profileImage = getProfileImageOrDefault(response.profileImage()); User user = new User(new OAuthInfo(response.oAuthProvider(), response.oAuthProviderId()), - Profile.builder().name(response.name()).nickname(request.nickname()) + Profile.builder().name(response.name()).nickname(nickname) .email(new Email(response.email())) .profileImageUrl(profileImage) .birth(new Birth(response.birthYear(), response.birthDay())).build()); @@ -64,7 +64,7 @@ public AuthTokens signup(SignupHttpDto.Request request) { Long userId = userCommand.saveUser(user); User newUser = userQuery.getUserById(userId); - interestCommand.saveAll(request.keywords(), newUser); + interestCommand.saveAll(keywords, newUser); return authTokensGenerator.generate(newUser.getId()); } diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/SignupDtoFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/SignupDtoFixture.java index 30993a54..49b7c288 100644 --- a/src/test/java/coffeemeet/server/common/fixture/dto/SignupDtoFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/dto/SignupDtoFixture.java @@ -3,8 +3,8 @@ import static org.instancio.Select.field; import coffeemeet.server.interest.domain.Keyword; -import coffeemeet.server.user.dto.SignupHttpDto; -import coffeemeet.server.user.dto.SignupHttpDto.Request; +import coffeemeet.server.user.controller.dto.SignupHttpDto; +import coffeemeet.server.user.controller.dto.SignupHttpDto.Request; import java.util.List; import org.instancio.Instancio; diff --git a/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java index 1d377d27..dfd2d45b 100644 --- a/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java +++ b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java @@ -39,7 +39,7 @@ import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.dto.MyProfileDto.Response; -import coffeemeet.server.user.dto.SignupHttpDto; +import coffeemeet.server.user.controller.dto.SignupHttpDto; import coffeemeet.server.user.controller.dto.UpdateProfileHttpDto.Request; import coffeemeet.server.user.dto.UserProfileDto; import com.epages.restdocs.apispec.Schema; @@ -60,7 +60,7 @@ void signupTest() throws Exception { SignupHttpDto.Request request = SignupDtoFixture.signupDto(); AuthTokens authTokens = new AuthTokens("accessToken", "refreshToken"); - given(userService.signup(any())).willReturn(authTokens); + given(userService.signup(any(), any(), any(), any())).willReturn(authTokens); mockMvc.perform(post("/api/v1/users/sign-up") .contentType(MediaType.APPLICATION_JSON) diff --git a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java index 47cd90a8..9bbcdee0 100644 --- a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java +++ b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java @@ -39,7 +39,7 @@ import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.dto.MyProfileDto; -import coffeemeet.server.user.dto.SignupHttpDto.Request; +import coffeemeet.server.user.controller.dto.SignupHttpDto.Request; import coffeemeet.server.user.dto.UserProfileDto.Response; import coffeemeet.server.user.service.cq.UserCommand; import coffeemeet.server.user.service.cq.UserQuery; @@ -102,7 +102,8 @@ void signupTest() { given(authTokensGenerator.generate(user.getId())).willReturn(authTokens); // when - AuthTokens result = userService.signup(request); + AuthTokens result = userService.signup(request.nickname(), request.keywords(), + request.authCode(), request.oAuthProvider()); // then assertThat(result.accessToken()).isEqualTo(authTokens.accessToken()); From 1a805fc76e1a998e244288907e2a5a321f132d17 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 14:39:57 +0900 Subject: [PATCH 269/311] =?UTF-8?q?feat:=20AuthErrorCode=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 --- .../server/auth/exception/AuthErrorCode.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/main/java/coffeemeet/server/auth/exception/AuthErrorCode.java diff --git a/src/main/java/coffeemeet/server/auth/exception/AuthErrorCode.java b/src/main/java/coffeemeet/server/auth/exception/AuthErrorCode.java new file mode 100644 index 00000000..bc43665e --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/exception/AuthErrorCode.java @@ -0,0 +1,29 @@ +package coffeemeet.server.auth.exception; + +import coffeemeet.server.common.execption.ErrorCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum AuthErrorCode implements ErrorCode { + INVALID_LOGIN_TYPE("A000", "지원하지 않는 로그인 타입입니다."), + AUTHENTICATION_FAILED("A001", "인증이 실패했습니다."), + AUTHORIZATION_FAILED("A003", "인가에 실패했습니다."), + ALREADY_REGISTERED("A009", "이미 가입된 사용자입니다."), + DELETED_USER("A010", "탈퇴한 지 30일이 지난 사용자입니다. 다시 회원가입해 주세요."); + + private final String errorCode; + private final String message; + + @Override + public String code() { + return errorCode; + } + + @Override + public String message() { + return message; + } + +} From 7bc406983a7589386416e2d6c0ef1f97eb249420 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 14:40:17 +0900 Subject: [PATCH 270/311] =?UTF-8?q?feat:=20InvalidAuthException=20?= =?UTF-8?q?=EC=BB=A4=EC=8A=A4=ED=85=80=20=EC=98=88=EC=99=B8=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/auth/domain/JwtTokenProvider.java | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/domain/JwtTokenProvider.java b/src/main/java/coffeemeet/server/auth/domain/JwtTokenProvider.java index 2b6fb6c4..241e07dd 100644 --- a/src/main/java/coffeemeet/server/auth/domain/JwtTokenProvider.java +++ b/src/main/java/coffeemeet/server/auth/domain/JwtTokenProvider.java @@ -1,5 +1,8 @@ package coffeemeet.server.auth.domain; +import static coffeemeet.server.auth.exception.AuthErrorCode.AUTHENTICATION_FAILED; + +import coffeemeet.server.common.execption.InvalidAuthException; import io.jsonwebtoken.Claims; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.Jwts; @@ -8,6 +11,7 @@ import io.jsonwebtoken.UnsupportedJwtException; import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.security.Keys; +import io.jsonwebtoken.security.SignatureException; import java.security.Key; import java.util.Date; import org.springframework.beans.factory.annotation.Value; @@ -16,9 +20,11 @@ @Component public class JwtTokenProvider { - private static final String EXPIRED_TOKEN_MESSAGE = "토큰이 만료되었습니다."; - private static final String INVALID_FORMAT_TOKEN_MESSAGE = "토큰의 형식이 적절하지 않습니다."; - private static final String INVALID_STRUCTURE_TOKEN_MESSAGE = "토큰이 올바르게 구성되지 않았거나, 적절하지 않게 수정되었습니다."; + private static final String EXPIRED_TOKEN_MESSAGE = "토큰(%s)이 만료되었습니다."; + private static final String INVALID_FORMAT_TOKEN_MESSAGE = "토큰(%s)의 형식이 적절하지 않습니다."; + private static final String INVALID_STRUCTURE_TOKEN_MESSAGE = "토큰(%s)이 올바르게 구성되지 않았거나, 적절하지 않게 수정되었습니다."; + private static final String FAILED_SIGNATURE_VERIFICATION_MESSAGE = "토큰(%s)의 서명 검증에 실패하였습니다."; + private final Key key; public JwtTokenProvider(@Value("${jwt.secret-key}") String secretKey) { @@ -59,11 +65,17 @@ private Claims parseClaims(String accessToken) { .parseClaimsJws(accessToken) .getBody(); } catch (ExpiredJwtException e) { - throw new IllegalArgumentException(EXPIRED_TOKEN_MESSAGE); + throw new InvalidAuthException( + AUTHENTICATION_FAILED, EXPIRED_TOKEN_MESSAGE); } catch (UnsupportedJwtException e) { - throw new IllegalArgumentException(INVALID_FORMAT_TOKEN_MESSAGE); + throw new InvalidAuthException( + AUTHENTICATION_FAILED, INVALID_FORMAT_TOKEN_MESSAGE); } catch (MalformedJwtException e) { - throw new IllegalArgumentException(INVALID_STRUCTURE_TOKEN_MESSAGE); + throw new InvalidAuthException( + AUTHENTICATION_FAILED, INVALID_STRUCTURE_TOKEN_MESSAGE); + } catch (SignatureException e) { + throw new InvalidAuthException( + AUTHENTICATION_FAILED, FAILED_SIGNATURE_VERIFICATION_MESSAGE); } } From 580dac06280df6c00d92cd17ded100540dbb0d0b Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 14:44:58 +0900 Subject: [PATCH 271/311] =?UTF-8?q?refactor:=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EB=A9=94=EC=84=B8=EC=A7=80=EC=97=90=20(%s)=20=ED=8F=AC?= =?UTF-8?q?=EB=A9=A7=ED=8C=85=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/auth/domain/JwtTokenProvider.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/domain/JwtTokenProvider.java b/src/main/java/coffeemeet/server/auth/domain/JwtTokenProvider.java index 241e07dd..39267352 100644 --- a/src/main/java/coffeemeet/server/auth/domain/JwtTokenProvider.java +++ b/src/main/java/coffeemeet/server/auth/domain/JwtTokenProvider.java @@ -66,16 +66,20 @@ private Claims parseClaims(String accessToken) { .getBody(); } catch (ExpiredJwtException e) { throw new InvalidAuthException( - AUTHENTICATION_FAILED, EXPIRED_TOKEN_MESSAGE); + AUTHENTICATION_FAILED, + String.format(EXPIRED_TOKEN_MESSAGE, accessToken)); } catch (UnsupportedJwtException e) { throw new InvalidAuthException( - AUTHENTICATION_FAILED, INVALID_FORMAT_TOKEN_MESSAGE); + AUTHENTICATION_FAILED, + String.format(INVALID_FORMAT_TOKEN_MESSAGE, accessToken)); } catch (MalformedJwtException e) { throw new InvalidAuthException( - AUTHENTICATION_FAILED, INVALID_STRUCTURE_TOKEN_MESSAGE); + AUTHENTICATION_FAILED, + String.format(INVALID_STRUCTURE_TOKEN_MESSAGE, accessToken)); } catch (SignatureException e) { throw new InvalidAuthException( - AUTHENTICATION_FAILED, FAILED_SIGNATURE_VERIFICATION_MESSAGE); + AUTHENTICATION_FAILED, + String.format(FAILED_SIGNATURE_VERIFICATION_MESSAGE, accessToken)); } } From 3d411348659ab744db4b21dc57d37affa4c8f60c Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 14:46:40 +0900 Subject: [PATCH 272/311] =?UTF-8?q?feat:=20AuthService,=20renew()=20?= =?UTF-8?q?=EC=BB=A4=EC=8A=A4=ED=85=80=20=EC=98=88=EC=99=B8=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/auth/service/AuthService.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index 32fe3e54..a75e7f26 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -1,9 +1,12 @@ package coffeemeet.server.auth.service; +import static coffeemeet.server.auth.exception.AuthErrorCode.AUTHENTICATION_FAILED; + import coffeemeet.server.auth.domain.AuthTokens; import coffeemeet.server.auth.domain.AuthTokensGenerator; import coffeemeet.server.auth.domain.JwtTokenProvider; import coffeemeet.server.auth.repository.RefreshTokenRepository; +import coffeemeet.server.common.execption.InvalidAuthException; import coffeemeet.server.user.service.UserService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -13,7 +16,7 @@ @RequiredArgsConstructor public class AuthService { - private static final String EXPIRED_REFRESH_TOKEN_MESSAGE = "리프레시 토큰이 만료되었습니다. 다시 로그인해 주세요."; + private static final String EXPIRED_REFRESH_TOKEN_MESSAGE = "리프레시 토큰(%s)이 만료되었습니다. 다시 로그인해 주세요."; private final UserService userService; private final AuthTokensGenerator authTokensGenerator; @@ -22,7 +25,9 @@ public class AuthService { public AuthTokens renew(Long userId, String refreshToken) { if (jwtTokenProvider.isExpiredRefreshToken(refreshToken)) { - throw new IllegalArgumentException(EXPIRED_REFRESH_TOKEN_MESSAGE); + throw new InvalidAuthException( + AUTHENTICATION_FAILED, + String.format(EXPIRED_REFRESH_TOKEN_MESSAGE, refreshToken)); } else { return authTokensGenerator.reissueAccessToken(userId, refreshToken); } From 2ae4719011358503cbc6cfdc86868192bfbc5d69 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 14:52:53 +0900 Subject: [PATCH 273/311] =?UTF-8?q?feat:=20CertificationErrorCode=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 --- .../exception/CertificationErrorCode.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java diff --git a/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java b/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java new file mode 100644 index 00000000..2c24db47 --- /dev/null +++ b/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java @@ -0,0 +1,25 @@ +package coffeemeet.server.certification.exception; + +import coffeemeet.server.common.execption.ErrorCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum CertificationErrorCode implements ErrorCode { + INVALID_VERIFICATION_CODE("C004", "잘못된 인증코드입니다."); + + private final String errorCode; + private final String message; + + @Override + public String code() { + return null; + } + + @Override + public String message() { + return null; + } + +} From d26a44a549b7ace2bc84803dc327c3bb7a14ce72 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 14:53:13 +0900 Subject: [PATCH 274/311] =?UTF-8?q?feat:=20InvalidInputException=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../certification/service/CertificationService.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java index eed3a600..aa028ba2 100644 --- a/src/main/java/coffeemeet/server/certification/service/CertificationService.java +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -1,13 +1,14 @@ package coffeemeet.server.certification.service; +import static coffeemeet.server.certification.exception.CertificationErrorCode.INVALID_VERIFICATION_CODE; import static coffeemeet.server.common.media.S3MediaService.KeyType.BUSINESS_CARD; import coffeemeet.server.certification.domain.CompanyEmail; import coffeemeet.server.certification.domain.Department; import coffeemeet.server.certification.service.cq.CertificationCommand; -import coffeemeet.server.certification.service.cq.CertificationQuery; import coffeemeet.server.certification.service.cq.EmailVerificationCommand; import coffeemeet.server.certification.service.cq.EmailVerificationQuery; +import coffeemeet.server.common.execption.InvalidInputException; import coffeemeet.server.common.media.EmailService; import coffeemeet.server.common.media.S3MediaService; import coffeemeet.server.common.util.FileUtils; @@ -22,14 +23,13 @@ @RequiredArgsConstructor public class CertificationService { - private static final String WRONG_VERIFICATION_CODE = "잘못된 인증코드입니다."; + private static final String WRONG_VERIFICATION_CODE_MESSAGE = "사용자(%s)가 잘못된 인증코드(%s)를 입력했습니다."; private static final RandomGenerator RANDOM_GENERATOR = RandomGenerator.getDefault(); private final S3MediaService s3MediaService; private final EmailService emailService; private final UserQuery userQuery; private final CertificationCommand certificationCommand; - private final CertificationQuery certificationQuery; private final EmailVerificationCommand emailVerificationCommand; private final EmailVerificationQuery emailVerificationQuery; @@ -67,7 +67,8 @@ public void sendVerificationMail(Long userId, String email) { public void compareCode(Long userId, String verificationCode) { String correctCode = emailVerificationQuery.getCodeById(userId); if (!correctCode.equals(verificationCode)) { - throw new IllegalArgumentException(WRONG_VERIFICATION_CODE); + throw new InvalidInputException(INVALID_VERIFICATION_CODE, + String.format(WRONG_VERIFICATION_CODE_MESSAGE, userId, verificationCode)); } } From fec0dcf4de193ea6568e67cc2542b75735011272 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 14:59:25 +0900 Subject: [PATCH 275/311] =?UTF-8?q?feat:=20EXISTED=5FCOMPANY=5FEMAIL=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/certification/exception/CertificationErrorCode.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java b/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java index 2c24db47..5fbb3327 100644 --- a/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java +++ b/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java @@ -7,6 +7,7 @@ @Getter @RequiredArgsConstructor public enum CertificationErrorCode implements ErrorCode { + EXISTED_COMPANY_EMAIL("C000", "이메일이 중복됩니다."), INVALID_VERIFICATION_CODE("C004", "잘못된 인증코드입니다."); private final String errorCode; From b9ad0083f97ed3bb5adcf48c4e96d5dc90269afc Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 14:59:43 +0900 Subject: [PATCH 276/311] =?UTF-8?q?feat:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../certification/service/cq/CertificationCommand.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java b/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java index 2767d1f4..791b9afd 100644 --- a/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java +++ b/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java @@ -1,9 +1,12 @@ package coffeemeet.server.certification.service.cq; +import static coffeemeet.server.certification.exception.CertificationErrorCode.EXISTED_COMPANY_EMAIL; + import coffeemeet.server.certification.domain.Certification; import coffeemeet.server.certification.domain.CompanyEmail; import coffeemeet.server.certification.domain.Department; import coffeemeet.server.certification.repository.CertificationRepository; +import coffeemeet.server.common.execption.InvalidInputException; import coffeemeet.server.user.domain.User; import java.util.function.Consumer; import lombok.RequiredArgsConstructor; @@ -15,7 +18,7 @@ @RequiredArgsConstructor public class CertificationCommand { - private static final String EXISTED_COMPANY_EMAIL = "이미 사용 중인 회사 이메일입니다."; + private static final String EXISTED_COMPANY_EMAIL_MESSAGE = "이미 사용 중인 회사 이메일(%s) 입니다."; private final CertificationRepository certificationRepository; @@ -33,7 +36,8 @@ public void newCertification(CompanyEmail companyEmail, String businessCardUrl, public void hasDuplicatedCompanyEmail(CompanyEmail companyEmail) { if (certificationRepository.existsByCompanyEmail(companyEmail)) { - throw new IllegalArgumentException(EXISTED_COMPANY_EMAIL); + throw new InvalidInputException(EXISTED_COMPANY_EMAIL, + String.format(EXISTED_COMPANY_EMAIL_MESSAGE, companyEmail.getValue())); } } From 6eeda0ab3b2b7f75acc178d5cf587b9ec8472287 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 15:07:02 +0900 Subject: [PATCH 277/311] =?UTF-8?q?feat:=20INVALID=5FS3=5FURL=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/common/execption/GlobalErrorCode.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/coffeemeet/server/common/execption/GlobalErrorCode.java b/src/main/java/coffeemeet/server/common/execption/GlobalErrorCode.java index 99c002da..bb2f0b0f 100644 --- a/src/main/java/coffeemeet/server/common/execption/GlobalErrorCode.java +++ b/src/main/java/coffeemeet/server/common/execption/GlobalErrorCode.java @@ -8,6 +8,7 @@ public enum GlobalErrorCode implements ErrorCode { VALIDATION_ERROR("G000", "유효하지 않은 입력입니다."), + INVALID_S3_URL("G004", "유효하지 않은 s3 url 입니다."), INTERNAL_SERVER_ERROR("G050", "예상치 못한 오류입니다."); private final String code; From e1cdd46dff1b317dc59711de4a9d0e54069c9e4b Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 15:07:11 +0900 Subject: [PATCH 278/311] =?UTF-8?q?feat:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/common/media/S3MediaService.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/common/media/S3MediaService.java b/src/main/java/coffeemeet/server/common/media/S3MediaService.java index cda107da..19d5dc43 100644 --- a/src/main/java/coffeemeet/server/common/media/S3MediaService.java +++ b/src/main/java/coffeemeet/server/common/media/S3MediaService.java @@ -1,5 +1,9 @@ package coffeemeet.server.common.media; +import static coffeemeet.server.common.execption.GlobalErrorCode.*; + +import coffeemeet.server.common.execption.GlobalErrorCode; +import coffeemeet.server.common.execption.InvalidInputException; import com.amazonaws.services.s3.AmazonS3; import java.io.File; import java.time.LocalDateTime; @@ -11,6 +15,7 @@ @Service public class S3MediaService { + private static final String INVALID_S3_URL_MESSAGE = "올바르지 않은 S3 URL(%s)입니다."; private final AmazonS3 amazonS3; private final String bucketName; @@ -42,7 +47,8 @@ public String generateKey(KeyType keyType) { public String extractKey(String s3Url, KeyType keyType) { int startIndex = s3Url.indexOf(keyType.value); if (startIndex == -1) { - throw new IllegalArgumentException("올바르지 않은 S3 URL입니다."); + throw new InvalidInputException(INVALID_S3_URL, + String.format(INVALID_S3_URL_MESSAGE, s3Url)); } return s3Url.substring(startIndex); } From 326b36891a0cec13b8bf856094339e435649366d Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 15:09:43 +0900 Subject: [PATCH 279/311] =?UTF-8?q?feat:=20CERTIFICATION=5FNOT=5FFOUND=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/certification/exception/CertificationErrorCode.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java b/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java index 5fbb3327..f6230757 100644 --- a/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java +++ b/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java @@ -8,6 +8,7 @@ @RequiredArgsConstructor public enum CertificationErrorCode implements ErrorCode { EXISTED_COMPANY_EMAIL("C000", "이메일이 중복됩니다."), + CERTIFICATION_NOT_FOUND("C004", "인증 정보를 찾을 수 없습니다."), INVALID_VERIFICATION_CODE("C004", "잘못된 인증코드입니다."); private final String errorCode; From 1d41905fd906821394ca05961da0a566c7e12aeb Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 15:09:53 +0900 Subject: [PATCH 280/311] =?UTF-8?q?feat:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../certification/service/cq/CertificationQuery.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/service/cq/CertificationQuery.java b/src/main/java/coffeemeet/server/certification/service/cq/CertificationQuery.java index 31061050..6f2625b3 100644 --- a/src/main/java/coffeemeet/server/certification/service/cq/CertificationQuery.java +++ b/src/main/java/coffeemeet/server/certification/service/cq/CertificationQuery.java @@ -1,7 +1,10 @@ package coffeemeet.server.certification.service.cq; +import static coffeemeet.server.certification.exception.CertificationErrorCode.CERTIFICATION_NOT_FOUND; + import coffeemeet.server.certification.domain.Certification; import coffeemeet.server.certification.repository.CertificationRepository; +import coffeemeet.server.common.execption.InvalidInputException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -11,13 +14,14 @@ @Transactional(readOnly = true) public class CertificationQuery { - private static final String CERTIFICATION_NOT_FOUND = "해당 사용자의 인증정보를 찾을 수 없습니다."; + private static final String CERTIFICATION_NOT_FOUND_MESSAGE = "해당 사용자(%s)의 인증정보를 찾을 수 없습니다."; private final CertificationRepository certificationRepository; public Certification getCertificationByUserId(Long userId) { return certificationRepository.findByUserId(userId) - .orElseThrow(() -> new IllegalArgumentException(CERTIFICATION_NOT_FOUND)); + .orElseThrow(() -> new InvalidInputException(CERTIFICATION_NOT_FOUND, + String.format(CERTIFICATION_NOT_FOUND_MESSAGE, userId))); } } From 471fc4e20208ebad722c29cc152faec372d0a0ed Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 15:13:57 +0900 Subject: [PATCH 281/311] =?UTF-8?q?feat:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/common/UserArgumentResolver.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java index 8a97a0a0..465d743a 100644 --- a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java +++ b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java @@ -1,9 +1,13 @@ package coffeemeet.server.common; +import static coffeemeet.server.auth.exception.AuthErrorCode.*; + import coffeemeet.server.auth.domain.JwtTokenProvider; import coffeemeet.server.auth.domain.RefreshToken; +import coffeemeet.server.auth.exception.AuthErrorCode; import coffeemeet.server.auth.repository.RefreshTokenRepository; import coffeemeet.server.common.annotation.Login; +import coffeemeet.server.common.execption.InvalidInputException; import coffeemeet.server.user.dto.AuthInfo; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; @@ -18,7 +22,7 @@ @RequiredArgsConstructor public class UserArgumentResolver implements HandlerMethodArgumentResolver { - public static final String USER_AUTHENTICATION_FAILED_MESSAGE = "사용자(%s)의 재인증(로그인)이 필요합니다."; + private static final String USER_AUTHENTICATION_FAILED_MESSAGE = "사용자(%s)의 재인증(로그인)이 필요합니다."; private static final String HEADER_AUTHENTICATION_FAILED_MESSAGE = "(%s)는 잘못된 권한 헤더입니다."; private final JwtTokenProvider jwtTokenProvider; @@ -42,15 +46,17 @@ public AuthInfo resolveArgument(MethodParameter parameter, ModelAndViewContainer RefreshToken refreshToken = getRefreshToken(userId); return new AuthInfo(userId, refreshToken.getValue()); } - throw new IllegalArgumentException( + throw new InvalidInputException( + AUTHENTICATION_FAILED, String.format(HEADER_AUTHENTICATION_FAILED_MESSAGE, authHeader) ); } private RefreshToken getRefreshToken(Long userId) { return refreshTokenRepository.findById(userId) - .orElseThrow(() -> new IllegalArgumentException(String.format( - USER_AUTHENTICATION_FAILED_MESSAGE, userId))); + .orElseThrow(() -> new InvalidInputException( + AUTHENTICATION_FAILED, + String.format(USER_AUTHENTICATION_FAILED_MESSAGE, userId))); } } From 4ad786ce9b0aaf857191e47f26708556e467bb59 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 15:16:55 +0900 Subject: [PATCH 282/311] =?UTF-8?q?feat:=20VERIFICATION=5FCODE=5FNOT=5FFOU?= =?UTF-8?q?ND=20=EC=97=90=EB=9F=AC=20=EC=BD=94=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/certification/exception/CertificationErrorCode.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java b/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java index f6230757..5d215835 100644 --- a/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java +++ b/src/main/java/coffeemeet/server/certification/exception/CertificationErrorCode.java @@ -9,6 +9,7 @@ public enum CertificationErrorCode implements ErrorCode { EXISTED_COMPANY_EMAIL("C000", "이메일이 중복됩니다."), CERTIFICATION_NOT_FOUND("C004", "인증 정보를 찾을 수 없습니다."), + VERIFICATION_CODE_NOT_FOUND("C004", "메일 인증 코드를 찾을 수 없습니다."), INVALID_VERIFICATION_CODE("C004", "잘못된 인증코드입니다."); private final String errorCode; From 192e6a4e3994f39e98aec60edd5405046ec1c330 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 15:17:08 +0900 Subject: [PATCH 283/311] =?UTF-8?q?feat:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../certification/service/cq/EmailVerificationQuery.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/service/cq/EmailVerificationQuery.java b/src/main/java/coffeemeet/server/certification/service/cq/EmailVerificationQuery.java index 8ac135bf..2cfed34f 100644 --- a/src/main/java/coffeemeet/server/certification/service/cq/EmailVerificationQuery.java +++ b/src/main/java/coffeemeet/server/certification/service/cq/EmailVerificationQuery.java @@ -1,7 +1,10 @@ package coffeemeet.server.certification.service.cq; +import static coffeemeet.server.certification.exception.CertificationErrorCode.VERIFICATION_CODE_NOT_FOUND; + import coffeemeet.server.certification.domain.EmailVerification; import coffeemeet.server.certification.repository.EmailVerificationRepository; +import coffeemeet.server.common.execption.InvalidInputException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -9,13 +12,15 @@ @RequiredArgsConstructor public class EmailVerificationQuery { - private static final String VERIFICATION_CODE_NOT_FOUND = "인증코드 기간이 만료되었거나 해당 유저가 인증 번호를 요청한 기록이 없습니다."; + private static final String VERIFICATION_CODE_NOT_FOUND_MESSAGE = "인증코드 기간이 만료되었거나 해당 유저(%s)가 인증 번호를 요청한 기록이 없습니다."; private final EmailVerificationRepository emailVerificationRepository; public String getCodeById(Long userId) { EmailVerification emailVerification = emailVerificationRepository.findById(userId) - .orElseThrow(() -> new IllegalArgumentException(VERIFICATION_CODE_NOT_FOUND)); + .orElseThrow(() -> new InvalidInputException( + VERIFICATION_CODE_NOT_FOUND, + String.format(VERIFICATION_CODE_NOT_FOUND_MESSAGE, userId))); return emailVerification.getCode(); } From c9f9a6d6e5c499d533728e5694d8a0e70bba7c07 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 15:19:03 +0900 Subject: [PATCH 284/311] =?UTF-8?q?feat:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oauth/authcode/AuthCodeRequestUrlProviderComposite.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderComposite.java b/src/main/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderComposite.java index 290c7edb..61674b98 100644 --- a/src/main/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderComposite.java +++ b/src/main/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderComposite.java @@ -1,5 +1,7 @@ package coffeemeet.server.oauth.authcode; +import coffeemeet.server.auth.exception.AuthErrorCode; +import coffeemeet.server.common.execption.InvalidAuthException; import coffeemeet.server.user.domain.OAuthProvider; import java.util.Map; import java.util.Optional; @@ -29,7 +31,8 @@ public String provide(OAuthProvider oAuthProvider) { private AuthCodeRequestUrlProvider getProvider(OAuthProvider oAuthProvider) { return Optional.ofNullable(mapping.get(oAuthProvider)) - .orElseThrow(() -> new IllegalArgumentException( + .orElseThrow(() -> new InvalidAuthException( + AuthErrorCode.INVALID_LOGIN_TYPE, String.format(INVALID_LOGIN_TYPE_MESSAGE, oAuthProvider) ) ); From e2b9e0355d86cab8b2852f76562a10e936e7cf94 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 15:20:46 +0900 Subject: [PATCH 285/311] =?UTF-8?q?feat:=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oauth/authcode/AuthCodeRequestUrlProviderComposite.java | 5 +++-- .../server/oauth/client/OAuthMemberClientComposite.java | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderComposite.java b/src/main/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderComposite.java index 61674b98..ca79b118 100644 --- a/src/main/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderComposite.java +++ b/src/main/java/coffeemeet/server/oauth/authcode/AuthCodeRequestUrlProviderComposite.java @@ -1,6 +1,7 @@ package coffeemeet.server.oauth.authcode; -import coffeemeet.server.auth.exception.AuthErrorCode; +import static coffeemeet.server.auth.exception.AuthErrorCode.INVALID_LOGIN_TYPE; + import coffeemeet.server.common.execption.InvalidAuthException; import coffeemeet.server.user.domain.OAuthProvider; import java.util.Map; @@ -32,7 +33,7 @@ public String provide(OAuthProvider oAuthProvider) { private AuthCodeRequestUrlProvider getProvider(OAuthProvider oAuthProvider) { return Optional.ofNullable(mapping.get(oAuthProvider)) .orElseThrow(() -> new InvalidAuthException( - AuthErrorCode.INVALID_LOGIN_TYPE, + INVALID_LOGIN_TYPE, String.format(INVALID_LOGIN_TYPE_MESSAGE, oAuthProvider) ) ); diff --git a/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java b/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java index b240569b..21792220 100644 --- a/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java +++ b/src/main/java/coffeemeet/server/oauth/client/OAuthMemberClientComposite.java @@ -1,5 +1,8 @@ package coffeemeet.server.oauth.client; +import static coffeemeet.server.auth.exception.AuthErrorCode.INVALID_LOGIN_TYPE; + +import coffeemeet.server.common.execption.InvalidAuthException; import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import coffeemeet.server.user.domain.OAuthProvider; import java.util.Map; @@ -27,7 +30,8 @@ public OAuthUserInfoDto.Response fetch(OAuthProvider oAuthProvider, String authC private OAuthMemberClient getClient(OAuthProvider oAuthProvider) { return Optional.ofNullable(mapping.get(oAuthProvider)) - .orElseThrow(() -> new IllegalArgumentException( + .orElseThrow(() -> new InvalidAuthException( + INVALID_LOGIN_TYPE, String.format(INVALID_LOGIN_TYPE_MESSAGE, oAuthProvider)) ); } From 2deff4541d248feed435575b98d28d74fc5529e0 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 15:21:03 +0900 Subject: [PATCH 286/311] style: code formatting --- .../java/coffeemeet/server/common/UserArgumentResolver.java | 3 +-- .../java/coffeemeet/server/common/media/S3MediaService.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java index 465d743a..d504a30b 100644 --- a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java +++ b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java @@ -1,10 +1,9 @@ package coffeemeet.server.common; -import static coffeemeet.server.auth.exception.AuthErrorCode.*; +import static coffeemeet.server.auth.exception.AuthErrorCode.AUTHENTICATION_FAILED; import coffeemeet.server.auth.domain.JwtTokenProvider; import coffeemeet.server.auth.domain.RefreshToken; -import coffeemeet.server.auth.exception.AuthErrorCode; import coffeemeet.server.auth.repository.RefreshTokenRepository; import coffeemeet.server.common.annotation.Login; import coffeemeet.server.common.execption.InvalidInputException; diff --git a/src/main/java/coffeemeet/server/common/media/S3MediaService.java b/src/main/java/coffeemeet/server/common/media/S3MediaService.java index 19d5dc43..b2724760 100644 --- a/src/main/java/coffeemeet/server/common/media/S3MediaService.java +++ b/src/main/java/coffeemeet/server/common/media/S3MediaService.java @@ -1,8 +1,7 @@ package coffeemeet.server.common.media; -import static coffeemeet.server.common.execption.GlobalErrorCode.*; +import static coffeemeet.server.common.execption.GlobalErrorCode.INVALID_S3_URL; -import coffeemeet.server.common.execption.GlobalErrorCode; import coffeemeet.server.common.execption.InvalidInputException; import com.amazonaws.services.s3.AmazonS3; import java.io.File; From 5d5fdec024366caec0d7fa3a7464fb1274e33ea6 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 15:21:54 +0900 Subject: [PATCH 287/311] =?UTF-8?q?refactor:=20=EC=A0=91=EA=B7=BC=20?= =?UTF-8?q?=EC=A0=9C=EC=96=B4=EC=9E=90=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/coffeemeet/server/auth/service/AuthServiceTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/coffeemeet/server/auth/service/AuthServiceTest.java b/src/test/java/coffeemeet/server/auth/service/AuthServiceTest.java index d02f6298..a5628fbf 100644 --- a/src/test/java/coffeemeet/server/auth/service/AuthServiceTest.java +++ b/src/test/java/coffeemeet/server/auth/service/AuthServiceTest.java @@ -23,7 +23,8 @@ @ExtendWith(MockitoExtension.class) class AuthServiceTest { - public static final String REFRESH_TOKEN = "Bearer aaaaaaaa.bbbbbbb.ccccccc"; + private static final String REFRESH_TOKEN = "Bearer aaaaaaaa.bbbbbbb.ccccccc"; + @InjectMocks private AuthService authService; From cc9e4b50aedf24c8b978c9733f27b2fdf2cceaea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 15:22:51 +0900 Subject: [PATCH 288/311] =?UTF-8?q?test:=20UserService=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/service/UserServiceTest.java | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java index 9bbcdee0..bb003232 100644 --- a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java +++ b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java @@ -6,7 +6,6 @@ import static coffeemeet.server.interest.domain.Keyword.COOK; import static coffeemeet.server.interest.domain.Keyword.GAME; import static coffeemeet.server.user.domain.OAuthProvider.KAKAO; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; import static org.mockito.ArgumentMatchers.any; @@ -14,8 +13,7 @@ import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doThrow; +import static org.mockito.BDDMockito.willDoNothing; import static org.mockito.Mockito.verify; import coffeemeet.server.auth.domain.AuthTokens; @@ -98,7 +96,7 @@ void signupTest() { given(oAuthService.getOAuthUserInfo(any(), any())).willReturn(response); given(userCommand.saveUser(any(User.class))).willReturn(user.getId()); given(userQuery.getUserById(user.getId())).willReturn(user); - doNothing().when(interestCommand).saveAll(any(), any()); + willDoNothing().given(interestCommand).saveAll(any(), any()); given(authTokensGenerator.generate(user.getId())).willReturn(authTokens); // when @@ -250,8 +248,8 @@ void updateProfileInfo() { ArrayList newKeywords = new ArrayList<>(Arrays.asList(COOK, GAME)); given(userQuery.getUserById(any())).willReturn(user); - doNothing().when(userCommand).updateUserInfo(any(), any()); - doNothing().when(interestCommand).updateInterests(any(), any()); + willDoNothing().given(userCommand).updateUserInfo(any(), any()); + willDoNothing().given(interestCommand).updateInterests(any(), any()); // when userService.updateProfileInfo(user.getId(), newNickname, newKeywords); @@ -267,17 +265,13 @@ void deleteUser() { // given User user = user(); - doNothing().when(userCommand).deleteUser(user.getId()); - given(userQuery.getUserById(user.getId())).willThrow( - new IllegalArgumentException()); + willDoNothing().given(userCommand).deleteUser(user.getId()); // when userService.deleteUser(user.getId()); // then - assertThatThrownBy(() -> userQuery.getUserById(user.getId())).isInstanceOf( - IllegalArgumentException.class); - + assertThat(true).isTrue(); } @DisplayName("닉네임 중복을 검사할 수 있다.") @@ -287,11 +281,13 @@ void checkDuplicatedNickname() { User user = user(); String nickname = user.getProfile().getNickname(); - doThrow(new IllegalArgumentException()).when(userQuery).hasDuplicatedNickname(nickname); + willDoNothing().given(userQuery).hasDuplicatedNickname(nickname); // when - assertThatThrownBy(() -> userService.checkDuplicatedNickname(nickname)) - .isInstanceOf(IllegalArgumentException.class); + userService.checkDuplicatedNickname(nickname); + + // then + assertThat(true).isTrue(); } } From 5c9f2be37aadd2c620b9dd7a19cbce6efcc81c59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 15:26:53 +0900 Subject: [PATCH 289/311] =?UTF-8?q?refactor:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../execption/DuplicatedDataException.java | 15 ++++++++ .../execption/InvalidInputException.java | 15 ++++++++ .../coffeemeet/server/user/domain/Birth.java | 10 ++++-- .../coffeemeet/server/user/domain/Email.java | 7 +++- .../server/user/domain/Profile.java | 15 ++++++-- .../server/user/exception/UserErrorCode.java | 34 +++++++++++++++++++ .../server/user/service/cq/UserQuery.java | 22 +++++++----- 7 files changed, 104 insertions(+), 14 deletions(-) create mode 100644 src/main/java/coffeemeet/server/common/execption/DuplicatedDataException.java create mode 100644 src/main/java/coffeemeet/server/common/execption/InvalidInputException.java create mode 100644 src/main/java/coffeemeet/server/user/exception/UserErrorCode.java diff --git a/src/main/java/coffeemeet/server/common/execption/DuplicatedDataException.java b/src/main/java/coffeemeet/server/common/execption/DuplicatedDataException.java new file mode 100644 index 00000000..e1c1c244 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/execption/DuplicatedDataException.java @@ -0,0 +1,15 @@ +package coffeemeet.server.common.execption; + +import lombok.Getter; + +@Getter +public class DuplicatedDataException extends CoffeeMeetException { + + private final ErrorCode errorCode; + + public DuplicatedDataException(ErrorCode errorCode, String message) { + super(message); + this.errorCode = errorCode; + } + +} diff --git a/src/main/java/coffeemeet/server/common/execption/InvalidInputException.java b/src/main/java/coffeemeet/server/common/execption/InvalidInputException.java new file mode 100644 index 00000000..67fadc15 --- /dev/null +++ b/src/main/java/coffeemeet/server/common/execption/InvalidInputException.java @@ -0,0 +1,15 @@ +package coffeemeet.server.common.execption; + +import lombok.Getter; + +@Getter +public class InvalidInputException extends CoffeeMeetException { + + private final ErrorCode errorCode; + + public InvalidInputException(ErrorCode errorCode, String message) { + super(message); + this.errorCode = errorCode; + } + +} diff --git a/src/main/java/coffeemeet/server/user/domain/Birth.java b/src/main/java/coffeemeet/server/user/domain/Birth.java index fafbbc8d..54346a60 100644 --- a/src/main/java/coffeemeet/server/user/domain/Birth.java +++ b/src/main/java/coffeemeet/server/user/domain/Birth.java @@ -1,5 +1,9 @@ package coffeemeet.server.user.domain; +import static coffeemeet.server.user.exception.UserErrorCode.INVALID_BIRTH_DAY; +import static coffeemeet.server.user.exception.UserErrorCode.INVALID_BIRTH_YEAR; + +import coffeemeet.server.common.execption.DataLengthExceededException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import lombok.AccessLevel; @@ -14,6 +18,8 @@ public class Birth { private static final int BIRTH_LENGTH = 4; + private static final String INVALID_BIRTH_YEAR_MESSAGE = "올바르지 않은 출생년도(%s)입니다."; + private static final String INVALID_BIRTH_DAY_MESSAGE = "올바르지 않은 생년월일(%s)입니다."; @Column(nullable = false, length = BIRTH_LENGTH) String birthYear; @@ -30,13 +36,13 @@ public Birth(@NonNull String birthYear, @NonNull String birthDay) { private void validateYear(String birthYear) { if (!StringUtils.hasText(birthYear) || birthYear.length() != BIRTH_LENGTH) { - throw new IllegalArgumentException("올바르지 않은 연도 형식입니다."); + throw new DataLengthExceededException(INVALID_BIRTH_YEAR, INVALID_BIRTH_YEAR_MESSAGE); } } private void validateDay(String birthDay) { if (!StringUtils.hasText(birthDay) || birthDay.length() != BIRTH_LENGTH) { - throw new IllegalArgumentException("올바르지 않은 날짜 형식입니다."); + throw new DataLengthExceededException(INVALID_BIRTH_DAY, INVALID_BIRTH_DAY_MESSAGE); } } diff --git a/src/main/java/coffeemeet/server/user/domain/Email.java b/src/main/java/coffeemeet/server/user/domain/Email.java index 2db64cdb..633b209e 100644 --- a/src/main/java/coffeemeet/server/user/domain/Email.java +++ b/src/main/java/coffeemeet/server/user/domain/Email.java @@ -1,5 +1,8 @@ package coffeemeet.server.user.domain; +import static coffeemeet.server.user.exception.UserErrorCode.INVALID_EMAIL; + +import coffeemeet.server.common.execption.MissMatchException; import coffeemeet.server.common.util.Patterns; import jakarta.persistence.Embeddable; import lombok.AccessLevel; @@ -13,6 +16,8 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Email { + private static final String INVALID_EMAIL_MESSAGE = "올바르지 않은 이메일입니다."; + private String email; public Email(@NonNull String email) { @@ -22,7 +27,7 @@ public Email(@NonNull String email) { private void validateEmail(String email) { if (!StringUtils.hasText(email) || !Patterns.EMAIL_PATTERN.matcher(email).matches()) { - throw new IllegalArgumentException("올바르지 않은 이메일입니다."); + throw new MissMatchException(INVALID_EMAIL, INVALID_EMAIL_MESSAGE); } } diff --git a/src/main/java/coffeemeet/server/user/domain/Profile.java b/src/main/java/coffeemeet/server/user/domain/Profile.java index cccc45a0..9894ec31 100644 --- a/src/main/java/coffeemeet/server/user/domain/Profile.java +++ b/src/main/java/coffeemeet/server/user/domain/Profile.java @@ -1,5 +1,11 @@ package coffeemeet.server.user.domain; +import static coffeemeet.server.user.exception.UserErrorCode.INVALID_NAME; +import static coffeemeet.server.user.exception.UserErrorCode.INVALID_NICKNAME; +import static coffeemeet.server.user.exception.UserErrorCode.INVALID_PROFILE_IMAGE; + +import coffeemeet.server.common.execption.DataLengthExceededException; +import coffeemeet.server.common.execption.InvalidInputException; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import jakarta.persistence.Embedded; @@ -16,6 +22,9 @@ public class Profile { private static final int NICKNAME_MAX_LENGTH = 20; + private static final String INVALID_NICKNAME_MESSAGE = "올바르지 않은 닉네임(%s)입니다."; + private static final String INVALID_NAME_MESSAGE = "올바르지 않은 이름(%s)입니다."; + private static final String INVALID_PROFILE_IMAGE_URL_MESSAGE = "올바르지 않은 프로필 사진(%s)입니다."; @Column(nullable = false) private String name; @@ -64,19 +73,19 @@ public void updateProfileImageUrl(String newProfileImageUrl) { private void validateNickname(String nickname) { if (!StringUtils.hasText(nickname) || nickname.length() > NICKNAME_MAX_LENGTH) { - throw new IllegalArgumentException("올바르지 않은 닉네임입니다."); + throw new DataLengthExceededException(INVALID_NICKNAME, INVALID_NICKNAME_MESSAGE); } } private void validateName(String name) { if (!StringUtils.hasText(name)) { - throw new IllegalArgumentException("올바르지 않은 이름입니다."); + throw new InvalidInputException(INVALID_NAME, INVALID_NAME_MESSAGE); } } private void validateProfileImageUrl(String profileImageUrl) { if (!StringUtils.hasText(profileImageUrl)) { - throw new IllegalArgumentException("올바르지 않은 프로필 이미지 url입니다."); + throw new InvalidInputException(INVALID_PROFILE_IMAGE, INVALID_PROFILE_IMAGE_URL_MESSAGE); } } diff --git a/src/main/java/coffeemeet/server/user/exception/UserErrorCode.java b/src/main/java/coffeemeet/server/user/exception/UserErrorCode.java new file mode 100644 index 00000000..9c3e3c9d --- /dev/null +++ b/src/main/java/coffeemeet/server/user/exception/UserErrorCode.java @@ -0,0 +1,34 @@ +package coffeemeet.server.user.exception; + +import coffeemeet.server.common.execption.ErrorCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum UserErrorCode implements ErrorCode { + INVALID_NICKNAME("U000", "올바르지 않은 닉네임입니다."), + INVALID_NAME("U000", "올바르지 않은 이름입니다."), + INVALID_PROFILE_IMAGE("U000", "올바르지 않은 프로필 사진입니다."), + INVALID_EMAIL("U000", "올바르지 않은 이메입니다."), + INVALID_BIRTH_YEAR("U000", "올바르지 않은 출생년도입니다."), + INVALID_BIRTH_DAY("U000", "올바르지 않은 날짜형입니다."), + NOT_EXIST_USER("U004", "존재하지 않는 사용자입니다"), + ALREADY_EXIST_NICKNAME("U009", "이미 존재하는 닉네임입니다."), + ALREADY_EXIST_USER("U009", "이미 존재하는 사용자입니다."), + ; + + private final String errorCode; + private final String message; + + @Override + public String code() { + return errorCode; + } + + @Override + public String message() { + return message; + } + +} diff --git a/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java b/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java index 32cc7301..5eb0ecf7 100644 --- a/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java +++ b/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java @@ -1,5 +1,11 @@ package coffeemeet.server.user.service.cq; +import static coffeemeet.server.user.exception.UserErrorCode.ALREADY_EXIST_NICKNAME; +import static coffeemeet.server.user.exception.UserErrorCode.ALREADY_EXIST_USER; +import static coffeemeet.server.user.exception.UserErrorCode.NOT_EXIST_USER; + +import coffeemeet.server.common.execption.DuplicatedDataException; +import coffeemeet.server.common.execption.NotFoundException; import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.repository.UserRepository; @@ -12,34 +18,34 @@ @Transactional(readOnly = true) public class UserQuery { - private static final String USER_NOT_REGISTERED_MESSAGE = "해당 아이디(%s)와 로그인 타입(%s)의 유저는 회원가입되지 않았습니다."; - private static final String ALREADY_REGISTERED_MESSAGE = "이미 가입된 사용자입니다."; + private static final String NOT_EXIST_USER_MESSAGE = "해당 아이디(%s)에 일치하는 사용자는 존재하지 않습니다."; + private static final String NOT_REGISTERED_USER_MESSAGE = "해당 로그인 타입(%s)에 대한 아이디(%s)와 일치하는 사용자는 존재하지 않습니다."; + private static final String ALREADY_EXIST_USER_MESSAGE = "해당 사용자(%s)는 이미 가입된 사용자입니다."; + private static final String ALREADY_EXIST_NICKNAME_MESSAGE = "해당 닉네임(%s)은 이미 존재하는 닉네임입니다."; private final UserRepository userRepository; public User getUserById(Long userId) { return userRepository.findById(userId) - .orElseThrow(IllegalArgumentException::new); + .orElseThrow(() -> new NotFoundException(NOT_EXIST_USER, NOT_EXIST_USER_MESSAGE)); } public User getUserByOAuthInfo(OAuthProvider oAuthProvider, String oAuthProviderId) { return userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( oAuthProvider, oAuthProviderId).orElseThrow( - () -> new IllegalArgumentException( - String.format(USER_NOT_REGISTERED_MESSAGE, oAuthProviderId, - oAuthProvider))); + () -> new NotFoundException(NOT_EXIST_USER, NOT_REGISTERED_USER_MESSAGE)); } public void hasDuplicatedNickname(String nickname) { if (userRepository.existsUserByProfile_Nickname(nickname)) { - throw new IllegalArgumentException("이미 존재하는 닉네임입니다."); + throw new DuplicatedDataException(ALREADY_EXIST_NICKNAME, ALREADY_EXIST_NICKNAME_MESSAGE); } } public void hasDuplicatedUser(OAuthProvider oAuthProvider, String oAuthProviderId) { if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( oAuthProvider, oAuthProviderId)) { - throw new IllegalArgumentException(ALREADY_REGISTERED_MESSAGE); + throw new DuplicatedDataException(ALREADY_EXIST_USER, ALREADY_EXIST_USER_MESSAGE); } } From 4150566416d36f0f3f902438b2081251db94a389 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 15:31:17 +0900 Subject: [PATCH 290/311] test: fix test code --- .../certification/service/cq/CertificationCommandTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/coffeemeet/server/certification/service/cq/CertificationCommandTest.java b/src/test/java/coffeemeet/server/certification/service/cq/CertificationCommandTest.java index 2d243bdf..ddaf33b3 100644 --- a/src/test/java/coffeemeet/server/certification/service/cq/CertificationCommandTest.java +++ b/src/test/java/coffeemeet/server/certification/service/cq/CertificationCommandTest.java @@ -15,6 +15,7 @@ import coffeemeet.server.certification.domain.CompanyEmail; import coffeemeet.server.certification.domain.Department; import coffeemeet.server.certification.repository.CertificationRepository; +import coffeemeet.server.common.execption.InvalidInputException; import coffeemeet.server.user.domain.User; import java.util.Optional; import java.util.function.Consumer; @@ -61,8 +62,7 @@ void checkDuplicatedCompanyEmailTest() { // when, then assertThatThrownBy( () -> certificationCommand.hasDuplicatedCompanyEmail(companyEmail)).isInstanceOf( - IllegalArgumentException.class) - .hasMessage("이미 사용 중인 회사 이메일입니다."); // todo 에러메세지 public으로 두는게 어떨까요? + InvalidInputException.class); } @Test From a83546b34a23547fb82a841310eb32b11b09633c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 15:54:49 +0900 Subject: [PATCH 291/311] =?UTF-8?q?refactor:=20=EC=9C=A0=EC=A0=80=20?= =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=20DTO=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/controller/UserController.java | 4 ++-- .../user/controller/dto/MyProfileHttpDto.java | 2 +- .../user/controller/dto/UserProfileHttpDto.java | 2 +- .../coffeemeet/server/user/service/UserService.java | 6 +++--- .../server/user/{ => service}/dto/MyProfileDto.java | 2 +- .../user/{ => service}/dto/OAuthUserInfo.java | 2 +- .../user/{ => service}/dto/UserProfileDto.java | 2 +- .../common/fixture/dto/MyProfileDtoFixture.java | 4 ++-- .../fixture/dto/OAuthInfoResponseFixture.java | 13 ------------- .../common/fixture/dto/UserProfileDtoFixture.java | 2 +- .../client/OAuthMemberClientCompositeTest.java | 4 ++-- .../server/oauth/service/OAuthServiceTest.java | 4 +++- .../server/user/controller/UserControllerTest.java | 4 ++-- .../server/user/service/UserServiceTest.java | 5 +++-- 14 files changed, 23 insertions(+), 33 deletions(-) rename src/main/java/coffeemeet/server/user/{ => service}/dto/MyProfileDto.java (96%) rename src/main/java/coffeemeet/server/user/{ => service}/dto/OAuthUserInfo.java (93%) rename src/main/java/coffeemeet/server/user/{ => service}/dto/UserProfileDto.java (94%) delete mode 100644 src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index 3f083200..fa143fcc 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -7,10 +7,10 @@ import coffeemeet.server.user.controller.dto.UserProfileHttpDto; import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.controller.dto.AuthInfo; -import coffeemeet.server.user.dto.MyProfileDto; +import coffeemeet.server.user.service.dto.MyProfileDto; import coffeemeet.server.user.controller.dto.SignupHttpDto; import coffeemeet.server.user.controller.dto.UpdateProfileHttpDto; -import coffeemeet.server.user.dto.UserProfileDto.Response; +import coffeemeet.server.user.service.dto.UserProfileDto.Response; import coffeemeet.server.user.service.UserService; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; diff --git a/src/main/java/coffeemeet/server/user/controller/dto/MyProfileHttpDto.java b/src/main/java/coffeemeet/server/user/controller/dto/MyProfileHttpDto.java index fad12706..9ef96f7b 100644 --- a/src/main/java/coffeemeet/server/user/controller/dto/MyProfileHttpDto.java +++ b/src/main/java/coffeemeet/server/user/controller/dto/MyProfileHttpDto.java @@ -2,7 +2,7 @@ import coffeemeet.server.certification.domain.Department; import coffeemeet.server.interest.domain.Keyword; -import coffeemeet.server.user.dto.MyProfileDto; +import coffeemeet.server.user.service.dto.MyProfileDto; import java.time.LocalDateTime; import java.util.List; diff --git a/src/main/java/coffeemeet/server/user/controller/dto/UserProfileHttpDto.java b/src/main/java/coffeemeet/server/user/controller/dto/UserProfileHttpDto.java index 36c3a3a5..05779cee 100644 --- a/src/main/java/coffeemeet/server/user/controller/dto/UserProfileHttpDto.java +++ b/src/main/java/coffeemeet/server/user/controller/dto/UserProfileHttpDto.java @@ -2,7 +2,7 @@ import coffeemeet.server.certification.domain.Department; import coffeemeet.server.interest.domain.Keyword; -import coffeemeet.server.user.dto.UserProfileDto; +import coffeemeet.server.user.service.dto.UserProfileDto; import java.util.List; public sealed interface UserProfileHttpDto permits UserProfileHttpDto.Response { diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 4936220c..5c8e135d 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -10,7 +10,6 @@ import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.interest.service.cq.InterestCommand; import coffeemeet.server.interest.service.cq.InterestQuery; -import coffeemeet.server.oauth.dto.OAuthUserInfoDto.Response; import coffeemeet.server.oauth.service.OAuthService; import coffeemeet.server.user.domain.Birth; import coffeemeet.server.user.domain.Email; @@ -18,8 +17,9 @@ import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; -import coffeemeet.server.user.dto.MyProfileDto; -import coffeemeet.server.user.dto.UserProfileDto; +import coffeemeet.server.user.service.dto.MyProfileDto; +import coffeemeet.server.user.service.dto.OAuthUserInfo; +import coffeemeet.server.user.service.dto.UserProfileDto; import coffeemeet.server.user.service.cq.UserCommand; import coffeemeet.server.user.service.cq.UserQuery; import java.io.File; diff --git a/src/main/java/coffeemeet/server/user/dto/MyProfileDto.java b/src/main/java/coffeemeet/server/user/service/dto/MyProfileDto.java similarity index 96% rename from src/main/java/coffeemeet/server/user/dto/MyProfileDto.java rename to src/main/java/coffeemeet/server/user/service/dto/MyProfileDto.java index 83496d80..c6adc737 100644 --- a/src/main/java/coffeemeet/server/user/dto/MyProfileDto.java +++ b/src/main/java/coffeemeet/server/user/service/dto/MyProfileDto.java @@ -1,4 +1,4 @@ -package coffeemeet.server.user.dto; +package coffeemeet.server.user.service.dto; import coffeemeet.server.certification.domain.Department; import coffeemeet.server.interest.domain.Keyword; diff --git a/src/main/java/coffeemeet/server/user/dto/OAuthUserInfo.java b/src/main/java/coffeemeet/server/user/service/dto/OAuthUserInfo.java similarity index 93% rename from src/main/java/coffeemeet/server/user/dto/OAuthUserInfo.java rename to src/main/java/coffeemeet/server/user/service/dto/OAuthUserInfo.java index b60760c6..cab73f1e 100644 --- a/src/main/java/coffeemeet/server/user/dto/OAuthUserInfo.java +++ b/src/main/java/coffeemeet/server/user/service/dto/OAuthUserInfo.java @@ -1,4 +1,4 @@ -package coffeemeet.server.user.dto; +package coffeemeet.server.user.service.dto; import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import coffeemeet.server.user.domain.OAuthProvider; diff --git a/src/main/java/coffeemeet/server/user/dto/UserProfileDto.java b/src/main/java/coffeemeet/server/user/service/dto/UserProfileDto.java similarity index 94% rename from src/main/java/coffeemeet/server/user/dto/UserProfileDto.java rename to src/main/java/coffeemeet/server/user/service/dto/UserProfileDto.java index 4bf52c5b..ea33be88 100644 --- a/src/main/java/coffeemeet/server/user/dto/UserProfileDto.java +++ b/src/main/java/coffeemeet/server/user/service/dto/UserProfileDto.java @@ -1,4 +1,4 @@ -package coffeemeet.server.user.dto; +package coffeemeet.server.user.service.dto; import coffeemeet.server.certification.domain.Department; import coffeemeet.server.interest.domain.Keyword; diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/MyProfileDtoFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/MyProfileDtoFixture.java index 3d54e37e..1a234a7c 100644 --- a/src/test/java/coffeemeet/server/common/fixture/dto/MyProfileDtoFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/dto/MyProfileDtoFixture.java @@ -3,8 +3,8 @@ import static org.instancio.Select.field; import coffeemeet.server.interest.domain.Keyword; -import coffeemeet.server.user.dto.MyProfileDto; -import coffeemeet.server.user.dto.MyProfileDto.Response; +import coffeemeet.server.user.service.dto.MyProfileDto; +import coffeemeet.server.user.service.dto.MyProfileDto.Response; import java.util.List; import org.instancio.Instancio; diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java deleted file mode 100644 index d4a771cf..00000000 --- a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthInfoResponseFixture.java +++ /dev/null @@ -1,13 +0,0 @@ -package coffeemeet.server.common.fixture.dto; - -import coffeemeet.server.oauth.dto.OAuthUserInfoDto; -import org.instancio.Instancio; - -public class OAuthInfoResponseFixture { - - public static OAuthUserInfoDto.Response oAuthInfoResponse() { - return Instancio.of(OAuthUserInfoDto.Response.class) - .create(); - } - -} diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/UserProfileDtoFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/UserProfileDtoFixture.java index ae79681a..078b3647 100644 --- a/src/test/java/coffeemeet/server/common/fixture/dto/UserProfileDtoFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/dto/UserProfileDtoFixture.java @@ -1,6 +1,6 @@ package coffeemeet.server.common.fixture.dto; -import coffeemeet.server.user.dto.UserProfileDto; +import coffeemeet.server.user.service.dto.UserProfileDto; import org.instancio.Instancio; public class UserProfileDtoFixture { diff --git a/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java index 1fea992b..96952a18 100644 --- a/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java +++ b/src/test/java/coffeemeet/server/oauth/client/OAuthMemberClientCompositeTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; -import coffeemeet.server.common.fixture.dto.OAuthInfoResponseFixture; +import coffeemeet.server.common.fixture.dto.OAuthUserInfoDtoFixture; import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import coffeemeet.server.user.domain.OAuthProvider; import java.util.Collections; @@ -34,7 +34,7 @@ void fetchTest() { // given String authCode = "authCode"; OAuthProvider oAuthProvider = OAuthProvider.KAKAO; - OAuthUserInfoDto.Response response = OAuthInfoResponseFixture.oAuthInfoResponse(); + OAuthUserInfoDto.Response response = OAuthUserInfoDtoFixture.response(); given(client.oAuthProvider()).willReturn(OAuthProvider.KAKAO); given(client.fetch(authCode)).willReturn(response); diff --git a/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java b/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java index 91953ce6..df142e28 100644 --- a/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java +++ b/src/test/java/coffeemeet/server/oauth/service/OAuthServiceTest.java @@ -8,6 +8,7 @@ import coffeemeet.server.oauth.client.OAuthMemberClientComposite; import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import coffeemeet.server.user.domain.OAuthProvider; +import coffeemeet.server.user.service.dto.OAuthUserInfo; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -49,11 +50,12 @@ void getOAuthInfoTest() { OAuthProvider oAuthProvider = OAuthProvider.KAKAO; String authCode = "authCode"; OAuthUserInfoDto.Response oAuthInfoResponse = OAuthUserInfoDtoFixture.response(); + OAuthUserInfo userInfo = OAuthUserInfo.from(oAuthInfoResponse); given(oAuthMemberClientComposite.fetch(oAuthProvider, authCode)).willReturn(oAuthInfoResponse); // when, then - assertThat(oAuthService.getOAuthUserInfo(oAuthProvider, authCode)).isEqualTo(oAuthInfoResponse); + assertThat(oAuthService.getOAuthUserInfo(oAuthProvider, authCode)).isEqualTo(userInfo); } } diff --git a/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java index dfd2d45b..5b90b0bf 100644 --- a/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java +++ b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java @@ -38,10 +38,10 @@ import coffeemeet.server.common.fixture.dto.UserProfileDtoFixture; import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.User; -import coffeemeet.server.user.dto.MyProfileDto.Response; +import coffeemeet.server.user.service.dto.MyProfileDto.Response; import coffeemeet.server.user.controller.dto.SignupHttpDto; import coffeemeet.server.user.controller.dto.UpdateProfileHttpDto.Request; -import coffeemeet.server.user.dto.UserProfileDto; +import coffeemeet.server.user.service.dto.UserProfileDto; import com.epages.restdocs.apispec.Schema; import java.util.Optional; import org.junit.jupiter.api.DisplayName; diff --git a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java index bb003232..0bac7838 100644 --- a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java +++ b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java @@ -36,9 +36,10 @@ import coffeemeet.server.user.domain.OAuthInfo; import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; -import coffeemeet.server.user.dto.MyProfileDto; +import coffeemeet.server.user.service.dto.MyProfileDto; import coffeemeet.server.user.controller.dto.SignupHttpDto.Request; -import coffeemeet.server.user.dto.UserProfileDto.Response; +import coffeemeet.server.user.service.dto.OAuthUserInfo; +import coffeemeet.server.user.service.dto.UserProfileDto.Response; import coffeemeet.server.user.service.cq.UserCommand; import coffeemeet.server.user.service.cq.UserQuery; import java.io.File; From f37d10d3c9442039c979ba6500c323fb205400c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 15:55:29 +0900 Subject: [PATCH 292/311] =?UTF-8?q?refactor:=20=EB=B6=84=EB=A6=AC=EB=90=9C?= =?UTF-8?q?=20OAuthUserInfo=20DTO=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/oauth/service/OAuthService.java | 8 ++++---- .../java/coffeemeet/server/user/service/UserService.java | 4 ++-- .../coffeemeet/server/user/service/UserServiceTest.java | 6 ++++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/coffeemeet/server/oauth/service/OAuthService.java b/src/main/java/coffeemeet/server/oauth/service/OAuthService.java index 23240129..fd9c5221 100644 --- a/src/main/java/coffeemeet/server/oauth/service/OAuthService.java +++ b/src/main/java/coffeemeet/server/oauth/service/OAuthService.java @@ -2,8 +2,8 @@ import coffeemeet.server.oauth.authcode.AuthCodeRequestUrlProviderComposite; import coffeemeet.server.oauth.client.OAuthMemberClientComposite; -import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import coffeemeet.server.user.domain.OAuthProvider; +import coffeemeet.server.user.service.dto.OAuthUserInfo; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -18,9 +18,9 @@ public String getAuthCodeRequestUrl(OAuthProvider oAuthProvider) { return authCodeRequestUrlProviderComposite.provide(oAuthProvider); } - public OAuthUserInfoDto.Response getOAuthUserInfo(OAuthProvider oAuthProvider, String authCode) { - return oauthMemberClientComposite.fetch(oAuthProvider, - authCode); + public OAuthUserInfo getOAuthUserInfo(OAuthProvider oAuthProvider, String authCode) { + return OAuthUserInfo.from(oauthMemberClientComposite.fetch(oAuthProvider, + authCode)); } } diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 5c8e135d..4ccce081 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -47,7 +47,7 @@ public class UserService { public AuthTokens signup(String nickname, List keywords, String authCode, OAuthProvider oAuthProvider) { - Response response = oAuthService.getOAuthUserInfo(oAuthProvider, + OAuthUserInfo response = oAuthService.getOAuthUserInfo(oAuthProvider, authCode); userQuery.hasDuplicatedUser(response.oAuthProvider(), response.oAuthProviderId()); @@ -69,7 +69,7 @@ public AuthTokens signup(String nickname, List keywords, String authCod } public AuthTokens login(OAuthProvider oAuthProvider, String authCode) { - Response response = oAuthService.getOAuthUserInfo(oAuthProvider, authCode); + OAuthUserInfo response = oAuthService.getOAuthUserInfo(oAuthProvider, authCode); User user = userQuery.getUserByOAuthInfo(oAuthProvider, response.oAuthProviderId()); return authTokensGenerator.generate(user.getId()); } diff --git a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java index 0bac7838..66591afc 100644 --- a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java +++ b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java @@ -92,9 +92,10 @@ void signupTest() { Request request = SignupDtoFixture.signupDto(); AuthTokens authTokens = AuthTokensFixture.authTokens(); OAuthUserInfoDto.Response response = OAuthUserInfoDtoFixture.response(); + OAuthUserInfo userInfo = OAuthUserInfo.from(response); User user = user(); - given(oAuthService.getOAuthUserInfo(any(), any())).willReturn(response); + given(oAuthService.getOAuthUserInfo(any(), any())).willReturn(userInfo); given(userCommand.saveUser(any(User.class))).willReturn(user.getId()); given(userQuery.getUserById(user.getId())).willReturn(user); willDoNothing().given(interestCommand).saveAll(any(), any()); @@ -118,8 +119,9 @@ void loginTest() { AuthTokens authTokens = AuthTokensFixture.authTokens(); OAuthUserInfoDto.Response response = OAuthUserInfoDtoFixture.response(); + OAuthUserInfo userInfo = OAuthUserInfo.from(response); - given(oAuthService.getOAuthUserInfo(any(), any())).willReturn(response); + given(oAuthService.getOAuthUserInfo(any(), any())).willReturn(userInfo); given(userQuery.getUserByOAuthInfo(any(), any())).willReturn(user); given(authTokensGenerator.generate(anyLong())).willReturn(authTokens); From 464154cc9165c054df361196ae2224ccd3d10193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 16:00:33 +0900 Subject: [PATCH 293/311] =?UTF-8?q?refactor:=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=EB=A9=94=EC=84=B8=EC=A7=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coffeemeet/server/user/domain/Birth.java | 10 +++++++-- .../coffeemeet/server/user/domain/Email.java | 5 ++++- .../server/user/domain/Profile.java | 15 ++++++++++--- .../server/user/service/cq/UserQuery.java | 22 ++++++++++++++----- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/domain/Birth.java b/src/main/java/coffeemeet/server/user/domain/Birth.java index 54346a60..bdd02372 100644 --- a/src/main/java/coffeemeet/server/user/domain/Birth.java +++ b/src/main/java/coffeemeet/server/user/domain/Birth.java @@ -36,13 +36,19 @@ public Birth(@NonNull String birthYear, @NonNull String birthDay) { private void validateYear(String birthYear) { if (!StringUtils.hasText(birthYear) || birthYear.length() != BIRTH_LENGTH) { - throw new DataLengthExceededException(INVALID_BIRTH_YEAR, INVALID_BIRTH_YEAR_MESSAGE); + throw new DataLengthExceededException( + INVALID_BIRTH_YEAR, + String.format(INVALID_BIRTH_YEAR_MESSAGE, birthYear) + ); } } private void validateDay(String birthDay) { if (!StringUtils.hasText(birthDay) || birthDay.length() != BIRTH_LENGTH) { - throw new DataLengthExceededException(INVALID_BIRTH_DAY, INVALID_BIRTH_DAY_MESSAGE); + throw new DataLengthExceededException( + INVALID_BIRTH_DAY, + String.format(INVALID_BIRTH_DAY_MESSAGE, birthDay) + ); } } diff --git a/src/main/java/coffeemeet/server/user/domain/Email.java b/src/main/java/coffeemeet/server/user/domain/Email.java index 633b209e..4437832e 100644 --- a/src/main/java/coffeemeet/server/user/domain/Email.java +++ b/src/main/java/coffeemeet/server/user/domain/Email.java @@ -27,7 +27,10 @@ public Email(@NonNull String email) { private void validateEmail(String email) { if (!StringUtils.hasText(email) || !Patterns.EMAIL_PATTERN.matcher(email).matches()) { - throw new MissMatchException(INVALID_EMAIL, INVALID_EMAIL_MESSAGE); + throw new MissMatchException( + INVALID_EMAIL, + String.format(INVALID_EMAIL_MESSAGE, email) + ); } } diff --git a/src/main/java/coffeemeet/server/user/domain/Profile.java b/src/main/java/coffeemeet/server/user/domain/Profile.java index 9894ec31..fd9f5545 100644 --- a/src/main/java/coffeemeet/server/user/domain/Profile.java +++ b/src/main/java/coffeemeet/server/user/domain/Profile.java @@ -73,19 +73,28 @@ public void updateProfileImageUrl(String newProfileImageUrl) { private void validateNickname(String nickname) { if (!StringUtils.hasText(nickname) || nickname.length() > NICKNAME_MAX_LENGTH) { - throw new DataLengthExceededException(INVALID_NICKNAME, INVALID_NICKNAME_MESSAGE); + throw new DataLengthExceededException( + INVALID_NICKNAME, + String.format(INVALID_NICKNAME_MESSAGE, nickname) + ); } } private void validateName(String name) { if (!StringUtils.hasText(name)) { - throw new InvalidInputException(INVALID_NAME, INVALID_NAME_MESSAGE); + throw new InvalidInputException( + INVALID_NAME, + String.format(INVALID_NAME_MESSAGE, name) + ); } } private void validateProfileImageUrl(String profileImageUrl) { if (!StringUtils.hasText(profileImageUrl)) { - throw new InvalidInputException(INVALID_PROFILE_IMAGE, INVALID_PROFILE_IMAGE_URL_MESSAGE); + throw new InvalidInputException( + INVALID_PROFILE_IMAGE, + String.format(INVALID_PROFILE_IMAGE_URL_MESSAGE, profileImageUrl) + ); } } diff --git a/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java b/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java index 5eb0ecf7..7bfce959 100644 --- a/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java +++ b/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java @@ -20,32 +20,44 @@ public class UserQuery { private static final String NOT_EXIST_USER_MESSAGE = "해당 아이디(%s)에 일치하는 사용자는 존재하지 않습니다."; private static final String NOT_REGISTERED_USER_MESSAGE = "해당 로그인 타입(%s)에 대한 아이디(%s)와 일치하는 사용자는 존재하지 않습니다."; - private static final String ALREADY_EXIST_USER_MESSAGE = "해당 사용자(%s)는 이미 가입된 사용자입니다."; + private static final String ALREADY_EXIST_USER_MESSAGE = "해당 로그인 타입(%s)에 대한 아이디(%s)에 해당하는 사용자가 이미 존재합니다."; private static final String ALREADY_EXIST_NICKNAME_MESSAGE = "해당 닉네임(%s)은 이미 존재하는 닉네임입니다."; private final UserRepository userRepository; public User getUserById(Long userId) { return userRepository.findById(userId) - .orElseThrow(() -> new NotFoundException(NOT_EXIST_USER, NOT_EXIST_USER_MESSAGE)); + .orElseThrow(() -> new NotFoundException( + NOT_EXIST_USER, + String.format(NOT_EXIST_USER_MESSAGE, userId)) + ); } public User getUserByOAuthInfo(OAuthProvider oAuthProvider, String oAuthProviderId) { return userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( oAuthProvider, oAuthProviderId).orElseThrow( - () -> new NotFoundException(NOT_EXIST_USER, NOT_REGISTERED_USER_MESSAGE)); + () -> new NotFoundException( + NOT_EXIST_USER, + String.format(NOT_REGISTERED_USER_MESSAGE, oAuthProvider, oAuthProviderId)) + ); } public void hasDuplicatedNickname(String nickname) { if (userRepository.existsUserByProfile_Nickname(nickname)) { - throw new DuplicatedDataException(ALREADY_EXIST_NICKNAME, ALREADY_EXIST_NICKNAME_MESSAGE); + throw new DuplicatedDataException( + ALREADY_EXIST_NICKNAME, + String.format(ALREADY_EXIST_NICKNAME_MESSAGE, nickname) + ); } } public void hasDuplicatedUser(OAuthProvider oAuthProvider, String oAuthProviderId) { if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( oAuthProvider, oAuthProviderId)) { - throw new DuplicatedDataException(ALREADY_EXIST_USER, ALREADY_EXIST_USER_MESSAGE); + throw new DuplicatedDataException( + ALREADY_EXIST_USER, + String.format(ALREADY_EXIST_USER_MESSAGE, oAuthProvider, oAuthProviderId) + ); } } From 2e230bcddf07e4363381e1bce402eccaca2af795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 16:04:47 +0900 Subject: [PATCH 294/311] =?UTF-8?q?refactor:=20userRepository=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=EB=AA=85=20=EB=B0=8F=20=ED=8C=8C=EB=9D=BC?= =?UTF-8?q?=EB=AF=B8=ED=84=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/user/repository/UserRepository.java | 10 +++------- .../server/user/service/cq/UserQuery.java | 16 ++++++++-------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/main/java/coffeemeet/server/user/repository/UserRepository.java b/src/main/java/coffeemeet/server/user/repository/UserRepository.java index 166c0cb9..0b86e1ac 100644 --- a/src/main/java/coffeemeet/server/user/repository/UserRepository.java +++ b/src/main/java/coffeemeet/server/user/repository/UserRepository.java @@ -1,19 +1,15 @@ package coffeemeet.server.user.repository; -import coffeemeet.server.user.domain.OAuthProvider; +import coffeemeet.server.user.domain.OAuthInfo; import coffeemeet.server.user.domain.User; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; public interface UserRepository extends JpaRepository { - boolean existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( - OAuthProvider oauthProvider, - String oauthProviderId); + boolean existsUserByOauthInfo(OAuthInfo oAuthInfo); - Optional getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( - OAuthProvider oauthProvider, - String oauthProviderId); + Optional findByOauthInfo(OAuthInfo oauthInfo); boolean existsUserByProfile_Nickname(String nickname); diff --git a/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java b/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java index 7bfce959..c318d57f 100644 --- a/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java +++ b/src/main/java/coffeemeet/server/user/service/cq/UserQuery.java @@ -6,6 +6,7 @@ import coffeemeet.server.common.execption.DuplicatedDataException; import coffeemeet.server.common.execption.NotFoundException; +import coffeemeet.server.user.domain.OAuthInfo; import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.User; import coffeemeet.server.user.repository.UserRepository; @@ -34,12 +35,12 @@ public User getUserById(Long userId) { } public User getUserByOAuthInfo(OAuthProvider oAuthProvider, String oAuthProviderId) { - return userRepository.getUserByOauthInfoOauthProviderAndOauthInfoOauthProviderId( - oAuthProvider, oAuthProviderId).orElseThrow( - () -> new NotFoundException( - NOT_EXIST_USER, - String.format(NOT_REGISTERED_USER_MESSAGE, oAuthProvider, oAuthProviderId)) - ); + return userRepository.findByOauthInfo(new OAuthInfo(oAuthProvider, oAuthProviderId)) + .orElseThrow( + () -> new NotFoundException( + NOT_EXIST_USER, + String.format(NOT_REGISTERED_USER_MESSAGE, oAuthProvider, oAuthProviderId)) + ); } public void hasDuplicatedNickname(String nickname) { @@ -52,8 +53,7 @@ public void hasDuplicatedNickname(String nickname) { } public void hasDuplicatedUser(OAuthProvider oAuthProvider, String oAuthProviderId) { - if (userRepository.existsUserByOauthInfo_oauthProviderAndOauthInfo_oauthProviderId( - oAuthProvider, oAuthProviderId)) { + if (userRepository.existsUserByOauthInfo(new OAuthInfo(oAuthProvider, oAuthProviderId))) { throw new DuplicatedDataException( ALREADY_EXIST_USER, String.format(ALREADY_EXIST_USER_MESSAGE, oAuthProvider, oAuthProviderId) From 152b113911a718fd4f275d7c9482941812c55c9e Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 17:16:25 +0900 Subject: [PATCH 295/311] test: apply test convention --- .../server/common/UserArgumentResolver.java | 2 +- .../user/controller/UserController.java | 8 ++--- .../server/user/service/UserService.java | 4 +-- .../CertificationControllerTest.java | 15 ++++---- .../common/config/ControllerTestConfig.java | 8 +---- .../fixture/dto/OAuthUserInfoDtoFixture.java | 2 +- .../user/controller/UserControllerTest.java | 36 ++++++++----------- .../server/user/service/UserServiceTest.java | 6 ++-- 8 files changed, 34 insertions(+), 47 deletions(-) diff --git a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java index 8d40696a..05b91911 100644 --- a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java +++ b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java @@ -6,8 +6,8 @@ import coffeemeet.server.auth.domain.RefreshToken; import coffeemeet.server.auth.repository.RefreshTokenRepository; import coffeemeet.server.common.annotation.Login; -import coffeemeet.server.user.controller.dto.AuthInfo; import coffeemeet.server.common.execption.InvalidInputException; +import coffeemeet.server.user.controller.dto.AuthInfo; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.springframework.core.MethodParameter; diff --git a/src/main/java/coffeemeet/server/user/controller/UserController.java b/src/main/java/coffeemeet/server/user/controller/UserController.java index fa143fcc..73da33c1 100644 --- a/src/main/java/coffeemeet/server/user/controller/UserController.java +++ b/src/main/java/coffeemeet/server/user/controller/UserController.java @@ -3,15 +3,15 @@ import coffeemeet.server.auth.domain.AuthTokens; import coffeemeet.server.common.annotation.Login; import coffeemeet.server.common.util.FileUtils; +import coffeemeet.server.user.controller.dto.AuthInfo; import coffeemeet.server.user.controller.dto.MyProfileHttpDto; +import coffeemeet.server.user.controller.dto.SignupHttpDto; +import coffeemeet.server.user.controller.dto.UpdateProfileHttpDto; import coffeemeet.server.user.controller.dto.UserProfileHttpDto; import coffeemeet.server.user.domain.OAuthProvider; -import coffeemeet.server.user.controller.dto.AuthInfo; +import coffeemeet.server.user.service.UserService; import coffeemeet.server.user.service.dto.MyProfileDto; -import coffeemeet.server.user.controller.dto.SignupHttpDto; -import coffeemeet.server.user.controller.dto.UpdateProfileHttpDto; import coffeemeet.server.user.service.dto.UserProfileDto.Response; -import coffeemeet.server.user.service.UserService; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; diff --git a/src/main/java/coffeemeet/server/user/service/UserService.java b/src/main/java/coffeemeet/server/user/service/UserService.java index 4ccce081..231f78fd 100644 --- a/src/main/java/coffeemeet/server/user/service/UserService.java +++ b/src/main/java/coffeemeet/server/user/service/UserService.java @@ -17,11 +17,11 @@ import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; +import coffeemeet.server.user.service.cq.UserCommand; +import coffeemeet.server.user.service.cq.UserQuery; import coffeemeet.server.user.service.dto.MyProfileDto; import coffeemeet.server.user.service.dto.OAuthUserInfo; import coffeemeet.server.user.service.dto.UserProfileDto; -import coffeemeet.server.user.service.cq.UserCommand; -import coffeemeet.server.user.service.cq.UserQuery; import java.io.File; import java.util.List; import lombok.RequiredArgsConstructor; diff --git a/src/test/java/coffeemeet/server/certification/controller/CertificationControllerTest.java b/src/test/java/coffeemeet/server/certification/controller/CertificationControllerTest.java index 2c5ee084..de8bf343 100644 --- a/src/test/java/coffeemeet/server/certification/controller/CertificationControllerTest.java +++ b/src/test/java/coffeemeet/server/certification/controller/CertificationControllerTest.java @@ -7,8 +7,10 @@ import static coffeemeet.server.common.fixture.entity.CertificationFixture.verificationCodeDtoRequest; import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.document; import static com.epages.restdocs.apispec.MockMvcRestDocumentationWrapper.resourceDetails; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.willDoNothing; import static org.springframework.http.HttpHeaders.AUTHORIZATION; import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.http.MediaType.MULTIPART_FORM_DATA; @@ -26,31 +28,30 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import coffeemeet.server.auth.domain.RefreshToken; -import coffeemeet.server.auth.service.AuthService; import coffeemeet.server.certification.service.CertificationService; import coffeemeet.server.common.config.ControllerTestConfig; -import coffeemeet.server.oauth.service.OAuthService; import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.mock.web.MockMultipartFile; import org.springframework.mock.web.MockPart; +@WebMvcTest(CertificationController.class) class CertificationControllerTest extends ControllerTestConfig { - @MockBean - protected AuthService authService; - @MockBean - protected OAuthService oAuthService; // TODO: 2023/10/30 authService, oAuthService Controller 테스트에서 전부 중복이라서 Config에 두는게 좋을 듯 @MockBean private CertificationService certificationService; - private RefreshToken refreshToken; @BeforeEach void setUp() { + Long userId = 1L; RefreshToken refreshToken = refreshToken(); given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + given(jwtTokenProvider.extractUserId(TOKEN)).willReturn(userId); + willDoNothing().given(certificationService) + .registerCertification(anyLong(), any(), any(), any()); } @Test diff --git a/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java index d5ea3328..43affd52 100644 --- a/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java +++ b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java @@ -5,11 +5,9 @@ import coffeemeet.server.auth.domain.JwtTokenProvider; import coffeemeet.server.auth.repository.RefreshTokenRepository; -import coffeemeet.server.user.service.UserService; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.restdocs.RestDocumentationContextProvider; import org.springframework.restdocs.RestDocumentationExtension; @@ -18,11 +16,10 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.filter.CharacterEncodingFilter; -@WebMvcTest @ExtendWith({RestDocumentationExtension.class}) public abstract class ControllerTestConfig { - protected static final String TOKEN = "Bearer aaaaaaaa.bbbbbbb.ccccccc"; // todo "Bearer header.payload.signature" 얘가 좀 더 의미 있는 듯 + protected static final String TOKEN = "Bearer header.payload.signature"; protected ObjectMapper objectMapper = new ObjectMapper(); @@ -34,9 +31,6 @@ public abstract class ControllerTestConfig { @MockBean protected RefreshTokenRepository refreshTokenRepository; - @MockBean - protected UserService userService; - @BeforeEach void setUp(WebApplicationContext ctx, RestDocumentationContextProvider restDocumentation) { mockMvc = MockMvcBuilders.webAppContextSetup(ctx) diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthUserInfoDtoFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthUserInfoDtoFixture.java index 2b111ca6..12283c69 100644 --- a/src/test/java/coffeemeet/server/common/fixture/dto/OAuthUserInfoDtoFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/dto/OAuthUserInfoDtoFixture.java @@ -11,7 +11,7 @@ public static OAuthUserInfoDto.Response response() { return Instancio.of(OAuthUserInfoDto.Response.class) .generate(field("birthYear"), gen -> gen.ints().range(1000, 9999).asString()) .generate(field("birthDay"), gen -> gen.ints().range(1000, 9999).asString()) - .set(field("email"),"test123@gmail.com") + .set(field("email"), "test123@gmail.com") .create(); } diff --git a/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java index 5b90b0bf..b470ebd7 100644 --- a/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java +++ b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java @@ -36,17 +36,19 @@ import coffeemeet.server.common.fixture.dto.SignupDtoFixture; import coffeemeet.server.common.fixture.dto.UpdateProfileDtoFixture; import coffeemeet.server.common.fixture.dto.UserProfileDtoFixture; +import coffeemeet.server.user.controller.dto.SignupHttpDto; +import coffeemeet.server.user.controller.dto.UpdateProfileHttpDto.Request; import coffeemeet.server.user.domain.OAuthProvider; import coffeemeet.server.user.domain.User; +import coffeemeet.server.user.service.UserService; import coffeemeet.server.user.service.dto.MyProfileDto.Response; -import coffeemeet.server.user.controller.dto.SignupHttpDto; -import coffeemeet.server.user.controller.dto.UpdateProfileHttpDto.Request; import coffeemeet.server.user.service.dto.UserProfileDto; import com.epages.restdocs.apispec.Schema; import java.util.Optional; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; import org.springframework.mock.web.MockMultipartFile; import org.springframework.restdocs.payload.JsonFieldType; @@ -54,6 +56,9 @@ @WebMvcTest(UserController.class) class UserControllerTest extends ControllerTestConfig { + @MockBean + private UserService userService; + @Test @DisplayName("회원가입을 할 수 있다.") void signupTest() throws Exception { @@ -121,12 +126,12 @@ void loginTest() throws Exception { @Test @DisplayName("사용자 프로필을 조회할 수 있다.") void findUserProfileTest() throws Exception { - long id = 1L; + Long userId = 1L; UserProfileDto.Response response = UserProfileDtoFixture.userProfileDtoResponse(); - given(userService.findUserProfile(id)).willReturn(response); + given(userService.findUserProfile(userId)).willReturn(response); - mockMvc.perform(get("/api/v1/users/{id}", id) + mockMvc.perform(get("/api/v1/users/{id}", userId) .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON) ) @@ -155,8 +160,7 @@ void findUserProfileTest() throws Exception { @Test @DisplayName("마이페이지를 조회할 수 있다.") void findMyProfileTest() throws Exception { - User user = user(); - Long userId = user.getId(); + Long userId = 1L; RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); @@ -190,24 +194,13 @@ void findMyProfileTest() throws Exception { ) ) ) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.name").value(response.name())) - .andExpect(jsonPath("$.nickname").value(response.nickname())) - .andExpect(jsonPath("$.email").value(response.email())) - .andExpect(jsonPath("$.profileImageUrl").value(response.profileImageUrl())) - .andExpect(jsonPath("$.birthYear").value(response.birthYear())) - .andExpect(jsonPath("$.birthDay").value(response.birthDay())) - .andExpect(jsonPath("$.reportedCount").value(response.reportedCount())) - .andExpect(jsonPath("$.sanctionPeriod").value(String.valueOf(response.sanctionPeriod()))) - .andExpect(jsonPath("$.department").value(String.valueOf(response.department()))) - .andExpect(jsonPath("$.interests[0]").value(response.interests().get(0).name())); + .andExpect(status().isOk()); } @Test @DisplayName("본인 프로필 사진을 수정할 수 있다.") void updateProfileImageTest() throws Exception { - User user = user(); - Long userId = user.getId(); + Long userId = 1L; RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); @@ -240,8 +233,7 @@ void updateProfileImageTest() throws Exception { @Test @DisplayName("본인 프로필 정보를 수정할 수 있다.") void updateProfileInfoTest() throws Exception { - User user = user(); - Long userId = user.getId(); + Long userId = 1L; Request request = UpdateProfileDtoFixture.updateProfileDtoRequest(); RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); diff --git a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java index 66591afc..9e2cd8e2 100644 --- a/src/test/java/coffeemeet/server/user/service/UserServiceTest.java +++ b/src/test/java/coffeemeet/server/user/service/UserServiceTest.java @@ -31,17 +31,17 @@ import coffeemeet.server.interest.service.cq.InterestQuery; import coffeemeet.server.oauth.dto.OAuthUserInfoDto; import coffeemeet.server.oauth.service.OAuthService; +import coffeemeet.server.user.controller.dto.SignupHttpDto.Request; import coffeemeet.server.user.domain.Birth; import coffeemeet.server.user.domain.Email; import coffeemeet.server.user.domain.OAuthInfo; import coffeemeet.server.user.domain.Profile; import coffeemeet.server.user.domain.User; +import coffeemeet.server.user.service.cq.UserCommand; +import coffeemeet.server.user.service.cq.UserQuery; import coffeemeet.server.user.service.dto.MyProfileDto; -import coffeemeet.server.user.controller.dto.SignupHttpDto.Request; import coffeemeet.server.user.service.dto.OAuthUserInfo; import coffeemeet.server.user.service.dto.UserProfileDto.Response; -import coffeemeet.server.user.service.cq.UserCommand; -import coffeemeet.server.user.service.cq.UserQuery; import java.io.File; import java.io.IOException; import java.util.ArrayList; From 0f736e7462feaf53ea6f653ecee88a280bef7b5d Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 17:44:32 +0900 Subject: [PATCH 296/311] =?UTF-8?q?feat:=20RefreshTokenCommand=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 --- .../auth/service/cq/RefreshTokenCommand.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/coffeemeet/server/auth/service/cq/RefreshTokenCommand.java diff --git a/src/main/java/coffeemeet/server/auth/service/cq/RefreshTokenCommand.java b/src/main/java/coffeemeet/server/auth/service/cq/RefreshTokenCommand.java new file mode 100644 index 00000000..174077b3 --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/service/cq/RefreshTokenCommand.java @@ -0,0 +1,24 @@ +package coffeemeet.server.auth.service.cq; + +import coffeemeet.server.auth.domain.RefreshToken; +import coffeemeet.server.auth.repository.RefreshTokenRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +@RequiredArgsConstructor +public class RefreshTokenCommand { + + private final RefreshTokenRepository refreshTokenRepository; + + public void createRefreshToken(RefreshToken refreshToken) { + refreshTokenRepository.save(refreshToken); + } + + public void deleteRefreshToken(Long userId) { + refreshTokenRepository.deleteById(userId); + } + +} From e73784083063d970b3843564bb7170c4e73b70ec Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 17:44:44 +0900 Subject: [PATCH 297/311] =?UTF-8?q?feat:=20RefreshTokenQuery=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 --- .../auth/service/cq/RefreshTokenQuery.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/main/java/coffeemeet/server/auth/service/cq/RefreshTokenQuery.java diff --git a/src/main/java/coffeemeet/server/auth/service/cq/RefreshTokenQuery.java b/src/main/java/coffeemeet/server/auth/service/cq/RefreshTokenQuery.java new file mode 100644 index 00000000..f3ef300a --- /dev/null +++ b/src/main/java/coffeemeet/server/auth/service/cq/RefreshTokenQuery.java @@ -0,0 +1,28 @@ +package coffeemeet.server.auth.service.cq; + +import static coffeemeet.server.auth.exception.AuthErrorCode.AUTHENTICATION_FAILED; + +import coffeemeet.server.auth.domain.RefreshToken; +import coffeemeet.server.auth.repository.RefreshTokenRepository; +import coffeemeet.server.common.execption.InvalidInputException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class RefreshTokenQuery { + + private static final String USER_AUTHENTICATION_FAILED_MESSAGE = "사용자(%s)의 재인증(로그인)이 필요합니다."; + + private final RefreshTokenRepository refreshTokenRepository; + + public RefreshToken getRefreshToken(Long userId) { + return refreshTokenRepository.findById(userId) + .orElseThrow(() -> new InvalidInputException( + AUTHENTICATION_FAILED, + String.format(USER_AUTHENTICATION_FAILED_MESSAGE, userId))); + } + +} From 1d60d897d8c9be4f50c66887fd22bb02d424d205 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 17:45:13 +0900 Subject: [PATCH 298/311] =?UTF-8?q?feat:=20RefreshToken=20=EC=BB=A4?= =?UTF-8?q?=EB=A7=A8=EB=93=9C,=20=EC=BF=BC=EB=A6=AC=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/auth/domain/AuthTokensGenerator.java | 9 +++++---- .../coffeemeet/server/auth/service/AuthService.java | 8 +++++--- .../server/common/UserArgumentResolver.java | 13 +++---------- .../server/common/config/AuthWebConfig.java | 5 +++-- .../server/auth/domain/AuthTokensGeneratorTest.java | 5 +++-- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/domain/AuthTokensGenerator.java b/src/main/java/coffeemeet/server/auth/domain/AuthTokensGenerator.java index b4620ef7..fcc9e4e0 100644 --- a/src/main/java/coffeemeet/server/auth/domain/AuthTokensGenerator.java +++ b/src/main/java/coffeemeet/server/auth/domain/AuthTokensGenerator.java @@ -1,6 +1,7 @@ package coffeemeet.server.auth.domain; import coffeemeet.server.auth.repository.RefreshTokenRepository; +import coffeemeet.server.auth.service.cq.RefreshTokenCommand; import java.util.Date; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -13,16 +14,16 @@ public class AuthTokensGenerator { private final JwtTokenProvider jwtTokenProvider; private final Long accessTokenExpireTime; private final Long refreshTokenExpireTime; - private final RefreshTokenRepository refreshTokenRepository; + private final RefreshTokenCommand refreshTokenCommand; public AuthTokensGenerator(JwtTokenProvider jwtTokenProvider, @Value("${jwt.access-token-expire-time}") Long accessTokenExpireTime, @Value("${jwt.refresh-token-expire-time}") Long refreshTokenExpireTime, - RefreshTokenRepository refreshTokenRepository) { + RefreshTokenCommand refreshTokenCommand) { this.jwtTokenProvider = jwtTokenProvider; this.accessTokenExpireTime = accessTokenExpireTime; this.refreshTokenExpireTime = refreshTokenExpireTime; - this.refreshTokenRepository = refreshTokenRepository; + this.refreshTokenCommand = refreshTokenCommand; } public AuthTokens generate(Long userId) { @@ -38,7 +39,7 @@ public AuthTokens generate(Long userId) { .userId(userId) .value(refreshToken) .build(); - refreshTokenRepository.save(refreshTokenEntity); + refreshTokenCommand.createRefreshToken(refreshTokenEntity); return AuthTokens.of( BEARER_TYPE + accessToken, diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index a75e7f26..99ce96ee 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -6,6 +6,8 @@ import coffeemeet.server.auth.domain.AuthTokensGenerator; import coffeemeet.server.auth.domain.JwtTokenProvider; import coffeemeet.server.auth.repository.RefreshTokenRepository; +import coffeemeet.server.auth.service.cq.RefreshTokenCommand; +import coffeemeet.server.auth.service.cq.RefreshTokenQuery; import coffeemeet.server.common.execption.InvalidAuthException; import coffeemeet.server.user.service.UserService; import lombok.RequiredArgsConstructor; @@ -21,7 +23,7 @@ public class AuthService { private final UserService userService; private final AuthTokensGenerator authTokensGenerator; private final JwtTokenProvider jwtTokenProvider; - private final RefreshTokenRepository refreshTokenRepository; + private final RefreshTokenCommand refreshTokenCommand; public AuthTokens renew(Long userId, String refreshToken) { if (jwtTokenProvider.isExpiredRefreshToken(refreshToken)) { @@ -34,13 +36,13 @@ public AuthTokens renew(Long userId, String refreshToken) { } public void logout(Long userId) { - refreshTokenRepository.deleteById(userId); + refreshTokenCommand.deleteRefreshToken(userId); } @Transactional public void delete(Long userId) { userService.deleteUser(userId); - refreshTokenRepository.deleteById(userId); + refreshTokenCommand.deleteRefreshToken(userId); } } diff --git a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java index 05b91911..30e9f549 100644 --- a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java +++ b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java @@ -5,6 +5,7 @@ import coffeemeet.server.auth.domain.JwtTokenProvider; import coffeemeet.server.auth.domain.RefreshToken; import coffeemeet.server.auth.repository.RefreshTokenRepository; +import coffeemeet.server.auth.service.cq.RefreshTokenQuery; import coffeemeet.server.common.annotation.Login; import coffeemeet.server.common.execption.InvalidInputException; import coffeemeet.server.user.controller.dto.AuthInfo; @@ -21,11 +22,10 @@ @RequiredArgsConstructor public class UserArgumentResolver implements HandlerMethodArgumentResolver { - private static final String USER_AUTHENTICATION_FAILED_MESSAGE = "사용자(%s)의 재인증(로그인)이 필요합니다."; private static final String HEADER_AUTHENTICATION_FAILED_MESSAGE = "(%s)는 잘못된 권한 헤더입니다."; private final JwtTokenProvider jwtTokenProvider; - private final RefreshTokenRepository refreshTokenRepository; + private final RefreshTokenQuery refreshTokenQuery; @Override public boolean supportsParameter(MethodParameter parameter) { @@ -42,7 +42,7 @@ public AuthInfo resolveArgument(MethodParameter parameter, ModelAndViewContainer if (authHeader != null && authHeader.startsWith("Bearer ")) { String token = authHeader.substring(7); Long userId = jwtTokenProvider.extractUserId(token); - RefreshToken refreshToken = getRefreshToken(userId); + RefreshToken refreshToken = refreshTokenQuery.getRefreshToken(userId); return new AuthInfo(userId, refreshToken.getValue()); } throw new InvalidInputException( @@ -51,11 +51,4 @@ public AuthInfo resolveArgument(MethodParameter parameter, ModelAndViewContainer ); } - private RefreshToken getRefreshToken(Long userId) { - return refreshTokenRepository.findById(userId) - .orElseThrow(() -> new InvalidInputException( - AUTHENTICATION_FAILED, - String.format(USER_AUTHENTICATION_FAILED_MESSAGE, userId))); - } - } diff --git a/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java b/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java index 49d145eb..fb56effb 100644 --- a/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java +++ b/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java @@ -2,6 +2,7 @@ import coffeemeet.server.auth.domain.JwtTokenProvider; import coffeemeet.server.auth.repository.RefreshTokenRepository; +import coffeemeet.server.auth.service.cq.RefreshTokenQuery; import coffeemeet.server.common.UserArgumentResolver; import coffeemeet.server.oauth.utils.converter.OAuthProviderConverter; import java.util.List; @@ -16,7 +17,7 @@ public class AuthWebConfig implements WebMvcConfigurer { private final JwtTokenProvider jwtTokenProvider; - private final RefreshTokenRepository refreshTokenRepository; + private final RefreshTokenQuery refreshTokenQuery; @Override public void addFormatters(FormatterRegistry registry) { @@ -25,7 +26,7 @@ public void addFormatters(FormatterRegistry registry) { @Override public void addArgumentResolvers(List resolvers) { - resolvers.add(new UserArgumentResolver(jwtTokenProvider, refreshTokenRepository)); + resolvers.add(new UserArgumentResolver(jwtTokenProvider, refreshTokenQuery)); } } diff --git a/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java b/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java index 09de8058..9eb726c4 100644 --- a/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java +++ b/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java @@ -7,6 +7,7 @@ import static org.mockito.BDDMockito.given; import coffeemeet.server.auth.repository.RefreshTokenRepository; +import coffeemeet.server.auth.service.cq.RefreshTokenCommand; import java.util.Date; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -32,12 +33,12 @@ class AuthTokensGeneratorTest { private JwtTokenProvider jwtTokenProvider; @Mock - private RefreshTokenRepository refreshTokenRepository; + private RefreshTokenCommand refreshTokenCommand; @BeforeEach public void init() { authTokensGenerator = new AuthTokensGenerator(jwtTokenProvider, accessTokenExpireTime, - refreshTokenExpireTime, refreshTokenRepository); + refreshTokenExpireTime, refreshTokenCommand); } @DisplayName("access token & refresh token 발급할 수 있다.") From e8cefdf81579a2a1f98ea1c106ff8050fd96b085 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 18:10:50 +0900 Subject: [PATCH 299/311] =?UTF-8?q?test:=20RefreshTokenCommandTest=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 --- .../service/cq/RefreshTokenCommandTest.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/test/java/coffeemeet/server/auth/service/cq/RefreshTokenCommandTest.java diff --git a/src/test/java/coffeemeet/server/auth/service/cq/RefreshTokenCommandTest.java b/src/test/java/coffeemeet/server/auth/service/cq/RefreshTokenCommandTest.java new file mode 100644 index 00000000..2757861d --- /dev/null +++ b/src/test/java/coffeemeet/server/auth/service/cq/RefreshTokenCommandTest.java @@ -0,0 +1,51 @@ +package coffeemeet.server.auth.service.cq; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.only; + +import coffeemeet.server.auth.domain.RefreshToken; +import coffeemeet.server.auth.repository.RefreshTokenRepository; +import coffeemeet.server.common.fixture.dto.RefreshTokenFixture; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class RefreshTokenCommandTest { + + @InjectMocks + private RefreshTokenCommand refreshTokenCommand; + + @Mock + private RefreshTokenRepository refreshTokenRepository; + + @DisplayName("리프레시 토큰을 생성할 수 있다.") + @Test + void createRefreshTokenTest() { + // given + RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); + + // when + refreshTokenCommand.createRefreshToken(refreshToken); + + // then + then(refreshTokenRepository).should(only()).save(any(RefreshToken.class)); + } + + @DisplayName("리프레시 토큰을 삭제할 수 있다.") + @Test + void deleteRefreshTokenTest() { + // given, when + Long userId = 1L; + refreshTokenCommand.deleteRefreshToken(userId); + + // then + then(refreshTokenRepository).should(only()).deleteById(anyLong()); + } + +} From 577c940df16053c1da18d4732f13d761d588c24b Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 18:11:03 +0900 Subject: [PATCH 300/311] =?UTF-8?q?test:=20RefreshTokenQueryTest=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 --- .../service/cq/RefreshTokenQueryTest.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/test/java/coffeemeet/server/auth/service/cq/RefreshTokenQueryTest.java diff --git a/src/test/java/coffeemeet/server/auth/service/cq/RefreshTokenQueryTest.java b/src/test/java/coffeemeet/server/auth/service/cq/RefreshTokenQueryTest.java new file mode 100644 index 00000000..7621ab61 --- /dev/null +++ b/src/test/java/coffeemeet/server/auth/service/cq/RefreshTokenQueryTest.java @@ -0,0 +1,41 @@ +package coffeemeet.server.auth.service.cq; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; + +import coffeemeet.server.auth.domain.RefreshToken; +import coffeemeet.server.auth.repository.RefreshTokenRepository; +import coffeemeet.server.common.fixture.dto.RefreshTokenFixture; +import java.util.Optional; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class RefreshTokenQueryTest { + + @InjectMocks + private RefreshTokenQuery refreshTokenQuery; + + @Mock + private RefreshTokenRepository refreshTokenRepository; + + @DisplayName("리프레시 토큰을 조회할 수 있다.") + @Test + void getRefreshTokenTest() { + // given + Long userId = 1L; + RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); + given(refreshTokenRepository.findById(userId)).willReturn(Optional.of(refreshToken)); + + // when + RefreshToken foundRefreshToken = refreshTokenQuery.getRefreshToken(userId); + + // then + assertThat(foundRefreshToken).isEqualTo(refreshToken); + } + +} From 19fff9bfc96f96f243101d998c4b91fc5f2ac669 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 18:11:46 +0900 Subject: [PATCH 301/311] style: code formatting --- .../java/coffeemeet/server/auth/domain/AuthTokensGenerator.java | 1 - src/main/java/coffeemeet/server/auth/service/AuthService.java | 2 -- .../java/coffeemeet/server/common/UserArgumentResolver.java | 1 - .../java/coffeemeet/server/common/config/AuthWebConfig.java | 1 - .../coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java | 1 - 5 files changed, 6 deletions(-) diff --git a/src/main/java/coffeemeet/server/auth/domain/AuthTokensGenerator.java b/src/main/java/coffeemeet/server/auth/domain/AuthTokensGenerator.java index fcc9e4e0..ec205485 100644 --- a/src/main/java/coffeemeet/server/auth/domain/AuthTokensGenerator.java +++ b/src/main/java/coffeemeet/server/auth/domain/AuthTokensGenerator.java @@ -1,6 +1,5 @@ package coffeemeet.server.auth.domain; -import coffeemeet.server.auth.repository.RefreshTokenRepository; import coffeemeet.server.auth.service.cq.RefreshTokenCommand; import java.util.Date; import org.springframework.beans.factory.annotation.Value; diff --git a/src/main/java/coffeemeet/server/auth/service/AuthService.java b/src/main/java/coffeemeet/server/auth/service/AuthService.java index 99ce96ee..34ccb68d 100644 --- a/src/main/java/coffeemeet/server/auth/service/AuthService.java +++ b/src/main/java/coffeemeet/server/auth/service/AuthService.java @@ -5,9 +5,7 @@ import coffeemeet.server.auth.domain.AuthTokens; import coffeemeet.server.auth.domain.AuthTokensGenerator; import coffeemeet.server.auth.domain.JwtTokenProvider; -import coffeemeet.server.auth.repository.RefreshTokenRepository; import coffeemeet.server.auth.service.cq.RefreshTokenCommand; -import coffeemeet.server.auth.service.cq.RefreshTokenQuery; import coffeemeet.server.common.execption.InvalidAuthException; import coffeemeet.server.user.service.UserService; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java index 30e9f549..947c20b6 100644 --- a/src/main/java/coffeemeet/server/common/UserArgumentResolver.java +++ b/src/main/java/coffeemeet/server/common/UserArgumentResolver.java @@ -4,7 +4,6 @@ import coffeemeet.server.auth.domain.JwtTokenProvider; import coffeemeet.server.auth.domain.RefreshToken; -import coffeemeet.server.auth.repository.RefreshTokenRepository; import coffeemeet.server.auth.service.cq.RefreshTokenQuery; import coffeemeet.server.common.annotation.Login; import coffeemeet.server.common.execption.InvalidInputException; diff --git a/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java b/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java index fb56effb..d2534d66 100644 --- a/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java +++ b/src/main/java/coffeemeet/server/common/config/AuthWebConfig.java @@ -1,7 +1,6 @@ package coffeemeet.server.common.config; import coffeemeet.server.auth.domain.JwtTokenProvider; -import coffeemeet.server.auth.repository.RefreshTokenRepository; import coffeemeet.server.auth.service.cq.RefreshTokenQuery; import coffeemeet.server.common.UserArgumentResolver; import coffeemeet.server.oauth.utils.converter.OAuthProviderConverter; diff --git a/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java b/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java index 9eb726c4..de8d44eb 100644 --- a/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java +++ b/src/test/java/coffeemeet/server/auth/domain/AuthTokensGeneratorTest.java @@ -6,7 +6,6 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; -import coffeemeet.server.auth.repository.RefreshTokenRepository; import coffeemeet.server.auth.service.cq.RefreshTokenCommand; import java.util.Date; import org.junit.jupiter.api.BeforeEach; From 3a9935a7b17604f2867274a4925164c6364268d3 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Tue, 31 Oct 2023 18:18:43 +0900 Subject: [PATCH 302/311] fix: fix test code --- .../server/auth/controller/AuthControllerTest.java | 7 +++---- .../coffeemeet/server/auth/service/AuthServiceTest.java | 8 ++++---- .../controller/CertificationControllerTest.java | 3 +-- .../server/common/config/ControllerTestConfig.java | 4 ++-- .../server/user/controller/UserControllerTest.java | 9 ++++----- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java b/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java index 4387a1f6..345feb1a 100644 --- a/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java +++ b/src/test/java/coffeemeet/server/auth/controller/AuthControllerTest.java @@ -24,7 +24,6 @@ import coffeemeet.server.common.fixture.dto.AuthTokensFixture; import coffeemeet.server.common.fixture.dto.RefreshTokenFixture; import com.epages.restdocs.apispec.Schema; -import java.util.Optional; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -46,7 +45,7 @@ void renewTest() throws Exception { RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); given(authService.renew(anyLong(), any())).willReturn(authTokens); - given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + given(refreshTokenQuery.getRefreshToken(anyLong())).willReturn(refreshToken); // when, then mockMvc.perform(post("/api/v1/auth/renew-token") @@ -78,7 +77,7 @@ void logoutTest() throws Exception { // given RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); willDoNothing().given(authService).logout(anyLong()); - given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + given(refreshTokenQuery.getRefreshToken(anyLong())).willReturn(refreshToken); // when, then mockMvc.perform(post("/api/v1/auth/logout") @@ -103,7 +102,7 @@ void deleteTest() throws Exception { // given RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); willDoNothing().given(authService).delete(anyLong()); - given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + given(refreshTokenQuery.getRefreshToken(anyLong())).willReturn(refreshToken); // when, then mockMvc.perform(post("/api/v1/auth/delete") diff --git a/src/test/java/coffeemeet/server/auth/service/AuthServiceTest.java b/src/test/java/coffeemeet/server/auth/service/AuthServiceTest.java index a5628fbf..56569f81 100644 --- a/src/test/java/coffeemeet/server/auth/service/AuthServiceTest.java +++ b/src/test/java/coffeemeet/server/auth/service/AuthServiceTest.java @@ -10,7 +10,7 @@ import coffeemeet.server.auth.domain.AuthTokens; import coffeemeet.server.auth.domain.AuthTokensGenerator; import coffeemeet.server.auth.domain.JwtTokenProvider; -import coffeemeet.server.auth.repository.RefreshTokenRepository; +import coffeemeet.server.auth.service.cq.RefreshTokenCommand; import coffeemeet.server.common.fixture.dto.AuthTokensFixture; import coffeemeet.server.user.service.UserService; import org.junit.jupiter.api.DisplayName; @@ -38,7 +38,7 @@ class AuthServiceTest { private JwtTokenProvider jwtTokenProvider; @Mock - private RefreshTokenRepository refreshTokenRepository; + private RefreshTokenCommand refreshTokenCommand; @DisplayName("access token 을 갱신할 수 있다.") @Test @@ -65,7 +65,7 @@ void renewTest() { @Test void logoutTest() { // given - willDoNothing().given(refreshTokenRepository).deleteById(anyLong()); + willDoNothing().given(refreshTokenCommand).deleteRefreshToken(anyLong()); // when authService.logout((long) Math.random()); @@ -78,7 +78,7 @@ void logoutTest() { @Test void deleteTest() { // given - willDoNothing().given(refreshTokenRepository).deleteById(anyLong()); + willDoNothing().given(refreshTokenCommand).deleteRefreshToken(anyLong()); willDoNothing().given(userService).deleteUser(anyLong()); // when diff --git a/src/test/java/coffeemeet/server/certification/controller/CertificationControllerTest.java b/src/test/java/coffeemeet/server/certification/controller/CertificationControllerTest.java index de8bf343..f144465d 100644 --- a/src/test/java/coffeemeet/server/certification/controller/CertificationControllerTest.java +++ b/src/test/java/coffeemeet/server/certification/controller/CertificationControllerTest.java @@ -30,7 +30,6 @@ import coffeemeet.server.auth.domain.RefreshToken; import coffeemeet.server.certification.service.CertificationService; import coffeemeet.server.common.config.ControllerTestConfig; -import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -48,7 +47,7 @@ class CertificationControllerTest extends ControllerTestConfig { void setUp() { Long userId = 1L; RefreshToken refreshToken = refreshToken(); - given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + given(refreshTokenQuery.getRefreshToken(anyLong())).willReturn(refreshToken); given(jwtTokenProvider.extractUserId(TOKEN)).willReturn(userId); willDoNothing().given(certificationService) .registerCertification(anyLong(), any(), any(), any()); diff --git a/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java index 43affd52..59dc84ad 100644 --- a/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java +++ b/src/test/java/coffeemeet/server/common/config/ControllerTestConfig.java @@ -4,7 +4,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import coffeemeet.server.auth.domain.JwtTokenProvider; -import coffeemeet.server.auth.repository.RefreshTokenRepository; +import coffeemeet.server.auth.service.cq.RefreshTokenQuery; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; @@ -29,7 +29,7 @@ public abstract class ControllerTestConfig { protected JwtTokenProvider jwtTokenProvider; @MockBean - protected RefreshTokenRepository refreshTokenRepository; + protected RefreshTokenQuery refreshTokenQuery; @BeforeEach void setUp(WebApplicationContext ctx, RestDocumentationContextProvider restDocumentation) { diff --git a/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java index b470ebd7..6223eaa4 100644 --- a/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java +++ b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java @@ -44,7 +44,6 @@ import coffeemeet.server.user.service.dto.MyProfileDto.Response; import coffeemeet.server.user.service.dto.UserProfileDto; import com.epages.restdocs.apispec.Schema; -import java.util.Optional; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -163,7 +162,7 @@ void findMyProfileTest() throws Exception { Long userId = 1L; RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); - given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + given(refreshTokenQuery.getRefreshToken(anyLong())).willReturn(refreshToken); Response response = MyProfileDtoFixture.myProfileDtoResponse(); when(jwtTokenProvider.extractUserId(TOKEN)).thenReturn(userId); @@ -203,7 +202,7 @@ void updateProfileImageTest() throws Exception { Long userId = 1L; RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); - given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + given(refreshTokenQuery.getRefreshToken(anyLong())).willReturn(refreshToken); given(jwtTokenProvider.extractUserId(TOKEN)).willReturn(userId); MockMultipartFile file = new MockMultipartFile("image", @@ -237,7 +236,7 @@ void updateProfileInfoTest() throws Exception { Request request = UpdateProfileDtoFixture.updateProfileDtoRequest(); RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); - given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + given(refreshTokenQuery.getRefreshToken(anyLong())).willReturn(refreshToken); given(jwtTokenProvider.extractUserId(TOKEN)).willReturn(userId); willDoNothing().given( userService).updateProfileInfo(any(), any(), any()); @@ -270,7 +269,7 @@ void checkNicknameDuplicationTest() throws Exception { String nickname = user.getProfile().getNickname(); RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); - given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + given(refreshTokenQuery.getRefreshToken(anyLong())).willReturn(refreshToken); mockMvc.perform(get("/api/v1/users/duplicate") .param("nickname", nickname) From 39385f50d63d34b7cdbb92c76b7181178465c9b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 17:25:56 +0900 Subject: [PATCH 303/311] =?UTF-8?q?test:=20UserController=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=A3=BC=EC=84=9D=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 --- .../user/controller/UserControllerTest.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java index 6223eaa4..a54e4563 100644 --- a/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java +++ b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java @@ -7,7 +7,6 @@ import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.willDoNothing; -import static org.mockito.Mockito.when; import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; @@ -61,11 +60,13 @@ class UserControllerTest extends ControllerTestConfig { @Test @DisplayName("회원가입을 할 수 있다.") void signupTest() throws Exception { + // given SignupHttpDto.Request request = SignupDtoFixture.signupDto(); AuthTokens authTokens = new AuthTokens("accessToken", "refreshToken"); given(userService.signup(any(), any(), any(), any())).willReturn(authTokens); + // when, then mockMvc.perform(post("/api/v1/users/sign-up") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) @@ -94,10 +95,12 @@ void signupTest() throws Exception { @Test @DisplayName("로그인을 할 수 있다.") void loginTest() throws Exception { + // given AuthTokens authTokens = new AuthTokens("accessToken", "refreshToken"); given(userService.login(any(), any())).willReturn(authTokens); + // when, then mockMvc.perform(get("/api/v1/users/login/{oAuthProvider}", OAuthProvider.KAKAO) .contentType(MediaType.APPLICATION_JSON) .param("authCode", "authCode")) @@ -125,11 +128,13 @@ void loginTest() throws Exception { @Test @DisplayName("사용자 프로필을 조회할 수 있다.") void findUserProfileTest() throws Exception { - Long userId = 1L; + // given + long userId = 1L; UserProfileDto.Response response = UserProfileDtoFixture.userProfileDtoResponse(); given(userService.findUserProfile(userId)).willReturn(response); + // when, then mockMvc.perform(get("/api/v1/users/{id}", userId) .accept(MediaType.APPLICATION_JSON) .contentType(MediaType.APPLICATION_JSON) @@ -159,6 +164,7 @@ void findUserProfileTest() throws Exception { @Test @DisplayName("마이페이지를 조회할 수 있다.") void findMyProfileTest() throws Exception { + // given Long userId = 1L; RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); @@ -167,7 +173,11 @@ void findMyProfileTest() throws Exception { when(jwtTokenProvider.extractUserId(TOKEN)).thenReturn(userId); when(userService.findMyProfile(anyLong())).thenReturn(response); + given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + given(jwtTokenProvider.extractUserId(TOKEN)).willReturn(userId); + given(userService.findMyProfile(anyLong())).willReturn(response); + // when, then mockMvc.perform(get("/api/v1/users/me") .header("Authorization", TOKEN) .contentType(MediaType.APPLICATION_JSON) @@ -199,6 +209,7 @@ void findMyProfileTest() throws Exception { @Test @DisplayName("본인 프로필 사진을 수정할 수 있다.") void updateProfileImageTest() throws Exception { + // given Long userId = 1L; RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); @@ -210,6 +221,7 @@ void updateProfileImageTest() throws Exception { "image/png", "testImage".getBytes()); + // when, given mockMvc.perform((multipart("/api/v1/users/me/profile-image") .file("profileImage", file.getBytes()) .header("Authorization", TOKEN) @@ -232,6 +244,7 @@ void updateProfileImageTest() throws Exception { @Test @DisplayName("본인 프로필 정보를 수정할 수 있다.") void updateProfileInfoTest() throws Exception { + // given Long userId = 1L; Request request = UpdateProfileDtoFixture.updateProfileDtoRequest(); RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); @@ -241,6 +254,7 @@ void updateProfileInfoTest() throws Exception { willDoNothing().given( userService).updateProfileInfo(any(), any(), any()); + // when, given mockMvc.perform(patch("/api/v1/users/me") .header("Authorization", TOKEN) .contentType(MediaType.APPLICATION_JSON) @@ -265,12 +279,14 @@ void updateProfileInfoTest() throws Exception { @Test @DisplayName("닉네임 중복을 확인할 수 있다.") void checkNicknameDuplicationTest() throws Exception { + // given User user = user(); String nickname = user.getProfile().getNickname(); RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); given(refreshTokenQuery.getRefreshToken(anyLong())).willReturn(refreshToken); + // when, given mockMvc.perform(get("/api/v1/users/duplicate") .param("nickname", nickname) ) From dabfac2c7a2e5f785505c78f898e48ff229bdd45 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 31 Oct 2023 18:28:42 +0900 Subject: [PATCH 304/311] =?UTF-8?q?test:=20DisplayName=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../certification/controller/CertificationControllerTest.java | 4 ++++ .../certification/repository/CertificationRepositoryTest.java | 3 +++ .../certification/service/CertificationServiceTest.java | 4 ++++ .../certification/service/cq/EmailVerificationQueryTest.java | 2 ++ 4 files changed, 13 insertions(+) diff --git a/src/test/java/coffeemeet/server/certification/controller/CertificationControllerTest.java b/src/test/java/coffeemeet/server/certification/controller/CertificationControllerTest.java index de8bf343..ca75c527 100644 --- a/src/test/java/coffeemeet/server/certification/controller/CertificationControllerTest.java +++ b/src/test/java/coffeemeet/server/certification/controller/CertificationControllerTest.java @@ -32,6 +32,7 @@ import coffeemeet.server.common.config.ControllerTestConfig; import java.util.Optional; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; @@ -55,6 +56,7 @@ void setUp() { } @Test + @DisplayName("회사 인증 정보를 등록할 수 있다.") void registerCompanyInfoTest() throws Exception { // given String sBusinessCard = "businessCard"; @@ -95,6 +97,7 @@ void registerCompanyInfoTest() throws Exception { } @Test + @DisplayName("이메일을 통해 인증번호를 전송할 수 있다.") void sendVerificationCodeByEmailTest() throws Exception { // given String emailDtoRequest = objectMapper.writeValueAsString(emailDtoRequest()); @@ -120,6 +123,7 @@ void sendVerificationCodeByEmailTest() throws Exception { } @Test + @DisplayName("이메일을 검증을 할 수 있다.") void verifyEmailTest() throws Exception { String verificationCodeDtoRequest = objectMapper.writeValueAsString( verificationCodeDtoRequest()); diff --git a/src/test/java/coffeemeet/server/certification/repository/CertificationRepositoryTest.java b/src/test/java/coffeemeet/server/certification/repository/CertificationRepositoryTest.java index 21e87b6a..ac0cc285 100644 --- a/src/test/java/coffeemeet/server/certification/repository/CertificationRepositoryTest.java +++ b/src/test/java/coffeemeet/server/certification/repository/CertificationRepositoryTest.java @@ -8,6 +8,7 @@ import coffeemeet.server.user.domain.User; import coffeemeet.server.user.repository.UserRepository; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; @@ -28,6 +29,7 @@ void setUp() { } @Test + @DisplayName("유저 아이디로 회사 인증 정보를 조회할 수 있다.") void findByUserIdTest() { // given Certification certification = certification(user); @@ -38,6 +40,7 @@ void findByUserIdTest() { } @Test + @DisplayName("존재하는 회사 이메일인지 확인할 수 있다.") void existsByCompanyEmailTest() { // given Certification certification = certification(user); diff --git a/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java b/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java index c92fbd06..59e0ecc1 100644 --- a/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java +++ b/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java @@ -25,6 +25,7 @@ import coffeemeet.server.user.service.cq.UserQuery; import java.io.File; import org.instancio.Instancio; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -51,6 +52,7 @@ class CertificationServiceTest { private EmailVerificationQuery emailVerificationQuery; @Test + @DisplayName("회사 정보를 등록할 수 있다.") void registerCertificationTest() { // given User user = user(); @@ -78,6 +80,7 @@ void registerCertificationTest() { } @Test + @DisplayName("회사 인증 메일을 전송할 수 있다.") void sendVerificationMailTest() { // given String email = email(); @@ -95,6 +98,7 @@ void sendVerificationMailTest() { } @Test + @DisplayName("인증 코드를 비교할 수 있다.") void compareCodeTest() { // given Long userId = Instancio.create(Long.class); diff --git a/src/test/java/coffeemeet/server/certification/service/cq/EmailVerificationQueryTest.java b/src/test/java/coffeemeet/server/certification/service/cq/EmailVerificationQueryTest.java index fd850641..45a59355 100644 --- a/src/test/java/coffeemeet/server/certification/service/cq/EmailVerificationQueryTest.java +++ b/src/test/java/coffeemeet/server/certification/service/cq/EmailVerificationQueryTest.java @@ -7,6 +7,7 @@ import coffeemeet.server.certification.domain.EmailVerification; import coffeemeet.server.certification.repository.EmailVerificationRepository; import java.util.Optional; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -22,6 +23,7 @@ class EmailVerificationQueryTest { private EmailVerificationRepository emailVerificationRepository; @Test + @DisplayName("유저 아이디로 EmailVerification를 조회할 수 있다.") void getCodeByIdTest() { // given EmailVerification emailVerification = emailVerification(); From 7c18d8735eafee801194666d23f1b0022adcac16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=87=E1=85=A1=E1=86=A8=E1=84=8B=E1=85=B3=E1=86=AB?= =?UTF-8?q?=E1=84=8C=E1=85=B5?= Date: Tue, 31 Oct 2023 18:06:47 +0900 Subject: [PATCH 305/311] =?UTF-8?q?test:=20UserController=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EB=82=A0=EC=A7=9C=20=ED=98=95=EC=8B=9D=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/controller/UserControllerTest.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java index a54e4563..56e70b22 100644 --- a/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java +++ b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java @@ -43,6 +43,7 @@ import coffeemeet.server.user.service.dto.MyProfileDto.Response; import coffeemeet.server.user.service.dto.UserProfileDto; import com.epages.restdocs.apispec.Schema; +import java.time.format.DateTimeFormatter; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -167,13 +168,9 @@ void findMyProfileTest() throws Exception { // given Long userId = 1L; RefreshToken refreshToken = RefreshTokenFixture.refreshToken(); - - given(refreshTokenQuery.getRefreshToken(anyLong())).willReturn(refreshToken); Response response = MyProfileDtoFixture.myProfileDtoResponse(); - when(jwtTokenProvider.extractUserId(TOKEN)).thenReturn(userId); - when(userService.findMyProfile(anyLong())).thenReturn(response); - given(refreshTokenRepository.findById(anyLong())).willReturn(Optional.ofNullable(refreshToken)); + given(refreshTokenQuery.getRefreshToken(anyLong())).willReturn(refreshToken); given(jwtTokenProvider.extractUserId(TOKEN)).willReturn(userId); given(userService.findMyProfile(anyLong())).willReturn(response); @@ -203,7 +200,19 @@ void findMyProfileTest() throws Exception { ) ) ) - .andExpect(status().isOk()); + .andExpect(status().isOk()) + .andExpect(jsonPath("$.name").value(response.name())) + .andExpect(jsonPath("$.nickname").value(response.nickname())) + .andExpect(jsonPath("$.email").value(response.email())) + .andExpect(jsonPath("$.profileImageUrl").value(response.profileImageUrl())) + .andExpect(jsonPath("$.birthYear").value(response.birthYear())) + .andExpect(jsonPath("$.birthDay").value(response.birthDay())) + .andExpect(jsonPath("$.reportedCount").value(response.reportedCount())) + .andExpect( + jsonPath("$.sanctionPeriod").value(response.sanctionPeriod() + .format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS")))) + .andExpect(jsonPath("$.department").value(String.valueOf(response.department()))) + .andExpect(jsonPath("$.interests[0]").value(response.interests().get(0).name())); } @Test From 0cad7e743f456984ce6dff7a0cb1f993478f312f Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 31 Oct 2023 18:39:09 +0900 Subject: [PATCH 306/311] refactor: new -> create --- .../server/certification/service/CertificationService.java | 4 ++-- .../server/certification/service/cq/CertificationCommand.java | 2 +- .../certification/service/cq/EmailVerificationCommand.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/coffeemeet/server/certification/service/CertificationService.java b/src/main/java/coffeemeet/server/certification/service/CertificationService.java index aa028ba2..eff6c4e2 100644 --- a/src/main/java/coffeemeet/server/certification/service/CertificationService.java +++ b/src/main/java/coffeemeet/server/certification/service/CertificationService.java @@ -42,7 +42,7 @@ public void registerCertification(long userId, String email, String departmentNa String businessCardUrl = s3MediaService.getUrl(key); Department department = Department.valueOf(departmentName); User user = userQuery.getUserById(userId); - certificationCommand.newCertification(companyEmail, businessCardUrl, department, user); + certificationCommand.createCertification(companyEmail, businessCardUrl, department, user); } private void uploadBusinessCard(long userId, String key, File businessCardUrl) { @@ -61,7 +61,7 @@ public void sendVerificationMail(Long userId, String email) { String verificationCode = generateVerificationCode(); emailService.sendVerificationCode(companyEmail, verificationCode); - emailVerificationCommand.newEmailVerification(userId, companyEmail, verificationCode); + emailVerificationCommand.createEmailVerification(userId, companyEmail, verificationCode); } public void compareCode(Long userId, String verificationCode) { diff --git a/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java b/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java index 791b9afd..5b8fc603 100644 --- a/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java +++ b/src/main/java/coffeemeet/server/certification/service/cq/CertificationCommand.java @@ -22,7 +22,7 @@ public class CertificationCommand { private final CertificationRepository certificationRepository; - public void newCertification(CompanyEmail companyEmail, String businessCardUrl, + public void createCertification(CompanyEmail companyEmail, String businessCardUrl, Department department, User user) { certificationRepository.save( Certification.builder() diff --git a/src/main/java/coffeemeet/server/certification/service/cq/EmailVerificationCommand.java b/src/main/java/coffeemeet/server/certification/service/cq/EmailVerificationCommand.java index 37323810..5412ecc3 100644 --- a/src/main/java/coffeemeet/server/certification/service/cq/EmailVerificationCommand.java +++ b/src/main/java/coffeemeet/server/certification/service/cq/EmailVerificationCommand.java @@ -12,7 +12,7 @@ public class EmailVerificationCommand { private final EmailVerificationRepository emailVerificationRepository; - public void newEmailVerification(Long userId, CompanyEmail companyEmail, + public void createEmailVerification(Long userId, CompanyEmail companyEmail, String verificationCode) { emailVerificationRepository.save(new EmailVerification(userId, companyEmail, verificationCode)); } From 916119758521f34ad2a61d9dbc229e2a972e09c6 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 31 Oct 2023 18:39:24 +0900 Subject: [PATCH 307/311] =?UTF-8?q?test:=20new=20->=20create=20=EB=A9=94?= =?UTF-8?q?=EC=86=8C=EB=93=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../certification/service/CertificationServiceTest.java | 4 ++-- .../certification/service/cq/CertificationCommandTest.java | 4 ++-- .../service/cq/EmailVerificationCommandTest.java | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java b/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java index 59e0ecc1..a23bb7fb 100644 --- a/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java +++ b/src/test/java/coffeemeet/server/certification/service/CertificationServiceTest.java @@ -74,7 +74,7 @@ void registerCertificationTest() { // then then(s3MediaService).should().generateKey(any()); then(s3MediaService).should().upload(any(), any(File.class)); - then(certificationCommand).should().newCertification(any(), any(), any(), any()); + then(certificationCommand).should().createCertification(any(), any(), any(), any()); fileUtils.close(); } @@ -94,7 +94,7 @@ void sendVerificationMailTest() { then(certificationCommand).should(only()).hasDuplicatedCompanyEmail(any()); then(emailService).should(only()).sendVerificationCode(any(), anyString()); then(emailVerificationCommand).should(only()) - .newEmailVerification(anyLong(), any(), anyString()); + .createEmailVerification(anyLong(), any(), anyString()); } @Test diff --git a/src/test/java/coffeemeet/server/certification/service/cq/CertificationCommandTest.java b/src/test/java/coffeemeet/server/certification/service/cq/CertificationCommandTest.java index ddaf33b3..d0cd9db2 100644 --- a/src/test/java/coffeemeet/server/certification/service/cq/CertificationCommandTest.java +++ b/src/test/java/coffeemeet/server/certification/service/cq/CertificationCommandTest.java @@ -38,7 +38,7 @@ class CertificationCommandTest { @Test @DisplayName("새로운 Certification 객체를 저장할 수 있다.") - void newCertificationTest() { + void createCertificationTest() { // given CompanyEmail companyEmail = companyEmail(); String businessCardUrl = businessCardUrl(); @@ -46,7 +46,7 @@ void newCertificationTest() { User user = user(); // when - certificationCommand.newCertification(companyEmail, businessCardUrl, department, user); + certificationCommand.createCertification(companyEmail, businessCardUrl, department, user); // then then(certificationRepository).should(only()).save(any(Certification.class)); diff --git a/src/test/java/coffeemeet/server/certification/service/cq/EmailVerificationCommandTest.java b/src/test/java/coffeemeet/server/certification/service/cq/EmailVerificationCommandTest.java index d2e60dcc..996bb8a4 100644 --- a/src/test/java/coffeemeet/server/certification/service/cq/EmailVerificationCommandTest.java +++ b/src/test/java/coffeemeet/server/certification/service/cq/EmailVerificationCommandTest.java @@ -25,14 +25,14 @@ class EmailVerificationCommandTest { @Test @DisplayName("새로운 EmailVerification 객체를 저장할 수 있다.") - void newEmailVerificationTest() { + void createEmailVerificationTest() { // given EmailVerification emailVerification = emailVerification(); given(emailVerificationRepository.save(any(EmailVerification.class))).willReturn( emailVerification); // when - emailVerificationCommand.newEmailVerification(emailVerification.getUserId(), + emailVerificationCommand.createEmailVerification(emailVerification.getUserId(), emailVerification.getCompanyEmail(), emailVerification.getCode()); // then From 1053af94d3b56fca45f27b5b00b2c65f815804b2 Mon Sep 17 00:00:00 2001 From: sangminnim Date: Tue, 31 Oct 2023 18:40:58 +0900 Subject: [PATCH 308/311] =?UTF-8?q?style:=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../certification/controller/CertificationController.java | 4 ++-- .../server/certification/{ => controller}/dto/EmailDto.java | 2 +- .../{ => controller}/dto/VerificationCodeDto.java | 2 +- .../server/common/fixture/entity/CertificationFixture.java | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) rename src/main/java/coffeemeet/server/certification/{ => controller}/dto/EmailDto.java (81%) rename src/main/java/coffeemeet/server/certification/{ => controller}/dto/VerificationCodeDto.java (84%) diff --git a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java index 197b8c61..62b62ada 100644 --- a/src/main/java/coffeemeet/server/certification/controller/CertificationController.java +++ b/src/main/java/coffeemeet/server/certification/controller/CertificationController.java @@ -1,7 +1,7 @@ package coffeemeet.server.certification.controller; -import coffeemeet.server.certification.dto.EmailDto; -import coffeemeet.server.certification.dto.VerificationCodeDto; +import coffeemeet.server.certification.controller.dto.EmailDto; +import coffeemeet.server.certification.controller.dto.VerificationCodeDto; import coffeemeet.server.certification.service.CertificationService; import coffeemeet.server.common.annotation.Login; import coffeemeet.server.common.util.FileUtils; diff --git a/src/main/java/coffeemeet/server/certification/dto/EmailDto.java b/src/main/java/coffeemeet/server/certification/controller/dto/EmailDto.java similarity index 81% rename from src/main/java/coffeemeet/server/certification/dto/EmailDto.java rename to src/main/java/coffeemeet/server/certification/controller/dto/EmailDto.java index 63d9fddc..4d04f708 100644 --- a/src/main/java/coffeemeet/server/certification/dto/EmailDto.java +++ b/src/main/java/coffeemeet/server/certification/controller/dto/EmailDto.java @@ -1,4 +1,4 @@ -package coffeemeet.server.certification.dto; +package coffeemeet.server.certification.controller.dto; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotNull; diff --git a/src/main/java/coffeemeet/server/certification/dto/VerificationCodeDto.java b/src/main/java/coffeemeet/server/certification/controller/dto/VerificationCodeDto.java similarity index 84% rename from src/main/java/coffeemeet/server/certification/dto/VerificationCodeDto.java rename to src/main/java/coffeemeet/server/certification/controller/dto/VerificationCodeDto.java index 11035e5c..e749309f 100644 --- a/src/main/java/coffeemeet/server/certification/dto/VerificationCodeDto.java +++ b/src/main/java/coffeemeet/server/certification/controller/dto/VerificationCodeDto.java @@ -1,4 +1,4 @@ -package coffeemeet.server.certification.dto; +package coffeemeet.server.certification.controller.dto; import jakarta.validation.constraints.NotNull; import org.hibernate.validator.constraints.Length; diff --git a/src/test/java/coffeemeet/server/common/fixture/entity/CertificationFixture.java b/src/test/java/coffeemeet/server/common/fixture/entity/CertificationFixture.java index 02118b08..6ac4d0e1 100644 --- a/src/test/java/coffeemeet/server/common/fixture/entity/CertificationFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/entity/CertificationFixture.java @@ -6,8 +6,8 @@ import coffeemeet.server.certification.domain.CompanyEmail; import coffeemeet.server.certification.domain.Department; import coffeemeet.server.certification.domain.EmailVerification; -import coffeemeet.server.certification.dto.EmailDto; -import coffeemeet.server.certification.dto.VerificationCodeDto; +import coffeemeet.server.certification.controller.dto.EmailDto; +import coffeemeet.server.certification.controller.dto.VerificationCodeDto; import coffeemeet.server.user.domain.User; import org.instancio.Instancio; import org.instancio.internal.generator.domain.internet.EmailGenerator; From 7b2b548bc7de2657e8beb7bbb0bb8b42a4ffa9b2 Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 1 Nov 2023 15:07:30 +0900 Subject: [PATCH 309/311] feat: create CD script --- .github/workflows/cd.yml | 74 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 .github/workflows/cd.yml diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 00000000..30fd5858 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,74 @@ +name: coffee-meet CD + +on: + pull_request: + branches: + - main + +jobs: + test_and_deploy: + runs-on: ubuntu-latest + steps: + - name: 현재 작업중인 Repository 가져온다. + uses: actions/checkout@v3 + + - name: CD 프로세스를 최적화 하기 위해 Gradle 정보를 캐싱한다. + uses: actions/cache@v3 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: JDK 17 설치한다. + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + + - name: .env 파일에 깃 Secrets 로부터 값을 가져와 기록한다. + run: echo "${{ secrets.ENV_PROPERTIES }}" > ./.env + + - name: Gradle 명령 실행을 위한 권한을 부여한다. + run: chmod +x gradlew + + - name: Gradle test & build 를 수행한다. + run: | + ./gradlew clean test -Pprofile=test + ./gradlew clean build + + - name: 현재 디렉토리에 있는 Dockerfile(Jar)을 이미지 빌드한다. + run: docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/boot-prac-ci . + + - name: Docker Hub 에 로그인한다. + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: 빌드된 도커 이미지(Jar)를 Docker Hub 에 푸쉬한다. + run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/boot-prac-ci:latest + + - name: ./.env 경로의 환경 변수 파일을 Ec2 서버의 기본 경로에 전달한다. + uses: appleboy/scp-action@master + with: + username: ubuntu + host: ${{ secrets.HOST }} + key: ${{ secrets.PRIVATE_KEY }} + source: "./.env" + target: "/home/ubuntu" + + - name: 기존의 Jar 이미지를 삭제하고, Docker Hub 를 통해 새 Jar 이미지를 실행한다. + uses: appleboy/ssh-action@v1.0.0 + with: + host: ${{ secrets.HOST }} + username: ubuntu + key: ${{ secrets.PRIVATE_KEY }} + script: | + sudo docker ps -q | grep -v $(sudo docker ps -qf "name=redis") | xargs -r sudo docker stop + sudo docker ps -aq | grep -v $(sudo docker ps -aqf "name=redis") | xargs -r sudo docker rm + sudo docker image prune -a -f + sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/boot-prac-ci:latest + sudo docker run -d --log-driver=syslog --env-file .env -p 8080:8080 ${{ secrets.DOCKERHUB_USERNAME }}/boot-prac-ci:latest From f393612c98682a6d3dce1567b476684b7e7b870c Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 1 Nov 2023 16:08:09 +0900 Subject: [PATCH 310/311] test: fix test code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - myProfileDtoResponse 제제 기간 직접 설정 --- .../server/common/fixture/dto/MyProfileDtoFixture.java | 2 ++ .../server/common/fixture/entity/CertificationFixture.java | 4 ++-- .../server/user/controller/UserControllerTest.java | 5 +---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/test/java/coffeemeet/server/common/fixture/dto/MyProfileDtoFixture.java b/src/test/java/coffeemeet/server/common/fixture/dto/MyProfileDtoFixture.java index 1a234a7c..93c9ff50 100644 --- a/src/test/java/coffeemeet/server/common/fixture/dto/MyProfileDtoFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/dto/MyProfileDtoFixture.java @@ -5,6 +5,7 @@ import coffeemeet.server.interest.domain.Keyword; import coffeemeet.server.user.service.dto.MyProfileDto; import coffeemeet.server.user.service.dto.MyProfileDto.Response; +import java.time.LocalDateTime; import java.util.List; import org.instancio.Instancio; @@ -16,6 +17,7 @@ public static MyProfileDto.Response myProfileDtoResponse() { .generate(field("birthDay"), gen -> gen.ints().range(1000, 9999).asString()) .set(field(Response::interests), keywords()) .set(field("email"), "test123@gmail.com") + .set(field("sanctionPeriod"), LocalDateTime.of(1999, 10, 13, 1, 1, 1, 1)) .create(); } diff --git a/src/test/java/coffeemeet/server/common/fixture/entity/CertificationFixture.java b/src/test/java/coffeemeet/server/common/fixture/entity/CertificationFixture.java index 6ac4d0e1..ee66d5ad 100644 --- a/src/test/java/coffeemeet/server/common/fixture/entity/CertificationFixture.java +++ b/src/test/java/coffeemeet/server/common/fixture/entity/CertificationFixture.java @@ -2,12 +2,12 @@ import static org.instancio.Select.field; +import coffeemeet.server.certification.controller.dto.EmailDto; +import coffeemeet.server.certification.controller.dto.VerificationCodeDto; import coffeemeet.server.certification.domain.Certification; import coffeemeet.server.certification.domain.CompanyEmail; import coffeemeet.server.certification.domain.Department; import coffeemeet.server.certification.domain.EmailVerification; -import coffeemeet.server.certification.controller.dto.EmailDto; -import coffeemeet.server.certification.controller.dto.VerificationCodeDto; import coffeemeet.server.user.domain.User; import org.instancio.Instancio; import org.instancio.internal.generator.domain.internet.EmailGenerator; diff --git a/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java index 56e70b22..d61efe57 100644 --- a/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java +++ b/src/test/java/coffeemeet/server/user/controller/UserControllerTest.java @@ -43,7 +43,6 @@ import coffeemeet.server.user.service.dto.MyProfileDto.Response; import coffeemeet.server.user.service.dto.UserProfileDto; import com.epages.restdocs.apispec.Schema; -import java.time.format.DateTimeFormatter; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -208,9 +207,7 @@ void findMyProfileTest() throws Exception { .andExpect(jsonPath("$.birthYear").value(response.birthYear())) .andExpect(jsonPath("$.birthDay").value(response.birthDay())) .andExpect(jsonPath("$.reportedCount").value(response.reportedCount())) - .andExpect( - jsonPath("$.sanctionPeriod").value(response.sanctionPeriod() - .format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS")))) + .andExpect(jsonPath("$.sanctionPeriod").value(String.valueOf(response.sanctionPeriod()))) .andExpect(jsonPath("$.department").value(String.valueOf(response.department()))) .andExpect(jsonPath("$.interests[0]").value(response.interests().get(0).name())); } From 98459c66c3f65cc7e9db9ecae135ab758ce7bcee Mon Sep 17 00:00:00 2001 From: yumyeonghan Date: Wed, 1 Nov 2023 16:11:07 +0900 Subject: [PATCH 311/311] feat: add Dockerfile --- Dockerfile | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..3e9a838e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,4 @@ +FROM openjdk:17-jdk-alpine +ARG JAR_FILE=build/libs/*.jar +COPY ${JAR_FILE} app.jar +ENTRYPOINT ["java", "-jar", "app.jar"]