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 function assertContextMenuItems({
77 cy.get('[data-cy=user-profile-panel-options-btn]').click();
78 cy.get('[data-cy=context-menu]').within(() => {
79 cy.get('[role=button]').contains('Advanced');
81 cy.get('[role=button]').should(account ? 'contain' : 'not.contain', 'Account Settings');
82 cy.get('[role=button]').should(activate ? 'contain' : 'not.contain', 'Activate User');
83 cy.get('[role=button]').should(deactivate ? 'contain' : 'not.contain', 'Deactivate User');
84 cy.get('[role=button]').should(login ? 'contain' : 'not.contain', 'Login As User');
85 cy.get('[role=button]').should(setup ? 'contain' : 'not.contain', 'Setup User');
87 cy.get('div[role=presentation]').click();
90 beforeEach(function() {
91 cy.updateResource(adminUser.token, 'users', adminUser.user.uuid, {
95 organization_email: '',
101 cy.updateResource(adminUser.token, 'users', activeUser.user.uuid, {
105 organization_email: '',
113 it('non-admin can edit own profile', function() {
114 cy.loginAs(activeUser);
116 cy.get('header button[title="Account Management"]').click();
117 cy.get('#account-menu').contains('My account').click();
119 // Admin actions should be hidden, no account menu
120 assertContextMenuItems({
128 // Check initial values
129 assertProfileValues({
132 email: 'user@example.local',
143 org_email: 'email@example.com',
144 role: 'Data Scientist',
145 website: 'example.com',
149 cy.get('[data-cy=profile-form] button[type="submit"]').click();
152 assertProfileValues({
155 email: 'user@example.local',
158 org_email: 'email@example.com',
159 role: 'Data Scientist',
160 website: 'example.com',
164 it('non-admin cannot edit other profile', function() {
165 cy.loginAs(activeUser);
166 cy.goToPath('/user/' + adminUser.user.uuid);
168 assertProfileValues({
171 email: 'admin@example.local',
179 // Inputs should be disabled
180 cy.get('[data-cy=profile-form] input[name="prefs.profile.organization"]').should('be.disabled');
181 cy.get('[data-cy=profile-form] input[name="prefs.profile.organization_email"]').should('be.disabled');
182 cy.get('[data-cy=profile-form] select[name="prefs.profile.role"]').should('be.disabled');
183 cy.get('[data-cy=profile-form] input[name="prefs.profile.website_url"]').should('be.disabled');
185 // Submit should be disabled
186 cy.get('[data-cy=profile-form] button[type="submit"]').should('be.disabled');
188 // Admin actions should be hidden, no account menu
189 assertContextMenuItems({
198 it('admin can edit own profile', function() {
199 cy.loginAs(adminUser);
201 cy.get('header button[title="Account Management"]').click();
202 cy.get('#account-menu').contains('My account').click();
204 // Admin actions should be visible, no account menu
205 assertContextMenuItems({
213 // Check initial values
214 assertProfileValues({
217 email: 'admin@example.local',
227 org: 'Admin org name',
228 org_email: 'admin@example.com',
230 website: 'admin.local',
232 cy.get('[data-cy=profile-form] button[type="submit"]').click();
235 assertProfileValues({
238 email: 'admin@example.local',
240 org: 'Admin org name',
241 org_email: 'admin@example.com',
243 website: 'admin.local',
247 it('admin can edit other profile', function() {
248 cy.loginAs(adminUser);
249 cy.goToPath('/user/' + activeUser.user.uuid);
252 assertProfileValues({
255 email: 'user@example.local',
264 org: 'Changed org name',
265 org_email: 'changed@example.com',
267 website: 'changed.local',
269 cy.get('[data-cy=profile-form] button[type="submit"]').click();
272 assertProfileValues({
275 email: 'user@example.local',
277 org: 'Changed org name',
278 org_email: 'changed@example.com',
280 website: 'changed.local',
283 // Admin actions should be visible, no account menu
284 assertContextMenuItems({
293 it('displays role groups on user profile', function() {
294 cy.loginAs(adminUser);
296 cy.createGroup(adminUser.token, {
299 }).as('roleGroup').then(function() {
300 cy.createLink(adminUser.token, {
302 link_class: 'permission',
303 head_uuid: this.roleGroup.uuid,
304 tail_uuid: adminUser.user.uuid
306 cy.createLink(adminUser.token, {
308 link_class: 'permission',
309 head_uuid: this.roleGroup.uuid,
310 tail_uuid: activeUser.user.uuid
314 cy.createGroup(adminUser.token, {
315 name: projectGroupName,
316 group_class: 'project',
317 }).as('projectGroup').then(function() {
318 cy.createLink(adminUser.token, {
320 link_class: 'permission',
321 head_uuid: this.projectGroup.uuid,
322 tail_uuid: adminUser.user.uuid
324 cy.createLink(adminUser.token, {
326 link_class: 'permission',
327 head_uuid: this.projectGroup.uuid,
328 tail_uuid: activeUser.user.uuid
332 cy.goToPath('/user/' + activeUser.user.uuid);
333 cy.get('div [role="tab"]').contains('GROUPS').click();
334 cy.get('[data-cy=user-profile-groups-data-explorer]').contains(roleGroupName);
335 cy.get('[data-cy=user-profile-groups-data-explorer]').should('not.contain', projectGroupName);
337 cy.goToPath('/user/' + adminUser.user.uuid);
338 cy.get('div [role="tab"]').contains('GROUPS').click();
339 cy.get('[data-cy=user-profile-groups-data-explorer]').contains(roleGroupName);
340 cy.get('[data-cy=user-profile-groups-data-explorer]').should('not.contain', projectGroupName);
343 it('allows performing admin functions', function() {
344 cy.loginAs(adminUser);
345 cy.goToPath('/user/' + activeUser.user.uuid);
347 // Check that user is active
348 cy.get('[data-cy=account-status]').contains('Active');
349 cy.get('div [role="tab"]').contains('GROUPS').click();
350 cy.get('[data-cy=user-profile-groups-data-explorer]').should('contain', 'All users');
351 cy.get('div [role="tab"]').contains('PROFILE').click();
352 assertContextMenuItems({
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 // Check that user is deactivated
366 cy.get('[data-cy=account-status]').contains('Inactive');
367 cy.get('div [role="tab"]').contains('GROUPS').click();
368 cy.get('[data-cy=user-profile-groups-data-explorer]').should('not.contain', 'All users');
369 cy.get('div [role="tab"]').contains('PROFILE').click();
370 assertContextMenuItems({
379 cy.get('[data-cy=user-profile-panel-options-btn]').click();
380 cy.get('[data-cy=context-menu]').contains('Setup User').click();
381 cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
383 // Check that user is setup
384 cy.get('[data-cy=account-status]').contains('Setup');
385 cy.get('div [role="tab"]').contains('GROUPS').click();
386 cy.get('[data-cy=user-profile-groups-data-explorer]').should('contain', 'All users');
387 cy.get('div [role="tab"]').contains('PROFILE').click();
388 assertContextMenuItems({
397 cy.get('[data-cy=user-profile-panel-options-btn]').click();
398 cy.get('[data-cy=context-menu]').contains('Activate User').click();
399 cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
401 // Check that user is active
402 cy.get('[data-cy=account-status]').contains('Active');
403 cy.get('div [role="tab"]').contains('GROUPS').click();
404 cy.get('[data-cy=user-profile-groups-data-explorer]').should('contain', 'All users');
405 cy.get('div [role="tab"]').contains('PROFILE').click();
406 assertContextMenuItems({
414 // Deactivate and activate user skipping setup
415 cy.get('[data-cy=user-profile-panel-options-btn]').click();
416 cy.get('[data-cy=context-menu]').contains('Deactivate User').click();
417 cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
419 cy.get('[data-cy=account-status]').contains('Inactive');
420 cy.get('div [role="tab"]').contains('GROUPS').click();
421 cy.get('[data-cy=user-profile-groups-data-explorer]').should('not.contain', 'All users');
422 cy.get('div [role="tab"]').contains('PROFILE').click();
423 assertContextMenuItems({
431 cy.get('[data-cy=user-profile-panel-options-btn]').click();
432 cy.get('[data-cy=context-menu]').contains('Activate User').click();
433 cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
435 // Check that user is active
436 cy.get('[data-cy=account-status]').contains('Active');
437 cy.get('div [role="tab"]').contains('GROUPS').click();
438 cy.get('[data-cy=user-profile-groups-data-explorer]').should('contain', 'All users');
439 cy.get('div [role="tab"]').contains('PROFILE').click();
440 assertContextMenuItems({