18123: Add basic group edit cypress tests.
authorStephen Smith <stephen@curii.com>
Tue, 23 Nov 2021 03:54:33 +0000 (22:54 -0500)
committerStephen Smith <stephen@curii.com>
Tue, 23 Nov 2021 03:54:33 +0000 (22:54 -0500)
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen@curii.com>

cypress/integration/group-manage.spec.js [new file with mode: 0644]
src/components/data-explorer/data-explorer.tsx
src/views-components/data-explorer/renderers.tsx
src/views/group-details-panel/group-details-panel.tsx
src/views/groups-panel/groups-panel.tsx

diff --git a/cypress/integration/group-manage.spec.js b/cypress/integration/group-manage.spec.js
new file mode 100644 (file)
index 0000000..8f63003
--- /dev/null
@@ -0,0 +1,127 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+describe('Group manage tests', function() {
+    let activeUser;
+    let adminUser;
+    let otherUser;
+
+    before(function() {
+        // Only set up common users once. These aren't set up as aliases because
+        // aliases are cleaned up after every test. Also it doesn't make sense
+        // to set the same users on beforeEach() over and over again, so we
+        // separate a little from Cypress' 'Best Practices' here.
+        cy.getUser('admin', 'Admin', 'User', true, true)
+            .as('adminUser').then(function() {
+                adminUser = this.adminUser;
+            }
+        );
+        cy.getUser('user', 'Active', 'User', false, true)
+            .as('activeUser').then(function() {
+                activeUser = this.activeUser;
+            }
+        );
+        cy.getUser('otheruser', 'Other', 'User', false, true)
+            .as('otherUser').then(function() {
+                otherUser = this.otherUser;
+            }
+        );
+    });
+
+    beforeEach(function() {
+        cy.clearCookies();
+        cy.clearLocalStorage();
+    });
+
+    it('creates a new group', function() {
+        const groupName = `Test group (${Math.floor(999999 * Math.random())})`;
+        cy.loginAs(activeUser);
+
+        // Navigate to Groups
+        cy.get('[data-cy=side-panel-tree]').contains('Groups').click();
+
+        // Create new group
+        cy.get('[data-cy=groups-panel-new-group]').click();
+        cy.get('[data-cy=form-dialog]')
+            .should('contain', 'Create a group')
+            .within(() => {
+                cy.get('input[name=name]').type(groupName);
+                cy.get('button[type=submit]').click();
+            });
+        
+        // Check that the group was created
+        cy.get('[data-cy=groups-panel-data-explorer]').contains(groupName).click();
+        cy.get('[data-cy=group-members-data-explorer]').contains('Active User');
+    });
+
+    it('adds users to the group', function() {
+        // Add other user to the group
+        cy.get('[data-cy=group-member-add]').click();
+        cy.get('[data-cy=form-dialog]')
+            .should('contain', 'Add users')
+            .within(() => {
+                cy.get('input').type("other");
+            });
+        cy.contains('Other User').click();
+        cy.get('[data-cy=form-dialog] button[type=submit]').click();
+
+        // Check that both users are present with appropriate permissions
+        cy.get('[data-cy=group-members-data-explorer]')
+            .contains('Other User')
+            .parents('tr')
+            .within(() => {
+                cy.contains('Read');
+            });
+        cy.get('[data-cy=group-members-data-explorer] tr')
+            .contains('Active User')
+            .parents('tr')
+            .within(() => {
+                cy.contains('Manage');
+            });
+    });
+
+    it('changes permission level of a member', function() {
+        // Test change permission level
+        cy.get('[data-cy=group-members-data-explorer]')
+            .contains('Other User')
+            .parents('tr')
+            .within(() => {
+                cy.contains('Read')
+                    .parents('td')
+                    .within(() => {
+                        cy.get('button').click();
+                    });
+            });
+        cy.get('[data-cy=form-dialog]')
+            .should('contain', 'Edit permission')
+            .within(() => {
+                cy.contains('Read').click();
+            });
+        cy.get('li span')
+            .contains('Write')
+            .parents('li')
+            .click();
+        cy.get('[data-cy=form-dialog] button[type=submit]').click();
+        cy.get('[data-cy=group-members-data-explorer]')
+            .contains('Other User')
+            .parents('tr')
+            .within(() => {
+                cy.contains('Write');
+            });
+    });
+
+    it('removes users from the group', function() {
+        // Remove other user
+        cy.get('[data-cy=group-members-data-explorer]')
+            .contains('Other User')
+            .parents('tr')
+            .within(() => {
+                cy.get('[data-cy=resource-delete-button]').click();
+            });
+        cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
+        cy.get('[data-cy=group-members-data-explorer]')
+            .should('not.contain', 'Other User');
+
+    });
+});
index f3cccfcec8a002894ae9313fbc89a956cf0e4385..928d3ed4867e68388ed1a416e25b51f4018a1c31 100644 (file)
@@ -96,7 +96,8 @@ export const DataExplorer = withStyles(styles)(
                 dataTableDefaultView, hideColumnSelector, actions, paperProps, hideSearchInput,
                 paperKey, fetchMode, currentItemUuid, title
             } = this.props;
