From f32f686608276f290fcfea4e23e78c6c3580d3ac Mon Sep 17 00:00:00 2001 From: bum12ark Date: Thu, 24 Feb 2022 11:07:34 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat(user-service):=20=EC=A0=90=EC=A3=BC=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20=EB=A1=9C=EC=A7=81=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 - request validation 구현 --- .../domain/user/service/UserService.java | 6 +-- .../domain/user/service/UserServiceImpl.java | 7 ++- .../domain/user/web/UserController.java | 49 ++++++++++++++----- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserService.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserService.java index a6e5a93..3d09f91 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserService.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserService.java @@ -2,12 +2,8 @@ package com.justpickup.userservice.domain.user.service; import com.justpickup.userservice.domain.user.dto.CustomerDto; import com.justpickup.userservice.domain.user.dto.StoreOwnerDto; -import com.justpickup.userservice.domain.user.entity.StoreOwner; public interface UserService { - - CustomerDto findCustomerByUserId(Long userId); - StoreOwner saveStoreOwner(StoreOwnerDto storeOwnerDto); - + void saveStoreOwner(StoreOwnerDto storeOwnerDto); } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserServiceImpl.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserServiceImpl.java index f3b01a4..aa4e323 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserServiceImpl.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserServiceImpl.java @@ -32,8 +32,6 @@ public class UserServiceImpl implements UserService, UserDetailsService { private final UserRepository userRepository; private final PasswordEncoder passwordEncoder; - - @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userRepository.findByEmail(username) @@ -54,12 +52,13 @@ public class UserServiceImpl implements UserService, UserDetailsService { @Override @Transactional - public StoreOwner saveStoreOwner(StoreOwnerDto storeOwnerDto) { + public void saveStoreOwner(StoreOwnerDto storeOwnerDto) { String encode = passwordEncoder.encode(storeOwnerDto.getPassword()); StoreOwner storeOwner = new StoreOwner(storeOwnerDto.getEmail(), encode, storeOwnerDto.getName(), storeOwnerDto.getPhoneNumber(), storeOwnerDto.getBusinessNumber()); - return userRepository.save(storeOwner); + StoreOwner save = userRepository.save(storeOwner); } + } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java index bd7b6a9..cb6fe14 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java @@ -1,24 +1,21 @@ package com.justpickup.userservice.domain.user.web; import com.justpickup.userservice.domain.user.dto.CustomerDto; -import com.justpickup.userservice.domain.user.entity.Customer; +import com.justpickup.userservice.domain.user.dto.StoreOwnerDto; import com.justpickup.userservice.domain.user.service.UserService; import com.justpickup.userservice.global.dto.Result; -import lombok.*; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpRequest; 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.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.RestTemplate; +import org.springframework.web.bind.annotation.*; -import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; -import java.util.Objects; -import java.util.Optional; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotEmpty; @RestController @RequiredArgsConstructor @@ -51,6 +48,36 @@ public class UserController { } } + @PostMapping("/store/join") + public ResponseEntity joinStoreOwner(@Valid @RequestBody JoinStoreOwnerRequest joinRequest) { + // 회원 가입 + userService.saveStoreOwner(joinRequest.toStoreOwnerDto()); + + return ResponseEntity.status(HttpStatus.CREATED) + .body(Result.createSuccessResult(null)); + } + + @Data @NoArgsConstructor @AllArgsConstructor + static class JoinStoreOwnerRequest { + @Email(message = "email 형식이 아닙니다.") + @NotEmpty + private String email; + @NotEmpty + private String password; + @NotEmpty + private String name; + @NotEmpty + private String phoneNumber; + @NotEmpty + private String businessNumber; + + public StoreOwnerDto toStoreOwnerDto() { + return StoreOwnerDto.builder() + .email(email).password(password).name(name) + .password(password).businessNumber(businessNumber) + .build(); + } + } } From eb7e7cc8b373486b4bcece8ece8211f80f140b30 Mon Sep 17 00:00:00 2001 From: bum12ark Date: Thu, 24 Feb 2022 20:10:12 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat(owner-vue):=20=EC=A0=90=EC=A3=BC?= =?UTF-8?q?=EC=9A=A9=20=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 입력값 validation 추가 --- owner-vue/src/App.vue | 29 ++---- owner-vue/src/api/user.js | 8 ++ owner-vue/src/main.js | 6 +- owner-vue/src/router/index.js | 71 +++++++++----- owner-vue/src/views/About.vue | 5 - owner-vue/src/views/Home.vue | 15 --- owner-vue/src/views/Layout/AuthLayout.vue | 21 +++++ .../src/views/Layout/DashboardLayout.vue | 33 +++++++ .../{components => views/Layout}/Sidebar.vue | 0 .../{components => views/Layout}/Topbar.vue | 0 owner-vue/src/views/RegisterUser.vue | 94 +++++++++++++++++++ owner-vue/vue.config.js | 12 --- 12 files changed, 213 insertions(+), 81 deletions(-) create mode 100644 owner-vue/src/api/user.js delete mode 100644 owner-vue/src/views/About.vue delete mode 100644 owner-vue/src/views/Home.vue create mode 100644 owner-vue/src/views/Layout/AuthLayout.vue create mode 100644 owner-vue/src/views/Layout/DashboardLayout.vue rename owner-vue/src/{components => views/Layout}/Sidebar.vue (100%) rename owner-vue/src/{components => views/Layout}/Topbar.vue (100%) create mode 100644 owner-vue/src/views/RegisterUser.vue diff --git a/owner-vue/src/App.vue b/owner-vue/src/App.vue index 1121e76..650d4c7 100644 --- a/owner-vue/src/App.vue +++ b/owner-vue/src/App.vue @@ -1,28 +1,13 @@ + + \ No newline at end of file diff --git a/owner-vue/src/api/user.js b/owner-vue/src/api/user.js new file mode 100644 index 0000000..50ad23c --- /dev/null +++ b/owner-vue/src/api/user.js @@ -0,0 +1,8 @@ +import axios from "axios"; + +export default { + + requestRegisterUser(user) { + return axios.post("http://localhost:8001/user-service/store-owner", user); + } +} \ No newline at end of file diff --git a/owner-vue/src/main.js b/owner-vue/src/main.js index 79288dd..c2d00de 100644 --- a/owner-vue/src/main.js +++ b/owner-vue/src/main.js @@ -1,9 +1,7 @@ -import 'font-awesome/css/font-awesome.min.css' // Ensure you are using css-loader import Vue from 'vue' import App from './App.vue' import vuetify from './plugins/vuetify' import router from './router' -import axios from "axios"; Vue.config.productionTip = false @@ -11,6 +9,4 @@ new Vue({ vuetify, router, render: h => h(App) -}).$mount('#app') -Vue.component('axios',axios) - +}).$mount('#app') \ No newline at end of file diff --git a/owner-vue/src/router/index.js b/owner-vue/src/router/index.js index 12f7d17..1fc109b 100644 --- a/owner-vue/src/router/index.js +++ b/owner-vue/src/router/index.js @@ -1,33 +1,60 @@ import Vue from 'vue' import VueRouter from 'vue-router' +import DashboardLayout from "@/views/Layout/DashboardLayout"; +import AuthLayout from "@/views/Layout/AuthLayout"; + Vue.use(VueRouter) const routes = [ + { + path: '/dashboard', + redirect: 'dashboard', + component: DashboardLayout, + children: [ + { + path: "/dashboard", + name: 'dashboard', + component: () => import('./../views/Dashboard') + }, + { + path: '/category', + name: 'category', + component: () => import('./../views/Category') + }, + { + path: '/menu', + name: 'menu', + component: () => import('./../views/Menu') + }, + { + path: '/prev-order', + name: 'prev-order', + component: () => import('./../views/PrevOrder') + }, + { + path: '/order', + name: 'order', + component: () => import('./../views/Order.vue') + } + ] + }, { path: '/', - name: 'dashboard', - component: () => import('./../views/Dashboard') - }, - { - path: '/category', - name: 'category', - component: () => import('./../views/Category') - }, - { - path: '/menu', - name: 'menu', - component: () => import('./../views/Menu') - }, - { - path: '/prev-order', - name: 'prev-order', - component: () => import('./../views/PrevOrder') - }, - { - path: '/order', - name: 'order', - component: () => import('./../views/Order.vue') + redirect: 'login', + component: AuthLayout, + children: [ + { + path: '/login', + name: 'login', + component: () => import('./../views/LoginUser.vue') + }, + { + path: '/register', + name: 'register', + component: () => import('./../views/RegisterUser.vue') + } + ] } ] diff --git a/owner-vue/src/views/About.vue b/owner-vue/src/views/About.vue deleted file mode 100644 index 3fa2807..0000000 --- a/owner-vue/src/views/About.vue +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/owner-vue/src/views/Home.vue b/owner-vue/src/views/Home.vue deleted file mode 100644 index 44553c4..0000000 --- a/owner-vue/src/views/Home.vue +++ /dev/null @@ -1,15 +0,0 @@ - - - diff --git a/owner-vue/src/views/Layout/AuthLayout.vue b/owner-vue/src/views/Layout/AuthLayout.vue new file mode 100644 index 0000000..f5d3b62 --- /dev/null +++ b/owner-vue/src/views/Layout/AuthLayout.vue @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/owner-vue/src/views/Layout/DashboardLayout.vue b/owner-vue/src/views/Layout/DashboardLayout.vue new file mode 100644 index 0000000..ea79710 --- /dev/null +++ b/owner-vue/src/views/Layout/DashboardLayout.vue @@ -0,0 +1,33 @@ + + + + + \ No newline at end of file diff --git a/owner-vue/src/components/Sidebar.vue b/owner-vue/src/views/Layout/Sidebar.vue similarity index 100% rename from owner-vue/src/components/Sidebar.vue rename to owner-vue/src/views/Layout/Sidebar.vue diff --git a/owner-vue/src/components/Topbar.vue b/owner-vue/src/views/Layout/Topbar.vue similarity index 100% rename from owner-vue/src/components/Topbar.vue rename to owner-vue/src/views/Layout/Topbar.vue diff --git a/owner-vue/src/views/RegisterUser.vue b/owner-vue/src/views/RegisterUser.vue new file mode 100644 index 0000000..40ea794 --- /dev/null +++ b/owner-vue/src/views/RegisterUser.vue @@ -0,0 +1,94 @@ + + + + + \ No newline at end of file diff --git a/owner-vue/vue.config.js b/owner-vue/vue.config.js index bc0acb2..167eb2e 100644 --- a/owner-vue/vue.config.js +++ b/owner-vue/vue.config.js @@ -2,16 +2,4 @@ module.exports = { transpileDependencies: [ 'vuetify' ], - devServer:{ - proxy:{ - 'store-service/' :{ - target: 'http://localhost:8001', - ws:true, - }, - 'order-service/' :{ - target: 'http://localhost:8001', - ws:true, - } - } - } } From 807f8c209f38b6a79d7cf5adb46d0f5bcb849741 Mon Sep 17 00:00:00 2001 From: bum12ark Date: Thu, 24 Feb 2022 21:05:43 +0900 Subject: [PATCH 3/6] =?UTF-8?q?test(user-service):=20=EC=A0=90=EC=A3=BC=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - spring security 관련 테스트 설정 추가 --- user-service/build.gradle | 4 +++- user-service/src/docs/asciidoc/api-docs.adoc | 6 +++++- .../userservice/domain/user/web/UserController.java | 2 +- .../userservice/global/security/SecurityConfig.java | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/user-service/build.gradle b/user-service/build.gradle index fea05ef..a5e8c0c 100644 --- a/user-service/build.gradle +++ b/user-service/build.gradle @@ -35,7 +35,7 @@ dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' /*implementation 'org.springframework.boot:spring-boot-starter-amqp'*/ implementation 'org.springframework.boot:spring-boot-starter-security' - compileOnly 'org.springframework.boot:spring-boot-starter-oauth2-client' + implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' implementation 'org.springframework.cloud:spring-cloud-starter-config' /*implementation 'org.springframework.kafka:spring-kafka'*/ implementation 'org.springframework.boot:spring-boot-starter-data-redis' @@ -55,6 +55,8 @@ dependencies { testImplementation 'org.springframework.security:spring-security-test' testImplementation 'com.h2database:h2' + testImplementation 'org.springframework.security:spring-security-test' + testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' // operation block 을 위한 의존성 asciidoctorExtensions 'org.springframework.restdocs:spring-restdocs-asciidoctor' diff --git a/user-service/src/docs/asciidoc/api-docs.adoc b/user-service/src/docs/asciidoc/api-docs.adoc index dfde993..da78051 100644 --- a/user-service/src/docs/asciidoc/api-docs.adoc +++ b/user-service/src/docs/asciidoc/api-docs.adoc @@ -68,4 +68,8 @@ domain-httpRequestCode-etc === 회원 조회 operation::customer-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] === 회원 조회 (존재하지 않는 회원) -operation::customer-get-notExistUserException[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] \ No newline at end of file +operation::customer-get-notExistUserException[snippets='curl-request,http-request,http-response,path-parameters,response-fields'] + +== 점주 +=== 회원가입 - 점주 +operation::storeOwner-post[snippets='curl-request,http-request,http-response,request-fields,response-fields'] \ No newline at end of file diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java index cb6fe14..377a1bb 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/web/UserController.java @@ -48,7 +48,7 @@ public class UserController { } } - @PostMapping("/store/join") + @PostMapping("/store-owner") public ResponseEntity joinStoreOwner(@Valid @RequestBody JoinStoreOwnerRequest joinRequest) { // 회원 가입 userService.saveStoreOwner(joinRequest.toStoreOwnerDto()); diff --git a/user-service/src/main/java/com/justpickup/userservice/global/security/SecurityConfig.java b/user-service/src/main/java/com/justpickup/userservice/global/security/SecurityConfig.java index d9863c3..e0da657 100644 --- a/user-service/src/main/java/com/justpickup/userservice/global/security/SecurityConfig.java +++ b/user-service/src/main/java/com/justpickup/userservice/global/security/SecurityConfig.java @@ -57,7 +57,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { .userService(oAuthService); http.addFilter(loginAuthenticationFilter); - http.addFilterBefore(new HeaderAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class); +// http.addFilterBefore(new HeaderAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class); } @Override From ac9ba94883ff03cc5a1dfd4c7a3c65e08e4d91f5 Mon Sep 17 00:00:00 2001 From: bum12ark Date: Thu, 24 Feb 2022 21:38:21 +0900 Subject: [PATCH 4/6] =?UTF-8?q?feat(owner-vue):=20=EC=A0=90=EC=A3=BC?= =?UTF-8?q?=EC=9A=A9=20=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20-=20?= =?UTF-8?q?=EC=9D=B4=EB=A9=94=EC=9D=BC=20=EC=A4=91=EB=B3=B5=20=EC=B2=B4?= =?UTF-8?q?=ED=81=AC=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 - 이메일 중복 체크 로직 추가 --- owner-vue/src/views/RegisterUser.vue | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/owner-vue/src/views/RegisterUser.vue b/owner-vue/src/views/RegisterUser.vue index 40ea794..9d71845 100644 --- a/owner-vue/src/views/RegisterUser.vue +++ b/owner-vue/src/views/RegisterUser.vue @@ -53,11 +53,11 @@ export default { name: "RegisterUser", data: function() { return { - email: 'test@naver.com', - password: '1234', - name: 'Park', - phoneNumber: '010-1234-5678', - businessNumber: '1234' + email: '', + password: '', + name: '', + phoneNumber: '', + businessNumber: '' } }, methods: { @@ -71,6 +71,7 @@ export default { phoneNumber: this.phoneNumber, businessNumber: this.businessNumber } + userApi.requestRegisterUser(user) .then( (response) => { if (response.status == '201') { @@ -82,7 +83,8 @@ export default { }) .catch( (error) => { console.log(error); - console.log(error.response.data); + let message = error.response.data.message; + if (message) alert(message); }); } } From 4af396636d481df4a615a2f70b587d0b5d433a0e Mon Sep 17 00:00:00 2001 From: bum12ark Date: Thu, 24 Feb 2022 21:39:30 +0900 Subject: [PATCH 5/6] =?UTF-8?q?feat(user-service):=20=EC=A0=90=EC=A3=BC=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20-=20=EC=A4=91=EB=B3=B5?= =?UTF-8?q?=20=EC=9D=B4=EB=A9=94=EC=9D=BC=20=EB=A1=9C=EC=A7=81=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 - 중복 이메일 로직 추가 - DuplicateUserEmailException 추가 - 테스트 추가 --- user-service/src/docs/asciidoc/api-docs.adoc | 4 +- .../user/exception/DuplicateUserEmail.java | 11 +++ .../user/repository/UserRepository.java | 1 + .../domain/user/service/UserServiceImpl.java | 8 +- .../domain/user/web/UserControllerTest.java | 93 ++++++++++++++++++- 5 files changed, 110 insertions(+), 7 deletions(-) create mode 100644 user-service/src/main/java/com/justpickup/userservice/domain/user/exception/DuplicateUserEmail.java diff --git a/user-service/src/docs/asciidoc/api-docs.adoc b/user-service/src/docs/asciidoc/api-docs.adoc index da78051..8bb36ad 100644 --- a/user-service/src/docs/asciidoc/api-docs.adoc +++ b/user-service/src/docs/asciidoc/api-docs.adoc @@ -72,4 +72,6 @@ operation::customer-get-notExistUserException[snippets='curl-request,http-reques == 점주 === 회원가입 - 점주 -operation::storeOwner-post[snippets='curl-request,http-request,http-response,request-fields,response-fields'] \ No newline at end of file +operation::storeOwner-post[snippets='curl-request,http-request,http-response,request-fields,response-fields'] +=== 회원가입 - 점주 : 중복 이메일 +operation::storeOwner-post-duplicateUserEmailException[snippets='curl-request,http-request,http-response,request-fields,response-fields'] \ No newline at end of file diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/exception/DuplicateUserEmail.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/exception/DuplicateUserEmail.java new file mode 100644 index 0000000..6d4f0a3 --- /dev/null +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/exception/DuplicateUserEmail.java @@ -0,0 +1,11 @@ +package com.justpickup.userservice.domain.user.exception; + +import com.justpickup.userservice.global.exception.CustomException; +import org.springframework.http.HttpStatus; + +public class DuplicateUserEmail extends CustomException { + + public DuplicateUserEmail(String message) { + super(HttpStatus.CONFLICT, message); + } +} diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/repository/UserRepository.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/repository/UserRepository.java index 4b8113c..c5efd3c 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/repository/UserRepository.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/repository/UserRepository.java @@ -7,4 +7,5 @@ import java.util.Optional; public interface UserRepository extends JpaRepository { Optional findByEmail(String username); + boolean existsByEmail(String email); } diff --git a/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserServiceImpl.java b/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserServiceImpl.java index aa4e323..7ac0eda 100644 --- a/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserServiceImpl.java +++ b/user-service/src/main/java/com/justpickup/userservice/domain/user/service/UserServiceImpl.java @@ -5,6 +5,7 @@ import com.justpickup.userservice.domain.user.dto.StoreOwnerDto; import com.justpickup.userservice.domain.user.entity.Customer; import com.justpickup.userservice.domain.user.entity.StoreOwner; import com.justpickup.userservice.domain.user.entity.User; +import com.justpickup.userservice.domain.user.exception.DuplicateUserEmail; import com.justpickup.userservice.domain.user.exception.NotExistUserException; import com.justpickup.userservice.domain.user.repository.CustomerRepository; import com.justpickup.userservice.domain.user.repository.UserRepository; @@ -53,9 +54,14 @@ public class UserServiceImpl implements UserService, UserDetailsService { @Override @Transactional public void saveStoreOwner(StoreOwnerDto storeOwnerDto) { + String email = storeOwnerDto.getEmail(); + boolean exists = userRepository.existsByEmail(email); + + if (exists) throw new DuplicateUserEmail(email + "은 중복된 이메일입니다."); + String encode = passwordEncoder.encode(storeOwnerDto.getPassword()); - StoreOwner storeOwner = new StoreOwner(storeOwnerDto.getEmail(), encode, storeOwnerDto.getName(), + StoreOwner storeOwner = new StoreOwner(email, encode, storeOwnerDto.getName(), storeOwnerDto.getPhoneNumber(), storeOwnerDto.getBusinessNumber()); StoreOwner save = userRepository.save(storeOwner); diff --git a/user-service/src/test/java/com/justpickup/userservice/domain/user/web/UserControllerTest.java b/user-service/src/test/java/com/justpickup/userservice/domain/user/web/UserControllerTest.java index d27be15..93c2c3d 100644 --- a/user-service/src/test/java/com/justpickup/userservice/domain/user/web/UserControllerTest.java +++ b/user-service/src/test/java/com/justpickup/userservice/domain/user/web/UserControllerTest.java @@ -3,25 +3,34 @@ package com.justpickup.userservice.domain.user.web; import com.fasterxml.jackson.databind.ObjectMapper; import com.justpickup.userservice.config.TestConfig; import com.justpickup.userservice.domain.user.dto.CustomerDto; +import com.justpickup.userservice.domain.user.exception.DuplicateUserEmail; import com.justpickup.userservice.domain.user.exception.NotExistUserException; import com.justpickup.userservice.domain.user.service.UserService; import com.justpickup.userservice.global.dto.Code; +import com.justpickup.userservice.global.security.SecurityConfig; +import com.justpickup.userservice.global.utils.CookieProvider; 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.restdocs.AutoConfigureRestDocs; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.Import; -import org.springframework.restdocs.payload.FieldDescriptor; +import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.willThrow; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; -import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; -import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; @@ -29,7 +38,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@WebMvcTest(UserController.class) +@WebMvcTest(controllers = UserController.class, + excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = SecurityConfig.class)} +) +@AutoConfigureMockMvc(addFilters = false) @Import(TestConfig.class) @AutoConfigureRestDocs(uriHost = "127.0.0.1", uriPort = 8001) class UserControllerTest { @@ -43,6 +55,9 @@ class UserControllerTest { @MockBean UserService userService; + @SpyBean + CookieProvider cookieProvider; + @Test @DisplayName("회원 조회") void getCustomer() throws Exception { @@ -115,4 +130,72 @@ class UserControllerTest { )) ; } + + @Test + @DisplayName("회원가입 - 점주") + void registerStoreOwner() throws Exception { + UserController.JoinStoreOwnerRequest requestBody = + new UserController.JoinStoreOwnerRequest("test@naver.com", "1234", "Park", + "010-1234-5678", "1234"); + + ResultActions actions = mockMvc.perform(post("/store-owner") + .content(objectMapper.writeValueAsString(requestBody)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + ); + + actions.andExpect(status().isCreated()) + .andDo(print()) + .andDo(document("storeOwner-post", + requestFields( + fieldWithPath("email").description("이메일"), + fieldWithPath("password").description("비밀번호"), + fieldWithPath("name").description("이름"), + fieldWithPath("phoneNumber").description("휴대폰번호"), + fieldWithPath("businessNumber").description("사업자등록번호") + ), + responseFields( + fieldWithPath("code").description("결과코드 SUCCESS/ERROR"), + fieldWithPath("message").description("메시지"), + fieldWithPath("data").description("데이터") + ) + )) + ; + } + + @Test + @DisplayName("회원가입 - 점주 : 존재하는 회원 이메일") + void registerStoreOwnerDuplicateUserEmailException() throws Exception { + String email = "test@naver.com"; + UserController.JoinStoreOwnerRequest requestBody = + new UserController.JoinStoreOwnerRequest(email, "1234", "Park", + "010-1234-5678", "1234"); + + willThrow(new DuplicateUserEmail(email + "은 중복된 이메일입니다.")) + .given(userService).saveStoreOwner(any()); + + ResultActions actions = mockMvc.perform(post("/store-owner") + .content(objectMapper.writeValueAsString(requestBody)) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + ); + + actions.andExpect(status().isConflict()) + .andDo(print()) + .andDo(document("storeOwner-post-duplicateUserEmailException", + requestFields( + fieldWithPath("email").description("이메일"), + fieldWithPath("password").description("비밀번호"), + fieldWithPath("name").description("이름"), + fieldWithPath("phoneNumber").description("휴대폰번호"), + fieldWithPath("businessNumber").description("사업자등록번호") + ), + responseFields( + fieldWithPath("code").description("결과코드 SUCCESS/ERROR"), + fieldWithPath("message").description("메시지"), + fieldWithPath("data").description("데이터") + ) + )) + ; + } } \ No newline at end of file From c78b360fc12c397737d87b4ed8bc0068629fcf22 Mon Sep 17 00:00:00 2001 From: bum12ark Date: Thu, 24 Feb 2022 21:49:38 +0900 Subject: [PATCH 6/6] =?UTF-8?q?feat(owner-apigateway-service):=20cors=20pr?= =?UTF-8?q?eflight=20=EA=B4=80=EB=A0=A8=20=EC=84=A4=EC=A0=95=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 - cors global filter 설정 추가 --- .../src/main/resources/application.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/owner-apigateway-service/src/main/resources/application.yml b/owner-apigateway-service/src/main/resources/application.yml index 59e992e..a4635b5 100644 --- a/owner-apigateway-service/src/main/resources/application.yml +++ b/owner-apigateway-service/src/main/resources/application.yml @@ -17,13 +17,14 @@ spring: globalcors: cors-configurations: '[/**]': - allowedOrigins: "http://localhost:8080" + allowedOrigins: "*" allowedMethods: - - POST - GET + - POST + - DELETE - PUT - OPTIONS - - DELETE + allowedHeaders: '*' routes: - id: owner-frontend-service uri: lb://OWNER-FRONTEND-SERVICE @@ -64,12 +65,18 @@ spring: - Method=POST filters: - RewritePath=/user-service/(?.*),/$\{segment} + - id: user-service + uri: lb://USER-SERVICE + predicates: + - Path=/user-service/store-owner + - Method=POST + filters: + - RewritePath=/user-service/(?.*),/$\{segment} - id: user-service uri: lb://USER-SERVICE predicates: - Path=/user-service/** filters: - - AuthorizationHeaderFilter - RewritePath=/user-service/(?.*),/$\{segment} token: