mirror of
https://github.com/discourse/discourse.git
synced 2025-09-05 08:59:27 +08:00
Login with email/forget password UI refactoring
* move button into login modal with social buttons * adds email link next to login field when filling it * adds proper validation messages * improves forgot password flash clearing * more tests
This commit is contained in:
parent
720e1965e3
commit
6f5acfe783
13 changed files with 277 additions and 86 deletions
|
@ -14,11 +14,13 @@ export default Ember.Component.extend({
|
||||||
|
|
||||||
Ember.run.scheduleOnce('afterRender', this, this._afterFirstRender);
|
Ember.run.scheduleOnce('afterRender', this, this._afterFirstRender);
|
||||||
this.appEvents.on('modal-body:flash', msg => this._flash(msg));
|
this.appEvents.on('modal-body:flash', msg => this._flash(msg));
|
||||||
|
this.appEvents.on('modal-body:clearFlash', () => this._clearFlash());
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
willDestroyElement() {
|
||||||
this._super();
|
this._super();
|
||||||
this.appEvents.off('modal-body:flash');
|
this.appEvents.off('modal-body:flash');
|
||||||
|
this.appEvents.off('modal-body:clearFlash');
|
||||||
},
|
},
|
||||||
|
|
||||||
_afterFirstRender() {
|
_afterFirstRender() {
|
||||||
|
@ -45,10 +47,16 @@ export default Ember.Component.extend({
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_clearFlash() {
|
||||||
|
$('#modal-alert').hide().removeClass('alert-error', 'alert-success');
|
||||||
|
},
|
||||||
|
|
||||||
_flash(msg) {
|
_flash(msg) {
|
||||||
$('#modal-alert').hide()
|
this._clearFlash();
|
||||||
.removeClass('alert-error', 'alert-success')
|
|
||||||
.addClass(`alert alert-${msg.messageClass || 'success'}`).html(msg.text || '')
|
$('#modal-alert')
|
||||||
.fadeIn();
|
.addClass(`alert alert-${msg.messageClass || 'success'}`)
|
||||||
|
.html(msg.text || '')
|
||||||
|
.fadeIn();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,8 +13,12 @@ export default Ember.Component.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
externalLogin: function(provider) {
|
emailLogin() {
|
||||||
this.sendAction('action', provider);
|
this.sendAction('emailLogin');
|
||||||
|
},
|
||||||
|
|
||||||
|
externalLogin(provider) {
|
||||||
|
this.sendAction('externalLogin', provider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -29,45 +29,36 @@ export default Ember.Controller.extend(ModalFunctionality, {
|
||||||
},
|
},
|
||||||
|
|
||||||
resetPassword() {
|
resetPassword() {
|
||||||
return this._submit('/session/forgot_password', 'forgot_password.complete');
|
if (this.get('submitDisabled')) return false;
|
||||||
},
|
this.set('disabled', true);
|
||||||
|
|
||||||
emailLogin() {
|
this.clearFlash();
|
||||||
return this._submit('/u/email-login', 'email_login.complete');
|
|
||||||
|
ajax('/session/forgot_password', {
|
||||||
|
data: { login: this.get('accountEmailOrUsername').trim() },
|
||||||
|
type: 'POST'
|
||||||
|
}).then(data => {
|
||||||
|
const accountEmailOrUsername = escapeExpression(this.get("accountEmailOrUsername"));
|
||||||
|
const isEmail = accountEmailOrUsername.match(/@/);
|
||||||
|
let key = `forgot_password.complete_${isEmail ? 'email' : 'username'}`;
|
||||||
|
if (data.user_found) {
|
||||||
|
this.set('offerHelp', I18n.t(`${key}_found`, {
|
||||||
|
email: accountEmailOrUsername,
|
||||||
|
username: accountEmailOrUsername
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
this.flash(I18n.t(`${key}_not_found`, {
|
||||||
|
email: accountEmailOrUsername,
|
||||||
|
username: accountEmailOrUsername
|
||||||
|
}), 'error');
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
this.flash(extractError(e), 'error');
|
||||||
|
}).finally(() => {
|
||||||
|
this.set('disabled', false);
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_submit(route, translationKey) {
|
|
||||||
if (this.get('submitDisabled')) return false;
|
|
||||||
this.set('disabled', true);
|
|
||||||
|
|
||||||
ajax(route, {
|
|
||||||
data: { login: this.get('accountEmailOrUsername').trim() },
|
|
||||||
type: 'POST'
|
|
||||||
}).then(data => {
|
|
||||||
const escaped = escapeExpression(this.get('accountEmailOrUsername'));
|
|
||||||
const isEmail = this.get('accountEmailOrUsername').match(/@/);
|
|
||||||
let key = `${translationKey}_${isEmail ? 'email' : 'username'}`;
|
|
||||||
let extraClass;
|
|
||||||
|
|
||||||
if (data.user_found === true) {
|
|
||||||
key += '_found';
|
|
||||||
this.set('accountEmailOrUsername', '');
|
|
||||||
this.set('offerHelp', I18n.t(key, { email: escaped, username: escaped }));
|
|
||||||
} else {
|
|
||||||
if (data.user_found === false) {
|
|
||||||
key += '_not_found';
|
|
||||||
extraClass = 'error';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.flash(I18n.t(key, { email: escaped, username: escaped }), extraClass);
|
|
||||||
}
|
|
||||||
}).catch(e => {
|
|
||||||
this.flash(extractError(e), 'error');
|
|
||||||
}).finally(() => {
|
|
||||||
this.set('disabled', false);
|
|
||||||
});
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,6 +4,8 @@ import showModal from 'discourse/lib/show-modal';
|
||||||
import { setting } from 'discourse/lib/computed';
|
import { setting } from 'discourse/lib/computed';
|
||||||
import { findAll } from 'discourse/models/login-method';
|
import { findAll } from 'discourse/models/login-method';
|
||||||
import { escape } from 'pretty-text/sanitizer';
|
import { escape } from 'pretty-text/sanitizer';
|
||||||
|
import { escapeExpression } from 'discourse/lib/utilities';
|
||||||
|
import { extractError } from 'discourse/lib/ajax-error';
|
||||||
import computed from 'ember-addons/ember-computed-decorators';
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
|
|
||||||
// This is happening outside of the app via popup
|
// This is happening outside of the app via popup
|
||||||
|
@ -24,8 +26,10 @@ export default Ember.Controller.extend(ModalFunctionality, {
|
||||||
authenticate: null,
|
authenticate: null,
|
||||||
loggingIn: false,
|
loggingIn: false,
|
||||||
loggedIn: false,
|
loggedIn: false,
|
||||||
|
processingEmailLink: false,
|
||||||
|
|
||||||
canLoginLocal: setting('enable_local_logins'),
|
canLoginLocal: setting('enable_local_logins'),
|
||||||
|
canLoginLocalWithEmail: setting('enable_local_logins_via_email'),
|
||||||
loginRequired: Em.computed.alias('application.loginRequired'),
|
loginRequired: Em.computed.alias('application.loginRequired'),
|
||||||
|
|
||||||
resetForm: function() {
|
resetForm: function() {
|
||||||
|
@ -59,6 +63,11 @@ export default Ember.Controller.extend(ModalFunctionality, {
|
||||||
return this.get('loggingIn') || this.get('authenticate');
|
return this.get('loggingIn') || this.get('authenticate');
|
||||||
}.property('loggingIn', 'authenticate'),
|
}.property('loggingIn', 'authenticate'),
|
||||||
|
|
||||||
|
@computed('canLoginLocalWithEmail', 'loginName', 'processingEmailLink')
|
||||||
|
showLoginWithEmailLink(canLoginLocalWithEmail, loginName, processingEmailLink) {
|
||||||
|
return canLoginLocalWithEmail && !Ember.isEmpty(loginName) && !processingEmailLink;
|
||||||
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
login() {
|
login() {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
@ -198,6 +207,37 @@ export default Ember.Controller.extend(ModalFunctionality, {
|
||||||
const forgotPasswordController = this.get('forgotPassword');
|
const forgotPasswordController = this.get('forgotPassword');
|
||||||
if (forgotPasswordController) { forgotPasswordController.set("accountEmailOrUsername", this.get("loginName")); }
|
if (forgotPasswordController) { forgotPasswordController.set("accountEmailOrUsername", this.get("loginName")); }
|
||||||
this.send("showForgotPassword");
|
this.send("showForgotPassword");
|
||||||
|
},
|
||||||
|
|
||||||
|
emailLogin() {
|
||||||
|
if (this.get('processingEmailLink')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Ember.isEmpty(this.get('loginName'))){
|
||||||
|
this.flash(I18n.t('login.blank_username'), 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.set('processingEmailLink', true);
|
||||||
|
|
||||||
|
ajax('/u/email-login', {
|
||||||
|
data: { login: this.get('loginName').trim() },
|
||||||
|
type: 'POST'
|
||||||
|
}).then(data => {
|
||||||
|
const loginName = escapeExpression(this.get('loginName'));
|
||||||
|
const isEmail = loginName.match(/@/);
|
||||||
|
let key = `email_login.complete_${isEmail ? 'email' : 'username'}`;
|
||||||
|
if (data.user_found) {
|
||||||
|
this.flash(I18n.t(`${key}_found`, { email: loginName, username: loginName }));
|
||||||
|
} else {
|
||||||
|
this.flash(I18n.t(`${key}_not_found`, { email: loginName, username: loginName }), 'error');
|
||||||
|
}
|
||||||
|
}).catch(e => {
|
||||||
|
this.flash(extractError(e), 'error');
|
||||||
|
}).finally(() => {
|
||||||
|
this.set('processingEmailLink', false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,10 @@ export default Ember.Mixin.create({
|
||||||
this.appEvents.trigger('modal-body:flash', { text, messageClass });
|
this.appEvents.trigger('modal-body:flash', { text, messageClass });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
clearFlash() {
|
||||||
|
this.appEvents.trigger('modal-body:clearFlash');
|
||||||
|
},
|
||||||
|
|
||||||
showModal(...args) {
|
showModal(...args) {
|
||||||
return showModal(...args);
|
return showModal(...args);
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
{{#each buttons as |b|}}
|
{{#each buttons as |b|}}
|
||||||
<button class="btn btn-social {{b.name}}" {{action "externalLogin" b}}>{{b.title}}</button>
|
<button class="btn btn-social {{b.name}}" {{action "externalLogin" b}}>{{b.title}}</button>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
|
{{#if canLoginLocalWithEmail}}
|
||||||
|
{{d-button
|
||||||
|
action="emailLogin"
|
||||||
|
label="email_login.button_label"
|
||||||
|
disabled=processingEmailLink
|
||||||
|
icon="envelope-o"
|
||||||
|
class="login-with-email-button"}}
|
||||||
|
{{/if}}
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
{{#login-modal screenX=lastX screenY=lastY loginName=loginName loginPassword=loginPassword loginSecondFactor=loginSecondFactor action="login"}}
|
{{#login-modal screenX=lastX screenY=lastY loginName=loginName loginPassword=loginPassword loginSecondFactor=loginSecondFactor action="login"}}
|
||||||
{{#d-modal-body title="login.title" class="login-modal"}}
|
{{#d-modal-body title="login.title" class="login-modal"}}
|
||||||
{{login-buttons action="externalLogin"}}
|
{{login-buttons
|
||||||
|
canLoginLocalWithEmail=canLoginLocalWithEmail
|
||||||
|
processingEmailLink=processingEmailLink
|
||||||
|
emailLogin='emailLogin'
|
||||||
|
externalLogin='externalLogin'}}
|
||||||
|
|
||||||
{{#if canLoginLocal}}
|
{{#if canLoginLocal}}
|
||||||
<form id='login-form' method='post'>
|
<form id='login-form' method='post'>
|
||||||
<div id="credentials">
|
<div id="credentials">
|
||||||
|
@ -13,6 +18,16 @@
|
||||||
{{text-field value=loginName type="email" placeholderKey="login.email_placeholder" id="login-account-name" autocorrect="off" autocapitalize="off"}}
|
{{text-field value=loginName type="email" placeholderKey="login.email_placeholder" id="login-account-name" autocorrect="off" autocapitalize="off"}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
{{#if showLoginWithEmailLink}}
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<a class="login-with-email-link" {{action "emailLogin"}}>
|
||||||
|
{{i18n 'email_login.link_label'}}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{/if}}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<label for='login-account-password'>{{i18n 'login.password'}} </label>
|
<label for='login-account-password'>{{i18n 'login.password'}} </label>
|
||||||
|
|
|
@ -13,12 +13,6 @@
|
||||||
label="forgot_password.reset"
|
label="forgot_password.reset"
|
||||||
disabled=submitDisabled
|
disabled=submitDisabled
|
||||||
class="btn-primary"}}
|
class="btn-primary"}}
|
||||||
{{#if siteSettings.enable_local_logins_via_email}}
|
|
||||||
{{d-button action="emailLogin"
|
|
||||||
label="email_login.label"
|
|
||||||
disabled=submitDisabled
|
|
||||||
class="email-login"}}
|
|
||||||
{{/if}}
|
|
||||||
{{else}}
|
{{else}}
|
||||||
{{d-button class="btn-large btn-primary"
|
{{d-button class="btn-large btn-primary"
|
||||||
label="forgot_password.button_ok"
|
label="forgot_password.button_ok"
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
{{#login-modal screenX=lastX screenY=lastY loginName=loginName loginPassword=loginPassword loginSecondFactor=loginSecondFactor action="login"}}
|
{{#login-modal screenX=lastX screenY=lastY loginName=loginName loginPassword=loginPassword loginSecondFactor=loginSecondFactor action="login"}}
|
||||||
{{#d-modal-body title="login.title" class="login-modal"}}
|
{{#d-modal-body title="login.title" class="login-modal"}}
|
||||||
{{login-buttons action="externalLogin"}}
|
{{login-buttons
|
||||||
|
canLoginLocalWithEmail=canLoginLocalWithEmail
|
||||||
|
processingEmailLink=processingEmailLink
|
||||||
|
emailLogin='emailLogin'
|
||||||
|
externalLogin='externalLogin'}}
|
||||||
|
|
||||||
{{#if canLoginLocal}}
|
{{#if canLoginLocal}}
|
||||||
<form id='login-form' method='post'>
|
<form id='login-form' method='post'>
|
||||||
<div id="credentials">
|
<div id="credentials">
|
||||||
|
@ -8,7 +13,13 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td><label for='login-account-name'>{{i18n 'login.username'}}</label></td>
|
<td><label for='login-account-name'>{{i18n 'login.username'}}</label></td>
|
||||||
<td>{{text-field value=loginName placeholderKey="login.email_placeholder" id="login-account-name" autocorrect="off" autocapitalize="off" autofocus="autofocus"}}</td>
|
<td>{{text-field value=loginName placeholderKey="login.email_placeholder" id="login-account-name" autocorrect="off" autocapitalize="off" autofocus="autofocus"}}</td>
|
||||||
<td></td>
|
<td>
|
||||||
|
{{#if showLoginWithEmailLink}}
|
||||||
|
<a class="login-with-email-link" {{action "emailLogin"}}>
|
||||||
|
{{i18n 'email_login.link_label'}}
|
||||||
|
</a>
|
||||||
|
{{/if}}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><label for='login-account-password'>{{i18n 'login.password'}}</label></td>
|
<td><label for='login-account-password'>{{i18n 'login.password'}}</label></td>
|
||||||
|
|
|
@ -128,7 +128,7 @@
|
||||||
&:before {
|
&:before {
|
||||||
margin-right: 9px;
|
margin-right: 9px;
|
||||||
font-family: FontAwesome;
|
font-family: FontAwesome;
|
||||||
font-size: 1.214em;
|
font-size: $font-0;
|
||||||
}
|
}
|
||||||
&.google, &.google_oauth2 {
|
&.google, &.google_oauth2 {
|
||||||
background: $google;
|
background: $google;
|
||||||
|
|
|
@ -1097,7 +1097,8 @@ en:
|
||||||
button_help: "Help"
|
button_help: "Help"
|
||||||
|
|
||||||
email_login:
|
email_login:
|
||||||
label: "Login With Email"
|
link_label: "Email me a magic link"
|
||||||
|
button_label: "with email"
|
||||||
complete_username: "If an account matches the username <b>%{username}</b>, you should receive an email with a magic login link shortly."
|
complete_username: "If an account matches the username <b>%{username}</b>, you should receive an email with a magic login link shortly."
|
||||||
complete_email: "If an account matches <b>%{email}</b>, you should receive an email with a magic login link shortly."
|
complete_email: "If an account matches <b>%{email}</b>, you should receive an email with a magic login link shortly."
|
||||||
complete_username_found: "We found an account that matches the username <b>%{username}</b>, you should receive an email with a magic login link shortly."
|
complete_username_found: "We found an account that matches the username <b>%{username}</b>, you should receive an email with a magic login link shortly."
|
||||||
|
@ -1116,6 +1117,7 @@ en:
|
||||||
caps_lock_warning: "Caps Lock is on"
|
caps_lock_warning: "Caps Lock is on"
|
||||||
error: "Unknown error"
|
error: "Unknown error"
|
||||||
rate_limit: "Please wait before trying to log in again."
|
rate_limit: "Please wait before trying to log in again."
|
||||||
|
blank_username: "Please enter your email or username."
|
||||||
blank_username_or_password: "Please enter your email or username, and password."
|
blank_username_or_password: "Please enter your email or username, and password."
|
||||||
reset_password: 'Reset Password'
|
reset_password: 'Reset Password'
|
||||||
logging_in: "Signing In..."
|
logging_in: "Signing In..."
|
||||||
|
|
|
@ -3,9 +3,6 @@ import { acceptance } from "helpers/qunit-helpers";
|
||||||
let userFound = false;
|
let userFound = false;
|
||||||
|
|
||||||
acceptance("Forgot password", {
|
acceptance("Forgot password", {
|
||||||
settings: {
|
|
||||||
enable_local_logins_via_email: true
|
|
||||||
},
|
|
||||||
beforeEach() {
|
beforeEach() {
|
||||||
const response = object => {
|
const response = object => {
|
||||||
return [
|
return [
|
||||||
|
@ -15,41 +12,44 @@ acceptance("Forgot password", {
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
server.post('/u/email-login', () => { // eslint-disable-line no-undef
|
server.post('/session/forgot_password', () => { // eslint-disable-line no-undef
|
||||||
return response({ "user_found": userFound });
|
return response({ "user_found": userFound });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test("logging in via email", assert => {
|
QUnit.test("requesting password reset", assert => {
|
||||||
visit("/");
|
visit("/");
|
||||||
click("header .login-button");
|
click("header .login-button");
|
||||||
|
|
||||||
andThen(() => {
|
|
||||||
assert.ok(exists('.login-modal'), "it shows the login modal");
|
|
||||||
});
|
|
||||||
|
|
||||||
click('#forgot-password-link');
|
click('#forgot-password-link');
|
||||||
|
|
||||||
fillIn("#username-or-email", 'someuser');
|
|
||||||
click('.email-login');
|
|
||||||
|
|
||||||
andThen(() => {
|
andThen(() => {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
find(".alert-error").html(),
|
find('button[title="Reset Password"]').attr("disabled"),
|
||||||
I18n.t('email_login.complete_username_not_found', { username: 'someuser' }),
|
"disabled",
|
||||||
'it should display the right error message'
|
'it should disable the button until the field is filled'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
fillIn("#username-or-email", 'someuser');
|
||||||
|
click('button[title="Reset Password"]');
|
||||||
|
|
||||||
|
andThen(() => {
|
||||||
|
assert.equal(
|
||||||
|
find(".alert-error").html().trim(),
|
||||||
|
I18n.t('forgot_password.complete_username_not_found', { username: 'someuser' }),
|
||||||
|
'it should display an error for an invalid username'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
fillIn("#username-or-email", 'someuser@gmail.com');
|
fillIn("#username-or-email", 'someuser@gmail.com');
|
||||||
click('.email-login');
|
click('button[title="Reset Password"]');
|
||||||
|
|
||||||
andThen(() => {
|
andThen(() => {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
find(".alert-error").html(),
|
find(".alert-error").html().trim(),
|
||||||
I18n.t('email_login.complete_email_not_found', { email: 'someuser@gmail.com' }),
|
I18n.t('forgot_password.complete_email_not_found', { email: 'someuser@gmail.com' }),
|
||||||
'it should display the right error message'
|
'it should display an error for an invalid email'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -59,32 +59,29 @@ QUnit.test("logging in via email", assert => {
|
||||||
userFound = true;
|
userFound = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
click('.email-login');
|
click('button[title="Reset Password"]');
|
||||||
|
|
||||||
andThen(() => {
|
andThen(() => {
|
||||||
|
assert.notOk(exists(find(".alert-error")), 'it should remove the flash error when succeeding');
|
||||||
|
|
||||||
assert.equal(
|
assert.equal(
|
||||||
find(".modal-body").html().trim(),
|
find(".modal-body").html().trim(),
|
||||||
I18n.t('email_login.complete_username_found', { username: 'someuser' }),
|
I18n.t('forgot_password.complete_username_found', { username: 'someuser' }),
|
||||||
'it should display the right message'
|
'it should display a success message for a valid username'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
visit("/");
|
visit("/");
|
||||||
click("header .login-button");
|
click("header .login-button");
|
||||||
|
|
||||||
andThen(() => {
|
|
||||||
assert.ok(exists('.login-modal'), "it shows the login modal");
|
|
||||||
});
|
|
||||||
|
|
||||||
click('#forgot-password-link');
|
click('#forgot-password-link');
|
||||||
fillIn("#username-or-email", 'someuser@gmail.com');
|
fillIn("#username-or-email", 'someuser@gmail.com');
|
||||||
click('.email-login');
|
click('button[title="Reset Password"]');
|
||||||
|
|
||||||
andThen(() => {
|
andThen(() => {
|
||||||
assert.equal(
|
assert.equal(
|
||||||
find(".modal-body").html().trim(),
|
find(".modal-body").html().trim(),
|
||||||
I18n.t('email_login.complete_email_found', { email: 'someuser@gmail.com' }),
|
I18n.t('forgot_password.complete_email_found', { email: 'someuser@gmail.com' }),
|
||||||
'it should display the right message'
|
'it should display a success message for a valid email'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
116
test/javascripts/acceptance/login-with-email-test.js.es6
Normal file
116
test/javascripts/acceptance/login-with-email-test.js.es6
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
import { acceptance } from "helpers/qunit-helpers";
|
||||||
|
|
||||||
|
let userFound = false;
|
||||||
|
|
||||||
|
acceptance("Login with email", {
|
||||||
|
settings: {
|
||||||
|
enable_local_logins_via_email: true,
|
||||||
|
enable_facebook_logins: true
|
||||||
|
},
|
||||||
|
beforeEach() {
|
||||||
|
const response = object => {
|
||||||
|
return [
|
||||||
|
200,
|
||||||
|
{ "Content-Type": "application/json" },
|
||||||
|
object
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
server.post('/u/email-login', () => { // eslint-disable-line no-undef
|
||||||
|
return response({ "user_found": userFound });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test("logging in via email (link)", assert => {
|
||||||
|
visit("/");
|
||||||
|
click("header .login-button");
|
||||||
|
|
||||||
|
andThen(() => {
|
||||||
|
assert.notOk(exists(".login-with-email-link"), 'it displays the link only when field is filled');
|
||||||
|
});
|
||||||
|
|
||||||
|
fillIn("#login-account-name", "someuser");
|
||||||
|
click(".login-with-email-link");
|
||||||
|
|
||||||
|
andThen(() => {
|
||||||
|
assert.equal(
|
||||||
|
find(".alert-error").html(),
|
||||||
|
I18n.t('email_login.complete_username_not_found', { username: 'someuser' }),
|
||||||
|
'it should display an error for an invalid username'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
fillIn("#login-account-name", 'someuser@gmail.com');
|
||||||
|
click('.login-with-email-link');
|
||||||
|
|
||||||
|
andThen(() => {
|
||||||
|
assert.equal(
|
||||||
|
find(".alert-error").html(),
|
||||||
|
I18n.t('email_login.complete_email_not_found', { email: 'someuser@gmail.com' }),
|
||||||
|
'it should display an error for an invalid email'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
fillIn("#login-account-name", 'someuser');
|
||||||
|
|
||||||
|
andThen(() => {
|
||||||
|
userFound = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
click('.login-with-email-link');
|
||||||
|
|
||||||
|
andThen(() => {
|
||||||
|
assert.equal(
|
||||||
|
find(".alert-success").html().trim(),
|
||||||
|
I18n.t('email_login.complete_username_found', { username: 'someuser' }),
|
||||||
|
'it should display a success message for a valid username'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
visit("/");
|
||||||
|
click("header .login-button");
|
||||||
|
fillIn("#login-account-name", 'someuser@gmail.com');
|
||||||
|
click('.login-with-email-link');
|
||||||
|
|
||||||
|
andThen(() => {
|
||||||
|
assert.equal(
|
||||||
|
find(".alert-success").html().trim(),
|
||||||
|
I18n.t('email_login.complete_email_found', { email: 'someuser@gmail.com' }),
|
||||||
|
'it should display a success message for a valid email'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
andThen(() => {
|
||||||
|
userFound = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test("logging in via email (button)", assert => {
|
||||||
|
visit("/");
|
||||||
|
click("header .login-button");
|
||||||
|
click('.login-with-email-button');
|
||||||
|
|
||||||
|
andThen(() => {
|
||||||
|
assert.equal(
|
||||||
|
find(".alert-error").html(),
|
||||||
|
I18n.t('login.blank_username'),
|
||||||
|
'it should display an error for blank username'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
andThen(() => {
|
||||||
|
userFound = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
fillIn("#login-account-name", 'someuser');
|
||||||
|
click('.login-with-email-button');
|
||||||
|
|
||||||
|
andThen(() => {
|
||||||
|
assert.equal(
|
||||||
|
find(".alert-success").html().trim(),
|
||||||
|
I18n.t('email_login.complete_username_found', { username: 'someuser' }),
|
||||||
|
'it should display a success message for a valid username'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Add table
Add a link
Reference in a new issue