Added browser tests for password reset.
This commit is contained in:
parent
67b32a0bca
commit
0d9adc0d64
12 changed files with 324 additions and 100 deletions
|
@ -44,120 +44,156 @@ class Index extends App.ControllerContent
|
|||
|
||||
# get data
|
||||
@ajax(
|
||||
id: 'password_reset'
|
||||
type: 'POST'
|
||||
url: @apiPath + '/users/password_reset'
|
||||
data: JSON.stringify(params)
|
||||
id: 'password_reset'
|
||||
type: 'POST'
|
||||
url: @apiPath + '/users/password_reset'
|
||||
data: JSON.stringify(params)
|
||||
processData: true
|
||||
success: @success
|
||||
error: @error
|
||||
success: @success
|
||||
)
|
||||
|
||||
success: (data, status, xhr) =>
|
||||
@render( sent: true )
|
||||
success: (data) =>
|
||||
if data.message is 'ok'
|
||||
|
||||
error: (data, status, xhr) =>
|
||||
@notify(
|
||||
type: 'error'
|
||||
msg: App.i18n.translateContent( 'Username or email address invalid, please try again.' )
|
||||
)
|
||||
@formEnable( @el.find('.form-password') )
|
||||
# if in developer mode, redirect to set new password
|
||||
if data.token && @Config.get('developer_mode') is true
|
||||
redirect = =>
|
||||
@navigate "#password_reset_verify/#{data.token}"
|
||||
@delay( redirect, 2000 )
|
||||
@render( sent: true )
|
||||
|
||||
else
|
||||
@$('[name=username]').val('')
|
||||
@notify(
|
||||
type: 'error'
|
||||
msg: App.i18n.translateContent( 'Username or email address invalid, please try again.' )
|
||||
)
|
||||
@formEnable( @el.find('.form-password') )
|
||||
|
||||
App.Config.set( 'reset_password', Index, 'Routes' )
|
||||
|
||||
class Verify extends App.ControllerContent
|
||||
events:
|
||||
'submit form': 'submit'
|
||||
'submit form': 'submit'
|
||||
'click .submit': 'submit'
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
@navHide()
|
||||
|
||||
# set title
|
||||
@title 'Reset Password'
|
||||
@navupdate '#reset_password_verify'
|
||||
|
||||
# get data
|
||||
params = {}
|
||||
params['token'] = @token
|
||||
params =
|
||||
token: @token
|
||||
@ajax(
|
||||
id: 'password_reset_verify'
|
||||
type: 'POST'
|
||||
url: @apiPath + '/users/password_reset_verify'
|
||||
data: JSON.stringify(params)
|
||||
id: 'password_reset_verify'
|
||||
type: 'POST'
|
||||
url: @apiPath + '/users/password_reset_verify'
|
||||
data: JSON.stringify(params)
|
||||
processData: true
|
||||
success: @render_success
|
||||
error: @render_failed
|
||||
success: @render_change
|
||||
)
|
||||
|
||||
render_success: =>
|
||||
configure_attributes = [
|
||||
{ name: 'password', display: 'Password', tag: 'input', type: 'password', limit: 100, null: false, class: 'input span4', },
|
||||
]
|
||||
render_change: (data) =>
|
||||
if data.message is 'ok'
|
||||
configure_attributes = [
|
||||
{ name: 'password', display: 'Password', tag: 'input', type: 'password', limit: 100, null: false, class: 'input', },
|
||||
]
|
||||
|
||||
@html App.view('password/reset_change')()
|
||||
@html App.view('password/reset_change')()
|
||||
|
||||
new App.ControllerForm(
|
||||
el: @el.find('#form-password-change')
|
||||
model: { configure_attributes: configure_attributes }
|
||||
autofocus: true
|
||||
)
|
||||
|
||||
render_failed: =>
|
||||
@html App.view('generic/hero_message')(
|
||||
head: 'Failed!'
|
||||
message: 'Token is not valid!'
|
||||
)
|
||||
new App.ControllerForm(
|
||||
el: @el.find('.form-password-change')
|
||||
model: { configure_attributes: configure_attributes }
|
||||
autofocus: true
|
||||
)
|
||||
else
|
||||
@html App.view('password/reset_failed')(
|
||||
head: 'Reset Password failed!'
|
||||
message: 'Token is invalid!'
|
||||
)
|
||||
|
||||
submit: (e) ->
|
||||
e.preventDefault()
|
||||
params = @formParam(e.target)
|
||||
params = @formParam(e.target)
|
||||
params['token'] = @token
|
||||
@password = params['password']
|
||||
@password = params['password']
|
||||
|
||||
# disable form
|
||||
@formDisable(e)
|
||||
|
||||
# validate
|
||||
if params['password_confirm'] isnt params['password']
|
||||
@formEnable(e)
|
||||
@$('[name=password]').val('')
|
||||
@$('[name=password_confirm]').val('')
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: 'Can\'t update password, your new passwords do not match. Please try again!'
|
||||
removeAll: true
|
||||
return
|
||||
if !params['password']
|
||||
@formEnable(e)
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: 'Please supply your new password!'
|
||||
removeAll: true
|
||||
return
|
||||
|
||||
# get data
|
||||
@ajax(
|
||||
id: 'password_reset_verify'
|
||||
type: 'POST'
|
||||
url: @apiPath + '/users/password_reset_verify'
|
||||
data: JSON.stringify(params)
|
||||
id: 'password_reset_verify'
|
||||
type: 'POST'
|
||||
url: @apiPath + '/users/password_reset_verify'
|
||||
data: JSON.stringify(params)
|
||||
processData: true
|
||||
success: @render_changed_success
|
||||
error: @render_changed_failed
|
||||
success: @render_changed
|
||||
)
|
||||
|
||||
render_changed_success: (data, status, xhr) =>
|
||||
App.Auth.login(
|
||||
data:
|
||||
username: data.user_login
|
||||
password: @password
|
||||
success: =>
|
||||
render_changed: (data, status, xhr) =>
|
||||
if data.message is 'ok'
|
||||
App.Auth.login(
|
||||
data:
|
||||
username: data.user_login
|
||||
password: @password
|
||||
success: =>
|
||||
|
||||
# login check
|
||||
App.Auth.loginCheck()
|
||||
# login check
|
||||
App.Auth.loginCheck()
|
||||
|
||||
# add notify
|
||||
@notify
|
||||
type: 'success'
|
||||
msg: 'Woo hoo! Your password has been changed!'
|
||||
removeAll: true
|
||||
# add notify
|
||||
@notify
|
||||
type: 'success'
|
||||
msg: 'Woo hoo! Your password has been changed!'
|
||||
removeAll: true
|
||||
|
||||
# redirect to #
|
||||
@navigate '#'
|
||||
# redirect to #
|
||||
@navigate '#'
|
||||
|
||||
error: =>
|
||||
error: =>
|
||||
@formEnable( @$('form') )
|
||||
|
||||
# add notify
|
||||
# add notify
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: 'Something went wrong. Please contact your administrator.'
|
||||
removeAll: true
|
||||
)
|
||||
else
|
||||
if data.notice
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: 'Something went wrong. Please contact your administrator.'
|
||||
msg: App.i18n.translateContent( data.notice[0], data.notice[1] )
|
||||
removeAll: true
|
||||
)
|
||||
else
|
||||
@notify
|
||||
type: 'error'
|
||||
msg: 'Unable to set password. Please contact your administrator.'
|
||||
removeAll: true
|
||||
@formEnable( @$('form') )
|
||||
|
||||
render_changed_failed: =>
|
||||
@html App.view('generic/hero_message')(
|
||||
head: 'Failed!'
|
||||
message: 'Ask your admin!'
|
||||
)
|
||||
|
||||
App.Config.set( 'password_reset_verify/:token', Verify, 'Routes' )
|
||||
App.Config.set( 'password_reset_verify/:token', Verify, 'Routes' )
|
|
@ -1,8 +0,0 @@
|
|||
<div class="hero-unit">
|
||||
<h2><%- @T( @head ) %> <small><%- @T( @head_small ) %></small></h2>
|
||||
<div class="container">
|
||||
<p>
|
||||
<%- @message %>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
|
@ -1,8 +1,12 @@
|
|||
<div class="fullHeight vertical center justified reset_password fit">
|
||||
<div class="hero-unit">
|
||||
<h2><%- @T( 'Choose your new password.' ) %><small></small></h2>
|
||||
<form id="form-password-change">
|
||||
<button class="btn btn--primary submit"><%- @T( 'Submit' ) %></button>
|
||||
<form>
|
||||
<div class="form-password-change"></div>
|
||||
<div class="form-controls">
|
||||
<a class="subtle-link standalone pull-left cancel" href="#/"><%- @T( 'Cancel & Go Back' ) %></a>
|
||||
<button class="btn btn--primary submit pull-right"><%- @T( 'Submit' ) %></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,9 @@
|
|||
<div class="reset_password fullscreen">
|
||||
<div class="fullscreen-center">
|
||||
<div class="hero-unit fullscreen-body">
|
||||
<h2><%- @T( @head ) %><small></small></h2>
|
||||
<p><%- @message %></p>
|
||||
<a href="#reset_password" class="subtle retry">» <%- @T('try again') %> «</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -367,12 +367,22 @@ curl http://localhost/api/v1/users/password_reset.json -v -u #{login}:#{password
|
|||
return
|
||||
end
|
||||
|
||||
success = User.password_reset_send( params[:username] )
|
||||
if success
|
||||
token = User.password_reset_send( params[:username] )
|
||||
if token
|
||||
|
||||
# only if system is in develop mode, send token back to browser for browser tests
|
||||
if Setting.get('developer_mode') == true
|
||||
render :json => { :message => 'ok', :token => token.name }, :status => :ok
|
||||
return
|
||||
end
|
||||
|
||||
# token sent to user, send ok to browser
|
||||
render :json => { :message => 'ok' }, :status => :ok
|
||||
else
|
||||
render :json => { :message => 'failed' }, :status => :unprocessable_entity
|
||||
return
|
||||
end
|
||||
|
||||
# unable to generate token
|
||||
render :json => { :message => 'failed' }, :status => :ok
|
||||
end
|
||||
|
||||
=begin
|
||||
|
@ -443,12 +453,12 @@ curl http://localhost/api/v1/users/password_change.json -v -u #{login}:#{passwor
|
|||
|
||||
# check old password
|
||||
if !params[:password_old]
|
||||
render :json => { :message => 'failed', :notice => ['Old password needed!'] }, :status => :ok
|
||||
render :json => { :message => 'failed', :notice => ['Current password needed!'] }, :status => :ok
|
||||
return
|
||||
end
|
||||
user = User.authenticate( current_user.login, params[:password_old] )
|
||||
if !user
|
||||
render :json => { :message => 'failed', :notice => ['Old password is wrong!'] }, :status => :ok
|
||||
render :json => { :message => 'failed', :notice => ['Current password is wrong!'] }, :status => :ok
|
||||
return
|
||||
end
|
||||
|
||||
|
|
|
@ -267,7 +267,7 @@ send reset password email with token to user
|
|||
|
||||
returns
|
||||
|
||||
result = true|false
|
||||
result = token
|
||||
|
||||
=end
|
||||
|
||||
|
@ -325,7 +325,7 @@ returns
|
|||
:subject => data[:subject],
|
||||
:body => data[:body]
|
||||
)
|
||||
true
|
||||
token
|
||||
end
|
||||
|
||||
=begin
|
||||
|
|
16
db/migrate/20141231000001_add_develop_mode.rb
Normal file
16
db/migrate/20141231000001_add_develop_mode.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
class AddDevelopMode < ActiveRecord::Migration
|
||||
def up
|
||||
Setting.create_if_not_exists(
|
||||
:title => 'Develop System',
|
||||
:name => 'developer_mode',
|
||||
:area => 'Core::Develop',
|
||||
:description => 'Defines if application is in developer mode (useful for developer, all users have the same password, password reset will work without email delivery).',
|
||||
:options => {},
|
||||
:state => false,
|
||||
:frontend => true
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
end
|
||||
end
|
|
@ -15,6 +15,15 @@ Setting.create_if_not_exists(
|
|||
:state => false,
|
||||
:frontend => true
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
:title => 'Developer System',
|
||||
:name => 'developer_mode',
|
||||
:area => 'Core::Develop',
|
||||
:description => 'Defines if application is in developer mode (useful for developer, all users have the same password, password reset will work without email delivery).',
|
||||
:options => {},
|
||||
:state => false,
|
||||
:frontend => true
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
:title => 'Online Service',
|
||||
:name => 'system_online_service',
|
||||
|
|
|
@ -23,7 +23,7 @@ returns
|
|||
:adapter => 'Auth::Internal',
|
||||
},
|
||||
{
|
||||
:adapter => 'Auth::Test',
|
||||
:adapter => 'Auth::Developer',
|
||||
},
|
||||
]
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
module Auth::Test
|
||||
module Auth::Developer
|
||||
def self.check( username, password, config, user )
|
||||
|
||||
# development systems
|
||||
if !ENV['RAILS_ENV'] || ENV['RAILS_ENV'] == 'development' || ENV['RAILS_ENV'] == 'test'
|
||||
if Setting.get('developer_mode') == true
|
||||
return user if password == 'test'
|
||||
end
|
||||
|
|
@ -28,8 +28,8 @@ rake db:seed
|
|||
# modify production.rb to serve assets
|
||||
cat config/environments/production.rb | sed -e 's/config.serve_static_assets = false/config.serve_static_assets = true/' > /tmp/production.rb && cp /tmp/production.rb config/environments/production.rb
|
||||
|
||||
# mofidy auth backend
|
||||
cat lib/auth/test.rb | sed "s/\] == 'test'/] == 'production'/" > /tmp/test.rb && cp /tmp/test.rb lib/auth/test.rb
|
||||
# set system to develop mode
|
||||
rails r "Setting.set('developer_mode', true)"
|
||||
|
||||
pumactl --pidfile tmp/pids/puma.pid stop
|
||||
script/websocket-server.rb stop
|
||||
|
@ -42,7 +42,7 @@ sleep 15
|
|||
#export REMOTE_URL='http://medenhofer:765d0dd4-994b-4e15-9f89-13f3aedeb462@ondemand.saucelabs.com:80/wd/hub' BROWSER_OS='Windows 2012' BROWSER_VERSION=20 BROWSER=firefox
|
||||
|
||||
rake test:browser["BROWSER_URL=http://localhost:4444"]
|
||||
#rake test:browser["BROWSER_URL=http://192.168.178.20:4444"]
|
||||
#rake test:browser["BROWSER_URL=http://192.168.178.28:4444"]
|
||||
|
||||
|
||||
script/websocket-server.rb stop
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# encoding: utf-8
|
||||
require 'browser_test_helper'
|
||||
|
||||
class SignupTest < TestCase
|
||||
class SignupPasswordChangeAndResetTest < TestCase
|
||||
def test_signup
|
||||
signup_user_email = 'signup-test-' + rand(999999).to_s + '@example.com'
|
||||
tests = [
|
||||
|
@ -112,7 +112,7 @@ class SignupTest < TestCase
|
|||
{
|
||||
:execute => 'watch_for',
|
||||
:area => 'body',
|
||||
:value => 'old password is wrong',
|
||||
:value => 'current password is wrong',
|
||||
},
|
||||
{
|
||||
:execute => 'set',
|
||||
|
@ -198,6 +198,154 @@ class SignupTest < TestCase
|
|||
:username => signup_user_email,
|
||||
:password => 'some-pass-new2',
|
||||
},
|
||||
{
|
||||
:execute => 'logout',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
:name => 'reset password',
|
||||
:action => [
|
||||
# got to wrong url
|
||||
{
|
||||
:execute => 'navigate',
|
||||
:to => browser_url + '/#password_reset_verify/not_existing_token',
|
||||
},
|
||||
{
|
||||
:execute => 'watch_for',
|
||||
:area => 'body',
|
||||
:value => 'Token is invalid',
|
||||
},
|
||||
|
||||
# correct way
|
||||
{
|
||||
:execute => 'click',
|
||||
:css => 'a[href="#reset_password"]',
|
||||
},
|
||||
{
|
||||
:execute => 'set',
|
||||
:css => 'input[name="username"]',
|
||||
:value => 'nonexisiting',
|
||||
},
|
||||
{
|
||||
:execute => 'click',
|
||||
:css => '.content .btn--primary',
|
||||
},
|
||||
{
|
||||
:execute => 'watch_for',
|
||||
:area => 'body',
|
||||
:value => 'address invalid',
|
||||
},
|
||||
{
|
||||
:execute => 'set',
|
||||
:css => 'input[name="username"]',
|
||||
:value => signup_user_email,
|
||||
},
|
||||
{
|
||||
:execute => 'click',
|
||||
:css => '.content .btn--primary',
|
||||
},
|
||||
{
|
||||
:execute => 'watch_for',
|
||||
:area => 'body',
|
||||
:value => 'sent password reset instructions',
|
||||
},
|
||||
|
||||
# redirect to "#password_reset_verify/#{token}" url by app, because of "developer_mode"
|
||||
{
|
||||
:execute => 'watch_for',
|
||||
:area => 'body',
|
||||
:value => 'Choose your new password',
|
||||
},
|
||||
|
||||
# set new password
|
||||
{
|
||||
:execute => 'set',
|
||||
:css => 'input[name="password"]',
|
||||
:value => 'some',
|
||||
},
|
||||
{
|
||||
:execute => 'set',
|
||||
:css => 'input[name="password_confirm"]',
|
||||
:value => 'some2',
|
||||
},
|
||||
{
|
||||
:execute => 'click',
|
||||
:css => '.content .btn--primary',
|
||||
},
|
||||
{
|
||||
:execute => 'watch_for',
|
||||
:area => 'body',
|
||||
:value => 'passwords do not match',
|
||||
},
|
||||
{
|
||||
:execute => 'set',
|
||||
:css => 'input[name="password"]',
|
||||
:value => 'some',
|
||||
},
|
||||
{
|
||||
:execute => 'set',
|
||||
:css => 'input[name="password_confirm"]',
|
||||
:value => 'some',
|
||||
},
|
||||
{
|
||||
:execute => 'click',
|
||||
:css => '.content .btn--primary',
|
||||
},
|
||||
{
|
||||
:execute => 'watch_for',
|
||||
:area => 'body',
|
||||
:value => 'it must be at least',
|
||||
},
|
||||
{
|
||||
:execute => 'set',
|
||||
:css => 'input[name="password"]',
|
||||
:value => 'some-pass-new',
|
||||
},
|
||||
{
|
||||
:execute => 'set',
|
||||
:css => 'input[name="password_confirm"]',
|
||||
:value => 'some-pass-new',
|
||||
},
|
||||
{
|
||||
:execute => 'click',
|
||||
:css => '.content .btn--primary',
|
||||
},
|
||||
{
|
||||
:execute => 'watch_for',
|
||||
:area => 'body',
|
||||
:value => 'must contain at least 1 digit',
|
||||
},
|
||||
{
|
||||
:execute => 'set',
|
||||
:css => 'input[name="password"]',
|
||||
:value => 'some-pass-new2',
|
||||
},
|
||||
{
|
||||
:execute => 'set',
|
||||
:css => 'input[name="password_confirm"]',
|
||||
:value => 'some-pass-new2',
|
||||
},
|
||||
{
|
||||
:execute => 'click',
|
||||
:css => '.content .btn--primary',
|
||||
},
|
||||
{
|
||||
:execute => 'watch_for',
|
||||
:area => 'body',
|
||||
:value => 'Your password has been changed',
|
||||
},
|
||||
{
|
||||
:execute => 'wait',
|
||||
:value => 5,
|
||||
},
|
||||
{
|
||||
:execute => 'match',
|
||||
:css => '.user-menu .user a',
|
||||
:attribute => 'title',
|
||||
:value => signup_user_email,
|
||||
:match_result => true,
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
Loading…
Reference in a new issue