mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-12-24 14:08:45 +00:00
unit test for DataInsightHeader and DataModelPage components (#15076)
* added unit test for DataInsightHeader componnet * added unit test for DataModelPage component
This commit is contained in:
parent
38f24fc363
commit
fc052f9be5
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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 { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
import { ROUTES } from '../../../constants/constants';
|
||||
import DataInsightHeader from './DataInsightHeader.component';
|
||||
|
||||
const mockPush = jest.fn();
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
useHistory: jest.fn().mockImplementation(() => ({
|
||||
push: mockPush,
|
||||
})),
|
||||
useParams: jest.fn(() => ({ tab: 'tab' })),
|
||||
}));
|
||||
|
||||
jest.mock('../../../components/DataInsightDetail/DataInsightSummary', () =>
|
||||
jest.fn(() => <div>DataInsightSummary</div>)
|
||||
);
|
||||
|
||||
jest.mock('../../../components/DataInsightDetail/KPIChart', () =>
|
||||
jest.fn(() => <div>KPIChart</div>)
|
||||
);
|
||||
|
||||
jest.mock('../../../components/DatePickerMenu/DatePickerMenu.component', () =>
|
||||
jest.fn(() => <div>DatePickerMenu</div>)
|
||||
);
|
||||
|
||||
jest.mock('../../../components/PermissionProvider/PermissionProvider', () => ({
|
||||
usePermissionProvider: jest.fn(() => ({
|
||||
permissions: {},
|
||||
})),
|
||||
}));
|
||||
|
||||
jest.mock('../../../components/SearchDropdown/SearchDropdown', () =>
|
||||
jest.fn(() => <div>SearchDropdown</div>)
|
||||
);
|
||||
|
||||
jest.mock('../../../utils/DataInsightUtils', () => ({
|
||||
getOptionalDataInsightTabFlag: jest.fn(() => ({
|
||||
showDataInsightSummary: true,
|
||||
showKpiChart: true,
|
||||
})),
|
||||
}));
|
||||
|
||||
jest.mock('../../../utils/date-time/DateTimeUtils', () => ({
|
||||
formatDate: jest.fn().mockReturnValue('formattedDate'),
|
||||
}));
|
||||
|
||||
jest.mock('../../../utils/PermissionsUtils', () => ({
|
||||
checkPermission: jest.fn().mockReturnValue(true),
|
||||
}));
|
||||
|
||||
jest.mock('../DataInsightProvider', () => ({
|
||||
useDataInsightProvider: jest
|
||||
.fn()
|
||||
.mockReturnValue({ chartFilter: {}, kpi: {} }),
|
||||
}));
|
||||
|
||||
const mockProps = {
|
||||
onScrollToChart: jest.fn(),
|
||||
};
|
||||
|
||||
describe('DataInsightHeader component', () => {
|
||||
it('should render all necessary elements', () => {
|
||||
render(<DataInsightHeader {...mockProps} />);
|
||||
|
||||
expect(screen.getByText('label.data-insight-plural')).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText('message.data-insight-subtitle')
|
||||
).toBeInTheDocument();
|
||||
|
||||
userEvent.click(
|
||||
screen.getByRole('button', {
|
||||
name: 'label.add-entity',
|
||||
})
|
||||
);
|
||||
|
||||
expect(mockPush).toHaveBeenCalledWith(ROUTES.ADD_KPI);
|
||||
|
||||
expect(screen.getAllByText('SearchDropdown')).toHaveLength(2);
|
||||
expect(
|
||||
screen.getByText('formattedDate - formattedDate')
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText('DatePickerMenu')).toBeInTheDocument();
|
||||
expect(screen.getByText('DataInsightSummary')).toBeInTheDocument();
|
||||
expect(screen.getByText('KPIChart')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,332 @@
|
||||
/*
|
||||
* 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,
|
||||
render,
|
||||
screen,
|
||||
waitForElementToBeRemoved,
|
||||
} from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
import { mockUserData } from '../../components/Users/mocks/User.mocks';
|
||||
import DataModelsPage from './DataModelPage.component';
|
||||
import {
|
||||
CREATE_THREAD,
|
||||
DATA_MODEL_DELETED,
|
||||
ERROR,
|
||||
ERROR_PLACEHOLDER,
|
||||
FETCH_ENTITY_PERMISSION_ERROR,
|
||||
FOLLOW_DATA_MODEL,
|
||||
TOGGLE_DELETE,
|
||||
UPDATE_DATA_MODEL,
|
||||
UPDATE_VOTE,
|
||||
} from './mocks/DataModelPage.mock';
|
||||
|
||||
const mockAddDataModelFollower = jest.fn().mockResolvedValue({});
|
||||
const mockGetDataModelByFqn = jest.fn().mockResolvedValue({});
|
||||
const mockPatchDataModelDetails = jest.fn().mockResolvedValue({});
|
||||
const mockRemoveDataModelFollower = jest.fn().mockResolvedValue({});
|
||||
const mockUpdateDataModelVotes = jest.fn().mockResolvedValue({});
|
||||
const mockPostThread = jest.fn().mockResolvedValue({});
|
||||
const mockGetEntityPermissionByFqn = jest.fn().mockResolvedValue({
|
||||
ViewAll: true,
|
||||
ViewBasic: true,
|
||||
});
|
||||
const mockUpdateTierTag = jest.fn();
|
||||
const mockShowErrorToast = jest.fn();
|
||||
const ENTITY_MISSING_ERROR = 'Entity missing error.';
|
||||
|
||||
jest.mock('../../components/Auth/AuthProviders/AuthProvider', () => ({
|
||||
useAuthContext: jest.fn(() => ({
|
||||
currentUser: mockUserData,
|
||||
})),
|
||||
}));
|
||||
|
||||
jest.mock('../../components/common/ErrorWithPlaceholder/ErrorPlaceHolder', () =>
|
||||
jest.fn().mockImplementation(() => <div>{ERROR_PLACEHOLDER}</div>)
|
||||
);
|
||||
|
||||
jest.mock('../../components/DataModels/DataModelDetails.component', () =>
|
||||
jest
|
||||
.fn()
|
||||
.mockImplementation(
|
||||
({
|
||||
createThread,
|
||||
dataModelData,
|
||||
handleColumnUpdateDataModel,
|
||||
handleFollowDataModel,
|
||||
handleToggleDelete,
|
||||
handleUpdateDescription,
|
||||
handleUpdateOwner,
|
||||
handleUpdateTags,
|
||||
handleUpdateTier,
|
||||
onUpdateDataModel,
|
||||
onUpdateVote,
|
||||
}) => (
|
||||
<div>
|
||||
DataModelDetails
|
||||
<p>{dataModelData.deleted ? DATA_MODEL_DELETED : ''}</p>
|
||||
<button onClick={createThread}>{CREATE_THREAD}</button>
|
||||
<button
|
||||
onClick={() => {
|
||||
handleColumnUpdateDataModel();
|
||||
handleUpdateDescription();
|
||||
handleUpdateOwner();
|
||||
handleUpdateTags();
|
||||
handleUpdateTier();
|
||||
onUpdateDataModel();
|
||||
}}>
|
||||
{UPDATE_DATA_MODEL}
|
||||
</button>
|
||||
<button onClick={handleFollowDataModel}>{FOLLOW_DATA_MODEL}</button>
|
||||
<button onClick={onUpdateVote}>{UPDATE_VOTE}</button>
|
||||
<button onClick={handleToggleDelete}>{TOGGLE_DELETE}</button>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
jest.mock('../../components/Loader/Loader', () =>
|
||||
jest.fn().mockImplementation(() => <div>Loader</div>)
|
||||
);
|
||||
|
||||
jest.mock('../../components/PermissionProvider/PermissionProvider', () => ({
|
||||
usePermissionProvider: jest.fn().mockReturnValue({
|
||||
getEntityPermissionByFqn: jest.fn(() => mockGetEntityPermissionByFqn()),
|
||||
}),
|
||||
}));
|
||||
|
||||
jest.mock('../../hooks/useFqn', () => ({
|
||||
useFqn: jest.fn().mockImplementation(() => ({ fqn: 'testFqn' })),
|
||||
}));
|
||||
|
||||
jest.mock('../../rest/dataModelsAPI', () => ({
|
||||
addDataModelFollower: () => mockAddDataModelFollower(),
|
||||
getDataModelByFqn: () => mockGetDataModelByFqn(),
|
||||
patchDataModelDetails: () => mockPatchDataModelDetails(),
|
||||
removeDataModelFollower: () => mockRemoveDataModelFollower(),
|
||||
updateDataModelVotes: () => mockUpdateDataModelVotes(),
|
||||
}));
|
||||
|
||||
jest.mock('../../rest/feedsAPI', () => ({
|
||||
postThread: () => mockPostThread(),
|
||||
}));
|
||||
|
||||
jest.mock('../../utils/CommonUtils', () => ({
|
||||
getEntityMissingError: jest.fn(() => ENTITY_MISSING_ERROR),
|
||||
sortTagsCaseInsensitive: jest.fn((tags) => tags),
|
||||
}));
|
||||
|
||||
jest.mock('../../utils/DataModelsUtils', () => ({
|
||||
getSortedDataModelColumnTags: jest.fn().mockImplementation((tags) => tags),
|
||||
}));
|
||||
|
||||
jest.mock('../../utils/TableUtils', () => {
|
||||
return {
|
||||
getTierTags: jest.fn().mockImplementation((tags) => tags),
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('../../utils/TagsUtils', () => ({
|
||||
updateTierTag: () => mockUpdateTierTag(),
|
||||
}));
|
||||
|
||||
jest.mock('../../utils/ToastUtils', () => ({
|
||||
showErrorToast: jest.fn((...args) => mockShowErrorToast(...args)),
|
||||
}));
|
||||
|
||||
jest.mock('fast-json-patch', () => ({
|
||||
...jest.requireActual('fast-json-patch'),
|
||||
compare: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('DataModelPage component', () => {
|
||||
it('should render necessary elements', async () => {
|
||||
render(<DataModelsPage />);
|
||||
await waitForElementToBeRemoved(() => screen.getByText('Loader'));
|
||||
|
||||
expect(mockGetDataModelByFqn).toHaveBeenCalled();
|
||||
expect(screen.getByText('DataModelDetails')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('toggle delete action check', async () => {
|
||||
render(<DataModelsPage />);
|
||||
await waitForElementToBeRemoved(() => screen.getByText('Loader'));
|
||||
|
||||
// toggle delete
|
||||
await act(async () => {
|
||||
userEvent.click(
|
||||
screen.getByRole('button', {
|
||||
name: TOGGLE_DELETE,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
expect(screen.getByText(DATA_MODEL_DELETED)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('follow data model action check', async () => {
|
||||
render(<DataModelsPage />);
|
||||
await waitForElementToBeRemoved(() => screen.getByText('Loader'));
|
||||
|
||||
// follow data model
|
||||
act(() => {
|
||||
userEvent.click(
|
||||
screen.getByRole('button', {
|
||||
name: FOLLOW_DATA_MODEL,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
expect(mockAddDataModelFollower).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('unfollow data model action check', async () => {
|
||||
mockGetDataModelByFqn.mockResolvedValueOnce({
|
||||
followers: [
|
||||
{
|
||||
id: mockUserData.id,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
render(<DataModelsPage />);
|
||||
await waitForElementToBeRemoved(() => screen.getByText('Loader'));
|
||||
|
||||
// unfollow data model
|
||||
await act(async () => {
|
||||
userEvent.click(
|
||||
screen.getByRole('button', {
|
||||
name: FOLLOW_DATA_MODEL,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
expect(mockRemoveDataModelFollower).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('create thread action checks', async () => {
|
||||
render(<DataModelsPage />);
|
||||
await waitForElementToBeRemoved(() => screen.getByText('Loader'));
|
||||
|
||||
// create thread
|
||||
userEvent.click(
|
||||
screen.getByRole('button', {
|
||||
name: CREATE_THREAD,
|
||||
})
|
||||
);
|
||||
|
||||
expect(mockPostThread).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('update data model action check', async () => {
|
||||
render(<DataModelsPage />);
|
||||
await waitForElementToBeRemoved(() => screen.getByText('Loader'));
|
||||
|
||||
// update data model
|
||||
await act(async () => {
|
||||
userEvent.click(
|
||||
screen.getByRole('button', {
|
||||
name: UPDATE_DATA_MODEL,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
expect(mockPatchDataModelDetails).toHaveBeenCalledTimes(6);
|
||||
});
|
||||
|
||||
it('update vote action check', async () => {
|
||||
render(<DataModelsPage />);
|
||||
await waitForElementToBeRemoved(() => screen.getByText('Loader'));
|
||||
|
||||
// update vote
|
||||
await act(async () => {
|
||||
userEvent.click(
|
||||
screen.getByRole('button', {
|
||||
name: UPDATE_VOTE,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
expect(mockUpdateDataModelVotes).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('errors check', async () => {
|
||||
mockPostThread.mockRejectedValueOnce(ERROR);
|
||||
mockPatchDataModelDetails.mockRejectedValue(ERROR);
|
||||
mockAddDataModelFollower.mockRejectedValueOnce(ERROR);
|
||||
mockUpdateDataModelVotes.mockRejectedValueOnce(ERROR);
|
||||
|
||||
await act(async () => {
|
||||
render(<DataModelsPage />);
|
||||
});
|
||||
|
||||
// create thread
|
||||
userEvent.click(
|
||||
screen.getByRole('button', {
|
||||
name: CREATE_THREAD,
|
||||
})
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
// update data model
|
||||
userEvent.click(
|
||||
screen.getByRole('button', {
|
||||
name: UPDATE_DATA_MODEL,
|
||||
})
|
||||
);
|
||||
|
||||
// follow data model
|
||||
userEvent.click(
|
||||
screen.getByRole('button', {
|
||||
name: FOLLOW_DATA_MODEL,
|
||||
})
|
||||
);
|
||||
|
||||
// update vote
|
||||
userEvent.click(
|
||||
screen.getByRole('button', {
|
||||
name: UPDATE_VOTE,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
expect(mockShowErrorToast).toHaveBeenCalledTimes(9);
|
||||
|
||||
mockPatchDataModelDetails.mockResolvedValue({});
|
||||
});
|
||||
|
||||
it('error when rendering component', async () => {
|
||||
mockGetEntityPermissionByFqn.mockRejectedValueOnce(ERROR);
|
||||
|
||||
await act(async () => {
|
||||
render(<DataModelsPage />);
|
||||
});
|
||||
|
||||
expect(screen.getByText(ERROR_PLACEHOLDER)).toBeInTheDocument();
|
||||
expect(mockShowErrorToast).toHaveBeenCalledWith(
|
||||
FETCH_ENTITY_PERMISSION_ERROR
|
||||
);
|
||||
});
|
||||
|
||||
it('error while fetching data model data', async () => {
|
||||
mockGetDataModelByFqn.mockRejectedValueOnce(ERROR);
|
||||
|
||||
await act(async () => {
|
||||
render(<DataModelsPage />);
|
||||
});
|
||||
|
||||
expect(screen.getByText(ERROR_PLACEHOLDER)).toBeInTheDocument();
|
||||
expect(mockShowErrorToast).toHaveBeenCalledWith(ERROR);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
export const ERROR = 'error';
|
||||
export const ERROR_PLACEHOLDER = 'ErrorPlaceHolder';
|
||||
export const FETCH_ENTITY_PERMISSION_ERROR =
|
||||
'server.fetch-entity-permissions-error';
|
||||
export const ENTITY_MISSING_ERROR = 'entity missing error';
|
||||
export const CREATE_THREAD = 'Create Thread';
|
||||
export const UPDATE_DATA_MODEL = 'Update Data Model';
|
||||
export const FOLLOW_DATA_MODEL = 'Follow Data Model';
|
||||
export const TOGGLE_DELETE = 'Toggle Delete';
|
||||
export const DATA_MODEL_DELETED = 'Data Model is deleted';
|
||||
export const UPDATE_VOTE = 'Update Vote';
|
||||
Loading…
x
Reference in New Issue
Block a user