summaryrefslogtreecommitdiffstats
path: root/cypress
diff options
context:
space:
mode:
authorFerdinand Thiessen <opensource@fthiessen.de>2023-06-29 15:33:36 +0200
committerChristopher Ng <chrng8@gmail.com>2023-06-30 11:38:11 -0700
commit97683a5b6657521d651d9c7e463951c1cf6ff51d (patch)
treef1046063ae94f5dc4a706ef374a0b13f9c69d55c /cypress
parentd76f39889a9cdf04c69d765c4440b53a8a173100 (diff)
downloadnextcloud-server-97683a5b6657521d651d9c7e463951c1cf6ff51d.tar.gz
nextcloud-server-97683a5b6657521d651d9c7e463951c1cf6ff51d.zip
fix(settings): Migrate away from deprecated `NcPopoverMenu`
* Replace popover menu with `NcActions` * Deduplicate user actions code between `UserRow` and `UserRowSimple` * Fix user action to cover whole row heigh to prevent dropdown from shining through the actions * Fix user action popover to be overlayed by current edited row actions Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
Diffstat (limited to 'cypress')
-rw-r--r--cypress/e2e/settings/users.cy.ts53
-rw-r--r--cypress/e2e/settings/users_disable.cy.ts89
-rw-r--r--cypress/e2e/settings/users_modify.cy.ts82
-rw-r--r--cypress/support/commands.ts32
4 files changed, 218 insertions, 38 deletions
diff --git a/cypress/e2e/settings/users.cy.ts b/cypress/e2e/settings/users.cy.ts
index ba1f4449ea0..bc5211e291f 100644
--- a/cypress/e2e/settings/users.cy.ts
+++ b/cypress/e2e/settings/users.cy.ts
@@ -25,9 +25,8 @@ import { User } from '@nextcloud/cypress'
const admin = new User('admin', 'admin')
const jdoe = new User('jdoe', 'jdoe')
-describe('Setting: Users list', function() {
+describe('Settings: Create and delete users', function() {
before(function() {
- cy.createUser(jdoe)
cy.login(admin)
})
@@ -35,48 +34,26 @@ describe('Setting: Users list', function() {
cy.deleteUser(jdoe)
})
- it('Can change the password', function() {
+ it('Can delete a user', function() {
+ // ensure user exists
+ cy.createUser(jdoe).login(admin)
+
// open the User settings
cy.visit('/settings/users')
- cy.get(`.user-list-grid .row[data-id="${jdoe.userId}"]`).within(($row) => {
+ // see that the user is in the list
+ cy.get(`.user-list-grid .row[data-id="${jdoe.userId}"]`).within(() => {
// see that the list of users contains the user jdoe
cy.contains(jdoe.userId).should('exist')
- // toggle the edit mode for the user jdoe
- cy.get('.userActions button .icon-rename').click()
+ // open the actions menu for the user
+ cy.get('.userActions button.action-item__menutoggle').click()
})
- cy.get(`.user-list-grid .row[data-id="${jdoe.userId}"]`).within(($row) => {
- // see that the edit mode is on
- cy.wrap($row).should('have.class', 'row--editable')
- // see that the password of user0 is ""
- cy.get('input[type="password"]').should('exist').and('have.value', '')
- // set the password for user0 to 123456
- cy.get('input[type="password"]').type('123456')
- // When I set the password for user0 to 123456
- cy.get('input[type="password"]').should('have.value', '123456')
- cy.get('.password button').click()
-
- // Ignore failure if modal is not shown
- cy.once('fail', (error) => {
- expect(error.name).to.equal('AssertionError')
- expect(error).to.have.property('node', '.modal-container')
- })
- // Make sure no confirmation modal is shown
- cy.root().closest('body').find('.modal-container').then(($modal) => {
- if ($modal.length > 0) {
- cy.wrap($modal).find('input[type="password"]').type(admin.password)
- cy.wrap($modal).find('button').contains('Confirm').click()
- }
- })
-
- // see that the password cell for user user0 is done loading
- cy.get('.user-row-text-field.icon-loading-small').should('exist')
- cy.waitUntil(() => cy.get('.user-row-text-field.icon-loading-small').should('not.exist'), { timeout: 10000 })
- // password input is emptied on change
- cy.get('input[type="password"]').should('have.value', '')
- })
- // Success message is shown
- cy.get('.toastify.toast-success').contains(/Password.+successfully.+changed/i).should('exist')
+ // The "Delete user" action in the actions menu is shown and clicked
+ cy.get('.action-item__popper .action').contains('Delete user').should('exist').click()
+ // And confirmation dialog accepted
+ cy.get('.oc-dialog button').contains(`Delete ${jdoe.userId}`).click()
+ // deleted clicked the user is not shown anymore
+ cy.get(`.user-list-grid .row[data-id="${jdoe.userId}"]`).should('not.exist')
})
})
diff --git a/cypress/e2e/settings/users_disable.cy.ts b/cypress/e2e/settings/users_disable.cy.ts
new file mode 100644
index 00000000000..7495950b3c1
--- /dev/null
+++ b/cypress/e2e/settings/users_disable.cy.ts
@@ -0,0 +1,89 @@
+/**
+ * @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
+ *
+ * @author Ferdinand Thiessen <opensource@fthiessen.de>
+ *
+ * @license AGPL-3.0-or-later
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+import { User } from '@nextcloud/cypress'
+
+const admin = new User('admin', 'admin')
+const jdoe = new User('jdoe', 'jdoe')
+
+describe('Settings: Disable and enable users', function() {
+ before(function() {
+ cy.createUser(jdoe)
+ cy.login(admin)
+ })
+
+ after(() => {
+ cy.deleteUser(jdoe)
+ })
+
+ it('Can disable the user', function() {
+ // ensure user is enabled
+ cy.enableUser(jdoe)
+ // open the User settings
+ cy.visit('/settings/users')
+ // see that the user is in the list of active users
+ cy.get(`.user-list-grid .row[data-id="${jdoe.userId}"]`).within(() => {
+ // see that the list of users contains the user jdoe
+ cy.contains(jdoe.userId).should('exist')
+ // open the actions menu for the user
+ cy.get('.userActions button.action-item__menutoggle').click()
+ })
+
+ // The "Disable user" action in the actions menu is shown and clicked
+ cy.get('.action-item__popper .action').contains('Disable user').should('exist').click()
+ // When clicked the section is not shown anymore
+ cy.get(`.user-list-grid .row[data-id="${jdoe.userId}"]`).should('not.exist')
+ // But the disabled user section now exists
+ cy.get('#disabled').should('exist')
+ // Open disabled users section
+ cy.get('#disabled a').click()
+ cy.url().should('match', /\/disabled/)
+ // The list of disabled users should now contain the user
+ cy.get(`.user-list-grid .row[data-id="${jdoe.userId}"]`).should('exist')
+ })
+
+ it('Can enable the user', function() {
+ // ensure user is disabled
+ cy.enableUser(jdoe, false)
+ // open the User settings
+ cy.visit('/settings/users')
+
+ // Open disabled users section
+ cy.get('#disabled a').click()
+ cy.url().should('match', /\/disabled/)
+
+ cy.get(`.user-list-grid .row[data-id="${jdoe.userId}"]`).within(() => {
+ // see that the list of disabled users contains the user jdoe
+ cy.contains(jdoe.userId).should('exist')
+ // open the actions menu for the user
+ cy.get('.userActions button.action-item__menutoggle').click()
+ })
+
+ // The "Enable user" action in the actions menu is shown and clicked
+ cy.get('.action-item__popper .action').contains('Enable user').should('exist').click()
+ // When clicked the section is not shown anymore
+ cy.get('#disabled').should('not.exist')
+ // Make sure it is still gone after the reload reload
+ cy.reload().login(admin)
+ cy.get('#disabled').should('not.exist')
+ })
+})
diff --git a/cypress/e2e/settings/users_modify.cy.ts b/cypress/e2e/settings/users_modify.cy.ts
new file mode 100644
index 00000000000..d78104c7591
--- /dev/null
+++ b/cypress/e2e/settings/users_modify.cy.ts
@@ -0,0 +1,82 @@
+/**
+ * @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
+ *
+ * @author Ferdinand Thiessen <opensource@fthiessen.de>
+ *
+ * @license AGPL-3.0-or-later
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+import { User } from '@nextcloud/cypress'
+
+const admin = new User('admin', 'admin')
+const jdoe = new User('jdoe', 'jdoe')
+
+describe('Settings: Change user properties', function() {
+ before(function() {
+ cy.createUser(jdoe)
+ cy.login(admin)
+ })
+
+ after(() => {
+ cy.deleteUser(jdoe)
+ })
+
+ it('Can change the password', function() {
+ // open the User settings
+ cy.visit('/settings/users')
+
+ cy.get(`.user-list-grid .row[data-id="${jdoe.userId}"]`).within(($row) => {
+ // see that the list of users contains the user jdoe
+ cy.contains(jdoe.userId).should('exist')
+ // toggle the edit mode for the user jdoe
+ cy.get('.userActions .action-items > button:first-of-type').click()
+ })
+
+ cy.get(`.user-list-grid .row[data-id="${jdoe.userId}"]`).within(($row) => {
+ // see that the edit mode is on
+ cy.wrap($row).should('have.class', 'row--editable')
+ // see that the password of user0 is ""
+ cy.get('input[type="password"]').should('exist').and('have.value', '')
+ // set the password for user0 to 123456
+ cy.get('input[type="password"]').type('123456')
+ // When I set the password for user0 to 123456
+ cy.get('input[type="password"]').should('have.value', '123456')
+ cy.get('.password button').click()
+
+ // Ignore failure if modal is not shown
+ cy.once('fail', (error) => {
+ expect(error.name).to.equal('AssertionError')
+ expect(error).to.have.property('node', '.modal-container')
+ })
+ // Make sure no confirmation modal is shown
+ cy.root().closest('body').find('.modal-container').then(($modal) => {
+ if ($modal.length > 0) {
+ cy.wrap($modal).find('input[type="password"]').type(admin.password)
+ cy.wrap($modal).find('button').contains('Confirm').click()
+ }
+ })
+
+ // see that the password cell for user user0 is done loading
+ cy.get('.user-row-text-field.icon-loading-small').should('exist')
+ cy.waitUntil(() => cy.get('.user-row-text-field.icon-loading-small').should('not.exist'), { timeout: 10000 })
+ // password input is emptied on change
+ cy.get('input[type="password"]').should('have.value', '')
+ })
+ // Success message is shown
+ cy.get('.toastify.toast-success').contains(/Password.+successfully.+changed/i).should('exist')
+ })
+})
diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts
index 31e867a5caf..e48965822fa 100644
--- a/cypress/support/commands.ts
+++ b/cypress/support/commands.ts
@@ -34,6 +34,11 @@ declare global {
namespace Cypress {
interface Chainable<Subject = any> {
/**
+ * Enable or disable a given user
+ */
+ enableUser(user: User, enable?: boolean): Cypress.Chainable<Cypress.Response<any>>,
+
+ /**
* Upload a file from the fixtures folder to a given user storage.
* **Warning**: Using this function will reset the previous session
*/
@@ -70,6 +75,33 @@ const url = (Cypress.config('baseUrl') || '').replace(/\/index.php\/?$/g, '')
Cypress.env('baseUrl', url)
/**
+ * Enable or disable a user
+ * TODO: standardise in @nextcloud/cypress
+ *
+ * @param {User} user the user to dis- / enable
+ * @param {boolean} enable True if the user should be enable, false to disable
+ */
+Cypress.Commands.add('enableUser', (user: User, enable = true) => {
+ const url = `${Cypress.config('baseUrl')}/ocs/v2.php/cloud/users/${user.userId}/${enable ? 'enable' : 'disable'}`.replace('index.php/', '')
+ return cy.request({
+ method: 'PUT',
+ url,
+ form: true,
+ auth: {
+ user: 'admin',
+ password: 'admin',
+ },
+ headers: {
+ 'OCS-ApiRequest': 'true',
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ },
+ }).then((response) => {
+ cy.log(`Enabled user ${user}`, response.status)
+ return cy.wrap(response)
+ })
+})
+
+/**
* cy.uploadedFile - uploads a file from the fixtures folder
* TODO: standardise in @nextcloud/cypress
*