Merge remote-tracking branch 'origin/main' into 18207-Workbench2-is-not-clearing...
[arvados-workbench2.git] / cypress / integration / project.spec.js
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 describe('Project tests', function() {
6     let activeUser;
7     let adminUser;
8
9     before(function() {
10         // Only set up common users once. These aren't set up as aliases because
11         // aliases are cleaned up after every test. Also it doesn't make sense
12         // to set the same users on beforeEach() over and over again, so we
13         // separate a little from Cypress' 'Best Practices' here.
14         cy.getUser('admin', 'Admin', 'User', true, true)
15             .as('adminUser').then(function() {
16                 adminUser = this.adminUser;
17             }
18         );
19         cy.getUser('user', 'Active', 'User', false, true)
20             .as('activeUser').then(function() {
21                 activeUser = this.activeUser;
22             }
23         );
24     });
25
26     beforeEach(function() {
27         cy.clearCookies();
28         cy.clearLocalStorage();
29     });
30
31     it('adds creates a new project with properties', function() {
32         const projName = `Test project (${Math.floor(999999 * Math.random())})`;
33         cy.loginAs(activeUser);
34         cy.get('[data-cy=side-panel-button]').click();
35         cy.get('[data-cy=side-panel-new-project]').click();
36         cy.get('[data-cy=form-dialog]')
37             .should('contain', 'New project')
38             .within(() => {
39                 cy.get('[data-cy=name-field]').within(() => {
40                     cy.get('input').type(projName);
41                 });
42
43             });
44         // Key: Color (IDTAGCOLORS) - Value: Magenta (IDVALCOLORS3)
45         cy.get('[data-cy=resource-properties-form]').within(() => {
46             cy.get('[data-cy=property-field-key]').within(() => {
47                 cy.get('input').type('Color');
48             });
49             cy.get('[data-cy=property-field-value]').within(() => {
50                 cy.get('input').type('Magenta');
51             });
52             cy.root().submit();
53         });
54         // Confirm proper vocabulary labels are displayed on the UI.
55         cy.get('[data-cy=form-dialog]').should('contain', 'Color: Magenta');
56
57         // Create project and confirm the properties' real values.
58         cy.get('[data-cy=form-submit-btn]').click();
59         cy.get('[data-cy=breadcrumb-last]').should('contain', projName);
60         cy.doRequest('GET', '/arvados/v1/groups', null, {
61             filters: `[["name", "=", "${projName}"], ["group_class", "=", "project"]]`,
62         })
63         .its('body.items').as('projects')
64         .then(function() {
65             expect(this.projects).to.have.lengthOf(1);
66             expect(this.projects[0].properties).to.deep.equal(
67                 {IDTAGCOLORS: 'IDVALCOLORS3'});
68         });
69     });
70
71     it('creates new project on home project and then a subproject inside it', function() {
72         const createProject = function(name, parentName) {
73             cy.get('[data-cy=side-panel-button]').click();
74             cy.get('[data-cy=side-panel-new-project]').click();
75             cy.get('[data-cy=form-dialog]')
76                 .should('contain', 'New project')
77                 .within(() => {
78                     cy.get('[data-cy=parent-field]').within(() => {
79                         cy.get('input').invoke('val').then((val) => {
80                             expect(val).to.include(parentName);
81                         });
82                     });
83                     cy.get('[data-cy=name-field]').within(() => {
84                         cy.get('input').type(name);
85                     });
86                 });
87             cy.get('[data-cy=form-submit-btn]').click();
88         }
89
90         cy.loginAs(activeUser);
91         cy.goToPath(`/projects/${activeUser.user.uuid}`);
92         cy.get('[data-cy=breadcrumb-first]').should('contain', 'Projects');
93         cy.get('[data-cy=breadcrumb-last]').should('not.exist');
94         // Create new project
95         const projName = `Test project (${Math.floor(999999 * Math.random())})`;
96         createProject(projName, 'Home project');
97         // Confirm that the user was taken to the newly created thing
98         cy.get('[data-cy=form-dialog]').should('not.exist');
99         cy.get('[data-cy=breadcrumb-first]').should('contain', 'Projects');
100         cy.get('[data-cy=breadcrumb-last]').should('contain', projName);
101         // Create a subproject
102         const subProjName = `Test project (${Math.floor(999999 * Math.random())})`;
103         createProject(subProjName, projName);
104         cy.get('[data-cy=form-dialog]').should('not.exist');
105         cy.get('[data-cy=breadcrumb-first]').should('contain', 'Projects');
106         cy.get('[data-cy=breadcrumb-last]').should('contain', subProjName);
107     });
108
109     it('navigates to the parent project after trashing the one being displayed', function() {
110         cy.createGroup(activeUser.token, {
111             name: `Test root project ${Math.floor(Math.random() * 999999)}`,
112             group_class: 'project',
113         }).as('testRootProject').then(function() {
114             cy.createGroup(activeUser.token, {
115                 name : `Test subproject ${Math.floor(Math.random() * 999999)}`,
116                 group_class: 'project',
117                 owner_uuid: this.testRootProject.uuid,
118             }).as('testSubProject');
119         });
120         cy.getAll('@testRootProject', '@testSubProject').then(function([testRootProject, testSubProject]) {
121             cy.loginAs(activeUser);
122
123             // Go to subproject and trash it.
124             cy.goToPath(`/projects/${testSubProject.uuid}`);
125             cy.get('[data-cy=side-panel-tree]').should('contain', testSubProject.name);
126             cy.get('[data-cy=breadcrumb-last]')
127                 .should('contain', testSubProject.name)
128                 .rightclick();
129             cy.get('[data-cy=context-menu]').contains('Move to trash').click();
130
131             // Confirm that the parent project should be displayed.
132             cy.get('[data-cy=breadcrumb-last]').should('contain', testRootProject.name);
133             cy.url().should('contain', `/projects/${testRootProject.uuid}`);
134             cy.get('[data-cy=side-panel-tree]').should('not.contain', testSubProject.name);
135
136             // Checks for bugfix #17637.
137             cy.get('[data-cy=not-found-content]').should('not.exist');
138             cy.get('[data-cy=not-found-page]').should('not.exist');
139         });
140     });
141
142     it('navigates to the root project after trashing the parent of the one being displayed', function() {
143         cy.createGroup(activeUser.token, {
144             name: `Test root project ${Math.floor(Math.random() * 999999)}`,
145             group_class: 'project',
146         }).as('testRootProject').then(function() {
147             cy.createGroup(activeUser.token, {
148                 name : `Test subproject ${Math.floor(Math.random() * 999999)}`,
149                 group_class: 'project',
150                 owner_uuid: this.testRootProject.uuid,
151             }).as('testSubProject').then(function() {
152                 cy.createGroup(activeUser.token, {
153                     name : `Test sub subproject ${Math.floor(Math.random() * 999999)}`,
154                     group_class: 'project',
155                     owner_uuid: this.testSubProject.uuid,
156                 }).as('testSubSubProject');
157             });
158         });
159         cy.getAll('@testRootProject', '@testSubProject', '@testSubSubProject').then(function([testRootProject, testSubProject, testSubSubProject]) {
160             cy.loginAs(activeUser);
161
162             // Go to innermost project and trash its parent.
163             cy.goToPath(`/projects/${testSubSubProject.uuid}`);
164             cy.get('[data-cy=side-panel-tree]').should('contain', testSubSubProject.name);
165             cy.get('[data-cy=breadcrumb-last]').should('contain', testSubSubProject.name);
166             cy.get('[data-cy=side-panel-tree]')
167                 .contains(testSubProject.name)
168                 .rightclick();
169             cy.get('[data-cy=context-menu]').contains('Move to trash').click();
170
171             // Confirm that the trashed project's parent should be displayed.
172             cy.get('[data-cy=breadcrumb-last]').should('contain', testRootProject.name);
173             cy.url().should('contain', `/projects/${testRootProject.uuid}`);
174             cy.get('[data-cy=side-panel-tree]').should('not.contain', testSubProject.name);
175             cy.get('[data-cy=side-panel-tree]').should('not.contain', testSubSubProject.name);
176
177             // Checks for bugfix #17637.
178             cy.get('[data-cy=not-found-content]').should('not.exist');
179             cy.get('[data-cy=not-found-page]').should('not.exist');
180         });
181     });
182
183     it('shows details panel when clicking on the info icon', () => {
184         cy.createGroup(activeUser.token, {
185             name: `Test root project ${Math.floor(Math.random() * 999999)}`,
186             group_class: 'project',
187         }).as('testRootProject').then(function(testRootProject) {
188             cy.loginAs(activeUser);
189
190             cy.get('[data-cy=side-panel-tree]').contains(testRootProject.name).click();
191
192             cy.get('[data-cy=additional-info-icon]').click();
193
194             cy.contains(testRootProject.uuid).should('exist');
195         });
196     });
197
198     it('clears search input when changing project', () => {
199         cy.createGroup(activeUser.token, {
200             name: `Test root project ${Math.floor(Math.random() * 999999)}`,
201             group_class: 'project',
202         }).as('testProject1');
203
204         cy.getAll('@testProject1').then(function([testProject1]) {
205             cy.loginAs(activeUser);
206
207             cy.get('[data-cy=side-panel-tree]').contains(testProject1.name).click();
208
209             cy.get('[data-cy=search-input] input').type('test123');
210
211             cy.get('[data-cy=side-panel-tree]').contains('Projects').click();
212
213             cy.get('[data-cy=search-input] input').should('not.have.value', 'test123');
214         });
215     });
216 });