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('API Details');
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 //de-select the context menu
88 cy.get('body').click();
91 beforeEach(function() {
92 cy.updateResource(adminUser.token, 'users', adminUser.user.uuid, {
96 organization_email: '',
102 cy.updateResource(adminUser.token, 'users', activeUser.user.uuid, {
106 organization_email: '',
114 it('non-admin can edit own profile', function() {
115 cy.loginAs(activeUser);
117 cy.get('header button[aria-label="Account Management"]').click();
118 cy.get('#account-menu').contains('My account').click();
120 // Admin actions should be hidden, no account menu
121 assertContextMenuItems({
129 // Check initial values
130 assertProfileValues({
133 email: 'user@example.local',
144 org_email: 'email@example.com',
145 role: 'Data Scientist',
146 website: 'example.com',
149 cy.get('[data-cy=profile-form] button[type="submit"]').should('not.be.disabled');
152 cy.get('[data-cy=profile-form] button[type="submit"]').click();
155 assertProfileValues({
158 email: 'user@example.local',
161 org_email: 'email@example.com',
162 role: 'Data Scientist',
163 website: 'example.com',
166 // if it worked, the save button should be disabled.
167 cy.get('[data-cy=profile-form] button[type="submit"]').should('be.disabled');
170 it('non-admin cannot edit other profile', function() {
171 cy.loginAs(activeUser);
172 cy.goToPath('/user/' + adminUser.user.uuid);
174 assertProfileValues({
177 email: 'admin@example.local',
185 // Inputs should be disabled
186 cy.get('[data-cy=profile-form] input[name="prefs.profile.organization"]').should('be.disabled');
187 cy.get('[data-cy=profile-form] input[name="prefs.profile.organization_email"]').should('be.disabled');
188 cy.get('[data-cy=profile-form] select[name="prefs.profile.role"]').should('be.disabled');
189 cy.get('[data-cy=profile-form] input[name="prefs.profile.website_url"]').should('be.disabled');
191 // Submit should be disabled
192 cy.get('[data-cy=profile-form] button[type="submit"]').should('be.disabled');
194 // Admin actions should be hidden, no account menu
195 assertContextMenuItems({
204 it('admin can edit own profile', function() {
205 cy.loginAs(adminUser);
207 cy.get('header button[aria-label="Account Management"]').click();
208 cy.get('#account-menu').contains('My account').click();
210 // Admin actions should be visible, no account menu
211 assertContextMenuItems({
219 // Check initial values
220 assertProfileValues({
223 email: 'admin@example.local',
233 org: 'Admin org name',
234 org_email: 'admin@example.com',
236 website: 'admin.local',
238 cy.get('[data-cy=profile-form] button[type="submit"]').click();
241 assertProfileValues({
244 email: 'admin@example.local',
246 org: 'Admin org name',
247 org_email: 'admin@example.com',
249 website: 'admin.local',
253 it('admin can edit other profile', function() {
254 cy.loginAs(adminUser);
255 cy.goToPath('/user/' + activeUser.user.uuid);
258 assertProfileValues({
261 email: 'user@example.local',
270 org: 'Changed org name',
271 org_email: 'changed@example.com',
273 website: 'changed.local',
275 cy.get('[data-cy=profile-form] button[type="submit"]').click();
278 assertProfileValues({
281 email: 'user@example.local',
283 org: 'Changed org name',
284 org_email: 'changed@example.com',
286 website: 'changed.local',
289 // Admin actions should be visible, no account menu
290 assertContextMenuItems({
299 it('displays role groups on user profile', function() {
300 cy.loginAs(adminUser);
302 cy.createGroup(adminUser.token, {
305 }).as('roleGroup').then(function() {
306 cy.createLink(adminUser.token, {
308 link_class: 'permission',
309 head_uuid: this.roleGroup.uuid,
310 tail_uuid: adminUser.user.uuid
312 cy.createLink(adminUser.token, {
314 link_class: 'permission',
315 head_uuid: this.roleGroup.uuid,
316 tail_uuid: activeUser.user.uuid
320 cy.createGroup(adminUser.token, {
321 name: projectGroupName,
322 group_class: 'project',
323 }).as('projectGroup').then(function() {
324 cy.createLink(adminUser.token, {
326 link_class: 'permission',
327 head_uuid: this.projectGroup.uuid,
328 tail_uuid: adminUser.user.uuid
330 cy.createLink(adminUser.token, {
332 link_class: 'permission',
333 head_uuid: this.projectGroup.uuid,
334 tail_uuid: activeUser.user.uuid
338 cy.goToPath('/user/' + activeUser.user.uuid);
339 cy.get('div [role="tab"]').contains('GROUPS').click();
340 cy.get('[data-cy=user-profile-groups-data-explorer]').contains(roleGroupName);
341 cy.get('[data-cy=user-profile-groups-data-explorer]').should('not.contain', projectGroupName);
343 cy.goToPath('/user/' + adminUser.user.uuid);
344 cy.get('div [role="tab"]').contains('GROUPS').click();
345 cy.get('[data-cy=user-profile-groups-data-explorer]').contains(roleGroupName);
346 cy.get('[data-cy=user-profile-groups-data-explorer]').should('not.contain', projectGroupName);
349 it('allows performing admin functions', function() {
350 cy.loginAs(adminUser);
351 cy.goToPath('/user/' + activeUser.user.uuid);
353 // Check that user is active
354 cy.get('[data-cy=account-status]').contains('Active');
355 cy.get('div [role="tab"]').contains('GROUPS').click();
356 cy.get('[data-cy=user-profile-groups-data-explorer]').should('contain', 'All users');
357 cy.get('div [role="tab"]').contains('PROFILE').click();
358 assertContextMenuItems({
367 cy.get('[data-cy=user-profile-panel-options-btn]').click();
368 cy.get('[data-cy=context-menu]').contains('Deactivate user').click();
369 cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
371 // Check that user is deactivated
372 cy.get('[data-cy=account-status]').contains('Inactive');
373 cy.get('div [role="tab"]').contains('GROUPS').click();
374 cy.get('[data-cy=user-profile-groups-data-explorer]').should('not.contain', 'All users');
375 cy.get('div [role="tab"]').contains('PROFILE').click();
376 assertContextMenuItems({
385 cy.get('[data-cy=user-profile-panel-options-btn]').click();
386 cy.get('[data-cy=context-menu]').contains('Setup user').click();
387 cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
389 // Check that user is setup
390 cy.get('[data-cy=account-status]').contains('Setup');
391 cy.get('div [role="tab"]').contains('GROUPS').click();
392 cy.get('[data-cy=user-profile-groups-data-explorer]').should('contain', 'All users');
393 cy.get('div [role="tab"]').contains('PROFILE').click();
394 assertContextMenuItems({
403 cy.get('[data-cy=user-profile-panel-options-btn]').click();
404 cy.get('[data-cy=context-menu]').contains('Activate user').click();
405 cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
407 // Check that user is active
408 cy.get('[data-cy=account-status]').contains('Active');
409 cy.get('div [role="tab"]').contains('GROUPS').click();
410 cy.get('[data-cy=user-profile-groups-data-explorer]').should('contain', 'All users');
411 cy.get('div [role="tab"]').contains('PROFILE').click();
412 assertContextMenuItems({
420 // Deactivate and activate user skipping setup
421 cy.get('[data-cy=user-profile-panel-options-btn]').click();
422 cy.get('[data-cy=context-menu]').contains('Deactivate user').click();
423 cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
425 cy.get('[data-cy=account-status]').contains('Inactive');
426 cy.get('div [role="tab"]').contains('GROUPS').click();
427 cy.get('[data-cy=user-profile-groups-data-explorer]').should('not.contain', 'All users');
428 cy.get('div [role="tab"]').contains('PROFILE').click();
429 assertContextMenuItems({
437 cy.get('[data-cy=user-profile-panel-options-btn]').click();
438 cy.get('[data-cy=context-menu]').contains('Activate user').click();
439 cy.get('[data-cy=confirmation-dialog-ok-btn]').click();
441 // Check that user is active
442 cy.get('[data-cy=account-status]').contains('Active');
443 cy.get('div [role="tab"]').contains('GROUPS').click();
444 cy.get('[data-cy=user-profile-groups-data-explorer]').should('contain', 'All users');
445 cy.get('div [role="tab"]').contains('PROFILE').click();
446 assertContextMenuItems({