Add register page

This commit is contained in:
Pig Fang 2018-08-12 11:16:57 +08:00
parent 59e4bf628e
commit b343707978
6 changed files with 282 additions and 45 deletions

View File

@ -0,0 +1,187 @@
<template>
<form>
<div class="form-group has-feedback">
<input
v-model="email"
type="email"
class="form-control"
:placeholder="$t('auth.email')"
ref="email"
>
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input
v-model="password"
type="password"
class="form-control"
:placeholder="$t('auth.password')"
ref="password"
>
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input
v-model="confirm"
type="password"
class="form-control"
:placeholder="$t('auth.repeat-pwd')"
ref="confirm"
>
<span class="glyphicon glyphicon-log-in form-control-feedback"></span>
</div>
<div
class="form-group has-feedback"
:title="$t('auth.nickname-intro')"
data-placement="top"
data-toggle="tooltip"
>
<input
v-model="nickname"
type="text"
class="form-control"
:placeholder="$t('auth.nickname')"
ref="nickname"
>
<span class="glyphicon glyphicon-pencil form-control-feedback"></span>
</div>
<div class="row">
<div class="col-xs-8">
<div class="form-group has-feedback">
<input
v-model="captcha"
type="text"
class="form-control"
:placeholder="$t('auth.captcha')"
ref="captcha"
>
</div>
</div>
<div class="col-xs-4">
<img
class="pull-right captcha"
:src="`${baseUrl}/auth/captcha?v=${time}`"
alt="CAPTCHA"
:title="$t('auth.change-captcha')"
@click="refreshCaptcha"
data-placement="top"
data-toggle="tooltip"
>
</div>
</div>
<div class="callout callout-info" :class="{ hide: !infoMsg }">{{ infoMsg }}</div>
<div class="callout callout-warning" :class="{ hide: !warningMsg }">{{ warningMsg }}</div>
<div class="row">
<div class="col-xs-8">
<a :href="`${baseUrl}/auth/login`" class="text-center" v-t="'auth.login-link'"></a>
</div>
<div class="col-xs-4">
<button v-if="pending" disabled class="btn btn-primary btn-block btn-flat">
<i class="fa fa-spinner fa-spin"></i> {{ $t('auth.registering') }}
</button>
<button
v-else
@click.prevent="submit"
class="btn btn-primary btn-block btn-flat"
>{{ $t('auth.register-button') }}</button>
</div>
</div>
</form>
</template>
<script>
import { swal } from '../../js/notify';
export default {
name: 'Register',
props: {
baseUrl: {
default: blessing.base_url
}
},
data: () => ({
email: '',
password: '',
confirm: '',
nickname: '',
captcha: '',
time: Date.now(),
infoMsg: '',
warningMsg: '',
pending: false
}),
methods: {
async submit() {
const {
email, password, confirm, nickname, captcha
} = this;
if (!email) {
this.infoMsg = this.$t('auth.emptyEmail');
this.$refs.email.focus();
return;
}
if (!/\S+@\S+\.\S+/.test(email)) {
this.infoMsg = this.$t('auth.invalidEmail');
this.$refs.email.focus();
return;
}
if (!password) {
this.infoMsg = this.$t('auth.emptyPassword');
this.$refs.password.focus();
return;
}
if (password.length < 8 || password.length > 32) {
this.infoMsg = this.$t('auth.invalidPassword');
this.$refs.password.focus();
return;
}
if (password !== confirm) {
this.infoMsg = this.$t('auth.invalidConfirmPwd');
this.$refs.confirm.focus();
return;
}
if (!nickname) {
this.infoMsg = this.$t('auth.emptyNickname');
this.$refs.nickname.focus();
return;
}
if (!captcha) {
this.infoMsg = this.$t('auth.emptyCaptcha');
this.$refs.captcha.focus();
return;
}
this.pending = true;
const { errno, msg } = await this.$http.post(
'/auth/register',
{ email, password, nickname, captcha }
);
if (errno === 0) {
swal({ type: 'success', html: msg });
setTimeout(() => {
window.location = `${blessing.base_url}/user`;
}, 1000);
} else {
this.infoMsg = '';
this.warningMsg = msg;
this.refreshCaptcha();
this.pending = false;
}
},
refreshCaptcha() {
this.time = Date.now();
}
}
};
</script>

View File

@ -39,4 +39,9 @@ export default [
component: () => import('./auth/Login'),
el: 'form'
},
{
path: 'auth/register',
component: () => import('./auth/Register'),
el: 'form'
},
];

View File