-            return <Paper className={classes.root} {...paperProps} key={paperKey}>
+            const dataCy = this.props["data-cy"];
+            return <Paper className={classes.root} {...paperProps} key={paperKey} data-cy={dataCy}>
                 {title && <div className={classes.title}>{title}</div>}
                 {(!hideColumnSelector || !hideSearchInput || !!actions) && <Toolbar className={title ? classes.toolbarUnderTitle : classes.toolbar}>
                     <Grid container justify="space-between" wrap="nowrap" alignItems="center">
index aa2009421e4a36dfc48ed74e7762d5e28ec05340..61086bd88769917e6dc7b5d339b962b2951e8941 100644 (file)
@@ -379,7 +379,7 @@ export const ResourceLinkTailUuid = connect(
 const renderLinkDelete = (dispatch: Dispatch, item: LinkResource) => {
     if (item.uuid) {
         return <Typography noWrap>
-            <IconButton onClick={() => dispatch<any>(openRemoveGroupMemberDialog(item.uuid))}>
+            <IconButton data-cy="resource-delete-button" onClick={() => dispatch<any>(openRemoveGroupMemberDialog(item.uuid))}>
                 <RemoveIcon />
             </IconButton>
         </Typography>;
index bade28cb949b35ceabfb805b1846e351cd7025ab..427f4fb89979a8630a4ca326063a001dc9cff3a5 100644 (file)
@@ -167,6 +167,7 @@ export const GroupDetailsPanel = connect(
                   {value === 0 &&
                       <DataExplorer
                           id={GROUP_DETAILS_MEMBERS_PANEL_ID}
+                          data-cy="group-members-data-explorer"
                           onRowClick={noop}
                           onRowDoubleClick={noop}
                           onContextMenu={noop}
@@ -177,6 +178,7 @@ export const GroupDetailsPanel = connect(
                                 this.props.groupCanManage &&
                                 <Grid container justify='flex-end'>
                                     <Button
+                                      data-cy="group-member-add"
                                       variant="contained"
                                       color="primary"
                                       onClick={this.props.onAddUser}>
index 4f25f6e5840fd6b9f49258f09092c237c21261d4..c96c06775376ae0eb47e35e464ce52b6cba54885 100644 (file)
@@ -79,6 +79,7 @@ export const GroupsPanel = connect(
             return (
                 <DataExplorer
                     id={GROUPS_PANEL_ID}
+                    data-cy="groups-panel-data-explorer"
                     onRowClick={noop}
                     onRowDoubleClick={noop}
                     onContextMenu={this.handleContextMenu}
@@ -87,6 +88,7 @@ export const GroupsPanel = connect(
                     actions={
                         <Grid container justify='flex-end'>
                             <Button
+                                data-cy="groups-panel-new-group"
                                 variant="contained"
                                 color="primary"
                                 onClick={this.props.onNewGroup}>