-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(ui): unit tests for users tab and user profile icon component (#…
…15053) * unit test case of Users tab * unit test case of user profile icon component * added test case of userProfileIcon * code cleanup and add test case of user profile icon * minor fix * minor fix
- Loading branch information
1 parent
dcc91a8
commit d4ac43d
Showing
10 changed files
with
413 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
173 changes: 173 additions & 0 deletions
173
...ta-ui/src/main/resources/ui/src/components/Users/UserProfileIcon/UserProfileIcon.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
/* | ||
* Copyright 2024 Collate. | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
import { act, fireEvent, render, screen } from '@testing-library/react'; | ||
import userEvent from '@testing-library/user-event'; | ||
import React from 'react'; | ||
import { getImageWithResolutionAndFallback } from '../../../utils/ProfilerUtils'; | ||
import { useApplicationConfigContext } from '../../ApplicationConfigProvider/ApplicationConfigProvider'; | ||
import { useAuthContext } from '../../Auth/AuthProviders/AuthProvider'; | ||
import { mockPersonaData, mockUserData } from '../mocks/User.mocks'; | ||
import { UserProfileIcon } from './UserProfileIcon.component'; | ||
|
||
const mockLogout = jest.fn(); | ||
const mockUpdateSelectedPersona = jest.fn(); | ||
|
||
jest.mock('../../ApplicationConfigProvider/ApplicationConfigProvider', () => ({ | ||
useApplicationConfigContext: jest.fn().mockImplementation(() => ({ | ||
selectedPersona: {}, | ||
updateSelectedPersona: mockUpdateSelectedPersona, | ||
})), | ||
})); | ||
|
||
jest.mock('../../../utils/EntityUtils', () => ({ | ||
getEntityName: jest.fn().mockReturnValue('Test User'), | ||
})); | ||
|
||
jest.mock('../../../utils/ProfilerUtils', () => ({ | ||
getImageWithResolutionAndFallback: jest | ||
.fn() | ||
.mockImplementation(() => 'valid-image-url'), | ||
ImageQuality: jest.fn().mockReturnValue('6x'), | ||
})); | ||
|
||
jest.mock('../../common/AvatarComponent/Avatar', () => | ||
jest.fn().mockReturnValue(<div>Avatar</div>) | ||
); | ||
|
||
jest.mock('react-router-dom', () => ({ | ||
Link: jest | ||
.fn() | ||
.mockImplementation(({ children }: { children: React.ReactNode }) => ( | ||
<p data-testid="link">{children}</p> | ||
)), | ||
})); | ||
|
||
jest.mock('../../Auth/AuthProviders/AuthProvider', () => ({ | ||
useAuthContext: jest.fn(() => ({ | ||
currentUser: mockUserData, | ||
})), | ||
onLogoutHandler: mockLogout, | ||
})); | ||
|
||
describe('UserProfileIcon', () => { | ||
it('should render User Profile Icon', () => { | ||
const { getByTestId } = render(<UserProfileIcon />); | ||
|
||
expect(getByTestId('dropdown-profile')).toBeInTheDocument(); | ||
}); | ||
|
||
it('should display the user name', () => { | ||
const { getByText } = render(<UserProfileIcon />); | ||
|
||
expect(getByText('Test User')).toBeInTheDocument(); | ||
}); | ||
|
||
it('should display default in case of no persona is selected', () => { | ||
const { getByText } = render(<UserProfileIcon />); | ||
|
||
expect(getByText('label.default')).toBeInTheDocument(); | ||
}); | ||
|
||
it('should display image if profile pic is valid', () => { | ||
const { getByTestId } = render(<UserProfileIcon />); | ||
|
||
expect(getByTestId('app-bar-user-profile-pic')).toBeInTheDocument(); | ||
}); | ||
|
||
it('should not display profile pic if image url is invalid', () => { | ||
(getImageWithResolutionAndFallback as jest.Mock).mockImplementation( | ||
() => undefined | ||
); | ||
const { queryByTestId, getByText } = render(<UserProfileIcon />); | ||
|
||
expect(queryByTestId('app-bar-user-profile-pic')).not.toBeInTheDocument(); | ||
expect(getByText('Avatar')).toBeInTheDocument(); | ||
}); | ||
|
||
it('should display the user team', () => { | ||
(useApplicationConfigContext as jest.Mock).mockImplementation(() => ({ | ||
selectedPersona: { | ||
id: '3362fe18-05ad-4457-9632-84f22887dda6', | ||
type: 'team', | ||
}, | ||
updateSelectedPersona: jest.fn(), | ||
})); | ||
const { getByTestId } = render(<UserProfileIcon />); | ||
|
||
expect(getByTestId('default-persona')).toHaveTextContent('Test User'); | ||
}); | ||
|
||
it('should show empty placeholder when no teams data', async () => { | ||
(useAuthContext as jest.Mock).mockImplementation(() => ({ | ||
currentUser: { ...mockUserData, teams: [] }, | ||
onLogoutHandler: mockLogout, | ||
})); | ||
const teamLabels = screen.queryAllByText('label.team-plural'); | ||
|
||
teamLabels.forEach((label) => { | ||
expect(label).toHaveTextContent('--'); | ||
}); | ||
}); | ||
|
||
it('should show checked if selected persona is true', async () => { | ||
(useAuthContext as jest.Mock).mockImplementation(() => ({ | ||
currentUser: { | ||
...mockUserData, | ||
personas: mockPersonaData, | ||
}, | ||
onLogoutHandler: mockLogout, | ||
})); | ||
(useApplicationConfigContext as jest.Mock).mockImplementation(() => ({ | ||
selectedPersona: { | ||
id: '0430976d-092a-46c9-90a8-61c6091a6f38', | ||
type: 'persona', | ||
}, | ||
updateSelectedPersona: jest.fn(), | ||
})); | ||
const { getByTestId } = render(<UserProfileIcon />); | ||
await act(async () => { | ||
userEvent.click(getByTestId('dropdown-profile')); | ||
}); | ||
await act(async () => { | ||
fireEvent.click(getByTestId('persona-label')); | ||
}); | ||
|
||
expect(getByTestId('check-outlined')).toBeInTheDocument(); | ||
}); | ||
|
||
it('should not show checked if selected persona is true', async () => { | ||
(useAuthContext as jest.Mock).mockImplementation(() => ({ | ||
currentUser: { | ||
...mockUserData, | ||
personas: mockPersonaData, | ||
}, | ||
onLogoutHandler: mockLogout, | ||
})); | ||
(useApplicationConfigContext as jest.Mock).mockImplementation(() => ({ | ||
selectedPersona: { | ||
id: 'test', | ||
type: 'persona', | ||
}, | ||
updateSelectedPersona: jest.fn(), | ||
})); | ||
const { getByTestId, queryByTestId } = render(<UserProfileIcon />); | ||
await act(async () => { | ||
userEvent.click(getByTestId('dropdown-profile')); | ||
}); | ||
await act(async () => { | ||
fireEvent.click(getByTestId('persona-label')); | ||
}); | ||
|
||
expect(queryByTestId('check-outlined')).not.toBeInTheDocument(); | ||
}); | ||
}); |
124 changes: 124 additions & 0 deletions
124
openmetadata-ui/src/main/resources/ui/src/components/Users/UsersTab/UsersTab.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
/* | ||
* Copyright 2024 Collate. | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
import { act, fireEvent, render, screen } from '@testing-library/react'; | ||
import userEvent from '@testing-library/user-event'; | ||
import React from 'react'; | ||
import { MemoryRouter } from 'react-router-dom'; | ||
import { getUserById } from '../../../rest/userAPI'; | ||
import { mockUsersTabData } from '../mocks/User.mocks'; | ||
import { UsersTab } from './UsersTabs.component'; | ||
|
||
jest.mock('../../../rest/userAPI', () => ({ | ||
getUserById: jest | ||
.fn() | ||
.mockImplementation(() => Promise.resolve(mockUsersTabData)), | ||
})); | ||
|
||
jest.mock('../../common/PopOverCard/UserPopOverCard', () => | ||
jest.fn().mockReturnValue('Aaron Johnson') | ||
); | ||
jest.mock('react-router-dom', () => ({ | ||
Link: jest | ||
.fn() | ||
.mockImplementation(({ children }: { children: React.ReactNode }) => ( | ||
<p data-testid="link">{children}</p> | ||
)), | ||
useHistory: jest.fn(), | ||
})); | ||
|
||
const mockUsers = [ | ||
{ | ||
deleted: false, | ||
displayName: 'Aaron Johnson', | ||
fullyQualifiedName: 'aaron_johnson0', | ||
href: 'http://localhost:8585/api/v1/users/f281e7fd-5fd3-4279-8a2d-ade80febd743', | ||
id: 'f281e7fd-5fd3-4279-8a2d-ade80febd743', | ||
name: 'aaron_johnson0', | ||
type: 'user', | ||
}, | ||
]; | ||
|
||
const mockOnRemoveUser = jest.fn(); | ||
|
||
describe('UsersTab', () => { | ||
it('should renders Users Tab', async () => { | ||
await act(async () => { | ||
render(<UsersTab users={mockUsers} onRemoveUser={mockOnRemoveUser} />, { | ||
wrapper: MemoryRouter, | ||
}); | ||
}); | ||
|
||
expect(await screen.findByText('label.username')).toBeInTheDocument(); | ||
expect(await screen.findByText('label.team-plural')).toBeInTheDocument(); | ||
expect(await screen.findByText('label.role-plural')).toBeInTheDocument(); | ||
expect(await screen.findByText('label.action-plural')).toBeInTheDocument(); | ||
}); | ||
|
||
it('should display the user details', async () => { | ||
await act(async () => { | ||
render(<UsersTab users={mockUsers} onRemoveUser={mockOnRemoveUser} />, { | ||
wrapper: MemoryRouter, | ||
}); | ||
}); | ||
|
||
expect(await screen.findByText('Aaron Johnson')).toBeInTheDocument(); | ||
expect(await screen.findByText('Sales')).toBeInTheDocument(); | ||
expect(await screen.findByText('Data Steward')).toBeInTheDocument(); | ||
}); | ||
|
||
it('should render empty placeholder if no data', async () => { | ||
(getUserById as jest.Mock).mockImplementation(() => Promise.resolve([])), | ||
await act(async () => { | ||
render(<UsersTab users={[]} onRemoveUser={mockOnRemoveUser} />, { | ||
wrapper: MemoryRouter, | ||
}); | ||
}); | ||
|
||
expect( | ||
await screen.findByTestId('assign-error-placeholder-label.user') | ||
).toBeInTheDocument(); | ||
}); | ||
|
||
it('should display the remove confirmation modal when remove button is clicked', async () => { | ||
await act(async () => { | ||
render(<UsersTab users={mockUsers} onRemoveUser={mockOnRemoveUser} />, { | ||
wrapper: MemoryRouter, | ||
}); | ||
}); | ||
await act(async () => { | ||
fireEvent.click(screen.getByTestId('remove-user-btn')); | ||
}); | ||
|
||
expect( | ||
await screen.getByTestId('remove-confirmation-modal') | ||
).toBeInTheDocument(); | ||
}); | ||
|
||
it('should close the remove confirmation modal when cancel button is clicked', async () => { | ||
await act(async () => { | ||
render(<UsersTab users={mockUsers} onRemoveUser={mockOnRemoveUser} />, { | ||
wrapper: MemoryRouter, | ||
}); | ||
}); | ||
await act(async () => { | ||
userEvent.click(screen.getByTestId('remove-user-btn')); | ||
}); | ||
await act(async () => { | ||
userEvent.click(screen.getByText('label.cancel')); | ||
}); | ||
|
||
expect( | ||
screen.queryByTestId('remove-confirmation-modal') | ||
).not.toBeInTheDocument(); | ||
}); | ||
}); |
Oops, something went wrong.