Merge branch 'master' into 메뉴_등록
This commit is contained in:
@@ -24,14 +24,14 @@ spring:
|
|||||||
cors-configurations:
|
cors-configurations:
|
||||||
'[/**]':
|
'[/**]':
|
||||||
allowedOrigins: "*"
|
allowedOrigins: "*"
|
||||||
allowedHeaders: "*"
|
|
||||||
allowedMethods:
|
allowedMethods:
|
||||||
- POST
|
|
||||||
- GET
|
- GET
|
||||||
|
- POST
|
||||||
|
- DELETE
|
||||||
- PUT
|
- PUT
|
||||||
- OPTIONS
|
- OPTIONS
|
||||||
- DELETE
|
- DELETE
|
||||||
# add-to-simple-url-handler-mapping: true
|
allowedHeaders: '*'
|
||||||
routes:
|
routes:
|
||||||
- id: owner-frontend-service
|
- id: owner-frontend-service
|
||||||
uri: lb://OWNER-FRONTEND-SERVICE
|
uri: lb://OWNER-FRONTEND-SERVICE
|
||||||
@@ -72,12 +72,18 @@ spring:
|
|||||||
- Method=POST
|
- Method=POST
|
||||||
filters:
|
filters:
|
||||||
- RewritePath=/user-service/(?<segment>.*),/$\{segment}
|
- RewritePath=/user-service/(?<segment>.*),/$\{segment}
|
||||||
|
- id: user-service
|
||||||
|
uri: lb://USER-SERVICE
|
||||||
|
predicates:
|
||||||
|
- Path=/user-service/store-owner
|
||||||
|
- Method=POST
|
||||||
|
filters:
|
||||||
|
- RewritePath=/user-service/(?<segment>.*),/$\{segment}
|
||||||
- id: user-service
|
- id: user-service
|
||||||
uri: lb://USER-SERVICE
|
uri: lb://USER-SERVICE
|
||||||
predicates:
|
predicates:
|
||||||
- Path=/user-service/**
|
- Path=/user-service/**
|
||||||
filters:
|
filters:
|
||||||
- AuthorizationHeaderFilter
|
|
||||||
- RewritePath=/user-service/(?<segment>.*),/$\{segment}
|
- RewritePath=/user-service/(?<segment>.*),/$\{segment}
|
||||||
|
|
||||||
token:
|
token:
|
||||||
|
|||||||
@@ -1,28 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-app id="inspire">
|
<router-view></router-view>
|
||||||
<Sidebar :drawer="drawer" />
|
|
||||||
<Topbar @drawerEvent="drawer = !drawer" />
|
|
||||||
<v-main style="background: #f5f5f540">
|
|
||||||
<v-container class="py-8 px-6" fluid>
|
|
||||||
<router-view></router-view>
|
|
||||||
</v-container>
|
|
||||||
</v-main>
|
|
||||||
</v-app>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Sidebar from "./components/Sidebar";
|
|
||||||
import Topbar from "./components/Topbar";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "App",
|
name: "App"
|
||||||
components: { Topbar, Sidebar},
|
}
|
||||||
data: () => ({
|
|
||||||
cards: ["Today", "Yesterday"],
|
|
||||||
drawer: null,
|
|
||||||
}),
|
|
||||||
mounted() {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
8
owner-vue/src/api/user.js
Normal file
8
owner-vue/src/api/user.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
requestRegisterUser(user) {
|
||||||
|
return axios.post("http://localhost:8001/user-service/store-owner", user);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import router from './router'
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import customUtil from './util/customUtil'
|
import customUtil from './util/customUtil'
|
||||||
|
|
||||||
|
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
Vue.prototype.$axios = axios;
|
Vue.prototype.$axios = axios;
|
||||||
Vue.prototype.$customUtil = customUtil;
|
Vue.prototype.$customUtil = customUtil;
|
||||||
@@ -16,4 +17,3 @@ new Vue({
|
|||||||
router,
|
router,
|
||||||
render: h => h(App)
|
render: h => h(App)
|
||||||
}).$mount('#app')
|
}).$mount('#app')
|
||||||
|
|
||||||
|
|||||||
@@ -1,33 +1,60 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import VueRouter from 'vue-router'
|
import VueRouter from 'vue-router'
|
||||||
|
|
||||||
|
import DashboardLayout from "@/views/Layout/DashboardLayout";
|
||||||
|
import AuthLayout from "@/views/Layout/AuthLayout";
|
||||||
|
|
||||||
Vue.use(VueRouter)
|
Vue.use(VueRouter)
|
||||||
|
|
||||||
const routes = [
|
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: '/',
|
path: '/',
|
||||||
name: 'dashboard',
|
redirect: 'login',
|
||||||
component: () => import('./../views/Dashboard')
|
component: AuthLayout,
|
||||||
},
|
children: [
|
||||||
{
|
{
|
||||||
path: '/category',
|
path: '/login',
|
||||||
name: 'category',
|
name: 'login',
|
||||||
component: () => import('./../views/Category')
|
component: () => import('./../views/LoginUser.vue')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/menu',
|
path: '/register',
|
||||||
name: 'menu',
|
name: 'register',
|
||||||
component: () => import('./../views/Menu')
|
component: () => import('./../views/RegisterUser.vue')
|
||||||
},
|
}
|
||||||
{
|
]
|
||||||
path: '/prev-order',
|
|
||||||
name: 'prev-order',
|
|
||||||
component: () => import('./../views/PrevOrder')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/order',
|
|
||||||
name: 'order',
|
|
||||||
component: () => import('./../views/Order.vue')
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="about">
|
|
||||||
<h1>This is an about page</h1>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="home">
|
|
||||||
<img alt="Vue logo" src="../assets/logo.png">
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// @ is an alias to /src
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Home',
|
|
||||||
components: {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
21
owner-vue/src/views/Layout/AuthLayout.vue
Normal file
21
owner-vue/src/views/Layout/AuthLayout.vue
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<template>
|
||||||
|
<v-app>
|
||||||
|
<v-app-bar app>Just Pickup - 점주용 페이지</v-app-bar>
|
||||||
|
|
||||||
|
<v-main>
|
||||||
|
<v-container fluid>
|
||||||
|
<router-view></router-view>
|
||||||
|
</v-container>
|
||||||
|
</v-main>
|
||||||
|
</v-app>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "AuthLayout"
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
33
owner-vue/src/views/Layout/DashboardLayout.vue
Normal file
33
owner-vue/src/views/Layout/DashboardLayout.vue
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<template>
|
||||||
|
<v-app id="inspire">
|
||||||
|
<side-bar v-bind:drawer="drawer"></side-bar>
|
||||||
|
<top-bar v-on:drawEvent="drawer = !drawer"></top-bar>
|
||||||
|
<v-main style="background: #f5f5f540">
|
||||||
|
<v-container class="py-8, px-6" fluid>
|
||||||
|
<router-view></router-view>
|
||||||
|
</v-container>
|
||||||
|
</v-main>
|
||||||
|
</v-app>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Sidebar from './Sidebar.vue'
|
||||||
|
import Topbar from "./Topbar.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "DashboardLayout",
|
||||||
|
components: {
|
||||||
|
'side-bar': Sidebar,
|
||||||
|
'top-bar': Topbar
|
||||||
|
},
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
drawer: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
96
owner-vue/src/views/RegisterUser.vue
Normal file
96
owner-vue/src/views/RegisterUser.vue
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
<template>
|
||||||
|
<v-card width="800" class="mx-auto mt-5">
|
||||||
|
<v-card-title>
|
||||||
|
<h1>Register</h1>
|
||||||
|
</v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
<v-form
|
||||||
|
ref="form"
|
||||||
|
lazy-validation
|
||||||
|
>
|
||||||
|
<v-text-field
|
||||||
|
v-model="email"
|
||||||
|
:rules="[v => /.+@.+\..+/.test(v) || 'E-mail must be valid', v => !!v || '이메일은 필수 값입니다']"
|
||||||
|
label="이메일"
|
||||||
|
></v-text-field>
|
||||||
|
<v-text-field
|
||||||
|
v-model="password"
|
||||||
|
:rules="[v => !!v || '비밀번호는 필수 값입니다']"
|
||||||
|
label="비밀번호"
|
||||||
|
type="Password"
|
||||||
|
append-icon="mdi-eye-off"
|
||||||
|
></v-text-field>
|
||||||
|
<v-text-field
|
||||||
|
v-model="name"
|
||||||
|
:rules="[v => !!v || '이름은 필수 값입니다']"
|
||||||
|
label="이름"
|
||||||
|
></v-text-field>
|
||||||
|
<v-text-field
|
||||||
|
v-model="phoneNumber"
|
||||||
|
:rules="[v => !!v || '전화번호는 필수 값입니다']"
|
||||||
|
label="전화번호"
|
||||||
|
></v-text-field>
|
||||||
|
<v-text-field
|
||||||
|
v-model="businessNumber"
|
||||||
|
:rules="[v => !!v || '사업자번호는 필수 값입니다']"
|
||||||
|
label="사업자번호"
|
||||||
|
></v-text-field>
|
||||||
|
</v-form>
|
||||||
|
</v-card-text>
|
||||||
|
<v-divider></v-divider>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn color="info" v-on:click="register">Register</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import userApi from '../api/user.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "RegisterUser",
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
email: '',
|
||||||
|
password: '',
|
||||||
|
name: '',
|
||||||
|
phoneNumber: '',
|
||||||
|
businessNumber: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
register: function() {
|
||||||
|
if (!this.$refs.form.validate()) return;
|
||||||
|
|
||||||
|
const user = {
|
||||||
|
email: this.email,
|
||||||
|
password: this.password,
|
||||||
|
name: this.name,
|
||||||
|
phoneNumber: this.phoneNumber,
|
||||||
|
businessNumber: this.businessNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
userApi.requestRegisterUser(user)
|
||||||
|
.then( (response) => {
|
||||||
|
if (response.status == '201') {
|
||||||
|
alert("사용자 등록이 성공되었습니다.");
|
||||||
|
this.$router.push('/login');
|
||||||
|
} else {
|
||||||
|
alert("사용자 등록에 실패하였습니다. 다시 시도해주세요.");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch( (error) => {
|
||||||
|
console.log(error);
|
||||||
|
let message = error.response.data.message;
|
||||||
|
if (message) alert(message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -35,7 +35,7 @@ dependencies {
|
|||||||
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
|
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
|
||||||
/*implementation 'org.springframework.boot:spring-boot-starter-amqp'*/
|
/*implementation 'org.springframework.boot:spring-boot-starter-amqp'*/
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
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.cloud:spring-cloud-starter-config'
|
||||||
/*implementation 'org.springframework.kafka:spring-kafka'*/
|
/*implementation 'org.springframework.kafka:spring-kafka'*/
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
|
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
|
||||||
@@ -55,6 +55,8 @@ dependencies {
|
|||||||
testImplementation 'org.springframework.security:spring-security-test'
|
testImplementation 'org.springframework.security:spring-security-test'
|
||||||
testImplementation 'com.h2database:h2'
|
testImplementation 'com.h2database:h2'
|
||||||
|
|
||||||
|
testImplementation 'org.springframework.security:spring-security-test'
|
||||||
|
|
||||||
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
|
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'
|
||||||
// operation block 을 위한 의존성
|
// operation block 을 위한 의존성
|
||||||
asciidoctorExtensions 'org.springframework.restdocs:spring-restdocs-asciidoctor'
|
asciidoctorExtensions 'org.springframework.restdocs:spring-restdocs-asciidoctor'
|
||||||
|
|||||||
@@ -68,4 +68,10 @@ domain-httpRequestCode-etc
|
|||||||
=== 회원 조회
|
=== 회원 조회
|
||||||
operation::customer-get[snippets='curl-request,http-request,http-response,path-parameters,response-fields']
|
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']
|
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']
|
||||||
|
=== 회원가입 - 점주 : 중복 이메일
|
||||||
|
operation::storeOwner-post-duplicateUserEmailException[snippets='curl-request,http-request,http-response,request-fields,response-fields']
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,4 +7,5 @@ import java.util.Optional;
|
|||||||
|
|
||||||
public interface UserRepository extends JpaRepository<User, Long> {
|
public interface UserRepository extends JpaRepository<User, Long> {
|
||||||
Optional<User> findByEmail(String username);
|
Optional<User> findByEmail(String username);
|
||||||
|
boolean existsByEmail(String email);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.CustomerDto;
|
||||||
import com.justpickup.userservice.domain.user.dto.StoreOwnerDto;
|
import com.justpickup.userservice.domain.user.dto.StoreOwnerDto;
|
||||||
import com.justpickup.userservice.domain.user.entity.StoreOwner;
|
|
||||||
|
|
||||||
public interface UserService {
|
public interface UserService {
|
||||||
|
|
||||||
|
|
||||||
CustomerDto findCustomerByUserId(Long userId);
|
CustomerDto findCustomerByUserId(Long userId);
|
||||||
StoreOwner saveStoreOwner(StoreOwnerDto storeOwnerDto);
|
void saveStoreOwner(StoreOwnerDto storeOwnerDto);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.Customer;
|
||||||
import com.justpickup.userservice.domain.user.entity.StoreOwner;
|
import com.justpickup.userservice.domain.user.entity.StoreOwner;
|
||||||
import com.justpickup.userservice.domain.user.entity.User;
|
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.exception.NotExistUserException;
|
||||||
import com.justpickup.userservice.domain.user.repository.CustomerRepository;
|
import com.justpickup.userservice.domain.user.repository.CustomerRepository;
|
||||||
import com.justpickup.userservice.domain.user.repository.UserRepository;
|
import com.justpickup.userservice.domain.user.repository.UserRepository;
|
||||||
@@ -32,8 +33,6 @@ public class UserServiceImpl implements UserService, UserDetailsService {
|
|||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
private final PasswordEncoder passwordEncoder;
|
private final PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
User user = userRepository.findByEmail(username)
|
User user = userRepository.findByEmail(username)
|
||||||
@@ -54,12 +53,18 @@ public class UserServiceImpl implements UserService, UserDetailsService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public StoreOwner saveStoreOwner(StoreOwnerDto storeOwnerDto) {
|
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());
|
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());
|
storeOwnerDto.getPhoneNumber(), storeOwnerDto.getBusinessNumber());
|
||||||
|
|
||||||
return userRepository.save(storeOwner);
|
StoreOwner save = userRepository.save(storeOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,21 @@
|
|||||||
package com.justpickup.userservice.domain.user.web;
|
package com.justpickup.userservice.domain.user.web;
|
||||||
|
|
||||||
import com.justpickup.userservice.domain.user.dto.CustomerDto;
|
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.domain.user.service.UserService;
|
||||||
import com.justpickup.userservice.global.dto.Result;
|
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 lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.http.HttpRequest;
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
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 javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.util.Objects;
|
import javax.validation.constraints.Email;
|
||||||
import java.util.Optional;
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@@ -51,6 +48,36 @@ public class UserController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/store-owner")
|
||||||
|
public ResponseEntity<Result> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
.userService(oAuthService);
|
.userService(oAuthService);
|
||||||
|
|
||||||
http.addFilter(loginAuthenticationFilter);
|
http.addFilter(loginAuthenticationFilter);
|
||||||
http.addFilterBefore(new HeaderAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class);
|
// http.addFilterBefore(new HeaderAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -3,25 +3,34 @@ package com.justpickup.userservice.domain.user.web;
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.justpickup.userservice.config.TestConfig;
|
import com.justpickup.userservice.config.TestConfig;
|
||||||
import com.justpickup.userservice.domain.user.dto.CustomerDto;
|
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.exception.NotExistUserException;
|
||||||
import com.justpickup.userservice.domain.user.service.UserService;
|
import com.justpickup.userservice.domain.user.service.UserService;
|
||||||
import com.justpickup.userservice.global.dto.Code;
|
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.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
|
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.autoconfigure.web.servlet.WebMvcTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
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.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.MockMvc;
|
||||||
import org.springframework.test.web.servlet.ResultActions;
|
import org.springframework.test.web.servlet.ResultActions;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.BDDMockito.given;
|
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.MockMvcRestDocumentation.document;
|
||||||
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*;
|
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
|
||||||
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
|
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
|
||||||
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
|
import static org.springframework.restdocs.payload.PayloadDocumentation.*;
|
||||||
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
|
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
|
||||||
import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
|
import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
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;
|
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)
|
@Import(TestConfig.class)
|
||||||
@AutoConfigureRestDocs(uriHost = "127.0.0.1", uriPort = 8001)
|
@AutoConfigureRestDocs(uriHost = "127.0.0.1", uriPort = 8001)
|
||||||
class UserControllerTest {
|
class UserControllerTest {
|
||||||
@@ -43,6 +55,9 @@ class UserControllerTest {
|
|||||||
@MockBean
|
@MockBean
|
||||||
UserService userService;
|
UserService userService;
|
||||||
|
|
||||||
|
@SpyBean
|
||||||
|
CookieProvider cookieProvider;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("회원 조회")
|
@DisplayName("회원 조회")
|
||||||
void getCustomer() throws Exception {
|
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("데이터")
|
||||||
|
)
|
||||||
|
))
|
||||||
|
;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user