2015-12-07 00:24:06 +03:00
/* jshint expr:true */
import {
describe ,
it ,
beforeEach ,
afterEach
} from 'mocha' ;
2016-11-14 16:16:51 +03:00
import { expect } from 'chai' ;
2015-12-07 00:24:06 +03:00
import startApp from '../helpers/start-app' ;
import destroyApp from '../helpers/destroy-app' ;
2016-11-14 16:16:51 +03:00
import { invalidateSession , authenticateSession } from '../helpers/ember-simple-auth' ;
import { errorOverride , errorReset } from '../helpers/adapter-error' ;
import { enableGhostOAuth } from '../helpers/configuration' ;
2017-01-02 21:50:36 +03:00
import { Response } from 'ember-cli-mirage' ;
2017-02-17 12:59:57 +03:00
import testSelector from 'ember-test-selectors' ;
2015-12-07 00:24:06 +03:00
describe ( 'Acceptance: Team' , function ( ) {
let application ;
beforeEach ( function ( ) {
application = startApp ( ) ;
} ) ;
afterEach ( function ( ) {
destroyApp ( application ) ;
} ) ;
it ( 'redirects to signin when not authenticated' , function ( ) {
invalidateSession ( application ) ;
visit ( '/team' ) ;
andThen ( function ( ) {
expect ( currentURL ( ) ) . to . equal ( '/signin' ) ;
} ) ;
} ) ;
it ( 'redirects correctly when authenticated as author' , function ( ) {
2016-04-08 18:00:16 +03:00
let role = server . create ( 'role' , { name : 'Author' } ) ;
2016-11-14 16:16:51 +03:00
server . create ( 'user' , { roles : [ role ] , slug : 'test-user' } ) ;
2015-12-07 00:24:06 +03:00
server . create ( 'user' , { slug : 'no-access' } ) ;
authenticateSession ( application ) ;
visit ( '/team/no-access' ) ;
andThen ( ( ) => {
expect ( currentURL ( ) , 'currentURL' ) . to . equal ( '/team/test-user' ) ;
} ) ;
} ) ;
it ( 'redirects correctly when authenticated as editor' , function ( ) {
2016-04-08 18:00:16 +03:00
let role = server . create ( 'role' , { name : 'Editor' } ) ;
2016-11-14 16:16:51 +03:00
server . create ( 'user' , { roles : [ role ] , slug : 'test-user' } ) ;
2015-12-07 00:24:06 +03:00
server . create ( 'user' , { slug : 'no-access' } ) ;
authenticateSession ( application ) ;
visit ( '/team/no-access' ) ;
andThen ( ( ) => {
expect ( currentURL ( ) , 'currentURL' ) . to . equal ( '/team' ) ;
} ) ;
} ) ;
2016-09-26 19:03:53 +03:00
describe ( 'when logged in as admin' , function ( ) {
let admin , adminRole ;
2016-06-14 14:46:24 +03:00
2015-12-07 00:24:06 +03:00
beforeEach ( function ( ) {
2017-01-02 21:50:36 +03:00
server . loadFixtures ( 'roles' ) ;
adminRole = server . schema . roles . find ( 1 ) ;
2015-12-07 00:24:06 +03:00
2017-01-02 21:50:36 +03:00
admin = server . create ( 'user' , { email : 'admin@example.com' , roles : [ adminRole ] } ) ;
2015-12-07 00:24:06 +03:00
2017-02-27 16:11:39 +03:00
// add an expired invite
server . create ( 'invite' , { expires : moment . utc ( ) . subtract ( 1 , 'day' ) . valueOf ( ) } ) ;
2015-12-07 00:24:06 +03:00
return authenticateSession ( application ) ;
} ) ;
it ( 'it renders and navigates correctly' , function ( ) {
2016-11-14 16:16:51 +03:00
server . create ( 'user' ) ;
2016-04-08 18:00:16 +03:00
let user2 = server . create ( 'user' ) ;
2015-12-07 00:24:06 +03:00
visit ( '/team' ) ;
andThen ( ( ) => {
// doesn't do any redirecting
expect ( currentURL ( ) , 'currentURL' ) . to . equal ( '/team' ) ;
// it has correct page title
expect ( document . title , 'page title' ) . to . equal ( 'Team - Test Blog' ) ;
// it shows 3 users in list (includes currently logged in user)
2017-02-17 12:59:57 +03:00
expect ( find ( testSelector ( 'user-id' ) ) . length , 'user list count' )
2015-12-07 00:24:06 +03:00
. to . equal ( 3 ) ;
2017-02-17 12:59:57 +03:00
click ( testSelector ( 'user-id' , user2 . id ) ) ;
2015-12-07 00:24:06 +03:00
andThen ( ( ) => {
// url is correct
expect ( currentURL ( ) , 'url after clicking user' ) . to . equal ( ` /team/ ${ user2 . slug } ` ) ;
// title is correct
expect ( document . title , 'title after clicking user' ) . to . equal ( 'Team - User - Test Blog' ) ;
// view title should exist and be linkable and active
2016-06-09 18:41:16 +03:00
expect ( find ( '.view-title a[href="/ghost/team"]' ) . hasClass ( 'active' ) , 'has linkable url back to team main page' )
2015-12-07 00:24:06 +03:00
. to . be . true ;
} ) ;
click ( '.view-title a' ) ;
andThen ( ( ) => {
// url should be /team again
expect ( currentURL ( ) , 'url after clicking back' ) . to . equal ( '/team' ) ;
} ) ;
} ) ;
} ) ;
2016-09-26 19:03:53 +03:00
it ( 'can manage invites' , function ( ) {
visit ( '/team' ) ;
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
andThen ( ( ) => {
// invite user button exists
expect (
2017-02-16 22:50:05 +03:00
find ( '.view-actions .gh-btn-green' ) . text ( ) . trim ( ) ,
2016-09-26 19:03:53 +03:00
'invite people button text'
) . to . equal ( 'Invite People' ) ;
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
// existing users are listed
expect (
2017-02-17 12:59:57 +03:00
find ( testSelector ( 'user-id' ) ) . length ,
2016-09-26 19:03:53 +03:00
'initial number of active users'
) . to . equal ( 1 ) ;
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
expect (
2017-02-17 12:59:57 +03:00
find ( testSelector ( 'user-id' , '1' ) ) . find ( testSelector ( 'role-name' ) ) . text ( ) . trim ( ) ,
2016-09-26 19:03:53 +03:00
'active user\'s role label'
) . to . equal ( 'Administrator' ) ;
2015-12-07 00:24:06 +03:00
2017-02-27 16:11:39 +03:00
// existing invites are shown
expect (
find ( testSelector ( 'invite-id' ) ) . length ,
'initial number of invited users'
) . to . equal ( 1 ) ;
expect (
find ( testSelector ( 'invite-id' , '1' ) ) . find ( testSelector ( 'invite-description' ) ) . text ( ) ,
'expired invite description'
) . to . match ( /expired/ ) ;
} ) ;
// remove expired invite
click ( ` ${ testSelector ( 'invite-id' , '1' ) } ${ testSelector ( 'revoke-button' ) } ` ) ;
andThen ( ( ) => {
2016-09-26 19:03:53 +03:00
expect (
2017-02-17 12:59:57 +03:00
find ( testSelector ( 'invite-id' ) ) . length ,
2016-09-26 19:03:53 +03:00
'initial number of invited users'
) . to . equal ( 0 ) ;
} ) ;
// click the invite people button
2017-02-16 22:50:05 +03:00
click ( '.view-actions .gh-btn-green' ) ;
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
andThen ( ( ) => {
let roleOptions = find ( '.fullscreen-modal select[name="role"] option' ) ;
function checkOwnerExists ( ) {
for ( let i in roleOptions ) {
if ( roleOptions [ i ] . tagName === 'option' && roleOptions [ i ] . text === 'Owner' ) {
return true ;
2015-12-07 00:24:06 +03:00
}
}
2016-09-26 19:03:53 +03:00
return false ;
}
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
function checkSelectedIsAuthor ( ) {
for ( let i in roleOptions ) {
if ( roleOptions [ i ] . selected ) {
return roleOptions [ i ] . text === 'Author' ;
2015-12-07 00:24:06 +03:00
}
}
2016-09-26 19:03:53 +03:00
return false ;
}
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
// modal is displayed
expect (
find ( '.fullscreen-modal h1' ) . text ( ) . trim ( ) ,
'correct modal is displayed'
) . to . equal ( 'Invite a New User' ) ;
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
// number of roles is correct
expect (
find ( '.fullscreen-modal select[name="role"] option' ) . length ,
'number of selectable roles'
) . to . equal ( 3 ) ;
expect ( checkOwnerExists ( ) , 'owner role isn\'t available' ) . to . be . false ;
expect ( checkSelectedIsAuthor ( ) , 'author role is selected initially' ) . to . be . true ;
2015-12-07 00:24:06 +03:00
} ) ;
2016-09-26 19:03:53 +03:00
// submit valid invite form
fillIn ( '.fullscreen-modal input[name="email"]' , 'invite1@example.com' ) ;
2017-02-16 22:50:05 +03:00
click ( '.fullscreen-modal .gh-btn-green' ) ;
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
andThen ( ( ) => {
// modal closes
expect (
find ( '.fullscreen-modal' ) . length ,
'number of modals after sending invite'
) . to . equal ( 0 ) ;
// invite is displayed, has correct e-mail + role
expect (
2017-02-17 12:59:57 +03:00
find ( testSelector ( 'invite-id' ) ) . length ,
2016-09-26 19:03:53 +03:00
'number of invites after first invite'
) . to . equal ( 1 ) ;
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
expect (
2017-02-27 16:11:39 +03:00
find ( testSelector ( 'invite-id' , '2' ) ) . find ( testSelector ( 'email' ) ) . text ( ) . trim ( ) ,
2016-09-26 19:03:53 +03:00
'displayed email of first invite'
) . to . equal ( 'invite1@example.com' ) ;
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
expect (
2017-02-27 16:11:39 +03:00
find ( testSelector ( 'invite-id' , '2' ) ) . find ( testSelector ( 'role-name' ) ) . text ( ) . trim ( ) ,
2016-09-26 19:03:53 +03:00
'displayed role of first invite'
) . to . equal ( 'Author' ) ;
2015-12-07 00:24:06 +03:00
2017-02-27 16:11:39 +03:00
expect (
find ( testSelector ( 'invite-id' , '2' ) ) . find ( testSelector ( 'invite-description' ) ) . text ( ) ,
'new invite description'
) . to . match ( /expires/ ) ;
2016-09-26 19:03:53 +03:00
// number of users is unchanged
expect (
2017-02-17 12:59:57 +03:00
find ( testSelector ( 'user-id' ) ) . length ,
2016-09-26 19:03:53 +03:00
'number of active users after first invite'
) . to . equal ( 1 ) ;
} ) ;
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
// submit new invite with different role
2017-02-16 22:50:05 +03:00
click ( '.view-actions .gh-btn-green' ) ;
2016-09-26 19:03:53 +03:00
fillIn ( '.fullscreen-modal input[name="email"]' , 'invite2@example.com' ) ;
fillIn ( '.fullscreen-modal select[name="role"]' , '2' ) ;
2017-02-16 22:50:05 +03:00
click ( '.fullscreen-modal .gh-btn-green' ) ;
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
andThen ( ( ) => {
// number of invites increases
expect (
2017-02-17 12:59:57 +03:00
find ( testSelector ( 'invite-id' ) ) . length ,
2016-09-26 19:03:53 +03:00
'number of invites after second invite'
) . to . equal ( 2 ) ;
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
// invite has correct e-mail + role
expect (
2017-02-27 16:11:39 +03:00
find ( testSelector ( 'invite-id' , '3' ) ) . find ( testSelector ( 'email' ) ) . text ( ) . trim ( ) ,
2016-09-26 19:03:53 +03:00
'displayed email of second invite'
) . to . equal ( 'invite2@example.com' ) ;
expect (
2017-02-27 16:11:39 +03:00
find ( testSelector ( 'invite-id' , '3' ) ) . find ( testSelector ( 'role-name' ) ) . text ( ) . trim ( ) ,
2016-09-26 19:03:53 +03:00
'displayed role of second invite'
) . to . equal ( 'Editor' ) ;
2015-12-07 00:24:06 +03:00
} ) ;
2016-09-26 19:03:53 +03:00
// submit invite form with existing user
2017-02-16 22:50:05 +03:00
click ( '.view-actions .gh-btn-green' ) ;
2016-09-26 19:03:53 +03:00
fillIn ( '.fullscreen-modal input[name="email"]' , 'admin@example.com' ) ;
2017-02-16 22:50:05 +03:00
click ( '.fullscreen-modal .gh-btn-green' ) ;
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
andThen ( ( ) => {
// validation message is displayed
expect (
find ( '.fullscreen-modal .error .response' ) . text ( ) . trim ( ) ,
'inviting existing user error'
) . to . equal ( 'A user with that email address already exists.' ) ;
} ) ;
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
// submit invite form with existing invite
fillIn ( '.fullscreen-modal input[name="email"]' , 'invite1@example.com' ) ;
2017-02-16 22:50:05 +03:00
click ( '.fullscreen-modal .gh-btn-green' ) ;
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
andThen ( ( ) => {
// validation message is displayed
expect (
find ( '.fullscreen-modal .error .response' ) . text ( ) . trim ( ) ,
'inviting invited user error'
) . to . equal ( 'A user with that email address was already invited.' ) ;
} ) ;
2015-11-18 13:50:48 +03:00
2016-09-26 19:03:53 +03:00
// submit invite form with an invalid email
fillIn ( '.fullscreen-modal input[name="email"]' , 'test' ) ;
2017-02-16 22:50:05 +03:00
click ( '.fullscreen-modal .gh-btn-green' ) ;
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
andThen ( ( ) => {
// validation message is displayed
expect (
find ( '.fullscreen-modal .error .response' ) . text ( ) . trim ( ) ,
'inviting invalid email error'
) . to . equal ( 'Invalid Email.' ) ;
} ) ;
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
click ( '.fullscreen-modal a.close' ) ;
// revoke latest invite
2017-02-27 16:11:39 +03:00
click ( ` ${ testSelector ( 'invite-id' , '3' ) } ${ testSelector ( 'revoke-button' ) } ` ) ;
2015-12-07 00:24:06 +03:00
2016-09-26 19:03:53 +03:00
andThen ( ( ) => {
// number of invites decreases
expect (
2017-02-17 12:59:57 +03:00
find ( testSelector ( 'invite-id' ) ) . length ,
2016-09-26 19:03:53 +03:00
'number of invites after revoke'
) . to . equal ( 1 ) ;
2015-11-18 13:50:48 +03:00
2016-09-26 19:03:53 +03:00
// notification is displayed
expect (
find ( '.gh-notification' ) . text ( ) . trim ( ) ,
'notifications contain revoke'
) . to . match ( /Invitation revoked\. \(invite2@example\.com\)/ ) ;
// correct invite is removed
expect (
2017-02-17 12:59:57 +03:00
find ( testSelector ( 'invite-id' ) ) . find ( testSelector ( 'email' ) ) . text ( ) . trim ( ) ,
2016-09-26 19:03:53 +03:00
'displayed email of remaining invite'
) . to . equal ( 'invite1@example.com' ) ;
} ) ;
// add another invite to test ordering on resend
2017-02-16 22:50:05 +03:00
click ( '.view-actions .gh-btn-green' ) ;
2016-09-26 19:03:53 +03:00
fillIn ( '.fullscreen-modal input[name="email"]' , 'invite3@example.com' ) ;
2017-02-16 22:50:05 +03:00
click ( '.fullscreen-modal .gh-btn-green' ) ;
2016-09-26 19:03:53 +03:00
andThen ( ( ) => {
// new invite should be last in the list
expect (
2017-02-17 12:59:57 +03:00
find ( ` ${ testSelector ( 'invite-id' ) } :last ` ) . find ( testSelector ( 'email' ) ) . text ( ) . trim ( ) ,
2016-09-26 19:03:53 +03:00
'last invite email in list'
) . to . equal ( 'invite3@example.com' ) ;
} ) ;
// resend first invite
2017-02-27 16:11:39 +03:00
click ( ` ${ testSelector ( 'invite-id' , '2' ) } ${ testSelector ( 'resend-button' ) } ` ) ;
2016-09-26 19:03:53 +03:00
andThen ( ( ) => {
// notification is displayed
expect (
find ( '.gh-notification' ) . text ( ) . trim ( ) ,
'notifications contain resend'
) . to . match ( /Invitation resent! \(invite1@example\.com\)/ ) ;
// first invite is still at the top
expect (
2017-02-17 12:59:57 +03:00
find ( ` ${ testSelector ( 'invite-id' ) } :first-of-type ` ) . find ( testSelector ( 'email' ) ) . text ( ) . trim ( ) ,
2016-09-26 19:03:53 +03:00
'first invite email in list'
) . to . equal ( 'invite1@example.com' ) ;
} ) ;
// regression test: can revoke a resent invite
2017-02-17 12:59:57 +03:00
click ( ` ${ testSelector ( 'invite-id' ) } :first-of-type ${ testSelector ( 'resend-button' ) } ` ) ;
click ( ` ${ testSelector ( 'invite-id' ) } :first-of-type ${ testSelector ( 'revoke-button' ) } ` ) ;
2016-09-26 19:03:53 +03:00
andThen ( ( ) => {
// number of invites decreases
expect (
2017-02-17 12:59:57 +03:00
find ( testSelector ( 'invite-id' ) ) . length ,
2016-09-26 19:03:53 +03:00
'number of invites after resend/revoke'
) . to . equal ( 1 ) ;
// notification is displayed
expect (
find ( '.gh-notification' ) . text ( ) . trim ( ) ,
'notifications contain revoke after resend/revoke'
) . to . match ( /Invitation revoked\. \(invite1@example\.com\)/ ) ;
2015-12-07 00:24:06 +03:00
} ) ;
} ) ;
2016-08-24 16:26:29 +03:00
it ( 'can delete users' , function ( ) {
let user1 = server . create ( 'user' ) ;
let user2 = server . create ( 'user' ) ;
2017-01-02 21:50:36 +03:00
let post = server . create ( 'post' ) ;
user2 . posts = [ post ] ;
2016-08-24 16:26:29 +03:00
visit ( '/team' ) ;
2017-02-17 12:59:57 +03:00
click ( testSelector ( 'user-id' , user1 . id ) ) ;
2016-08-24 16:26:29 +03:00
// user deletion displays modal
click ( 'button.delete' ) ;
andThen ( ( ) => {
expect (
find ( '.fullscreen-modal .modal-content:contains("delete this user")' ) . length ,
'user deletion modal displayed after button click'
) . to . equal ( 1 ) ;
// user has no posts so no warning about post deletion
expect (
find ( '.fullscreen-modal .modal-content:contains("is the author of")' ) . length ,
'deleting user with no posts has no post count'
) . to . equal ( 0 ) ;
} ) ;
// cancelling user deletion closes modal
click ( '.fullscreen-modal button:contains("Cancel")' ) ;
andThen ( ( ) => {
expect (
find ( '.fullscreen-modal' ) . length === 0 ,
'delete user modal is closed when cancelling'
) . to . be . true ;
} ) ;
// deleting a user with posts
visit ( '/team' ) ;
2017-02-17 12:59:57 +03:00
click ( testSelector ( 'user-id' , user2 . id ) ) ;
2016-08-24 16:26:29 +03:00
click ( 'button.delete' ) ;
andThen ( ( ) => {
// user has posts so should warn about post deletion
expect (
find ( '.fullscreen-modal .modal-content:contains("is the author of 1 post")' ) . length ,
'deleting user with posts has post count'
) . to . equal ( 1 ) ;
} ) ;
click ( '.fullscreen-modal button:contains("Delete")' ) ;
andThen ( ( ) => {
// redirected to team page
expect ( currentURL ( ) ) . to . equal ( '/team' ) ;
// deleted user is not in list
expect (
2017-02-17 12:59:57 +03:00
find ( testSelector ( 'user-id' , user2 . id ) ) . length ,
2016-08-24 16:26:29 +03:00
'deleted user is not in user list after deletion'
) . to . equal ( 0 ) ;
} ) ;
} ) ;
2015-12-07 00:24:06 +03:00
describe ( 'existing user' , function ( ) {
let user ;
beforeEach ( function ( ) {
2016-06-14 14:46:24 +03:00
user = server . create ( 'user' , {
2016-05-17 21:14:14 +03:00
slug : 'test-1' ,
name : 'Test User' ,
facebook : 'test' ,
twitter : '@test'
} ) ;
2015-12-07 00:24:06 +03:00
} ) ;
it ( 'input fields reset and validate correctly' , function ( ) {
// test user name
visit ( '/team/test-1' ) ;
andThen ( ( ) => {
expect ( currentURL ( ) , 'currentURL' ) . to . equal ( '/team/test-1' ) ;
expect ( find ( '.user-details-top .first-form-group input.user-name' ) . val ( ) , 'current user name' ) . to . equal ( 'Test User' ) ;
} ) ;
// test empty user name
fillIn ( '.user-details-top .first-form-group input.user-name' , '' ) ;
triggerEvent ( '.user-details-top .first-form-group input.user-name' , 'blur' ) ;
andThen ( ( ) => {
2016-04-25 12:54:36 +03:00
expect ( find ( '.user-details-top .first-form-group' ) . hasClass ( 'error' ) , 'username input is in error state with blank input' ) . to . be . true ;
2015-12-07 00:24:06 +03:00
} ) ;
// test too long user name
fillIn ( '.user-details-top .first-form-group input.user-name' , new Array ( 160 ) . join ( 'a' ) ) ;
triggerEvent ( '.user-details-top .first-form-group input.user-name' , 'blur' ) ;
andThen ( ( ) => {
2016-04-25 12:54:36 +03:00
expect ( find ( '.user-details-top .first-form-group' ) . hasClass ( 'error' ) , 'username input is in error state with too long input' ) . to . be . true ;
2015-12-07 00:24:06 +03:00
} ) ;
// reset name field
fillIn ( '.user-details-top .first-form-group input.user-name' , 'Test User' ) ;
andThen ( ( ) => {
expect ( find ( '.user-details-bottom input[name="user"]' ) . val ( ) , 'slug value is default' ) . to . equal ( 'test-1' ) ;
} ) ;
fillIn ( '.user-details-bottom input[name="user"]' , '' ) ;
triggerEvent ( '.user-details-bottom input[name="user"]' , 'blur' ) ;
andThen ( ( ) => {
expect ( find ( '.user-details-bottom input[name="user"]' ) . val ( ) , 'slug value is reset to original upon empty string' ) . to . equal ( 'test-1' ) ;
} ) ;
fillIn ( '.user-details-bottom input[name="user"]' , 'white space' ) ;
triggerEvent ( '.user-details-bottom input[name="user"]' , 'blur' ) ;
andThen ( ( ) => {
expect ( find ( '.user-details-bottom input[name="user"]' ) . val ( ) , 'slug value is correctly dasherized' ) . to . equal ( 'white-space' ) ;
} ) ;
fillIn ( '.user-details-bottom input[name="email"]' , 'thisisnotanemail' ) ;
triggerEvent ( '.user-details-bottom input[name="email"]' , 'blur' ) ;
andThen ( ( ) => {
2016-04-25 12:54:36 +03:00
expect ( find ( '.user-details-bottom .form-group:nth-of-type(2)' ) . hasClass ( 'error' ) , 'email input should be in error state with invalid email' ) . to . be . true ;
2015-12-07 00:24:06 +03:00
} ) ;
fillIn ( '.user-details-bottom input[name="email"]' , 'test@example.com' ) ;
fillIn ( '#user-location' , new Array ( 160 ) . join ( 'a' ) ) ;
triggerEvent ( '#user-location' , 'blur' ) ;
andThen ( ( ) => {
2016-08-24 16:26:29 +03:00
expect ( find ( '#user-location' ) . closest ( '.form-group' ) . hasClass ( 'error' ) , 'location input should be in error state' ) . to . be . true ;
2015-12-07 00:24:06 +03:00
} ) ;
fillIn ( '#user-location' , '' ) ;
fillIn ( '#user-website' , 'thisisntawebsite' ) ;
triggerEvent ( '#user-website' , 'blur' ) ;
andThen ( ( ) => {
2016-08-24 16:26:29 +03:00
expect ( find ( '#user-website' ) . closest ( '.form-group' ) . hasClass ( 'error' ) , 'website input should be in error state' ) . to . be . true ;
2015-12-07 00:24:06 +03:00
} ) ;
2016-05-16 21:16:40 +03:00
// Testing Facebook input
2016-05-17 21:14:14 +03:00
andThen ( ( ) => {
// displays initial value
expect ( find ( '#user-facebook' ) . val ( ) , 'initial facebook value' )
. to . equal ( 'https://www.facebook.com/test' ) ;
} ) ;
triggerEvent ( '#user-facebook' , 'focus' ) ;
triggerEvent ( '#user-facebook' , 'blur' ) ;
andThen ( ( ) => {
// regression test: we still have a value after the input is
// focused and then blurred without any changes
expect ( find ( '#user-facebook' ) . val ( ) , 'facebook value after blur with no change' )
. to . equal ( 'https://www.facebook.com/test' ) ;
} ) ;
2016-03-03 11:52:27 +03:00
fillIn ( '#user-facebook' , '' ) ;
fillIn ( '#user-facebook' , ')(*&%^%)' ) ;
triggerEvent ( '#user-facebook' , 'blur' ) ;
andThen ( ( ) => {
2016-08-24 16:26:29 +03:00
expect ( find ( '#user-facebook' ) . closest ( '.form-group' ) . hasClass ( 'error' ) , 'facebook input should be in error state' ) . to . be . true ;
2016-03-03 11:52:27 +03:00
} ) ;
fillIn ( '#user-facebook' , '' ) ;
2016-05-16 21:16:40 +03:00
fillIn ( '#user-facebook' , 'pages/)(*&%^%)' ) ;
2016-03-03 11:52:27 +03:00
triggerEvent ( '#user-facebook' , 'blur' ) ;
andThen ( ( ) => {
2016-05-16 21:16:40 +03:00
expect ( find ( '#user-facebook' ) . val ( ) ) . to . be . equal ( 'https://www.facebook.com/pages/)(*&%^%)' ) ;
2016-08-24 16:26:29 +03:00
expect ( find ( '#user-facebook' ) . closest ( '.form-group' ) . hasClass ( 'error' ) , 'facebook input should be in error state' ) . to . be . false ;
2016-03-03 11:52:27 +03:00
} ) ;
fillIn ( '#user-facebook' , '' ) ;
2016-05-16 21:16:40 +03:00
fillIn ( '#user-facebook' , 'testing' ) ;
triggerEvent ( '#user-facebook' , 'blur' ) ;
andThen ( ( ) => {
expect ( find ( '#user-facebook' ) . val ( ) ) . to . be . equal ( 'https://www.facebook.com/testing' ) ;
2016-08-24 16:26:29 +03:00
expect ( find ( '#user-facebook' ) . closest ( '.form-group' ) . hasClass ( 'error' ) , 'facebook input should be in error state' ) . to . be . false ;
2016-05-16 21:16:40 +03:00
} ) ;
fillIn ( '#user-facebook' , '' ) ;
fillIn ( '#user-facebook' , 'somewebsite.com/pages/some-facebook-page/857469375913?ref=ts' ) ;
triggerEvent ( '#user-facebook' , 'blur' ) ;
andThen ( ( ) => {
expect ( find ( '#user-facebook' ) . val ( ) ) . to . be . equal ( 'https://www.facebook.com/pages/some-facebook-page/857469375913?ref=ts' ) ;
2016-08-24 16:26:29 +03:00
expect ( find ( '#user-facebook' ) . closest ( '.form-group' ) . hasClass ( 'error' ) , 'facebook input should be in error state' ) . to . be . false ;
2016-05-16 21:16:40 +03:00
} ) ;
fillIn ( '#user-facebook' , '' ) ;
fillIn ( '#user-facebook' , 'test' ) ;
2016-03-03 11:52:27 +03:00
triggerEvent ( '#user-facebook' , 'blur' ) ;
andThen ( ( ) => {
2016-08-24 16:26:29 +03:00
expect ( find ( '#user-facebook' ) . closest ( '.form-group' ) . hasClass ( 'error' ) , 'facebook input should be in error state' ) . to . be . true ;
2016-03-03 11:52:27 +03:00
} ) ;
fillIn ( '#user-facebook' , '' ) ;
2016-05-16 21:16:40 +03:00
fillIn ( '#user-facebook' , 'http://twitter.com/testuser' ) ;
triggerEvent ( '#user-facebook' , 'blur' ) ;
andThen ( ( ) => {
expect ( find ( '#user-facebook' ) . val ( ) ) . to . be . equal ( 'https://www.facebook.com/testuser' ) ;
2016-08-24 16:26:29 +03:00
expect ( find ( '#user-facebook' ) . closest ( '.form-group' ) . hasClass ( 'error' ) , 'facebook input should be in error state' ) . to . be . false ;
2016-05-16 21:16:40 +03:00
} ) ;
fillIn ( '#user-facebook' , '' ) ;
fillIn ( '#user-facebook' , 'facebook.com/testing' ) ;
2016-03-03 11:52:27 +03:00
triggerEvent ( '#user-facebook' , 'blur' ) ;
andThen ( ( ) => {
2016-05-16 21:16:40 +03:00
expect ( find ( '#user-facebook' ) . val ( ) ) . to . be . equal ( 'https://www.facebook.com/testing' ) ;
2016-08-24 16:26:29 +03:00
expect ( find ( '#user-facebook' ) . closest ( '.form-group' ) . hasClass ( 'error' ) , 'facebook input should be in error state' ) . to . be . false ;
2016-03-03 11:52:27 +03:00
} ) ;
2016-05-16 21:16:40 +03:00
// Testing Twitter input
2016-05-17 21:14:14 +03:00
andThen ( ( ) => {
// loads fixtures and performs transform
expect ( find ( '#user-twitter' ) . val ( ) , 'initial twitter value' )
. to . equal ( 'https://twitter.com/test' ) ;
} ) ;
triggerEvent ( '#user-twitter' , 'focus' ) ;
triggerEvent ( '#user-twitter' , 'blur' ) ;
andThen ( ( ) => {
// regression test: we still have a value after the input is
// focused and then blurred without any changes
expect ( find ( '#user-twitter' ) . val ( ) , 'twitter value after blur with no change' )
. to . equal ( 'https://twitter.com/test' ) ;
} ) ;
2016-03-03 11:52:27 +03:00
fillIn ( '#user-twitter' , '' ) ;
fillIn ( '#user-twitter' , ')(*&%^%)' ) ;
triggerEvent ( '#user-twitter' , 'blur' ) ;
andThen ( ( ) => {
2016-08-24 16:26:29 +03:00
expect ( find ( '#user-twitter' ) . closest ( '.form-group' ) . hasClass ( 'error' ) , 'twitter input should be in error state' ) . to . be . true ;
2016-03-03 11:52:27 +03:00
} ) ;
fillIn ( '#user-twitter' , '' ) ;
fillIn ( '#user-twitter' , 'name' ) ;
triggerEvent ( '#user-twitter' , 'blur' ) ;
andThen ( ( ) => {
expect ( find ( '#user-twitter' ) . val ( ) ) . to . be . equal ( 'https://twitter.com/name' ) ;
2016-08-24 16:26:29 +03:00
expect ( find ( '#user-twitter' ) . closest ( '.form-group' ) . hasClass ( 'error' ) , 'twitter input should be in error state' ) . to . be . false ;
2016-03-03 11:52:27 +03:00
} ) ;
fillIn ( '#user-twitter' , '' ) ;
fillIn ( '#user-twitter' , 'http://github.com/user' ) ;
triggerEvent ( '#user-twitter' , 'blur' ) ;
andThen ( ( ) => {
2016-05-16 21:16:40 +03:00
expect ( find ( '#user-twitter' ) . val ( ) ) . to . be . equal ( 'https://twitter.com/user' ) ;
2016-08-24 16:26:29 +03:00
expect ( find ( '#user-twitter' ) . closest ( '.form-group' ) . hasClass ( 'error' ) , 'twitter input should be in error state' ) . to . be . false ;
2016-03-03 11:52:27 +03:00
} ) ;
fillIn ( '#user-twitter' , '' ) ;
fillIn ( '#user-twitter' , 'twitter.com/user' ) ;
triggerEvent ( '#user-twitter' , 'blur' ) ;
andThen ( ( ) => {
expect ( find ( '#user-twitter' ) . val ( ) ) . to . be . equal ( 'https://twitter.com/user' ) ;
2016-08-24 16:26:29 +03:00
expect ( find ( '#user-twitter' ) . closest ( '.form-group' ) . hasClass ( 'error' ) , 'twitter input should be in error state' ) . to . be . false ;
2016-03-03 11:52:27 +03:00
} ) ;
2015-12-07 00:24:06 +03:00
fillIn ( '#user-website' , '' ) ;
fillIn ( '#user-bio' , new Array ( 210 ) . join ( 'a' ) ) ;
triggerEvent ( '#user-bio' , 'blur' ) ;
andThen ( ( ) => {
2016-08-24 16:26:29 +03:00
expect ( find ( '#user-bio' ) . closest ( '.form-group' ) . hasClass ( 'error' ) , 'bio input should be in error state' ) . to . be . true ;
2015-12-07 00:24:06 +03:00
} ) ;
2016-06-14 14:46:24 +03:00
// password reset ------
// button triggers validation
click ( '.button-change-password' ) ;
andThen ( ( ) => {
expect (
find ( '#user-password-new' ) . closest ( '.form-group' ) . hasClass ( 'error' ) ,
'new password has error class when blank'
) . to . be . true ;
expect (
find ( '#user-password-new' ) . siblings ( '.response' ) . text ( ) ,
'new password error when blank'
) . to . match ( /can't be blank/ ) ;
} ) ;
// typing in inputs clears validation
fillIn ( '#user-password-new' , 'password' ) ;
triggerEvent ( '#user-password-new' , 'input' ) ;
andThen ( ( ) => {
expect (
find ( '#user-password-new' ) . closest ( '.form-group' ) . hasClass ( 'error' ) ,
'password validation is visible after typing'
) . to . be . false ;
} ) ;
// enter key triggers action
keyEvent ( '#user-password-new' , 'keyup' , 13 ) ;
andThen ( ( ) => {
expect (
find ( '#user-new-password-verification' ) . closest ( '.form-group' ) . hasClass ( 'error' ) ,
'confirm password has error class when it doesn\'t match'
) . to . be . true ;
expect (
find ( '#user-new-password-verification' ) . siblings ( '.response' ) . text ( ) ,
'confirm password error when it doesn\'t match'
) . to . match ( /do not match/ ) ;
} ) ;
// submits with correct details
fillIn ( '#user-new-password-verification' , 'password' ) ;
click ( '.button-change-password' ) ;
andThen ( ( ) => {
// hits the endpoint
let [ lastRequest ] = server . pretender . handledRequests . slice ( - 1 ) ;
2016-09-26 19:59:04 +03:00
let params = JSON . parse ( lastRequest . requestBody ) ;
2016-06-14 14:46:24 +03:00
expect ( lastRequest . url , 'password request URL' )
. to . match ( /\/users\/password/ ) ;
2016-11-14 16:16:51 +03:00
// eslint-disable-next-line camelcase
2016-06-14 14:46:24 +03:00
expect ( params . password [ 0 ] . user _id ) . to . equal ( user . id . toString ( ) ) ;
expect ( params . password [ 0 ] . newPassword ) . to . equal ( 'password' ) ;
expect ( params . password [ 0 ] . ne2Password ) . to . equal ( 'password' ) ;
// clears the fields
expect (
find ( '#user-password-new' ) . val ( ) ,
'password field after submit'
) . to . be . blank ;
expect (
find ( '#user-new-password-verification' ) . val ( ) ,
'password verification field after submit'
) . to . be . blank ;
// displays a notification
expect (
find ( '.gh-notifications .gh-notification' ) . length ,
'password saved notification is displayed'
) . to . equal ( 1 ) ;
} ) ;
} ) ;
} ) ;
2016-09-30 14:43:40 +03:00
describe ( 'using Ghost OAuth' , function ( ) {
beforeEach ( function ( ) {
2016-10-28 16:07:50 +03:00
enableGhostOAuth ( server ) ;
2016-09-30 14:43:40 +03:00
} ) ;
it ( 'doesn\'t show the password reset form' , function ( ) {
visit ( ` /team/ ${ admin . slug } ` ) ;
andThen ( ( ) => {
// ensure that the normal form is displayed so we don't get
// false positives
expect (
find ( 'input#user-slug' ) . length ,
'profile form is displayed'
) . to . equal ( 1 ) ;
// check that the password form is hidden
expect (
find ( '#password-reset' ) . length ,
'presence of password reset form'
) . to . equal ( 0 ) ;
expect (
find ( '#user-password-new' ) . length ,
'presence of new password field'
) . to . equal ( 0 ) ;
} ) ;
} ) ;
} ) ;
2016-06-14 14:46:24 +03:00
describe ( 'own user' , function ( ) {
it ( 'requires current password when changing password' , function ( ) {
visit ( ` /team/ ${ admin . slug } ` ) ;
// test the "old password" field is validated
click ( '.button-change-password' ) ;
andThen ( ( ) => {
// old password has error
expect (
find ( '#user-password-old' ) . closest ( '.form-group' ) . hasClass ( 'error' ) ,
'old password has error class when blank'
) . to . be . true ;
expect (
find ( '#user-password-old' ) . siblings ( '.response' ) . text ( ) ,
'old password error when blank'
) . to . match ( /is required/ ) ;
// new password has error
expect (
find ( '#user-password-new' ) . closest ( '.form-group' ) . hasClass ( 'error' ) ,
'new password has error class when blank'
) . to . be . true ;
expect (
find ( '#user-password-new' ) . siblings ( '.response' ) . text ( ) ,
'new password error when blank'
) . to . match ( /can't be blank/ ) ;
} ) ;
// validation is cleared when typing
fillIn ( '#user-password-old' , 'password' ) ;
triggerEvent ( '#user-password-old' , 'input' ) ;
andThen ( ( ) => {
expect (
find ( '#user-password-old' ) . closest ( '.form-group' ) . hasClass ( 'error' ) ,
'old password validation is in error state after typing'
) . to . be . false ;
} ) ;
2015-12-07 00:24:06 +03:00
} ) ;
} ) ;
2016-08-24 16:26:29 +03:00
it ( 'redirects to 404 when user does not exist' , function ( ) {
2016-02-05 15:16:29 +03:00
server . get ( '/users/slug/unknown/' , function ( ) {
2017-01-02 21:50:36 +03:00
return new Response ( 404 , { 'Content-Type' : 'application/json' } , { errors : [ { message : 'User not found.' , errorType : 'NotFoundError' } ] } ) ;
2015-12-07 00:24:06 +03:00
} ) ;
2016-02-05 15:16:29 +03:00
errorOverride ( ) ;
2015-12-07 00:24:06 +03:00
2016-02-05 15:16:29 +03:00
visit ( '/team/unknown' ) ;
2015-12-07 00:24:06 +03:00
2016-02-05 15:16:29 +03:00
andThen ( ( ) => {
errorReset ( ) ;
expect ( currentPath ( ) ) . to . equal ( 'error404' ) ;
expect ( currentURL ( ) ) . to . equal ( '/team/unknown' ) ;
2015-12-07 00:24:06 +03:00
} ) ;
} ) ;
} ) ;
2016-09-26 19:03:53 +03:00
describe ( 'when logged in as author' , function ( ) {
2016-11-14 16:16:51 +03:00
let adminRole , authorRole ;
2016-09-26 19:03:53 +03:00
beforeEach ( function ( ) {
adminRole = server . create ( 'role' , { name : 'Administrator' } ) ;
authorRole = server . create ( 'role' , { name : 'Author' } ) ;
2016-11-14 16:16:51 +03:00
server . create ( 'user' , { roles : [ authorRole ] } ) ;
2016-09-26 19:03:53 +03:00
server . get ( '/invites/' , function ( ) {
2017-01-02 21:50:36 +03:00
return new Response ( 403 , { } , {
2016-09-26 19:03:53 +03:00
errors : [ {
errorType : 'NoPermissionError' ,
message : 'You do not have permission to perform this action'
} ]
} ) ;
} ) ;
return authenticateSession ( application ) ;
} ) ;
it ( 'can access the team page' , function ( ) {
2016-11-14 16:16:51 +03:00
server . create ( 'user' , { roles : [ adminRole ] } ) ;
server . create ( 'invite' , { roles : [ authorRole ] } ) ;
2016-09-26 19:03:53 +03:00
errorOverride ( ) ;
visit ( '/team' ) ;
andThen ( ( ) => {
errorReset ( ) ;
expect ( currentPath ( ) ) . to . equal ( 'team.index' ) ;
expect ( find ( '.gh-alert' ) . length ) . to . equal ( 0 ) ;
} ) ;
} ) ;
} ) ;
2015-12-07 00:24:06 +03:00
} ) ;