From e14d06503ebb292fb81d5bd453eedc9d2697dcfa Mon Sep 17 00:00:00 2001 From: Ashish Gupta Date: Wed, 18 Jan 2023 12:22:11 +0530 Subject: [PATCH] UI : Added Flag to exclude bot from user search (#9766) * Added Flag to exclude bot from user search * added cypress and remove unwanted code * changes as per comments * remove unwanted code --- .../ui/cypress/e2e/Pages/Users.spec.js | 26 +++ .../components/UserList/UserListV1.test.tsx | 165 ++++++++++++++++++ .../ui/src/components/UserList/UserListV1.tsx | 6 +- .../src/pages/UserListPage/UserListPageV1.tsx | 2 +- 4 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 openmetadata-ui/src/main/resources/ui/src/components/UserList/UserListV1.test.tsx diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Users.spec.js b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Users.spec.js index ee2b9b43d9a..8731294ffbb 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Users.spec.js +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/Users.spec.js @@ -27,6 +27,28 @@ const userEmail = `${userName}@gmail.com`; const adminName = `Admincttest${uuid()}`; const adminEmail = `${adminName}@gmail.com`; +const searchBotText = 'bot'; + +const searchBotUser = () => { + // Search the bot user + interceptURL( + 'GET', + `/api/v1/search/query?q=*${searchBotText}***(isBot:false)&from=0&size=15&index=user_search_index`, + 'searchUser' + ); + cy.get('[data-testid="searchbar"]') + .should('exist') + .should('be.visible') + .type(searchBotText); + + verifyResponseStatusCode('@searchUser', 200); + + cy.get('.ant-table-placeholder > .ant-table-cell').should( + 'not.contain', + searchBotText + ); +}; + describe('Users flow should work properly', () => { beforeEach(() => { cy.login(); @@ -75,6 +97,10 @@ describe('Users flow should work properly', () => { softDeleteUser(userName); deleteSoftDeletedUser(userName); }); + + it('Search bot user', () => { + searchBotUser(); + }); }); describe('Admin flow should work properly', () => { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/UserList/UserListV1.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/UserList/UserListV1.test.tsx new file mode 100644 index 00000000000..7f05afa6f22 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/components/UserList/UserListV1.test.tsx @@ -0,0 +1,165 @@ +/* + * Copyright 2022 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 { cleanup, render, screen } from '@testing-library/react'; +import { MOCK_USER_DATA } from 'pages/UserListPage/mockUserData'; +import React from 'react'; +import { MemoryRouter } from 'react-router-dom'; +import { act } from 'react-test-renderer'; +import UserListV1 from './UserListV1'; + +jest.mock('rest/userAPI', () => ({ + updateUser: jest.fn().mockImplementation(() => Promise.resolve()), +})); + +jest.mock('../../generated/api/teams/createUser', () => ({ + CreateUser: jest.fn().mockImplementation(() => Promise.resolve()), +})); + +jest.mock('../../utils/ToastUtils', () => ({ + showErrorToast: jest.fn(), + showSuccessToast: jest.fn(), +})); + +jest.mock('../common/DeleteWidget/DeleteWidgetModal', () => { + return jest.fn().mockImplementation(() =>
DeleteWidgetModal
); +}); + +jest.mock('../common/error-with-placeholder/ErrorPlaceHolder', () => { + return jest.fn().mockImplementation(() =>
ErrorPlaceHolder
); +}); + +jest.mock('../common/next-previous/NextPrevious', () => { + return jest.fn().mockImplementation(() =>
NextPrevious
); +}); + +jest.mock('../header/PageHeader.component', () => { + return jest.fn().mockImplementation(() =>
PageHeader
); +}); + +jest.mock('../Loader/Loader', () => { + return jest.fn().mockImplementation(() =>
Loader
); +}); + +jest.mock('../common/searchbar/Searchbar', () => { + return jest + .fn() + .mockImplementation((prop) => ( + prop.onSearch(e.target.value)} + /> + )); +}); + +const mockFunction = jest.fn(); + +const MOCK_PROPS_DATA = { + data: MOCK_USER_DATA.data, + paging: MOCK_USER_DATA.paging, + searchTerm: '', + currentPage: 1, + isDataLoading: false, + showDeletedUser: false, + onSearch: mockFunction, + onShowDeletedUserChange: mockFunction, + onPagingChange: mockFunction, + afterDeleteAction: mockFunction, + isAdminPage: false, +}; + +describe('Test UserListV1 component', () => { + beforeEach(() => { + cleanup(); + }); + + it('should render component', async () => { + await act(async () => { + render(, { + wrapper: MemoryRouter, + }); + }); + + const userListComponent = await screen.findByTestId( + 'user-list-v1-component' + ); + const pageHeader = await screen.findByText('PageHeader'); + + expect(userListComponent).toBeInTheDocument(); + expect(pageHeader).toBeInTheDocument(); + }); + + it('should render ErrorPlaceHolder', async () => { + await act(async () => { + render(, { + wrapper: MemoryRouter, + }); + }); + + const emptyComponent = await screen.findByText('ErrorPlaceHolder'); + + expect(emptyComponent).toBeInTheDocument(); + }); + + it('should render Users table', async () => { + await act(async () => { + render(, { + wrapper: MemoryRouter, + }); + }); + + const userListComponent = await screen.findByTestId( + 'user-list-v1-component' + ); + + expect(userListComponent).toBeInTheDocument(); + + const table = await screen.findByTestId('user-list-table'); + + expect(table).toBeInTheDocument(); + + const userName = await screen.findByText('label.username'); + const teams = await screen.findByText('label.team-plural'); + const role = await screen.findByText('label.role-plural'); + + expect(userName).toBeInTheDocument(); + expect(teams).toBeInTheDocument(); + expect(role).toBeInTheDocument(); + + const rows = await screen.findAllByRole('row'); + + expect(rows).toHaveLength(MOCK_PROPS_DATA.data.length + 1); + }); + + it('Should not render data when bot is search', async () => { + await act(async () => { + render(, { + wrapper: MemoryRouter, + }); + }); + + const userListComponent = await screen.findByTestId( + 'user-list-v1-component' + ); + + expect(userListComponent).toBeInTheDocument(); + + const table = await screen.findByTestId('user-list-table'); + + const noDataTable = await screen.findByText('No data'); + + expect(table).toBeInTheDocument(); + expect(noDataTable).toBeInTheDocument(); + }); +}); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/UserList/UserListV1.tsx b/openmetadata-ui/src/main/resources/ui/src/components/UserList/UserListV1.tsx index 53a3ff061ac..90f5ecca03c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/UserList/UserListV1.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/UserList/UserListV1.tsx @@ -220,7 +220,10 @@ const UserListV1: FC = ({ } return ( - + = ({ bordered className="user-list-table" columns={columns} + data-testid="user-list-table" dataSource={data} loading={{ spinning: isDataLoading, diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/UserListPage/UserListPageV1.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/UserListPage/UserListPageV1.tsx index 5166b7a3985..1d62ccc2269 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/UserListPage/UserListPageV1.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/UserListPage/UserListPageV1.tsx @@ -102,7 +102,7 @@ const UserListPageV1 = () => { isAdmin = false, isDeleted = false ) => { - let filters = ''; + let filters = '(isBot:false)'; if (isAdmin) { filters = '(isAdmin:true)'; }