From 024e19f97b3bd79a8e6062d3bce5fa0ba103e790 Mon Sep 17 00:00:00 2001 From: Ashish Gupta Date: Wed, 27 Mar 2024 11:52:00 +0530 Subject: [PATCH] fix reloading of user profile page on edit action perform (#15673) * fix reloading of user profile page on data change * supported unit test update handler in UserPage --- .../Settings/Users/Users.component.test.tsx | 80 +++++++- .../Settings/Users/Users.component.tsx | 6 +- .../Settings/Users/Users.interface.ts | 2 +- .../UserProfileDetails.component.tsx | 9 +- .../UserProfileDetails.interface.ts | 2 +- .../UserProfileDetails.test.tsx | 65 ++++++- .../UserProfileRoles.component.tsx | 17 +- .../UserProfileRoles.interface.ts | 2 +- .../UserProfileRoles.test.tsx | 31 ++- .../UserProfileTeams.component.tsx | 9 +- .../UserProfileTeams.interface.ts | 2 +- .../UserProfileTeams.test.tsx | 32 +++- .../PermissionProvider/PermissionProvider.tsx | 2 +- .../src/pages/UserPage/UserPage.component.tsx | 23 ++- .../ui/src/pages/UserPage/UserPage.test.tsx | 179 ++++++++---------- 15 files changed, 321 insertions(+), 140 deletions(-) diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/Users.component.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/Users.component.test.tsx index 872ad133d36..39f8f90d5b1 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/Users.component.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/Users.component.test.tsx @@ -74,9 +74,14 @@ jest.mock( jest.mock( '../../MyData/Persona/PersonaSelectableList/PersonaSelectableList.component', () => ({ - PersonaSelectableList: jest - .fn() - .mockReturnValue(

PersonaSelectableList

), + PersonaSelectableList: jest.fn().mockImplementation(({ onUpdate }) => ( +
+

PersonaSelectableList

+ +
+ )), }) ); @@ -133,16 +138,22 @@ jest.mock('../../PageLayoutV1/PageLayoutV1', () => ); jest.mock('../../common/EntityDescription/DescriptionV1', () => { - return jest.fn().mockReturnValue(

Description

); + return jest.fn().mockImplementation(({ onDescriptionUpdate }) => ( +
+ Description + +
+ )); }); -const updateUserDetails = jest.fn(); const mockProp = { queryFilters: { myData: 'my-data', following: 'following', }, - updateUserDetails, + updateUserDetails: jest.fn(), handlePaginate: jest.fn(), }; @@ -190,14 +201,69 @@ describe('Test User Component', () => { 'UserProfileInheritedRoles' ); const UserProfileRoles = await findByText(container, 'UserProfileRoles'); - const UserProfileTeams = await findByText(container, 'UserProfileTeams'); + const description = await findByText(container, 'Description'); + expect(description).toBeInTheDocument(); expect(UserProfileRoles).toBeInTheDocument(); expect(UserProfileTeams).toBeInTheDocument(); expect(UserProfileInheritedRoles).toBeInTheDocument(); }); + it('should call updateUserDetails on click of SaveDescriptionButton', async () => { + const { container } = render( + , + { + wrapper: MemoryRouter, + } + ); + + const collapsibleButton = await findByRole(container, 'img'); + + userEvent.click(collapsibleButton); + + const saveDescriptionButton = await findByText( + container, + 'SaveDescriptionButton' + ); + + userEvent.click(saveDescriptionButton); + + expect(mockProp.updateUserDetails).toHaveBeenCalledWith( + { + description: 'testDescription', + }, + 'description' + ); + }); + + it('should call updateUserDetails on click of SavePersonaSelectableListButton', async () => { + const { container } = render( + , + { + wrapper: MemoryRouter, + } + ); + + const collapsibleButton = await findByRole(container, 'img'); + + userEvent.click(collapsibleButton); + + const savePersonaSelectableListButton = await findByText( + container, + 'SavePersonaSelectableListButton' + ); + + userEvent.click(savePersonaSelectableListButton); + + expect(mockProp.updateUserDetails).toHaveBeenCalledWith( + { + personas: [], + }, + 'personas' + ); + }); + it('Tab should not visible to normal user', async () => { const { container } = render( , diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/Users.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/Users.component.tsx index 88ec28c07f5..14dc3ba29b7 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/Users.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/Users.component.tsx @@ -115,9 +115,9 @@ const Users = ({ userData, queryFilters, updateUserDetails }: Props) => { const handlePersonaUpdate = useCallback( async (personas: EntityReference[]) => { - await updateUserDetails({ ...userData, personas }); + await updateUserDetails({ personas }, 'personas'); }, - [updateUserDetails, userData] + [updateUserDetails] ); const tabDataRender = useCallback( @@ -232,7 +232,7 @@ const Users = ({ userData, queryFilters, updateUserDetails }: Props) => { const handleDescriptionChange = useCallback( async (description: string) => { - await updateUserDetails({ description }); + await updateUserDetails({ description }, 'description'); setIsDescriptionEdit(false); }, diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/Users.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/Users.interface.ts index dfb3135f497..e7089488181 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/Users.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/Users.interface.ts @@ -21,7 +21,7 @@ export interface Props { following: string; }; handlePaginate: (page: string | number) => void; - updateUserDetails: (data: Partial) => Promise; + updateUserDetails: (data: Partial, key: keyof User) => Promise; authenticationMechanism?: PersonalAccessToken; } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileDetails/UserProfileDetails.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileDetails/UserProfileDetails.component.tsx index ec90bf8658a..0bfccf33e8f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileDetails/UserProfileDetails.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileDetails/UserProfileDetails.component.tsx @@ -105,7 +105,10 @@ const UserProfileDetails = ({ const handleDisplayNameSave = useCallback(async () => { if (displayName !== userData.displayName) { setIsLoading(true); - await updateUserDetails({ displayName: displayName ?? '' }); + await updateUserDetails( + { displayName: displayName ?? '' }, + 'displayName' + ); setIsLoading(false); } setIsDisplayNameEdit(false); @@ -260,9 +263,9 @@ const UserProfileDetails = ({ const handleDefaultPersonaUpdate = useCallback( async (defaultPersona?: EntityReference) => { - await updateUserDetails({ ...userData, defaultPersona }); + await updateUserDetails({ defaultPersona }, 'defaultPersona'); }, - [updateUserDetails, userData] + [updateUserDetails] ); const defaultPersonaRender = useMemo( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileDetails/UserProfileDetails.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileDetails/UserProfileDetails.interface.ts index b4feb0ab295..f6a6f816858 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileDetails/UserProfileDetails.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileDetails/UserProfileDetails.interface.ts @@ -15,5 +15,5 @@ import { User } from '../../../../../generated/entity/teams/user'; export interface UserProfileDetailsProps { userData: User; - updateUserDetails: (data: Partial) => Promise; + updateUserDetails: (data: Partial, key: keyof User) => Promise; } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileDetails/UserProfileDetails.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileDetails/UserProfileDetails.test.tsx index 5ba0452a6b3..1036c315882 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileDetails/UserProfileDetails.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileDetails/UserProfileDetails.test.tsx @@ -10,7 +10,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { fireEvent, render, screen } from '@testing-library/react'; +import { act, fireEvent, render, screen } from '@testing-library/react'; import React from 'react'; import { MemoryRouter } from 'react-router-dom'; import { AuthProvider } from '../../../../../generated/settings/settings'; @@ -63,7 +63,15 @@ jest.mock('../UserProfileImage/UserProfileImage.component', () => { }); jest.mock('../../../../common/InlineEdit/InlineEdit.component', () => { - return jest.fn().mockReturnValue(

InlineEdit

); + return jest.fn().mockImplementation(({ onSave, children }) => ( +
+ InlineEdit + {children} + +
+ )); }); jest.mock('../../ChangePasswordForm', () => { @@ -73,9 +81,16 @@ jest.mock('../../ChangePasswordForm', () => { jest.mock( '../../../../MyData/Persona/PersonaSelectableList/PersonaSelectableList.component', () => ({ - PersonaSelectableList: jest - .fn() - .mockReturnValue(

PersonaSelectableList

), + PersonaSelectableList: jest.fn().mockImplementation(({ onUpdate }) => ( +
+ PersonaSelectableList + +
+ )), }) ); @@ -208,4 +223,44 @@ describe('Test User Profile Details Component', () => { expect(screen.getByText('InlineEdit')).toBeInTheDocument(); }); + + it('should call updateUserDetails on click of DisplayNameButton', async () => { + render(, { + wrapper: MemoryRouter, + }); + + act(() => { + fireEvent.click(screen.getByTestId('edit-displayName')); + }); + + expect(screen.getByText('InlineEdit')).toBeInTheDocument(); + + act(() => { + fireEvent.change(screen.getByTestId('displayName'), { + target: { value: 'test' }, + }); + }); + + act(() => { + fireEvent.click(screen.getByTestId('display-name-save-button')); + }); + + expect(mockPropsData.updateUserDetails).toHaveBeenCalledWith( + { displayName: 'test' }, + 'displayName' + ); + }); + + it('should call updateUserDetails on click of PersonaSaveButton', async () => { + render(, { + wrapper: MemoryRouter, + }); + + fireEvent.click(screen.getByTestId('persona-save-button')); + + expect(mockPropsData.updateUserDetails).toHaveBeenCalledWith( + { defaultPersona: USER_DATA.defaultPersona }, + 'defaultPersona' + ); + }); }); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileRoles/UserProfileRoles.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileRoles/UserProfileRoles.component.tsx index 1a4592d7fa4..e6a69c06fdc 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileRoles/UserProfileRoles.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileRoles/UserProfileRoles.component.tsx @@ -98,14 +98,17 @@ const UserProfileRoles = ({ const isAdmin = selectedRoles.find( (roleId) => roleId === toLower(TERM_ADMIN) ); - await updateUserDetails({ - roles: updatedRoles.map((roleId) => { - const role = roles.find((r) => r.id === roleId); + await updateUserDetails( + { + roles: updatedRoles.map((roleId) => { + const role = roles.find((r) => r.id === roleId); - return { id: roleId, type: 'role', name: role?.name ?? '' }; - }), - isAdmin: Boolean(isAdmin), - }); + return { id: roleId, type: 'role', name: role?.name ?? '' }; + }), + isAdmin: Boolean(isAdmin), + }, + 'roles' + ); setIsLoading(false); setIsRolesEdit(false); }; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileRoles/UserProfileRoles.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileRoles/UserProfileRoles.interface.ts index c288aa62d19..d92bfc26abb 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileRoles/UserProfileRoles.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileRoles/UserProfileRoles.interface.ts @@ -15,5 +15,5 @@ import { User } from '../../../../../generated/entity/teams/user'; export interface UserProfileRolesProps { isUserAdmin?: boolean; userRoles: User['roles']; - updateUserDetails: (data: Partial) => Promise; + updateUserDetails: (data: Partial, key: keyof User) => Promise; } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileRoles/UserProfileRoles.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileRoles/UserProfileRoles.test.tsx index 11db0b0e931..a0d4500691a 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileRoles/UserProfileRoles.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileRoles/UserProfileRoles.test.tsx @@ -11,7 +11,7 @@ * limitations under the License. */ -import { fireEvent, render, screen } from '@testing-library/react'; +import { act, fireEvent, render, screen } from '@testing-library/react'; import React from 'react'; import { useAuth } from '../../../../../hooks/authHooks'; import { getRoles } from '../../../../../rest/rolesAPIV1'; @@ -29,7 +29,14 @@ jest.mock('../../../../../hooks/authHooks', () => ({ })); jest.mock('../../../../common/InlineEdit/InlineEdit.component', () => { - return jest.fn().mockReturnValue(

InlineEdit

); + return jest.fn().mockImplementation(({ onSave }) => ( +
+ InlineEdit + +
+ )); }); jest.mock('../../../../common/Chip/Chip.component', () => { @@ -101,6 +108,26 @@ describe('Test User Profile Roles Component', () => { expect(screen.getByText('InlineEdit')).toBeInTheDocument(); }); + it('should call updateUserDetails on click save', async () => { + (useAuth as jest.Mock).mockImplementation(() => ({ + isAdminUser: true, + })); + render(); + + fireEvent.click(screen.getByTestId('edit-roles-button')); + + expect(screen.getByText('InlineEdit')).toBeInTheDocument(); + + act(() => { + fireEvent.click(screen.getByTestId('save')); + }); + + expect(mockPropsData.updateUserDetails).toHaveBeenCalledWith( + { roles: [], isAdmin: false }, + 'roles' + ); + }); + it('should call roles api on edit button action', async () => { (useAuth as jest.Mock).mockImplementation(() => ({ isAdminUser: true, diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileTeams/UserProfileTeams.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileTeams/UserProfileTeams.component.tsx index 707eaf14ceb..ffd74682fc0 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileTeams/UserProfileTeams.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileTeams/UserProfileTeams.component.tsx @@ -40,9 +40,12 @@ const UserProfileTeams = ({ const handleTeamsSave = async () => { setIsLoading(true); - await updateUserDetails({ - teams: selectedTeams.map((teamId) => ({ id: teamId.id, type: 'team' })), - }); + await updateUserDetails( + { + teams: selectedTeams.map((teamId) => ({ id: teamId.id, type: 'team' })), + }, + 'teams' + ); setIsLoading(false); setIsTeamsEdit(false); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileTeams/UserProfileTeams.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileTeams/UserProfileTeams.interface.ts index 8161d651940..3bfbf87771d 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileTeams/UserProfileTeams.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileTeams/UserProfileTeams.interface.ts @@ -14,5 +14,5 @@ import { User } from '../../../../../generated/entity/teams/user'; export interface UserProfileTeamsProps { teams: User['teams']; - updateUserDetails: (data: Partial) => Promise; + updateUserDetails: (data: Partial, key: keyof User) => Promise; } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileTeams/UserProfileTeams.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileTeams/UserProfileTeams.test.tsx index 701d1a60059..e9ead86f9b0 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileTeams/UserProfileTeams.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/UsersProfile/UserProfileTeams/UserProfileTeams.test.tsx @@ -11,7 +11,7 @@ * limitations under the License. */ -import { fireEvent, render, screen } from '@testing-library/react'; +import { act, fireEvent, render, screen } from '@testing-library/react'; import React from 'react'; import { useAuth } from '../../../../../hooks/authHooks'; import { USER_DATA, USER_TEAMS } from '../../../../../mocks/User.mock'; @@ -28,11 +28,18 @@ jest.mock('../../../../../hooks/authHooks', () => ({ })); jest.mock('../../../../../utils/CommonUtils', () => ({ - getNonDeletedTeams: jest.fn(), + getNonDeletedTeams: jest.fn().mockReturnValue([]), })); jest.mock('../../../../common/InlineEdit/InlineEdit.component', () => { - return jest.fn().mockReturnValue(

InlineEdit

); + return jest.fn().mockImplementation(({ onSave }) => ( +
+ InlineEdit + +
+ )); }); jest.mock('../../../../common/Chip/Chip.component', () => { @@ -74,6 +81,25 @@ describe('Test User Profile Teams Component', () => { expect(screen.getByText('InlineEdit')).toBeInTheDocument(); }); + it('should call updateUserDetails on click save', async () => { + render(); + + const editButton = screen.getByTestId('edit-teams-button'); + + fireEvent.click(editButton); + + expect(screen.getByText('InlineEdit')).toBeInTheDocument(); + + act(() => { + fireEvent.click(screen.getByTestId('save')); + }); + + expect(mockPropsData.updateUserDetails).toHaveBeenCalledWith( + { teams: [] }, + 'teams' + ); + }); + it('should not render edit button to non admin user', async () => { (useAuth as jest.Mock).mockImplementation(() => ({ isAdminUser: false, diff --git a/openmetadata-ui/src/main/resources/ui/src/context/PermissionProvider/PermissionProvider.tsx b/openmetadata-ui/src/main/resources/ui/src/context/PermissionProvider/PermissionProvider.tsx index 2f8bac19767..f751b787c54 100644 --- a/openmetadata-ui/src/main/resources/ui/src/context/PermissionProvider/PermissionProvider.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/context/PermissionProvider/PermissionProvider.tsx @@ -180,7 +180,7 @@ const PermissionProvider: FC = ({ children }) => { if (isEmpty(currentUser)) { resetPermissions(); } - }, [currentUser]); + }, [currentUser?.teams, currentUser?.roles]); const contextValues = useMemo( () => ({ diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/UserPage/UserPage.component.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/UserPage/UserPage.component.tsx index 044514b974c..1c6561caf73 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/UserPage/UserPage.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/UserPage/UserPage.component.tsx @@ -14,7 +14,7 @@ import { Typography } from 'antd'; import { AxiosError } from 'axios'; import { compare } from 'fast-json-patch'; -import { isEmpty } from 'lodash'; +import { isEmpty, isUndefined } from 'lodash'; import Qs from 'qs'; import { default as React, @@ -104,17 +104,30 @@ const UserPage = () => { }; const updateUserDetails = useCallback( - async (data: Partial) => { + async (data: Partial, key: keyof User) => { const updatedDetails = { ...userData, ...data }; const jsonPatch = compare(userData, updatedDetails); try { const response = await updateUserDetail(userData.id, jsonPatch); if (response) { - if (userData.id === currentUser?.id) { - updateCurrentUser(response); + const newCurrentUserData = { + ...currentUser, + [key]: response[key], + }; + const newUserData = { ...userData, [key]: response[key] }; + + if (key === 'defaultPersona') { + if (isUndefined(response.defaultPersona)) { + // remove key from object if value is undefined + delete newCurrentUserData[key]; + delete newUserData[key]; + } } - setUserData((prev) => ({ ...prev, ...response })); + if (userData.id === currentUser?.id) { + updateCurrentUser(newCurrentUserData as User); + } + setUserData(newUserData); } else { throw t('message.unexpected-error'); } diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/UserPage/UserPage.test.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/UserPage/UserPage.test.tsx index 2e818c86d40..436d9a71b6c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/UserPage/UserPage.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/UserPage/UserPage.test.tsx @@ -11,104 +11,32 @@ * limitations under the License. */ -import { findByTestId, findByText, render } from '@testing-library/react'; +import { + act, + findByTestId, + findByText, + fireEvent, + render, + screen, +} from '@testing-library/react'; import React from 'react'; import { MemoryRouter } from 'react-router-dom'; -import { EntityType } from '../../enums/entity.enum'; -import { getUserByName } from '../../rest/userAPI'; +import { useApplicationStore } from '../../hooks/useApplicationStore'; +import { USER_DATA } from '../../mocks/User.mock'; +import { getUserByName, updateUserDetail } from '../../rest/userAPI'; import UserPage from './UserPage.component'; -const mockUserData = { - id: 'd6764107-e8b4-4748-b256-c86fecc66064', - name: 'xyz', - displayName: 'XYZ', - version: 0.1, - updatedAt: 1648704499857, - updatedBy: 'xyz', - email: 'xyz@gmail.com', - href: 'http://localhost:8585/api/v1/users/d6764107-e8b4-4748-b256-c86fecc66064', - isAdmin: false, - domain: { - id: '303ca53b-5050-4caa-9c4e-d4fdada76a53', - type: EntityType.DOMAIN, - name: 'Engineering', - fullyQualifiedName: 'Engineering', - description: 'description', - inherited: true, - href: 'http://localhost:8585/api/v1/domains/303ca53b-5050-4caa-9c4e-d4fdada76a53', - }, - profile: { - images: { - image: - 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s96-c', - image24: - 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s24-c', - image32: - 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s32-c', - image48: - 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s48-c', - image72: - 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s72-c', - image192: - 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s192-c', - image512: - 'https://lh3.googleusercontent.com/a-/AOh14Gh8NPux8jEPIuyPWOxAB1od9fGN188Kcp5HeXgc=s512-c', - }, - }, - teams: [ - { - id: '3362fe18-05ad-4457-9632-84f22887dda6', - type: 'team', - name: 'Finance', - description: 'This is Finance description.', - displayName: 'Finance', - deleted: false, - href: 'http://localhost:8585/api/v1/teams/3362fe18-05ad-4457-9632-84f22887dda6', - }, - { - id: '5069ddd4-d47e-4b2c-a4c4-4c849b97b7f9', - type: 'team', - name: 'Data_Platform', - description: 'This is Data_Platform description.', - displayName: 'Data_Platform', - deleted: false, - href: 'http://localhost:8585/api/v1/teams/5069ddd4-d47e-4b2c-a4c4-4c849b97b7f9', - }, - { - id: '7182cc43-aebc-419d-9452-ddbe2fc4e640', - type: 'team', - name: 'Customer_Support', - description: 'This is Customer_Support description.', - displayName: 'Customer_Support', - deleted: false, - href: 'http://localhost:8585/api/v1/teams/7182cc43-aebc-419d-9452-ddbe2fc4e640', - }, - ], - owns: [], - follows: [], - deleted: false, - roles: [ - { - id: 'ce4df2a5-aaf5-4580-8556-254f42574aa7', - type: 'role', - name: 'DataConsumer', - description: - 'Users with Data Consumer role use different data assets for their day to day work.', - displayName: 'Data Consumer', - deleted: false, - href: 'http://localhost:8585/api/v1/roles/ce4df2a5-aaf5-4580-8556-254f42574aa7', - }, - ], -}; - jest.mock('../../components/MyData/LeftSidebar/LeftSidebar.component', () => jest.fn().mockReturnValue(

Sidebar

) ); +const mockUpdateCurrentUser = jest.fn(); + jest.mock('../../hooks/useApplicationStore', () => { return { useApplicationStore: jest.fn(() => ({ - isAuthDisabled: true, + currentUser: USER_DATA, + updateCurrentUser: mockUpdateCurrentUser, })), }; }); @@ -124,20 +52,26 @@ jest.mock('../../components/common/Loader/Loader', () => { }); jest.mock('../../components/Settings/Users/Users.component', () => { - return jest.fn().mockReturnValue(

User Component

); + return jest.fn().mockImplementation(({ updateUserDetails }) => ( +
+

User Component

+ +
+ )); }); jest.mock('../../rest/userAPI', () => ({ - getUserByName: jest + getUserByName: jest.fn().mockImplementation(() => Promise.resolve(USER_DATA)), + updateUserDetail: jest .fn() - .mockImplementation(() => Promise.resolve({ data: mockUserData })), -})); - -jest.mock('../../rest/userAPI', () => ({ - getUserByName: jest - .fn() - .mockImplementation(() => Promise.resolve({ data: mockUserData })), - updateUserDetail: jest.fn(), + .mockImplementation(() => + Promise.resolve({ ...USER_DATA, defaultPersona: undefined }) + ), })); jest.mock('../../rest/feedsAPI', () => ({ @@ -176,4 +110,55 @@ describe('Test the User Page', () => { expect(errorPlaceholder).toBeInTheDocument(); }); + + it('Should call and update state data with patch api for defaultPersona', async () => { + const userData = { ...USER_DATA }; + delete userData.defaultPersona; + + await act(async () => { + render(, { wrapper: MemoryRouter }); + }); + + await act(async () => { + fireEvent.click(screen.getByText('UserComponentSaveButton')); + }); + + expect(updateUserDetail).toHaveBeenCalledWith(USER_DATA.id, [ + { + op: 'remove', + path: '/defaultPersona', + }, + ]); + + expect(mockUpdateCurrentUser).toHaveBeenCalledWith(userData); + }); + + it('Should call updateCurrentUser if user is currentUser logged in', async () => { + await act(async () => { + render(, { wrapper: MemoryRouter }); + }); + + await act(async () => { + fireEvent.click(screen.getByText('UserComponentSaveButton')); + }); + + expect(mockUpdateCurrentUser).toHaveBeenCalled(); + }); + + it('Should not call updateCurrentUser if user is not currentUser logged in', async () => { + (useApplicationStore as unknown as jest.Mock).mockImplementation(() => ({ + currentUser: { ...USER_DATA, id: '123' }, + updateCurrentUser: mockUpdateCurrentUser, + })); + + await act(async () => { + render(, { wrapper: MemoryRouter }); + }); + + await act(async () => { + fireEvent.click(screen.getByText('UserComponentSaveButton')); + }); + + expect(mockUpdateCurrentUser).not.toHaveBeenCalled(); + }); });