1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 describe('User profile tests', function() {
8 const roleGroupName = `Test role group (${Math.floor(999999 * Math.random())})`;
9 const projectGroupName = `Test project group (${Math.floor(999999 * Math.random())})`;
12 // Only set up common users once. These aren't set up as aliases because
13 // aliases are cleaned up after every test. Also it doesn't make sense
14 // to set the same users on beforeEach() over and over again, so we
15 // separate a little from Cypress' 'Best Practices' here.
16 cy.getUser('admin', 'Admin', 'User', true, true)
17 .as('adminUser').then(function() {
18 adminUser = this.adminUser;
21 cy.getUser('user', 'Active', 'User', false, true)
22 .as('activeUser').then(function() {
23 activeUser = this.activeUser;
28 function assertProfileValues({
38 cy.get('[data-cy=profile-form] input[name="firstName"]').invoke('val').should('equal', firstName);
39 cy.get('[data-cy=profile-form] input[name="lastName"]').invoke('val').should('equal', lastName);
40 cy.get('[data-cy=profile-form] [data-cy=email] [data-cy=value]').contains(email);
41 cy.get('[data-cy=profile-form] [data-cy=username] [data-cy=value]').contains(username);
43 cy.get('[data-cy=profile-form] input[name="prefs.profile.organization"]').invoke('val').should('equal', org);
44 cy.get('[data-cy=profile-form] input[name="prefs.profile.organization_email"]').invoke('val').should('equal', org_email);
45 cy.get('[data-cy=profile-form] select[name="prefs.profile.role"]').invoke('val').should('equal', role);
46 cy.get('[data-cy=profile-form] input[name="prefs.profile.website_url"]').invoke('val').should('equal', website);
49 function enterProfileValues({
55 cy.get('[data-cy=profile-form] input[name="prefs.profile.organization"]').clear();
57 cy.get('[data-cy=profile-form] input[name="prefs.profile.organization"]').type(org);
59 cy.get('[data-cy=profile-form] input[name="prefs.profile.organization_email"]').clear();
61 cy.get('[data-cy=profile-form] input[name="prefs.profile.organization_email"]').type(org_email);
63 cy.get('[data-cy=profile-form] select[name="prefs.profile.role"]').select(role);
64 cy.get('[data-cy=profile-form] input[name="prefs.profile.website_url"]').clear();
66 cy.get('[data-cy=profile-form] input[name="prefs.profile.website_url"]').type(website);
70 beforeEach(function() {
71 cy.loginAs(adminUser);
72 cy.goToPath('/my-account');
79 cy.get('[data-cy=profile-form] button[type="submit"]').then((btn) => {
80 if (!btn.is(':disabled')) {
86 cy.goToPath('/user/' + activeUser.user.uuid);
93 cy.get('[data-cy=profile-form] button[type="submit"]').then((btn) => {
94 if (!btn.is(':disabled')) {
100 it('non-admin can edit own profile', function() {
101 cy.loginAs(activeUser);
103 cy.get('header button[title="Account Management"]').click();
104 cy.get('#account-menu').contains('My account').click();
106 // Admin tab should be hidden
107 cy.get('div [role="tab"]').should('not.contain', 'ADMIN');
109 // Check initial values
110 assertProfileValues({
113 email: 'user@example.local',
124 org_email: 'email@example.com',
125 role: 'Data Scientist',
126 website: 'example.com',
130 cy.get('[data-cy=profile-form] button[type="submit"]').click();
133 assertProfileValues({
136 email: 'user@example.local',
139 org_email: 'email@example.com',
140 role: 'Data Scientist',
141 website: 'example.com',
145 it('non-admin cannot edit other profile', function() {
146 cy.loginAs(activeUser);
147 cy.goToPath('/user/' + adminUser.user.uuid);
149 assertProfileValues({
152 email: 'admin@example.local',
160 // Inputs should be disabled
161 cy.get('[data-cy=profile-form] input[name="prefs.profile.organization"]').should('be.disabled');
162 cy.get('[data-cy=profile-form] input[name="prefs.profile.organization_email"]').should('be.disabled');
163 cy.get('[data-cy=profile-form] select[name="prefs.profile.role"]').should('be.disabled');
164 cy.get('[data-cy=profile-form] input[name="prefs.profile.website_url"]').should('be.disabled');
166 // Submit should be disabled
167 cy.get('[data-cy=profile-form] button[type="submit"]').should('be.disabled');
169 // Admin context items should be hidden
170 cy.get('[data-cy=user-profile-panel-options-btn]').click();
171 cy.get('[data-cy=context-menu]').within(() => {
172 cy.get('[role=button]').should('not.contain', 'Activate User')
173 cy.get('[role=button]').should('not.contain', 'Deactivate User')
174 cy.get('[role=button]').should('not.contain', 'Login As User')
175 cy.get('[role=button]').should('not.contain', 'Setup User');
177 cy.get('div[role=presentation]').click();
180 it('admin can edit own profile', function() {
181 cy.loginAs(adminUser);
183 cy.get('header button[title="Account Management"]').click();
184 cy.get('#account-menu').contains('My account').click();
186 // Admin context items should be visible
187 cy.get('[data-cy=user-profile-panel-options-btn]').click();
188 cy.get('[data-cy=context-menu]').within(() => {
189 cy.get('[role=button]').contains('Activate User')
190 cy.get('[role=button]').contains('Deactivate User')
191 cy.get('[role=button]').contains('Login As User')
192 cy.get('[role=button]').contains('Setup User');
194 cy.get('div[role=presentation]').click();
196 // Check initial values
197 assertProfileValues({
200 email: 'admin@example.local',
210 org: 'Admin org name',
211 org_email: 'admin@example.com',
213 website: 'admin.local',
215 cy.get('[data-cy=profile-form] button[type="submit"]').click();
218 assertProfileValues({
221 email: 'admin@example.local',
223 org: 'Admin org name',
224 org_email: 'admin@example.com',
226 website: 'admin.local',
230 it('admin can edit other profile', function() {
231 cy.loginAs(adminUser);
232 cy.goToPath('/user/' + activeUser.user.uuid);
235 assertProfileValues({
238 email: 'user@example.local',
247 org: 'Changed org name',
248 org_email: 'changed@example.com',
250 website: 'changed.local',
252 cy.get('[data-cy=profile-form] button[type="submit"]').click();
255 assertProfileValues({
258 email: 'user@example.local',
260 org: 'Changed org name',
261 org_email: 'changed@example.com',
263 website: 'changed.local',
267 it('displays role groups on user profile', function() {
268 cy.loginAs(adminUser);
270 cy.createGroup(adminUser.token, {
273 }).as('roleGroup').then(function() {
274 cy.createLink(adminUser.token, {
276 link_class: 'permission',
277 head_uuid: this.roleGroup.uuid,
278 tail_uuid: adminUser.user.uuid
280 cy.createLink(adminUser.token, {
282 link_class: 'permission',
283 head_uuid: this.roleGroup.uuid,
284 tail_uuid: activeUser.user.uuid
288 cy.createGroup(adminUser.token, {
289 name: projectGroupName,
290 group_class: 'project',
291 }).as('projectGroup').then(function() {
292 cy.createLink(adminUser.token, {
294 link_class: 'permission',
295 head_uuid: this.projectGroup.uuid,
296 tail_uuid: adminUser.user.uuid
298 cy.createLink(adminUser.token, {
300 link_class: 'permission',
301 head_uuid: this.projectGroup.uuid,
302 tail_uuid: activeUser.user.uuid
306 cy.goToPath('/user/' + activeUser.user.uuid);
307 cy.get('div [role="tab"]').contains('GROUPS').click();
308 cy.get('[data-cy=user-profile-groups-data-explorer]').contains(roleGroupName);
309 cy.get('[data-cy=user-profile-groups-data-explorer]').should('not.contain', projectGroupName);
311 cy.goToPath('/user/' + adminUser.user.uuid);
312 cy.get('div [role="tab"]').contains('GROUPS').click();
313 cy.get('[data-cy=user-profile-groups-data-explorer]').contains(roleGroupName);
314 cy.get('[data-cy=user-profile-groups-data-explorer]').should('not.contain', projectGroupName);
317 it('allows performing admin functions', function() {
318 cy.loginAs(adminUser);
319 cy.goToPath('/user/' + activeUser.user.uuid);
321 // Check that user is active
322 cy.get('[data-cy=account-status]').contains('Active');
323 cy.get('div [role="tab"]').contains('GROUPS').click();
324 cy.get('[data-cy=user-profile-groups-data-explorer]').should('contain', 'All users');
325 cy.get('div [role="tab"]').contains('PROFILE').click();
328 cy.get('[data-cy=user-profile-panel-options-btn]').click();
329 cy.get('[data-cy=context-menu]').contains('Deactivate User').click();
330 cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
332 // Check that user is deactivated
333 cy.get('[data-cy=account-status]').contains('Inactive');
334 cy.get('div [role="tab"]').contains('GROUPS').click();
335 cy.get('[data-cy=user-profile-groups-data-explorer]').should('not.contain', 'All users');
336 cy.get('div [role="tab"]').contains('PROFILE').click();
339 cy.get('[data-cy=user-profile-panel-options-btn]').click();
340 cy.get('[data-cy=context-menu]').contains('Setup User').click();
341 cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
343 // Check that user is setup
344 cy.get('[data-cy=account-status]').contains('Setup');
345 cy.get('div [role="tab"]').contains('GROUPS').click();
346 cy.get('[data-cy=user-profile-groups-data-explorer]').should('contain', 'All users');
347 cy.get('div [role="tab"]').contains('PROFILE').click();
350 cy.get('[data-cy=user-profile-panel-options-btn]').click();
351 cy.get('[data-cy=context-menu]').contains('Activate User').click();
352 cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
354 // Check that user is active
355 cy.get('[data-cy=account-status]').contains('Active');
356 cy.get('div [role="tab"]').contains('GROUPS').click();
357 cy.get('[data-cy=user-profile-groups-data-explorer]').should('contain', 'All users');
358 cy.get('div [role="tab"]').contains('PROFILE').click();
360 // Deactivate and activate user skipping setup
361 cy.get('[data-cy=user-profile-panel-options-btn]').click();
362 cy.get('[data-cy=context-menu]').contains('Deactivate User').click();
363 cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
365 cy.get('[data-cy=account-status]').contains('Inactive');
366 cy.get('div [role="tab"]').contains('GROUPS').click();
367 cy.get('[data-cy=user-profile-groups-data-explorer]').should('not.contain', 'All users');
368 cy.get('div [role="tab"]').contains('PROFILE').click();
370 cy.get('[data-cy=user-profile-panel-options-btn]').click();
371 cy.get('[data-cy=context-menu]').contains('Activate User').click();
372 cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
374 // Check that user is active
375 cy.get('[data-cy=account-status]').contains('Active');
376 cy.get('div [role="tab"]').contains('GROUPS').click();
377 cy.get('[data-cy=user-profile-groups-data-explorer]').should('contain', 'All users');