@ -0,0 +1,83 @@
import Vue from 'vue';
import { mount } from '@vue/test-utils';
import Register from '@/components/auth/Register';
import { swal } from '@/js/notify';
jest.mock('@/js/notify');
test('click to refresh captcha', () => {
jest.spyOn(Date, 'now');
const wrapper = mount(Register);
wrapper.find('img').trigger('click');
expect(Date.now).toHaveBeenCalledTimes(2);
});
test('register', async () => {
jest.spyOn(Date, 'now');
Vue.prototype.$http.post
.mockResolvedValueOnce({ errno: 1, msg: 'fail' })
.mockResolvedValueOnce({ errno: 0, msg: 'ok' });
const wrapper = mount(Register);
const button = wrapper.find('button');
const info = wrapper.find('.callout-info');
const warning = wrapper.find('.callout-warning');
button.trigger('click');
expect(Vue.prototype.$http.post).not.toBeCalled();
expect(info.text()).toBe('auth.emptyEmail');
wrapper.find('[type="email"]').setValue('a');
button.trigger('click');
expect(Vue.prototype.$http.post).not.toBeCalled();
expect(info.text()).toBe('auth.invalidEmail');
wrapper.find('[type="email"]').setValue('a@b.c');
button.trigger('click');
expect(Vue.prototype.$http.post).not.toBeCalled();
expect(info.text()).toBe('auth.emptyPassword');
wrapper.findAll('[type="password"]').at(0).setValue('123456');
button.trigger('click');
expect(Vue.prototype.$http.post).not.toBeCalled();
expect(info.text()).toBe('auth.invalidPassword');
wrapper.findAll('[type="password"]').at(0).setValue('12345678');
button.trigger('click');
expect(Vue.prototype.$http.post).not.toBeCalled();
expect(info.text()).toBe('auth.invalidConfirmPwd');
wrapper.findAll('[type="password"]').at(1).setValue('123456');
button.trigger('click');
expect(Vue.prototype.$http.post).not.toBeCalled();
expect(info.text()).toBe('auth.invalidConfirmPwd');
wrapper.findAll('[type="password"]').at(1).setValue('12345678');
button.trigger('click');
expect(Vue.prototype.$http.post).not.toBeCalled();
expect(info.text()).toBe('auth.emptyNickname');
wrapper.findAll('[type="text"]').at(0).setValue('abc');
button.trigger('click');
expect(Vue.prototype.$http.post).not.toBeCalled();
expect(info.text()).toBe('auth.emptyCaptcha');
wrapper.findAll('[type="text"]').at(1).setValue('captcha');
button.trigger('click');
await wrapper.vm.$nextTick();
expect(Vue.prototype.$http.post).toBeCalledWith(
'/auth/register',
{
email: 'a@b.c',
password: '12345678',
nickname: 'abc',
captcha: 'captcha'
}
);
expect(warning.text()).toBe('fail');
expect(Date.now).toHaveBeenCalledTimes(2);
button.trigger('click');
await wrapper.vm.$nextTick();
jest.runAllTimers();
expect(swal).toBeCalledWith({ type: 'success', html: 'ok' });
});

View File

@ -26,6 +26,9 @@ auth:
login-link: Already registered? Log in here.
forgot-link: Forgot password?
keep: Remember me
repeat-pwd: Repeat your password
nickname-intro: Whatever you like expect special characters
register-button: Register
skinlib:
addToCloset: Add to closet

View File

@ -26,6 +26,9 @@ auth:
login-link: 已经有账号了?登录
forgot-link: 忘记密码?
keep: 记住我
repeat-pwd: 重复密码
nickname-intro: 昵称可使用汉字,不可包含特殊字符
register-button: 注册
skinlib:
addToCloset: 添加至衣柜

View File

@ -12,51 +12,7 @@
<div class="register-box-body">
<p class="login-box-msg">@lang('auth.register.message', ['sitename' => option_localized('site_name')])</p>
<form id="register-form">
<div class="form-group has-feedback">
<input id="email" type="email" class="form-control" placeholder="@lang('auth.email')">
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input id="password" type="password" class="form-control" placeholder="@lang('auth.password')">
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input id="confirm-pwd" type="password" class="form-control" placeholder="@lang('auth.register.repeat-pwd')">
<span class="glyphicon glyphicon-log-in form-control-feedback"></span>
</div>
<div class="form-group has-feedback" title="@lang('auth.register.nickname-intro')" data-placement="top" data-toggle="tooltip">
<input id="nickname" type="text" class="form-control" placeholder="@lang('auth.nickname')">
<span class="glyphicon glyphicon-pencil form-control-feedback"></span>
</div>
<div class="row">
<div class="col-xs-8">
<div class="form-group has-feedback">
<input id="captcha" type="text" class="form-control" placeholder="@lang('auth.captcha')">
</div>
</div>
<!-- /.col -->
<div class="col-xs-4">
<img class="pull-right captcha" src="{{ url('auth/captcha?v='.time()) }}" alt="CAPTCHA" title="@lang('auth.change-captcha')" data-placement="top" data-toggle="tooltip">
</div>
<!-- /.col -->
</div>
<div id="msg" class="callout hide"></div>
<div class="row">
<div class="col-xs-8">
<a href="{{ url('auth/login') }}" class="text-center">@lang('auth.login-link')</a>
</div>
<!-- /.col -->
<div class="col-xs-4">
<button id="register-button" class="btn btn-primary btn-block btn-flat">@lang('auth.register.button')</button>
</div>
<!-- /.col -->
</div>
</form>
<form></form>
</div>
<!-- /.form-box -->
</div>