From 121165a587c43edfab0431aa1685dd8975a71e88 Mon Sep 17 00:00:00 2001 From: Peter Amstutz Date: Wed, 30 Aug 2023 16:23:33 -0400 Subject: [PATCH 1/1] 20913: Fix test to check that use profile gets saved Arvados-DCO-1.1-Signed-off-by: Peter Amstutz --- cypress/integration/user-profile.spec.js | 5 + .../user-profile/user-profile-actions.ts | 256 +++++++++--------- 2 files changed, 133 insertions(+), 128 deletions(-) diff --git a/cypress/integration/user-profile.spec.js b/cypress/integration/user-profile.spec.js index d91dbb0b..0a06eaf3 100644 --- a/cypress/integration/user-profile.spec.js +++ b/cypress/integration/user-profile.spec.js @@ -145,6 +145,8 @@ describe('User profile tests', function() { website: 'example.com', }); + cy.get('[data-cy=profile-form] button[type="submit"]').should('not.be.disabled'); + // Submit cy.get('[data-cy=profile-form] button[type="submit"]').click(); @@ -159,6 +161,9 @@ describe('User profile tests', function() { role: 'Data Scientist', website: 'example.com', }); + + // if it worked, the save button should be disabled. + cy.get('[data-cy=profile-form] button[type="submit"]').should('be.disabled'); }); it('non-admin cannot edit other profile', function() { diff --git a/src/store/user-profile/user-profile-actions.ts b/src/store/user-profile/user-profile-actions.ts index 9935518b..44b17c60 100644 --- a/src/store/user-profile/user-profile-actions.ts +++ b/src/store/user-profile/user-profile-actions.ts @@ -29,149 +29,149 @@ export const getCurrentUserProfilePanelUuid = getProperty(USER_PROFILE_P export const getUserProfileIsInaccessible = getProperty(IS_PROFILE_INACCESSIBLE); export const loadUserProfilePanel = (userUuid?: string) => - async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { - // Reset isInacessible to ensure error screen is hidden - dispatch(propertiesActions.SET_PROPERTY({ key: IS_PROFILE_INACCESSIBLE, value: false })); - // Get user uuid from route or use current user uuid - const uuid = userUuid || getState().auth.user?.uuid; - if (uuid) { - await dispatch(propertiesActions.SET_PROPERTY({ key: USER_PROFILE_PANEL_ID, value: uuid })); - try { - const user = await services.userService.get(uuid, false); - dispatch(initialize(USER_PROFILE_FORM, user)); - dispatch(updateResources([user])); - dispatch(UserProfileGroupsActions.REQUEST_ITEMS()); - } catch (e) { - if (e.status === 404) { - await dispatch(propertiesActions.SET_PROPERTY({ key: IS_PROFILE_INACCESSIBLE, value: true })); - dispatch(reset(USER_PROFILE_FORM)); - } else { - dispatch(snackbarActions.OPEN_SNACKBAR({ - message: 'Could not load user profile', - kind: SnackbarKind.ERROR - })); + async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + // Reset isInacessible to ensure error screen is hidden + dispatch(propertiesActions.SET_PROPERTY({ key: IS_PROFILE_INACCESSIBLE, value: false })); + // Get user uuid from route or use current user uuid + const uuid = userUuid || getState().auth.user?.uuid; + if (uuid) { + await dispatch(propertiesActions.SET_PROPERTY({ key: USER_PROFILE_PANEL_ID, value: uuid })); + try { + const user = await services.userService.get(uuid, false, ["uuid", "first_name", "last_name", "email", "username", "prefs", "is_admin", "is_active"]); + dispatch(initialize(USER_PROFILE_FORM, user)); + dispatch(updateResources([user])); + dispatch(UserProfileGroupsActions.REQUEST_ITEMS()); + } catch (e) { + if (e.status === 404) { + await dispatch(propertiesActions.SET_PROPERTY({ key: IS_PROFILE_INACCESSIBLE, value: true })); + dispatch(reset(USER_PROFILE_FORM)); + } else { + dispatch(snackbarActions.OPEN_SNACKBAR({ + message: 'Could not load user profile', + kind: SnackbarKind.ERROR + })); + } + } } - } } - } export const saveEditedUser = (resource: any) => - async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { - try { - const user = await services.userService.update(resource.uuid, resource); - dispatch(updateResources([user])); - dispatch(initialize(USER_PROFILE_FORM, user)); - dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Profile has been updated.", hideDuration: 2000, kind: SnackbarKind.SUCCESS })); - } catch (e) { - dispatch(snackbarActions.OPEN_SNACKBAR({ - message: "Could not update profile", - kind: SnackbarKind.ERROR, - })); - } - }; + async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + try { + const user = await services.userService.update(resource.uuid, resource); + dispatch(updateResources([user])); + dispatch(initialize(USER_PROFILE_FORM, user)); + dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Profile has been updated.", hideDuration: 2000, kind: SnackbarKind.SUCCESS })); + } catch (e) { + dispatch(snackbarActions.OPEN_SNACKBAR({ + message: "Could not update profile", + kind: SnackbarKind.ERROR, + })); + } + }; export const openSetupDialog = (uuid: string) => - (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { - dispatch(dialogActions.OPEN_DIALOG({ - id: SETUP_DIALOG, - data: { - title: 'Setup user', - text: 'Are you sure you want to setup this user?', - confirmButtonLabel: 'Confirm', - uuid - } - })); - }; + (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + dispatch(dialogActions.OPEN_DIALOG({ + id: SETUP_DIALOG, + data: { + title: 'Setup user', + text: 'Are you sure you want to setup this user?', + confirmButtonLabel: 'Confirm', + uuid + } + })); + }; export const openActivateDialog = (uuid: string) => - (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { - dispatch(dialogActions.OPEN_DIALOG({ - id: ACTIVATE_DIALOG, - data: { - title: 'Activate user', - text: 'Are you sure you want to activate this user?', - confirmButtonLabel: 'Confirm', - uuid - } - })); - }; + (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + dispatch(dialogActions.OPEN_DIALOG({ + id: ACTIVATE_DIALOG, + data: { + title: 'Activate user', + text: 'Are you sure you want to activate this user?', + confirmButtonLabel: 'Confirm', + uuid + } + })); + }; export const openDeactivateDialog = (uuid: string) => - (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { - dispatch(dialogActions.OPEN_DIALOG({ - id: DEACTIVATE_DIALOG, - data: { - title: 'Deactivate user', - text: 'Are you sure you want to deactivate this user?', - confirmButtonLabel: 'Confirm', - uuid - } - })); - }; + (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + dispatch(dialogActions.OPEN_DIALOG({ + id: DEACTIVATE_DIALOG, + data: { + title: 'Deactivate user', + text: 'Are you sure you want to deactivate this user?', + confirmButtonLabel: 'Confirm', + uuid + } + })); + }; export const setup = (uuid: string) => - async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { - try { - const resources = await services.userService.setup(uuid); - dispatch(updateResources(resources.items)); - - // Refresh data explorer - dispatch(UserProfileGroupsActions.REQUEST_ITEMS()); - - dispatch(snackbarActions.OPEN_SNACKBAR({ message: "User has been setup", hideDuration: 2000, kind: SnackbarKind.SUCCESS })); - } catch (e) { - dispatch(snackbarActions.OPEN_SNACKBAR({ message: e.message, hideDuration: 2000, kind: SnackbarKind.ERROR })); - } finally { - dispatch(dialogActions.CLOSE_DIALOG({ id: SETUP_DIALOG })); - } - }; + async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + try { + const resources = await services.userService.setup(uuid); + dispatch(updateResources(resources.items)); + + // Refresh data explorer + dispatch(UserProfileGroupsActions.REQUEST_ITEMS()); + + dispatch(snackbarActions.OPEN_SNACKBAR({ message: "User has been setup", hideDuration: 2000, kind: SnackbarKind.SUCCESS })); + } catch (e) { + dispatch(snackbarActions.OPEN_SNACKBAR({ message: e.message, hideDuration: 2000, kind: SnackbarKind.ERROR })); + } finally { + dispatch(dialogActions.CLOSE_DIALOG({ id: SETUP_DIALOG })); + } + }; export const activate = (uuid: string) => - async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { - try { - const user = await services.userService.activate(uuid); - dispatch(updateResources([user])); + async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + try { + const user = await services.userService.activate(uuid); + dispatch(updateResources([user])); - // Refresh data explorer - dispatch(UserProfileGroupsActions.REQUEST_ITEMS()); + // Refresh data explorer + dispatch(UserProfileGroupsActions.REQUEST_ITEMS()); - dispatch(snackbarActions.OPEN_SNACKBAR({ message: "User has been activated", hideDuration: 2000, kind: SnackbarKind.SUCCESS })); - } catch (e) { - dispatch(snackbarActions.OPEN_SNACKBAR({ message: e.message, hideDuration: 2000, kind: SnackbarKind.ERROR })); - } - }; + dispatch(snackbarActions.OPEN_SNACKBAR({ message: "User has been activated", hideDuration: 2000, kind: SnackbarKind.SUCCESS })); + } catch (e) { + dispatch(snackbarActions.OPEN_SNACKBAR({ message: e.message, hideDuration: 2000, kind: SnackbarKind.ERROR })); + } + }; export const deactivate = (uuid: string) => - async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { - try { - const { resources, auth } = getState(); - // Call unsetup - const user = await services.userService.unsetup(uuid); - dispatch(updateResources([user])); - - // Find and remove all users membership - const allUsersGroupUuid = getBuiltinGroupUuid(auth.localCluster, BuiltinGroups.ALL); - const memberships = filterResources((resource: LinkResource) => - resource.kind === ResourceKind.LINK && - resource.linkClass === LinkClass.PERMISSION && - resource.headUuid === allUsersGroupUuid && - resource.tailUuid === uuid - )(resources); - // Remove all users membership locally - dispatch(deleteResources(memberships.map(link => link.uuid))); - - // Refresh data explorer - dispatch(UserProfileGroupsActions.REQUEST_ITEMS()); - - dispatch(snackbarActions.OPEN_SNACKBAR({ - message: "User has been deactivated.", - hideDuration: 2000, - kind: SnackbarKind.SUCCESS - })); - } catch (e) { - dispatch(snackbarActions.OPEN_SNACKBAR({ - message: "Could not deactivate user", - kind: SnackbarKind.ERROR, - })); - } - }; + async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + try { + const { resources, auth } = getState(); + // Call unsetup + const user = await services.userService.unsetup(uuid); + dispatch(updateResources([user])); + + // Find and remove all users membership + const allUsersGroupUuid = getBuiltinGroupUuid(auth.localCluster, BuiltinGroups.ALL); + const memberships = filterResources((resource: LinkResource) => + resource.kind === ResourceKind.LINK && + resource.linkClass === LinkClass.PERMISSION && + resource.headUuid === allUsersGroupUuid && + resource.tailUuid === uuid + )(resources); + // Remove all users membership locally + dispatch(deleteResources(memberships.map(link => link.uuid))); + + // Refresh data explorer + dispatch(UserProfileGroupsActions.REQUEST_ITEMS()); + + dispatch(snackbarActions.OPEN_SNACKBAR({ + message: "User has been deactivated.", + hideDuration: 2000, + kind: SnackbarKind.SUCCESS + })); + } catch (e) { + dispatch(snackbarActions.OPEN_SNACKBAR({ + message: "Could not deactivate user", + kind: SnackbarKind.ERROR, + })); + } + }; -- 2.30.2