From 6cfa306700b091bbbf7ff7e0de10b8001b9ac95c Mon Sep 17 00:00:00 2001 From: seungyeop-lee Date: Tue, 4 Jun 2024 14:07:11 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=EC=95=BD=EA=B4=80=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20API=20=EC=82=AD=EC=A0=9C=20#62?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/api/web/routes/user/UserApi.java | 23 -------------- .../web/routes/user/UserRestController.java | 9 ------ .../api/web/routes/user/UserWebService.java | 7 ----- .../routes/user/reqres/UserTermsResponse.java | 30 ------------------- 4 files changed, 69 deletions(-) delete mode 100644 api/src/main/java/vook/server/api/web/routes/user/reqres/UserTermsResponse.java diff --git a/api/src/main/java/vook/server/api/web/routes/user/UserApi.java b/api/src/main/java/vook/server/api/web/routes/user/UserApi.java index 5df235d..48dd646 100644 --- a/api/src/main/java/vook/server/api/web/routes/user/UserApi.java +++ b/api/src/main/java/vook/server/api/web/routes/user/UserApi.java @@ -12,9 +12,6 @@ import vook.server.api.web.routes.user.reqres.UserInfoResponse; import vook.server.api.web.routes.user.reqres.UserOnboardingCompleteRequest; import vook.server.api.web.routes.user.reqres.UserRegisterRequest; -import vook.server.api.web.routes.user.reqres.UserTermsResponse; - -import java.util.List; @Tag(name = "user", description = "사용자 관련 API") public interface UserApi { @@ -39,26 +36,6 @@ public interface UserApi { class UserApiUerInfoResponse extends CommonApiResponse { } - @Operation( - summary = "약관 목록", - security = { - @SecurityRequirement(name = "AccessToken") - } - ) - @ApiResponses(value = { - @ApiResponse( - responseCode = "200", - description = "성공", - content = @Content( - schema = @Schema(implementation = UserApiTermsResponse.class) - ) - ), - }) - CommonApiResponse> terms(); - - class UserApiTermsResponse extends CommonApiResponse> { - } - @Operation( summary = "회원가입", security = { diff --git a/api/src/main/java/vook/server/api/web/routes/user/UserRestController.java b/api/src/main/java/vook/server/api/web/routes/user/UserRestController.java index de6639c..e4382cf 100644 --- a/api/src/main/java/vook/server/api/web/routes/user/UserRestController.java +++ b/api/src/main/java/vook/server/api/web/routes/user/UserRestController.java @@ -9,9 +9,6 @@ import vook.server.api.web.routes.user.reqres.UserInfoResponse; import vook.server.api.web.routes.user.reqres.UserOnboardingCompleteRequest; import vook.server.api.web.routes.user.reqres.UserRegisterRequest; -import vook.server.api.web.routes.user.reqres.UserTermsResponse; - -import java.util.List; @Slf4j @RestController @@ -30,12 +27,6 @@ public CommonApiResponse userInfo( return CommonApiResponse.okWithResult(response); } - @Override - @GetMapping("/terms") - public CommonApiResponse> terms() { - return CommonApiResponse.okWithResult(service.terms()); - } - @Override @PostMapping("/register") public CommonApiResponse register( diff --git a/api/src/main/java/vook/server/api/web/routes/user/UserWebService.java b/api/src/main/java/vook/server/api/web/routes/user/UserWebService.java index 7567a87..3813dd8 100644 --- a/api/src/main/java/vook/server/api/web/routes/user/UserWebService.java +++ b/api/src/main/java/vook/server/api/web/routes/user/UserWebService.java @@ -6,12 +6,10 @@ import vook.server.api.app.terms.TermsService; import vook.server.api.app.user.UserService; import vook.server.api.config.auth.common.VookLoginUser; -import vook.server.api.model.terms.Terms; import vook.server.api.model.user.User; import vook.server.api.web.routes.user.reqres.UserInfoResponse; import vook.server.api.web.routes.user.reqres.UserOnboardingCompleteRequest; import vook.server.api.web.routes.user.reqres.UserRegisterRequest; -import vook.server.api.web.routes.user.reqres.UserTermsResponse; import java.util.List; @@ -28,11 +26,6 @@ public UserInfoResponse userInfo(VookLoginUser loginUser) { return UserInfoResponse.from(user); } - public List terms() { - List terms = termsService.findAll(); - return UserTermsResponse.from(terms); - } - public void register(VookLoginUser loginUser, UserRegisterRequest request) { List agreeTermsId = request.getAgreeTermsId(); if (!termsService.includeAllRequiredTerms(agreeTermsId)) { diff --git a/api/src/main/java/vook/server/api/web/routes/user/reqres/UserTermsResponse.java b/api/src/main/java/vook/server/api/web/routes/user/reqres/UserTermsResponse.java deleted file mode 100644 index 93c58e7..0000000 --- a/api/src/main/java/vook/server/api/web/routes/user/reqres/UserTermsResponse.java +++ /dev/null @@ -1,30 +0,0 @@ -package vook.server.api.web.routes.user.reqres; - -import lombok.Getter; -import vook.server.api.model.terms.Terms; - -import java.util.List; - -@Getter -public class UserTermsResponse { - - private Long id; - private String title; - private String content; - private Boolean required; - - public static List from(List terms) { - return terms.stream() - .map(UserTermsResponse::from) - .toList(); - } - - public static UserTermsResponse from(Terms terms) { - UserTermsResponse response = new UserTermsResponse(); - response.id = terms.getId(); - response.title = terms.getTitle(); - response.content = terms.getContent(); - response.required = terms.getRequired(); - return response; - } -} From be7248d0d9458289496fa6d71944046828d367e5 Mon Sep 17 00:00:00 2001 From: seungyeop-lee Date: Tue, 4 Jun 2024 14:19:40 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=EC=95=BD=EA=B4=80=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EB=A1=9C=EC=A7=81=20=EC=82=AD=EC=A0=9C=20#62?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/api/app/terms/TermsService.java | 31 ------------ .../api/app/terms/repo/TermsRepository.java | 10 ---- .../vook/server/api/app/user/UserService.java | 15 ++---- .../api/app/user/data/RegisterCommand.java | 25 ++-------- .../user/repo/UserTermsAgreeRepository.java | 7 --- .../server/api/devhelper/InitService.java | 24 ---------- .../vook/server/api/model/terms/Terms.java | 33 ------------- .../java/vook/server/api/model/user/User.java | 7 --- .../vook/server/api/model/user/UserInfo.java | 6 ++- .../server/api/model/user/UserTermsAgree.java | 37 --------------- .../api/web/routes/user/UserWebService.java | 10 +--- .../user/reqres/UserRegisterRequest.java | 47 ++----------------- 12 files changed, 18 insertions(+), 234 deletions(-) delete mode 100644 api/src/main/java/vook/server/api/app/terms/TermsService.java delete mode 100644 api/src/main/java/vook/server/api/app/terms/repo/TermsRepository.java delete mode 100644 api/src/main/java/vook/server/api/app/user/repo/UserTermsAgreeRepository.java delete mode 100644 api/src/main/java/vook/server/api/model/terms/Terms.java delete mode 100644 api/src/main/java/vook/server/api/model/user/UserTermsAgree.java diff --git a/api/src/main/java/vook/server/api/app/terms/TermsService.java b/api/src/main/java/vook/server/api/app/terms/TermsService.java deleted file mode 100644 index 5cd87a5..0000000 --- a/api/src/main/java/vook/server/api/app/terms/TermsService.java +++ /dev/null @@ -1,31 +0,0 @@ -package vook.server.api.app.terms; - -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import vook.server.api.app.terms.repo.TermsRepository; -import vook.server.api.model.terms.Terms; - -import java.util.HashSet; -import java.util.List; -import java.util.Optional; - -@Service -@RequiredArgsConstructor -public class TermsService { - - private final TermsRepository repository; - - public List findAll() { - return repository.findAll(); - } - - public Optional find(Long id) { - return repository.findById(id); - } - - public boolean includeAllRequiredTerms(List agreeTermsId) { - List requiredTerms = repository.findAllByRequired(true); - List requiredTermsId = requiredTerms.stream().map(Terms::getId).toList(); - return new HashSet<>(agreeTermsId).containsAll(requiredTermsId); - } -} diff --git a/api/src/main/java/vook/server/api/app/terms/repo/TermsRepository.java b/api/src/main/java/vook/server/api/app/terms/repo/TermsRepository.java deleted file mode 100644 index 512c594..0000000 --- a/api/src/main/java/vook/server/api/app/terms/repo/TermsRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package vook.server.api.app.terms.repo; - -import org.springframework.data.jpa.repository.JpaRepository; -import vook.server.api.model.terms.Terms; - -import java.util.List; - -public interface TermsRepository extends JpaRepository { - List findAllByRequired(Boolean required); -} diff --git a/api/src/main/java/vook/server/api/app/user/UserService.java b/api/src/main/java/vook/server/api/app/user/UserService.java index 152d8e1..6ec626e 100644 --- a/api/src/main/java/vook/server/api/app/user/UserService.java +++ b/api/src/main/java/vook/server/api/app/user/UserService.java @@ -8,11 +8,9 @@ import vook.server.api.app.user.repo.SocialUserRepository; import vook.server.api.app.user.repo.UserInfoRepository; import vook.server.api.app.user.repo.UserRepository; -import vook.server.api.app.user.repo.UserTermsAgreeRepository; import vook.server.api.model.user.SocialUser; import vook.server.api.model.user.User; import vook.server.api.model.user.UserInfo; -import vook.server.api.model.user.UserTermsAgree; import java.util.Optional; @@ -23,7 +21,6 @@ public class UserService { private final UserRepository repository; private final SocialUserRepository socialUserRepository; private final UserInfoRepository userInfoRepository; - private final UserTermsAgreeRepository userTermsAgreeRepository; public Optional findByProvider(String provider, String providerUserId) { return socialUserRepository.findByProviderAndProviderUserId(provider, providerUserId); @@ -47,16 +44,14 @@ public Optional findByUid(String uid) { public void register(RegisterCommand command) { User user = repository.findByUid(command.getUserUid()).orElseThrow(); - UserInfo userInfo = UserInfo.forRegisterOf(command.getNickname(), user); + UserInfo userInfo = UserInfo.forRegisterOf( + command.getNickname(), + user, + command.isMarketingEmailOptIn() + ); UserInfo savedUserInfo = userInfoRepository.save(userInfo); user.addUserInfo(savedUserInfo); - for (RegisterCommand.TermsAgree termsAgree : command.getTermsAgrees()) { - UserTermsAgree userTermsAgree = UserTermsAgree.of(user, termsAgree.getTerms(), termsAgree.getAgree()); - UserTermsAgree savedUserTermsAgree = userTermsAgreeRepository.save(userTermsAgree); - user.addUserTermsAgree(savedUserTermsAgree); - } - user.registered(); } diff --git a/api/src/main/java/vook/server/api/app/user/data/RegisterCommand.java b/api/src/main/java/vook/server/api/app/user/data/RegisterCommand.java index e76e7b1..e1fe00e 100644 --- a/api/src/main/java/vook/server/api/app/user/data/RegisterCommand.java +++ b/api/src/main/java/vook/server/api/app/user/data/RegisterCommand.java @@ -1,42 +1,23 @@ package vook.server.api.app.user.data; import lombok.Getter; -import vook.server.api.model.terms.Terms; - -import java.util.List; @Getter public class RegisterCommand { private String userUid; private String nickname; - private List termsAgrees; + private boolean marketingEmailOptIn; public static RegisterCommand of( String userUid, String nickname, - List termsAgrees + boolean marketingEmailOptIn ) { RegisterCommand command = new RegisterCommand(); command.userUid = userUid; command.nickname = nickname; - command.termsAgrees = termsAgrees; + command.marketingEmailOptIn = marketingEmailOptIn; return command; } - - @Getter - public static class TermsAgree { - private Terms terms; - private Boolean agree; - - public static TermsAgree of( - Terms terms, - Boolean agree - ) { - TermsAgree result = new TermsAgree(); - result.terms = terms; - result.agree = agree; - return result; - } - } } diff --git a/api/src/main/java/vook/server/api/app/user/repo/UserTermsAgreeRepository.java b/api/src/main/java/vook/server/api/app/user/repo/UserTermsAgreeRepository.java deleted file mode 100644 index bf212f7..0000000 --- a/api/src/main/java/vook/server/api/app/user/repo/UserTermsAgreeRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package vook.server.api.app.user.repo; - -import org.springframework.data.jpa.repository.JpaRepository; -import vook.server.api.model.user.UserTermsAgree; - -public interface UserTermsAgreeRepository extends JpaRepository { -} diff --git a/api/src/main/java/vook/server/api/devhelper/InitService.java b/api/src/main/java/vook/server/api/devhelper/InitService.java index 76bd72c..bc0f168 100644 --- a/api/src/main/java/vook/server/api/devhelper/InitService.java +++ b/api/src/main/java/vook/server/api/devhelper/InitService.java @@ -6,17 +6,12 @@ import org.springframework.transaction.annotation.Transactional; import vook.server.api.app.demo.repo.DemoTermRepository; import vook.server.api.app.demo.repo.DemoTermSynonymRepository; -import vook.server.api.app.terms.repo.TermsRepository; import vook.server.api.app.user.repo.SocialUserRepository; import vook.server.api.app.user.repo.UserInfoRepository; import vook.server.api.app.user.repo.UserRepository; -import vook.server.api.app.user.repo.UserTermsAgreeRepository; import vook.server.api.model.demo.DemoTerm; -import vook.server.api.model.terms.Terms; import vook.server.api.outbound.search.DemoTermSearchService; -import java.io.IOException; -import java.io.InputStream; import java.util.List; @Service @@ -28,21 +23,15 @@ public class InitService { private final DemoTermRepository demoTermRepository; private final DemoTermSynonymRepository demoTermSynonymRepository; - private final UserTermsAgreeRepository userTermsAgreeRepository; private final UserInfoRepository userInfoRepository; private final SocialUserRepository socialUserRepository; private final UserRepository userRepository; - private final TermsRepository termsRepository; private final DemoTermSearchService searchService; private final TestTermsLoader testTermsLoader; public void init() { deleteAll(); - termsRepository.save(Terms.of("이용약관", loadContents("classpath:init/이용약관.txt"), true)); - termsRepository.save(Terms.of("개인정보 수집 이용 약관", loadContents("classpath:init/개인정보_수집_이용_약관.txt"), true)); - termsRepository.save(Terms.of("마케팅 메일 수신 약관", loadContents("classpath:init/마케팅_메일_수신_약관.txt"), false)); - List devTerms = testTermsLoader.getTerms("classpath:init/개발.tsv"); demoTermRepository.saveAll(devTerms); @@ -56,24 +45,11 @@ private void deleteAll() { demoTermRepository.deleteAllInBatch(); // 사용자 - userTermsAgreeRepository.deleteAllInBatch(); userInfoRepository.deleteAllInBatch(); socialUserRepository.deleteAllInBatch(); userRepository.deleteAllInBatch(); - // 약관 - termsRepository.deleteAllInBatch(); - // 검색 엔진 searchService.clearAll(); } - - private String loadContents(String location) { - try { - InputStream inputStream = resourceLoader.getResource(location).getInputStream(); - return new String(inputStream.readAllBytes()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } } diff --git a/api/src/main/java/vook/server/api/model/terms/Terms.java b/api/src/main/java/vook/server/api/model/terms/Terms.java deleted file mode 100644 index ed2f3fa..0000000 --- a/api/src/main/java/vook/server/api/model/terms/Terms.java +++ /dev/null @@ -1,33 +0,0 @@ -package vook.server.api.model.terms; - -import jakarta.persistence.*; -import lombok.Getter; - -@Getter -@Entity -@Table(name = "terms") -public class Terms { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String title; - - @Column(columnDefinition = "TEXT") - private String content; - - private Boolean required; - - public static Terms of( - String title, - String content, - Boolean required - ) { - Terms result = new Terms(); - result.title = title; - result.content = content; - result.required = required; - return result; - } -} diff --git a/api/src/main/java/vook/server/api/model/user/User.java b/api/src/main/java/vook/server/api/model/user/User.java index 59d12e4..d02d893 100644 --- a/api/src/main/java/vook/server/api/model/user/User.java +++ b/api/src/main/java/vook/server/api/model/user/User.java @@ -32,9 +32,6 @@ public class User { @OneToOne(mappedBy = "user") private UserInfo userInfo; - @OneToMany(mappedBy = "user", fetch = FetchType.LAZY) - private List userTermsAgrees = new ArrayList<>(); - public static User forSignUpFromSocialOf( String email ) { @@ -53,10 +50,6 @@ public void addUserInfo(UserInfo userInfo) { this.userInfo = userInfo; } - public void addUserTermsAgree(UserTermsAgree userTermsAgree) { - userTermsAgrees.add(userTermsAgree); - } - public void registered() { this.status = UserStatus.REGISTERED; } diff --git a/api/src/main/java/vook/server/api/model/user/UserInfo.java b/api/src/main/java/vook/server/api/model/user/UserInfo.java index 16fccb8..d0bffae 100644 --- a/api/src/main/java/vook/server/api/model/user/UserInfo.java +++ b/api/src/main/java/vook/server/api/model/user/UserInfo.java @@ -14,6 +14,8 @@ public class UserInfo { private String nickname; + private Boolean marketingEmailOptIn; + private String funnel; private String job; @@ -24,11 +26,13 @@ public class UserInfo { public static UserInfo forRegisterOf( String nickname, - User user + User user, + boolean marketingEmailOptIn ) { UserInfo result = new UserInfo(); result.nickname = nickname; result.user = user; + result.marketingEmailOptIn = marketingEmailOptIn; return result; } diff --git a/api/src/main/java/vook/server/api/model/user/UserTermsAgree.java b/api/src/main/java/vook/server/api/model/user/UserTermsAgree.java deleted file mode 100644 index b2ee978..0000000 --- a/api/src/main/java/vook/server/api/model/user/UserTermsAgree.java +++ /dev/null @@ -1,37 +0,0 @@ -package vook.server.api.model.user; - -import jakarta.persistence.*; -import lombok.Getter; -import vook.server.api.model.terms.Terms; - -@Getter -@Entity -@Table(name = "user_terms_agree") -public class UserTermsAgree { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @ManyToOne - @JoinColumn(name = "user_id") - private User user; - - @ManyToOne - @JoinColumn(name = "terms_id") - private Terms terms; - - private Boolean agree; - - public static UserTermsAgree of( - User user, - Terms terms, - Boolean agree - ) { - UserTermsAgree result = new UserTermsAgree(); - result.user = user; - result.terms = terms; - result.agree = agree; - return result; - } -} diff --git a/api/src/main/java/vook/server/api/web/routes/user/UserWebService.java b/api/src/main/java/vook/server/api/web/routes/user/UserWebService.java index 3813dd8..ff02735 100644 --- a/api/src/main/java/vook/server/api/web/routes/user/UserWebService.java +++ b/api/src/main/java/vook/server/api/web/routes/user/UserWebService.java @@ -3,7 +3,6 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import vook.server.api.app.terms.TermsService; import vook.server.api.app.user.UserService; import vook.server.api.config.auth.common.VookLoginUser; import vook.server.api.model.user.User; @@ -11,15 +10,12 @@ import vook.server.api.web.routes.user.reqres.UserOnboardingCompleteRequest; import vook.server.api.web.routes.user.reqres.UserRegisterRequest; -import java.util.List; - @Service @Transactional @RequiredArgsConstructor public class UserWebService { private final UserService userService; - private final TermsService termsService; public UserInfoResponse userInfo(VookLoginUser loginUser) { User user = userService.findByUid(loginUser.getUid()).orElseThrow(); @@ -27,11 +23,7 @@ public UserInfoResponse userInfo(VookLoginUser loginUser) { } public void register(VookLoginUser loginUser, UserRegisterRequest request) { - List agreeTermsId = request.getAgreeTermsId(); - if (!termsService.includeAllRequiredTerms(agreeTermsId)) { - throw new IllegalArgumentException("동의 필수인 약관이 누락되었습니다."); - } - userService.register(request.toCommand(loginUser.getUid(), termsService::find)); + userService.register(request.toCommand(loginUser.getUid())); } public void onboardingComplete(VookLoginUser loginUser, UserOnboardingCompleteRequest request) { diff --git a/api/src/main/java/vook/server/api/web/routes/user/reqres/UserRegisterRequest.java b/api/src/main/java/vook/server/api/web/routes/user/reqres/UserRegisterRequest.java index 17bb106..02d84fe 100644 --- a/api/src/main/java/vook/server/api/web/routes/user/reqres/UserRegisterRequest.java +++ b/api/src/main/java/vook/server/api/web/routes/user/reqres/UserRegisterRequest.java @@ -1,59 +1,20 @@ package vook.server.api.web.routes.user.reqres; -import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import vook.server.api.app.user.data.RegisterCommand; -import vook.server.api.model.terms.Terms; - -import java.util.List; -import java.util.Optional; @Data public class UserRegisterRequest { - @Schema private String nickname; + private boolean requiredTermsAgree; + private boolean marketingEmailOptIn; - @Schema - private List termsAgrees; - - public RegisterCommand toCommand(String userUid, TermsFinder termsFinder) { + public RegisterCommand toCommand(String userUid) { return RegisterCommand.of( userUid, nickname, - termsAgrees.stream().map(termsAgree -> { - Terms terms = termsFinder.find(termsAgree.id).orElseThrow(); - return RegisterCommand.TermsAgree.of(terms, termsAgree.agree); - }).toList() + marketingEmailOptIn ); } - - @FunctionalInterface - public interface TermsFinder { - Optional find(Long id); - } - - @Schema(hidden = true) - public List getAgreeTermsId() { - return termsAgrees.stream() - .filter(t -> t.agree) - .map(t -> t.id) - .toList(); - } - - @Data - public static class TermsAgree { - private Long id; - private Boolean agree; - - public static TermsAgree of( - Long id, - Boolean agree - ) { - TermsAgree result = new TermsAgree(); - result.id = id; - result.agree = agree; - return result; - } - } } From 6b2a854146840fbf5d52479d97a44aac96498236 Mon Sep 17 00:00:00 2001 From: seungyeop-lee Date: Tue, 4 Jun 2024 14:58:57 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EB=B0=8F=20=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=ED=85=8C=EC=8A=A4=ED=8A=B8=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 --- .../java/vook/server/api/model/user/User.java | 1 + .../api/testhelper/HttpEntityBuilder.java | 18 +++ ...{ApiTest.java => IntegrationTestBase.java} | 7 +- .../api/testhelper/TestDataCreator.java | 45 +++++++ .../server/api/testhelper/WebApiTest.java | 10 ++ .../server/api/testhelper/WebServiceTest.java | 7 + .../web/routes/demo/DemoWebServiceTest.java | 4 +- .../routes/health/HealthControllerTest.java | 4 +- .../routes/user/UserRestControllerTest.java | 44 ++++++ .../web/routes/user/UserWebServiceTest.java | 126 ++++++++++++++++++ 10 files changed, 256 insertions(+), 10 deletions(-) create mode 100644 api/src/test/java/vook/server/api/testhelper/HttpEntityBuilder.java rename api/src/test/java/vook/server/api/testhelper/{ApiTest.java => IntegrationTestBase.java} (89%) create mode 100644 api/src/test/java/vook/server/api/testhelper/TestDataCreator.java create mode 100644 api/src/test/java/vook/server/api/testhelper/WebApiTest.java create mode 100644 api/src/test/java/vook/server/api/testhelper/WebServiceTest.java create mode 100644 api/src/test/java/vook/server/api/web/routes/user/UserRestControllerTest.java create mode 100644 api/src/test/java/vook/server/api/web/routes/user/UserWebServiceTest.java diff --git a/api/src/main/java/vook/server/api/model/user/User.java b/api/src/main/java/vook/server/api/model/user/User.java index d02d893..cfa454b 100644 --- a/api/src/main/java/vook/server/api/model/user/User.java +++ b/api/src/main/java/vook/server/api/model/user/User.java @@ -19,6 +19,7 @@ public class User { private String uid; + @Column(unique = true) private String email; @Enumerated(EnumType.STRING) diff --git a/api/src/test/java/vook/server/api/testhelper/HttpEntityBuilder.java b/api/src/test/java/vook/server/api/testhelper/HttpEntityBuilder.java new file mode 100644 index 0000000..b7d5842 --- /dev/null +++ b/api/src/test/java/vook/server/api/testhelper/HttpEntityBuilder.java @@ -0,0 +1,18 @@ +package vook.server.api.testhelper; + +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; + +public class HttpEntityBuilder { + + private final HttpHeaders headers = new HttpHeaders(); + + public HttpEntityBuilder addHeader(String key, String value) { + headers.add(key, value); + return this; + } + + public HttpEntity build() { + return new HttpEntity<>(headers); + } +} diff --git a/api/src/test/java/vook/server/api/testhelper/ApiTest.java b/api/src/test/java/vook/server/api/testhelper/IntegrationTestBase.java similarity index 89% rename from api/src/test/java/vook/server/api/testhelper/ApiTest.java rename to api/src/test/java/vook/server/api/testhelper/IntegrationTestBase.java index 689c31d..44e6479 100644 --- a/api/src/test/java/vook/server/api/testhelper/ApiTest.java +++ b/api/src/test/java/vook/server/api/testhelper/IntegrationTestBase.java @@ -1,9 +1,7 @@ package vook.server.api.testhelper; import org.junit.jupiter.api.BeforeEach; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -16,10 +14,7 @@ import static vook.server.api.config.TimeZoneConfig.DEFAULT_TIME_ZONE; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -public abstract class ApiTest { - - @Autowired - protected TestRestTemplate rest; +public abstract class IntegrationTestBase { @ServiceConnection protected static final MariaDBContainer mariaDBContainer = new MariaDBContainer<>("mariadb:10.11") diff --git a/api/src/test/java/vook/server/api/testhelper/TestDataCreator.java b/api/src/test/java/vook/server/api/testhelper/TestDataCreator.java new file mode 100644 index 0000000..7d9f312 --- /dev/null +++ b/api/src/test/java/vook/server/api/testhelper/TestDataCreator.java @@ -0,0 +1,45 @@ +package vook.server.api.testhelper; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import vook.server.api.app.auth.TokenService; +import vook.server.api.app.auth.data.GeneratedToken; +import vook.server.api.app.user.UserService; +import vook.server.api.app.user.data.CompleteOnboardingCommand; +import vook.server.api.app.user.data.RegisterCommand; +import vook.server.api.app.user.data.SignUpFromSocialCommand; +import vook.server.api.model.user.SocialUser; +import vook.server.api.model.user.User; + +@Component +@Transactional +@RequiredArgsConstructor +public class TestDataCreator { + + private final UserService userService; + private final TokenService tokenService; + + public User createUnregisteredUser() { + SocialUser user = userService.signUpFromSocial( + SignUpFromSocialCommand.of("testProvider", "testProviderUserId", "testEmail@test.com") + ); + return user.getUser(); + } + + public User createRegisteredUser() { + User user = createUnregisteredUser(); + userService.register(RegisterCommand.of(user.getUid(), "testNickname", true)); + return userService.findByUid(user.getUid()).orElseThrow(); + } + + public User createCompletedOnboardingUser() { + User user = createRegisteredUser(); + userService.completeOnboarding(CompleteOnboardingCommand.of(user.getUid(), "testFunnel", "testJob")); + return userService.findByUid(user.getUid()).orElseThrow(); + } + + public GeneratedToken createToken(User user) { + return tokenService.generateToken(user.getUid()); + } +} diff --git a/api/src/test/java/vook/server/api/testhelper/WebApiTest.java b/api/src/test/java/vook/server/api/testhelper/WebApiTest.java new file mode 100644 index 0000000..d8abc27 --- /dev/null +++ b/api/src/test/java/vook/server/api/testhelper/WebApiTest.java @@ -0,0 +1,10 @@ +package vook.server.api.testhelper; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.web.client.TestRestTemplate; + +public abstract class WebApiTest extends IntegrationTestBase { + + @Autowired + protected TestRestTemplate rest; +} diff --git a/api/src/test/java/vook/server/api/testhelper/WebServiceTest.java b/api/src/test/java/vook/server/api/testhelper/WebServiceTest.java new file mode 100644 index 0000000..d223b7d --- /dev/null +++ b/api/src/test/java/vook/server/api/testhelper/WebServiceTest.java @@ -0,0 +1,7 @@ +package vook.server.api.testhelper; + +import org.springframework.transaction.annotation.Transactional; + +@Transactional +public abstract class WebServiceTest extends IntegrationTestBase { +} diff --git a/api/src/test/java/vook/server/api/web/routes/demo/DemoWebServiceTest.java b/api/src/test/java/vook/server/api/web/routes/demo/DemoWebServiceTest.java index adf5009..c955ab1 100644 --- a/api/src/test/java/vook/server/api/web/routes/demo/DemoWebServiceTest.java +++ b/api/src/test/java/vook/server/api/web/routes/demo/DemoWebServiceTest.java @@ -10,7 +10,7 @@ import vook.server.api.devhelper.TestTermsLoader; import vook.server.api.model.demo.DemoTerm; import vook.server.api.outbound.search.DemoTermSearchService; -import vook.server.api.testhelper.ApiTest; +import vook.server.api.testhelper.IntegrationTestBase; import vook.server.api.web.routes.demo.reqres.SearchTermRequest; import vook.server.api.web.routes.demo.reqres.SearchTermResponse; @@ -20,7 +20,7 @@ @Transactional @TestInstance(TestInstance.Lifecycle.PER_CLASS) -class DemoWebServiceTest extends ApiTest { +class DemoWebServiceTest extends IntegrationTestBase { @Autowired private DemoWebService demoWebService; diff --git a/api/src/test/java/vook/server/api/web/routes/health/HealthControllerTest.java b/api/src/test/java/vook/server/api/web/routes/health/HealthControllerTest.java index 950e511..5dd285d 100644 --- a/api/src/test/java/vook/server/api/web/routes/health/HealthControllerTest.java +++ b/api/src/test/java/vook/server/api/web/routes/health/HealthControllerTest.java @@ -4,11 +4,11 @@ import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import vook.server.api.testhelper.ApiTest; +import vook.server.api.testhelper.WebApiTest; import static org.assertj.core.api.Assertions.assertThat; -class HealthControllerTest extends ApiTest { +class HealthControllerTest extends WebApiTest { @Test @DisplayName("헬스체크") diff --git a/api/src/test/java/vook/server/api/web/routes/user/UserRestControllerTest.java b/api/src/test/java/vook/server/api/web/routes/user/UserRestControllerTest.java new file mode 100644 index 0000000..677f683 --- /dev/null +++ b/api/src/test/java/vook/server/api/web/routes/user/UserRestControllerTest.java @@ -0,0 +1,44 @@ +package vook.server.api.web.routes.user; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import vook.server.api.app.auth.data.GeneratedToken; +import vook.server.api.model.user.User; +import vook.server.api.model.user.UserStatus; +import vook.server.api.testhelper.HttpEntityBuilder; +import vook.server.api.testhelper.TestDataCreator; +import vook.server.api.testhelper.WebApiTest; + +import static org.assertj.core.api.Assertions.assertThat; + +class UserRestControllerTest extends WebApiTest { + + @Autowired + TestDataCreator testDataCreator; + + @Test + void userInfo() { + // given + User unregisteredUser = testDataCreator.createUnregisteredUser(); + GeneratedToken token = testDataCreator.createToken(unregisteredUser); + + // when + var res = rest.exchange( + "/user/info", + HttpMethod.GET, + new HttpEntityBuilder() + .addHeader("Authorization", "Bearer " + token.getAccessToken()) + .build(), + UserApi.UserApiUerInfoResponse.class + ); + + // then + assertThat(res.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(res.getBody()).isNotNull(); + assertThat(res.getBody().getResult().getUid()).isEqualTo(unregisteredUser.getUid()); + assertThat(res.getBody().getResult().getEmail()).isEqualTo(unregisteredUser.getEmail()); + assertThat(res.getBody().getResult().getStatus()).isEqualTo(UserStatus.SOCIAL_LOGIN_COMPLETED); + } +} diff --git a/api/src/test/java/vook/server/api/web/routes/user/UserWebServiceTest.java b/api/src/test/java/vook/server/api/web/routes/user/UserWebServiceTest.java new file mode 100644 index 0000000..daa3a69 --- /dev/null +++ b/api/src/test/java/vook/server/api/web/routes/user/UserWebServiceTest.java @@ -0,0 +1,126 @@ +package vook.server.api.web.routes.user; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import vook.server.api.app.user.UserService; +import vook.server.api.config.auth.common.VookLoginUser; +import vook.server.api.model.user.User; +import vook.server.api.model.user.UserStatus; +import vook.server.api.testhelper.TestDataCreator; +import vook.server.api.testhelper.WebServiceTest; +import vook.server.api.web.routes.user.reqres.UserInfoResponse; +import vook.server.api.web.routes.user.reqres.UserOnboardingCompleteRequest; +import vook.server.api.web.routes.user.reqres.UserRegisterRequest; + +import static org.assertj.core.api.Assertions.assertThat; + +class UserWebServiceTest extends WebServiceTest { + + @Autowired + UserWebService userWebService; + + @Autowired + TestDataCreator testDataCreator; + @Autowired + UserService userService; + + @Test + @DisplayName("사용자 정보 조회 - 정상; 회원가입 전 사용자") + void userInfo1() { + // given + User unregisteredUser = testDataCreator.createUnregisteredUser(); + VookLoginUser vookLoginUser = VookLoginUser.of(unregisteredUser.getUid()); + + // when + UserInfoResponse response = userWebService.userInfo(vookLoginUser); + + // then + assertThat(response).isNotNull(); + assertThat(response.getUid()).isEqualTo(unregisteredUser.getUid()); + assertThat(response.getEmail()).isEqualTo(unregisteredUser.getEmail()); + assertThat(response.getNickname()).isNull(); + assertThat(response.getStatus()).isEqualTo(UserStatus.SOCIAL_LOGIN_COMPLETED); + } + + @Test + @DisplayName("사용자 정보 조회 - 정상; 회원가입 후 사용자") + void userInfo2() { + // given + User registeredUser = testDataCreator.createRegisteredUser(); + VookLoginUser vookLoginUser = VookLoginUser.of(registeredUser.getUid()); + + // when + UserInfoResponse response = userWebService.userInfo(vookLoginUser); + + // then + assertThat(response).isNotNull(); + assertThat(response.getUid()).isEqualTo(registeredUser.getUid()); + assertThat(response.getEmail()).isEqualTo(registeredUser.getEmail()); + assertThat(response.getNickname()).isEqualTo(registeredUser.getUserInfo().getNickname()); + assertThat(response.getStatus()).isEqualTo(UserStatus.REGISTERED); + } + + @Test + @DisplayName("사용자 정보 조회 - 정상; 온보딩 완료 사용자") + void userInfo3() { + // given + User completedOnboardingUser = testDataCreator.createCompletedOnboardingUser(); + VookLoginUser vookLoginUser = VookLoginUser.of(completedOnboardingUser.getUid()); + + // when + UserInfoResponse response = userWebService.userInfo(vookLoginUser); + + // then + assertThat(response).isNotNull(); + assertThat(response.getUid()).isEqualTo(completedOnboardingUser.getUid()); + assertThat(response.getEmail()).isEqualTo(completedOnboardingUser.getEmail()); + assertThat(response.getNickname()).isEqualTo(completedOnboardingUser.getUserInfo().getNickname()); + assertThat(response.getStatus()).isEqualTo(UserStatus.ONBOARDING_COMPLETED); + } + + @Test + @DisplayName("회원 가입 - 정상") + void register1() { + // given + User unregisteredUser = testDataCreator.createUnregisteredUser(); + VookLoginUser vookLoginUser = VookLoginUser.of(unregisteredUser.getUid()); + + UserRegisterRequest request = new UserRegisterRequest(); + request.setNickname("nickname"); + request.setRequiredTermsAgree(true); + request.setMarketingEmailOptIn(true); + + // when + userWebService.register(vookLoginUser, request); + + // then + User user = userService.findByUid(unregisteredUser.getUid()).orElseThrow(); + assertThat(user.getStatus()).isEqualTo(UserStatus.REGISTERED); + assertThat(user.getUserInfo()).isNotNull(); + assertThat(user.getUserInfo().getNickname()).isEqualTo(request.getNickname()); + assertThat(user.getUserInfo().getMarketingEmailOptIn()).isEqualTo(request.isMarketingEmailOptIn()); + } + + @Test + @DisplayName("온보딩 완료 - 정상") + void onboardingComplete1() { + // given + User registeredUser = testDataCreator.createRegisteredUser(); + VookLoginUser vookLoginUser = VookLoginUser.of(registeredUser.getUid()); + + UserOnboardingCompleteRequest request = new UserOnboardingCompleteRequest(); + request.setFunnel("testFunnel"); + request.setJob("testJob"); + + // when + userWebService.onboardingComplete(vookLoginUser, request); + + // then + User user = userService.findByUid(registeredUser.getUid()).orElseThrow(); + assertThat(user.getStatus()).isEqualTo(UserStatus.ONBOARDING_COMPLETED); + assertThat(user.getUserInfo()).isNotNull(); + assertThat(user.getUserInfo().getFunnel()).isEqualTo(request.getFunnel()); + assertThat(user.getUserInfo().getJob()).isEqualTo(request.getJob()); + } +} From 2433b24f91c180cbad2a74133b597885e321384c Mon Sep 17 00:00:00 2001 From: seungyeop-lee Date: Wed, 5 Jun 2024 20:43:56 +0900 Subject: [PATCH 4/4] chore: dagger version up 0.11.4 -> 0.11.6 --- .github/workflows/deploy-dev.yml | 2 +- .github/workflows/deploy-stag.yml | 2 +- cicd/dagger.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-dev.yml b/.github/workflows/deploy-dev.yml index fed2eb5..ce183eb 100644 --- a/.github/workflows/deploy-dev.yml +++ b/.github/workflows/deploy-dev.yml @@ -24,7 +24,7 @@ jobs: SSH_DEST: ${{ secrets.DEV_SSH_DEST }} SSH_KEY: ${{ secrets.DEV_SSH_KEY }} with: - version: 0.11.4 + version: 0.11.6 verb: call module: ./cicd args: >- diff --git a/.github/workflows/deploy-stag.yml b/.github/workflows/deploy-stag.yml index c9ed2ae..ffad63f 100644 --- a/.github/workflows/deploy-stag.yml +++ b/.github/workflows/deploy-stag.yml @@ -24,7 +24,7 @@ jobs: SSH_DEST: ${{ secrets.STAG_SSH_DEST }} SSH_KEY: ${{ secrets.STAG_SSH_KEY }} with: - version: 0.11.4 + version: 0.11.6 verb: call module: ./cicd args: >- diff --git a/cicd/dagger.json b/cicd/dagger.json index d06cab5..12deb9a 100644 --- a/cicd/dagger.json +++ b/cicd/dagger.json @@ -24,5 +24,5 @@ } ], "source": "dagger", - "engineVersion": "v0.11.4" + "engineVersion": "v0.11.6" }