diff --git a/test/acceptance/features/Api/apiAddUsers.feature b/test/acceptance/features/Api/apiAddUsers.feature index 32d94a7b3cf..37d15e019db 100644 --- a/test/acceptance/features/Api/apiAddUsers.feature +++ b/test/acceptance/features/Api/apiAddUsers.feature @@ -60,8 +60,8 @@ Feature: Add user Then the response status code should be "200" And user with login "" should exist Examples: - | last name | login | - | swi@ | s$5^2 | - | g!!@%ui | नेपाली | - | swikriti@h | सिमप्ले $%#?&@name.txt | - | !@#$%^&*()-_+ | España§àôœ€ | \ No newline at end of file + | last name | login | + | swi@ | s$5^2 | + | g!!@%ui | नेपाली | + | swikriti@h | सिमप्ले $%#?&@name.txt | + | !@#$%^&*()-_+ | España§àôœ€ | \ No newline at end of file diff --git a/test/acceptance/features/Api/apiListUsers.feature b/test/acceptance/features/Api/apiListUsers.feature new file mode 100644 index 00000000000..c5b64ece7be --- /dev/null +++ b/test/acceptance/features/Api/apiListUsers.feature @@ -0,0 +1,23 @@ +Feature: list users + As an admin user + I want to view the list of users + So that I can manage users + + Scenario: Admin user should be able to see list of created users + Given the admin has created the following users + | login | last name | password | + | Harry | Potter | hello123 | + When the admin gets the list of all users using the API + Then the response status code should be "200" + And the user list returned by API should be following + | login | last name | + | dolibarr | SuperAdmin | + | Harry | Potter | + + Scenario: Non-admin user should not be able to see list of created users + Given the admin has created the following users + | login | last name | password | api_key | + | Harry | Potter | hello123 | harrypotter | + When user "Harry" with password "hello123" tries to list all users using the API + Then the response status code should be "401" + And the error message should be "Unauthorized: You are not allowed to read list of users" diff --git a/test/acceptance/index.js b/test/acceptance/index.js index a9fcda8105a..08eaa728110 100644 --- a/test/acceptance/index.js +++ b/test/acceptance/index.js @@ -1,14 +1,14 @@ -const { setDefaultTimeout, After, Before } = require('cucumber') -const { createSession, closeSession, startWebDriver, stopWebDriver } = require('nightwatch-api') +const {setDefaultTimeout, After, Before} = require('cucumber') +const {createSession, closeSession, startWebDriver, stopWebDriver} = require('nightwatch-api') setDefaultTimeout(60000) Before(async () => { - await startWebDriver(); - await createSession(); + await startWebDriver(); + await createSession(); }) After(async () => { - await closeSession(); - await stopWebDriver(); + await closeSession(); + await stopWebDriver(); }) diff --git a/test/acceptance/pageObjects/addUsersPage.js b/test/acceptance/pageObjects/addUsersPage.js index 7f31523b842..a365a6d0121 100644 --- a/test/acceptance/pageObjects/addUsersPage.js +++ b/test/acceptance/pageObjects/addUsersPage.js @@ -1,128 +1,128 @@ const util = require('util'); module.exports = { - url: function () { - return this.api.launchUrl + 'user/card.php?leftmenu=users&action=create'; - }, + url: function () { + return this.api.launchUrl + 'user/card.php?leftmenu=users&action=create'; + }, - commands: [ - { - adminCreatesUser: async function (dataTable) { - const userDetails = dataTable.rowsHash(); - let administrator = userDetails['administrator']; - let gender = userDetails['gender']; - await this.waitForElementVisible('@newUserAddOption') - .useXpath() - .waitForElementVisible('@lastnameField') - .clearValue('@lastnameField') - .setValue('@lastnameField', userDetails['last name']) - .waitForElementVisible('@loginField') - .clearValue('@loginField') - .setValue('@loginField', userDetails['login']) - .waitForElementVisible('@newUserPasswordField') - .clearValue('@newUserPasswordField') - .setValue('@newUserPasswordField', userDetails['password']); + commands: [ + { + adminCreatesUser: async function (dataTable) { + const userDetails = dataTable.rowsHash(); + let administrator = userDetails['administrator']; + let gender = userDetails['gender']; + await this.waitForElementVisible('@newUserAddOption') + .useXpath() + .waitForElementVisible('@lastnameField') + .clearValue('@lastnameField') + .setValue('@lastnameField', userDetails['last name']) + .waitForElementVisible('@loginField') + .clearValue('@loginField') + .setValue('@loginField', userDetails['login']) + .waitForElementVisible('@newUserPasswordField') + .clearValue('@newUserPasswordField') + .setValue('@newUserPasswordField', userDetails['password']); - if (userDetails['administrator']) { - const admin = util.format(this.elements.administratorSelectOption.selector, administrator); - await this.waitForElementVisible('@administratorField') - .click('@administratorField') - .waitForElementVisible(admin) - .click(admin); - } + if (userDetails['administrator']) { + const admin = util.format(this.elements.administratorSelectOption.selector, administrator); + await this.waitForElementVisible('@administratorField') + .click('@administratorField') + .waitForElementVisible(admin) + .click(admin); + } - if (userDetails['gender']) { - const genderValue = util.format(this.elements.genderSelectOption.selector, gender) - await this.waitForElementVisible('@genderField') - .click('@genderField') - .waitForElementVisible(genderValue) - .click(genderValue); - } - return this.waitForElementVisible('@submitButton') - .click('@submitButton') - .useCss(); - }, + if (userDetails['gender']) { + const genderValue = util.format(this.elements.genderSelectOption.selector, gender) + await this.waitForElementVisible('@genderField') + .click('@genderField') + .waitForElementVisible(genderValue) + .click(genderValue); + } + return this.waitForElementVisible('@submitButton') + .click('@submitButton') + .useCss(); + }, - noPermissionMessage: async function (message) { - await this.useXpath() - .waitForElementVisible('@noPermissionDefinedMessage') - .expect.element('@noPermissionDefinedMessage') - .text.to.equal(message); - return this.useCss(); - }, + noPermissionMessage: async function (message) { + await this.useXpath() + .waitForElementVisible('@noPermissionDefinedMessage') + .expect.element('@noPermissionDefinedMessage') + .text.to.equal(message); + return this.useCss(); + }, - newUserShouldBeCreated: async function (lastname) { - await this.useXpath() - .waitForElementVisible('@newUserCreated') - .expect.element('@newUserCreated') - .text.to.equal(lastname); - return this.useCss(); - }, + newUserShouldBeCreated: async function (lastname) { + await this.useXpath() + .waitForElementVisible('@newUserCreated') + .expect.element('@newUserCreated') + .text.to.equal(lastname); + return this.useCss(); + }, - noPermissionDefinedMessageNotShown: function (message) { - return this.useXpath() - .waitForElementNotPresent('@noPermissionDefinedMessage') - .useCss(); - }, + noPermissionDefinedMessageNotShown: function (message) { + return this.useXpath() + .waitForElementNotPresent('@noPermissionDefinedMessage') + .useCss(); + }, - userNotCreated: function (lastname) { - return this.waitForElementVisible('@newUserAddOption'); - } - } - ], + userNotCreated: function (lastname) { + return this.waitForElementVisible('@newUserAddOption'); + } + } + ], - elements: { - newUserAddOption: { - selector: '.fiche' - }, + elements: { + newUserAddOption: { + selector: '.fiche' + }, - lastnameField: { - selector: '//table[@class="border centpercent"]/tbody/tr/td//input[@id="lastname"]', - locateStrategy: 'xpath' - }, + lastnameField: { + selector: '//table[@class="border centpercent"]/tbody/tr/td//input[@id="lastname"]', + locateStrategy: 'xpath' + }, - loginField: { - selector: '//table[@class="border centpercent"]/tbody/tr/td//input[@name="login"]', - locateStrategy: 'xpath' - }, + loginField: { + selector: '//table[@class="border centpercent"]/tbody/tr/td//input[@name="login"]', + locateStrategy: 'xpath' + }, - newUserPasswordField: { - selector: '//table[@class="border centpercent"]/tbody/tr/td//input[@name="password"]', - locateStrategy: 'xpath' - }, + newUserPasswordField: { + selector: '//table[@class="border centpercent"]/tbody/tr/td//input[@name="password"]', + locateStrategy: 'xpath' + }, - submitButton: { - selector: '//div[@class="center"]/input[@class="button"]', - locateStrategy: 'xpath' - }, + submitButton: { + selector: '//div[@class="center"]/input[@class="button"]', + locateStrategy: 'xpath' + }, - administratorField: { - selector: '//table[@class="border centpercent"]/tbody/tr/td//select[@id="admin"]', - locateStrategy: 'xpath' - }, + administratorField: { + selector: '//table[@class="border centpercent"]/tbody/tr/td//select[@id="admin"]', + locateStrategy: 'xpath' + }, - administratorSelectOption: { - selector: '//select[@id="admin"]/option[.="%s"]', - locateStrategy: 'xpath' + administratorSelectOption: { + selector: '//select[@id="admin"]/option[.="%s"]', + locateStrategy: 'xpath' - }, + }, - genderField: { - selector: '//table[@class="border centpercent"]/tbody/tr/td//select[@id="gender"]', - locateStrategy: 'xpath' - }, - genderSelectOption: { - selector: '//select[@id="gender"]/option[.="%s"]', - locateStrategy: 'xpath' - }, + genderField: { + selector: '//table[@class="border centpercent"]/tbody/tr/td//select[@id="gender"]', + locateStrategy: 'xpath' + }, + genderSelectOption: { + selector: '//select[@id="gender"]/option[.="%s"]', + locateStrategy: 'xpath' + }, - noPermissionDefinedMessage: { - selector: '//div[@class="jnotify-message"]', - locateStrategy: 'xpath' - }, + noPermissionDefinedMessage: { + selector: '//div[@class="jnotify-message"]', + locateStrategy: 'xpath' + }, - newUserCreated: { - selector: '//div[contains(@class,"valignmiddle")]//div[contains(@class,"inline-block floatleft valignmiddle")]', - locateStrategy: 'xpath' - } - } + newUserCreated: { + selector: '//div[contains(@class,"valignmiddle")]//div[contains(@class,"inline-block floatleft valignmiddle")]', + locateStrategy: 'xpath' + } + } }; diff --git a/test/acceptance/pageObjects/homePage.js b/test/acceptance/pageObjects/homePage.js index 7c225e90f5a..c17be05ecae 100644 --- a/test/acceptance/pageObjects/homePage.js +++ b/test/acceptance/pageObjects/homePage.js @@ -1,44 +1,44 @@ module.exports = { - url: function () { - return this.api.launchUrl + 'admin/index.php?mainmenu=home&leftmenu=setup&mesg=setupnotcomplete'; - }, + url: function () { + return this.api.launchUrl + 'admin/index.php?mainmenu=home&leftmenu=setup&mesg=setupnotcomplete'; + }, - commands: [ - { - browsedToNewUserPage: function () { - return this.useXpath() - .waitForElementVisible('@usersAndGroups') - .click('@usersAndGroups') - .waitForElementVisible('@newUser') - .click('@newUser') - .useCss(); - }, + commands: [ + { + browsedToNewUserPage: function () { + return this.useXpath() + .waitForElementVisible('@usersAndGroups') + .click('@usersAndGroups') + .waitForElementVisible('@newUser') + .click('@newUser') + .useCss(); + }, - browsedToListOfUsers: function () { - return this.useXpath() - .waitForElementVisible('@usersAndGroups') - .click('@usersAndGroups') - .waitForElementVisible('@listOfUsers') - .click('@listOfUsers') - .useCss(); - } - } - ], + browsedToListOfUsers: function () { + return this.useXpath() + .waitForElementVisible('@usersAndGroups') + .click('@usersAndGroups') + .waitForElementVisible('@listOfUsers') + .click('@listOfUsers') + .useCss(); + } + } + ], - elements: { - usersAndGroups: { - selector: '//div[@class="menu_titre"]/a[@title="Users & Groups"]', - locateStrategy: 'xpath' - }, + elements: { + usersAndGroups: { + selector: '//div[@class="menu_titre"]/a[@title="Users & Groups"]', + locateStrategy: 'xpath' + }, - newUser: { - selector: '//div[@class="menu_contenu menu_contenu_user_card"]/a[@title="New user"]', - locateStrategy: 'xpath' - }, + newUser: { + selector: '//div[@class="menu_contenu menu_contenu_user_card"]/a[@title="New user"]', + locateStrategy: 'xpath' + }, - listOfUsers: { - selector: '//a[@class="vsmenu"][@title="List of users"]', - locateStrategy: 'xpath' - } - } + listOfUsers: { + selector: '//a[@class="vsmenu"][@title="List of users"]', + locateStrategy: 'xpath' + } + } }; diff --git a/test/acceptance/pageObjects/listUsersPage.js b/test/acceptance/pageObjects/listUsersPage.js index 3567bb576ab..74b97459bd5 100644 --- a/test/acceptance/pageObjects/listUsersPage.js +++ b/test/acceptance/pageObjects/listUsersPage.js @@ -1,47 +1,47 @@ const util = require('util'); module.exports = { - url: function () { - return this.api.launchUrl + 'user/list.php?leftmenu=users'; - }, + url: function () { + return this.api.launchUrl + 'user/list.php?leftmenu=users'; + }, - commands: [ - { - listOfUsersDisplayed: async function (dataTable) { - const usersList = dataTable.hashes(); - this.useXpath(); - for (const row of usersList) { - let login = row['login']; - let lastName = row['last name']; - const userDetail = util.format(this.elements.userList.selector, login, lastName); - await this.waitForElementVisible('@userRow') - .waitForElementVisible(userDetail); - } - return this.useCss(); - }, + commands: [ + { + listOfUsersDisplayed: async function (dataTable) { + const usersList = dataTable.hashes(); + this.useXpath(); + for (const row of usersList) { + let login = row['login']; + let lastName = row['last name']; + const userDetail = util.format(this.elements.userList.selector, login, lastName); + await this.waitForElementVisible('@userRow') + .waitForElementVisible(userDetail); + } + return this.useCss(); + }, - numberOfUsersDisplayed: async function (number) { - const userCount = util.format(this.elements.numberOfUsers.selector, number); - await this.useXpath() - .waitForElementVisible(userCount); - return this.useCss(); - } - } - ], + numberOfUsersDisplayed: async function (number) { + const userCount = util.format(this.elements.numberOfUsers.selector, number); + await this.useXpath() + .waitForElementVisible(userCount); + return this.useCss(); + } + } + ], - elements: { - userRow: { - selector: '//table[contains(@class,"tagtable")]/tbody/tr[position()>2]', - locateStrategy: 'xpath' - }, + elements: { + userRow: { + selector: '//table[contains(@class,"tagtable")]/tbody/tr[position()>2]', + locateStrategy: 'xpath' + }, - numberOfUsers: { - selector: '//div[contains(@class, "titre inline-block") and contains(., "List of users")]/span[.="(%d)"]', - locateStrategy: 'xpath' - }, + numberOfUsers: { + selector: '//div[contains(@class, "titre inline-block") and contains(., "List of users")]/span[.="(%d)"]', + locateStrategy: 'xpath' + }, - userList: { - selector: '//table[contains(@class,"tagtable")]/tbody/tr[position()>2]/td/a//span[normalize-space(@class="nopadding usertext")][.="%s"]/../../following-sibling::td[.="%s"]', - locateStrategy: 'xpath' - } - } + userList: { + selector: '//table[contains(@class,"tagtable")]/tbody/tr[position()>2]/td/a//span[normalize-space(@class="nopadding usertext")][.="%s"]/../../following-sibling::td[.="%s"]', + locateStrategy: 'xpath' + } + } }; diff --git a/test/acceptance/pageObjects/loginPage.js b/test/acceptance/pageObjects/loginPage.js index b95fd1645ab..8e514625f4a 100644 --- a/test/acceptance/pageObjects/loginPage.js +++ b/test/acceptance/pageObjects/loginPage.js @@ -1,84 +1,84 @@ module.exports = { - url: function () { - return this.api.launchUrl; - }, + url: function () { + return this.api.launchUrl; + }, - commands: [ - { - waitForLoginPage: function () { - return this.waitForElementVisible('@loginTable'); - }, + commands: [ + { + waitForLoginPage: function () { + return this.waitForElementVisible('@loginTable'); + }, - userLogsInWithUsernameAndPassword: function (username, password) { - return this.waitForElementVisible('@userNameField') - .setValue('@userNameField', username) - .waitForElementVisible('@passwordField') - .setValue('@passwordField', password) - .useXpath() - .waitForElementVisible('@loginButton') - .click('@loginButton') - .useCss(); - }, + userLogsInWithUsernameAndPassword: function (username, password) { + return this.waitForElementVisible('@userNameField') + .setValue('@userNameField', username) + .waitForElementVisible('@passwordField') + .setValue('@passwordField', password) + .useXpath() + .waitForElementVisible('@loginButton') + .click('@loginButton') + .useCss(); + }, - successfulLogin: function () { - return this.waitForElementNotPresent('@loginTable') - .waitForElementVisible('@userProfileDropdown'); - }, + successfulLogin: function () { + return this.waitForElementNotPresent('@loginTable') + .waitForElementVisible('@userProfileDropdown'); + }, - userIsLoggedIn: async function (login) { - await this.waitForElementNotPresent('@loginTable') - .useXpath() - .waitForElementVisible('@userLogin') - .expect.element('@userLogin') - .text.to.equal(login); - return this.useCss(); - }, + userIsLoggedIn: async function (login) { + await this.waitForElementNotPresent('@loginTable') + .useXpath() + .waitForElementVisible('@userLogin') + .expect.element('@userLogin') + .text.to.equal(login); + return this.useCss(); + }, - unsuccessfulLogin: function () { - return this.waitForElementVisible('@loginTable') - .waitForElementNotPresent('@userProfileDropdown'); - }, + unsuccessfulLogin: function () { + return this.waitForElementVisible('@loginTable') + .waitForElementNotPresent('@userProfileDropdown'); + }, - loginErrorDisplayed: async function (errorMessage) { - await this.useXpath() - .waitForElementVisible('@loginError') - .expect.element('@loginError') - .text.to.equal(errorMessage); - return this.useCss(); - } - } - ], + loginErrorDisplayed: async function (errorMessage) { + await this.useXpath() + .waitForElementVisible('@loginError') + .expect.element('@loginError') + .text.to.equal(errorMessage); + return this.useCss(); + } + } + ], - elements: { - loginButton: { - selector: '//div[@id="login-submit-wrapper"]/input[@type="submit"]', - locateStrategy: 'xpath' - }, + elements: { + loginButton: { + selector: '//div[@id="login-submit-wrapper"]/input[@type="submit"]', + locateStrategy: 'xpath' + }, - userNameField: { - selector: '#username' - }, + userNameField: { + selector: '#username' + }, - passwordField: { - selector: '#password' - }, + passwordField: { + selector: '#password' + }, - loginTable: { - selector: '.login_table' - }, + loginTable: { + selector: '.login_table' + }, - userProfileDropdown: { - selector: '#topmenu-login-dropdown' - }, + userProfileDropdown: { + selector: '#topmenu-login-dropdown' + }, - userLogin: { - selector: '//div[@id="topmenu-login-dropdown"]/a//span[contains(@class,"atoploginusername")]', - locateStrategy: 'xpath' - }, + userLogin: { + selector: '//div[@id="topmenu-login-dropdown"]/a//span[contains(@class,"atoploginusername")]', + locateStrategy: 'xpath' + }, - loginError: { - selector: '//div[@class="center login_main_message"]/div[@class="error"]', - locateStrategy: 'xpath' - } - } + loginError: { + selector: '//div[@class="center login_main_message"]/div[@class="error"]', + locateStrategy: 'xpath' + } + } }; diff --git a/test/acceptance/pageObjects/logoutPage.js b/test/acceptance/pageObjects/logoutPage.js index a63b8415238..a5b8f481d03 100644 --- a/test/acceptance/pageObjects/logoutPage.js +++ b/test/acceptance/pageObjects/logoutPage.js @@ -1,34 +1,34 @@ module.exports = { - url: function () { - return this.api.launchUrl + 'admin/index.php?mainmenu=home&leftmenu=setup&mesg=setupnotcomplete'; - }, + url: function () { + return this.api.launchUrl + 'admin/index.php?mainmenu=home&leftmenu=setup&mesg=setupnotcomplete'; + }, - commands: - [ - { - userOpensProfile: async function () { - await this.useXpath() - .waitForElementVisible('@userProfileDropdown') - .click('@userProfileDropdown') - return this.useCss(); - }, + commands: + [ + { + userOpensProfile: async function () { + await this.useXpath() + .waitForElementVisible('@userProfileDropdown') + .click('@userProfileDropdown') + return this.useCss(); + }, - userLogsOut: function () { - return this.waitForElementVisible('@logoutButton') - .click('@logoutButton'); - } - } - ], + userLogsOut: function () { + return this.waitForElementVisible('@logoutButton') + .click('@logoutButton'); + } + } + ], - elements: { + elements: { - logoutButton: { - selector: '.pull-right' - }, + logoutButton: { + selector: '.pull-right' + }, - userProfileDropdown: { - selector: '//div[@id="topmenu-login-dropdown"]', - locateStrategy: 'xpath' - } - } + userProfileDropdown: { + selector: '//div[@id="topmenu-login-dropdown"]', + locateStrategy: 'xpath' + } + } }; diff --git a/test/acceptance/setup.js b/test/acceptance/setup.js index 123d6b3c5ec..51d719cb9a7 100644 --- a/test/acceptance/setup.js +++ b/test/acceptance/setup.js @@ -1,13 +1,18 @@ -const { Before, After } = require('cucumber'); -const { client } = require('nightwatch-api'); +const {Before, After} = require('cucumber'); +const {client} = require('nightwatch-api'); const fetch = require('node-fetch'); let initialUsers = {}; let dolApiKey = ''; -const getUsers = async function () { +const getUsers = async function (api_key = null) { const header = {}; + let dolApiKey; const url = client.globals.backend_url + 'api/index.php/users'; - const users = {}; + if (api_key === null) { + dolApiKey = client.globals.dolApiKey; + } else { + dolApiKey = api_key; + } header['Accept'] = 'application/json'; header['DOLAPIKEY'] = dolApiKey; await fetch(url, { @@ -15,63 +20,80 @@ const getUsers = async function () { headers: header }) .then(async (response) => { - const json_response = await response.json(); - for (const user of json_response) { - users[user.id] = user.id; - } + client.globals.response = response; }); +}; + +const getUsersId = async function () { + const users = {}; + await getUsers(); + const json_response = await client.globals.response.json(); + for (const user of json_response) { + users[user.id] = user.id; + } return users; }; -Before(async function getDolApiKey() { - const header = {} - const adminUsername = client.globals.adminUsername; - const adminPassword = client.globals.adminPassword; - const params = new URLSearchParams() - params.set('login', adminUsername) - params.set('password', adminPassword) - const apiKey = client.globals.backend_url + `api/index.php/login?${params.toString()}`; - header['Accept'] = 'application/json' - await fetch(apiKey, { - method: 'GET', - headers: header - }) - .then(async (response) => { - const jsonResponse = await response.json() - dolApiKey = jsonResponse['success']['token'] - client.globals.dolApiKey = dolApiKey - }) -}) +const getDolApiKey = async function (login = null, password = null) { + const header = {}; + if (login === null && password === null) { + login = client.globals.adminUsername; + password = client.globals.adminPassword; + } + const params = new URLSearchParams(); + params.set('login', login); + params.set('password', password); + const apiKey = client.globals.backend_url + `api/index.php/login?${params.toString()}`; + header['Accept'] = 'application/json'; + await fetch(apiKey, { + method: 'GET', + headers: header + }) + .then(async (response) => { + const jsonResponse = await response.json(); + dolApiKey = jsonResponse['success']['token']; + if (login === client.globals.adminUsername && password === client.globals.adminPassword) { + client.globals.dolApiKey = dolApiKey; + } + }); + return dolApiKey; +}; + +Before(async function getAdminDolApiKey() { + await getDolApiKey(); +}); Before(async () => { - initialUsers = await getUsers(); + initialUsers = await getUsersId(); }); After(async () => { - const finalUsers = await getUsers(); - const header = {}; - const url = client.globals.backend_url + 'api/index.php/users/'; - header['Accept'] = 'application/json'; - header['DOLAPIKEY'] = dolApiKey; - let found; - for (const finaluser in finalUsers) { - for (const initialuser in initialUsers) { - found = false; - if (initialuser === finaluser) { - found = true; - break; - } - } - if (!found) { - await fetch(url + finaluser, { - method: 'DELETE', - headers: header - }) - .then(res => { - if (res.status < 200 || res.status >= 400) { - throw new Error("Failed to delete user: " + res.statusText); - } - }); - } - } + const finalUsers = await getUsersId(); + const header = {}; + const url = client.globals.backend_url + 'api/index.php/users/'; + header['Accept'] = 'application/json'; + header['DOLAPIKEY'] = client.globals.dolApiKey; + let found; + for (const finaluser in finalUsers) { + for (const initialuser in initialUsers) { + found = false; + if (initialuser === finaluser) { + found = true; + break; + } + } + if (!found) { + await fetch(url + finaluser, { + method: 'DELETE', + headers: header + }) + .then(res => { + if (res.status < 200 || res.status >= 400) { + throw new Error("Failed to delete user: " + res.statusText); + } + }); + } + } }); + +module.exports = {getDolApiKey, getUsers}; diff --git a/test/acceptance/stepDefinitions/addUsersContext.js b/test/acceptance/stepDefinitions/addUsersContext.js index 076c5d24226..52dbee94470 100644 --- a/test/acceptance/stepDefinitions/addUsersContext.js +++ b/test/acceptance/stepDefinitions/addUsersContext.js @@ -2,7 +2,6 @@ const {Given, When, Then} = require('cucumber'); const {client} = require('nightwatch-api'); const fetch = require('node-fetch'); const assert = require('assert'); -let response; let Login = {}; Given('the administrator has browsed to the new users page', function () { @@ -57,7 +56,7 @@ Then('the response message should be {string}', function (expectedResponseMessag return getResponseMessage(expectedResponseMessage); }); -const createUserRequest = function (login, lastname, password) { +const createUserRequest = function (login, lastname, password, api_key = null) { const header = {}; const url = client.globals.backend_url + 'api/index.php/users'; header['Accept'] = 'application/json'; @@ -70,7 +69,8 @@ const createUserRequest = function (login, lastname, password) { { login: login, lastname: lastname, - pass: password + pass: password, + api_key: api_key } ) }); @@ -80,20 +80,31 @@ const adminCreatesUserWithAPI = function (dataTable) { const userDetails = dataTable.rowsHash(); return createUserRequest(userDetails['login'], userDetails['last name'], userDetails['password']) .then((res) => { - response = res; + client.globals.response = res; }); }; const adminHasCreatedUser = async function (dataTable) { const userDetails = dataTable.hashes(); for (const user of userDetails) { - await createUserRequest(user['login'], user['last name'], user['password']) - .then((response) => { - if (response.status < 200 || response.status >= 400) { - throw new Error('Failed to create user: ' + user['login'] + - ' ' + response.statusText); - } - }); + + if (user['api_key']) { + await createUserRequest(user['login'], user['last name'], user['password'], user['api_key']) + .then((response) => { + if (response.status < 200 || response.status >= 400) { + throw new Error('Failed to create user: ' + user['login'] + + ' ' + response.statusText); + } + }); + } else { + await createUserRequest(user['login'], user['last name'], user['password']) + .then((response) => { + if (response.status < 200 || response.status >= 400) { + throw new Error('Failed to create user: ' + user['login'] + + ' ' + response.statusText); + } + }); + } } }; @@ -137,13 +148,13 @@ const userShouldExist = async function (login) { }; const getStatusCode = async function (expectedStatusCode) { - const actualStatusCode = response.status.toString(); + const actualStatusCode = client.globals.response.status.toString(); return assert.strictEqual(actualStatusCode, expectedStatusCode, `The expected status code was ${expectedStatusCode} but got ${actualStatusCode}`); }; const getResponseMessage = async function (expectedResponseMessage) { - const json_response = await response.json(); + const json_response = await client.globals.response.json(); const actualResponseMessage = json_response['error']['0']; return assert.strictEqual(actualResponseMessage, expectedResponseMessage, `the expected response message was ${expectedResponseMessage} but got ${actualResponseMessage}`); diff --git a/test/acceptance/stepDefinitions/listUsersContext.js b/test/acceptance/stepDefinitions/listUsersContext.js index 78912abd3a0..8acbcd766bb 100644 --- a/test/acceptance/stepDefinitions/listUsersContext.js +++ b/test/acceptance/stepDefinitions/listUsersContext.js @@ -1,14 +1,62 @@ -const { When, Then } = require('cucumber'); -const { client } = require('nightwatch-api'); +const {When, Then} = require('cucumber'); +const {client} = require('nightwatch-api'); +const {getDolApiKey, getUsers} = require('../setup'); +const assert = require('assert'); When('the administrator browses to the list of users page using the webUI', function () { - return client.page.homePage().browsedToListOfUsers(); + return client.page.homePage().browsedToListOfUsers(); }); Then('following users should be displayed in the users list', function (dataTable) { - return client.page.listUsersPage().listOfUsersDisplayed(dataTable); + return client.page.listUsersPage().listOfUsersDisplayed(dataTable); }); Then('the number of created users should be {int}', function (number) { - return client.page.listUsersPage().numberOfUsersDisplayed(number); + return client.page.listUsersPage().numberOfUsersDisplayed(number); }); + +When('the admin gets the list of all users using the API', function () { + return getUsers(); +}); + +Then('the user list returned by API should be following', function (dataTable) { + return theUsersShouldBe(dataTable); +}); + +When('user {string} with password {string} tries to list all users using the API', async function (login, password) { + const userDolApikey = await getDolApiKey(login, password); + return getUsers(userDolApikey); +}); + +Then('the error message should be {string}', function (errorMessage) { + return getErrorMessage(errorMessage); +}); + +const theUsersShouldBe = async function (dataTable) { + const expectedUsers = dataTable.hashes(); + let users = {}; + const json_response = await client.globals.response.json(); + + for (const expectedUser of expectedUsers) { + let found; + for (const user of json_response) { + users["login"] = user.login; + users["last name"] = user.lastname; + found = false; + if (expectedUser["login"] === users.login && expectedUser["last name"] === users["last name"]) { + found = true; + break; + } else { + found = false; + } + } + assert.strictEqual(found, true); + } +}; + +const getErrorMessage = async function (expectedErrorMessage) { + const json_response = await client.globals.response.json(); + const actualErrorMessage = json_response['error']['message']; + return assert.strictEqual(actualErrorMessage, expectedErrorMessage, + `the expected response message was ${expectedErrorMessage} but got ${actualErrorMessage}`); +}; diff --git a/test/acceptance/stepDefinitions/loginContext.js b/test/acceptance/stepDefinitions/loginContext.js index ea9aa07949b..686b3715597 100644 --- a/test/acceptance/stepDefinitions/loginContext.js +++ b/test/acceptance/stepDefinitions/loginContext.js @@ -1,5 +1,5 @@ -const { Given, When, Then } = require('cucumber') -const { client } = require('nightwatch-api') +const {Given, When, Then} = require('cucumber') +const {client} = require('nightwatch-api') Given('the administrator has logged in using the webUI', async function () { await client.page.loginPage().navigate().waitForLoginPage(); @@ -8,21 +8,21 @@ Given('the administrator has logged in using the webUI', async function () { }); Given('the user has browsed to the login page', function () { - return client.page.loginPage().navigate(); + return client.page.loginPage().navigate(); }); When('user logs in with username {string} and password {string}', function (username, password) { - return client.page.loginPage().userLogsInWithUsernameAndPassword(username, password); + return client.page.loginPage().userLogsInWithUsernameAndPassword(username, password); }); Then('the user should be directed to the homepage', function () { - return client.page.loginPage().successfulLogin(); + return client.page.loginPage().successfulLogin(); }); Then('the user should not be able to login', function () { - return client.page.loginPage().unsuccessfulLogin(); + return client.page.loginPage().unsuccessfulLogin(); }); Then('error message {string} should be displayed in the webUI', function (errormessage) { - return client.page.loginPage().loginErrorDisplayed(errormessage); + return client.page.loginPage().loginErrorDisplayed(errormessage); }); diff --git a/test/acceptance/stepDefinitions/logoutContext.js b/test/acceptance/stepDefinitions/logoutContext.js index 018bf566cfb..ec264ae5e26 100644 --- a/test/acceptance/stepDefinitions/logoutContext.js +++ b/test/acceptance/stepDefinitions/logoutContext.js @@ -1,14 +1,14 @@ -const { When, Then } = require('cucumber'); -const { client } = require('nightwatch-api'); +const {When, Then} = require('cucumber'); +const {client} = require('nightwatch-api'); When('the user opens the user profile using the webUI', function () { - return client.page.logoutPage().userOpensProfile(); + return client.page.logoutPage().userOpensProfile(); }); When('the user logs out using the webUI', function () { - return client.page.logoutPage().userLogsOut(); + return client.page.logoutPage().userLogsOut(); }); Then('the user should be logged out successfully', function () { - return client.page.loginPage().waitForLoginPage(); + return client.page.loginPage().waitForLoginPage(); });