diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ContainerVersion/ContainerVersion.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/ContainerVersion/ContainerVersion.component.tsx index 113979b4886..4f6c05c7d99 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ContainerVersion/ContainerVersion.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/ContainerVersion/ContainerVersion.component.tsx @@ -18,8 +18,11 @@ import { CustomPropertyProps } from 'components/common/CustomPropertyTable/Custo import DescriptionV1 from 'components/common/description/DescriptionV1'; import ErrorPlaceHolder from 'components/common/error-with-placeholder/ErrorPlaceHolder'; import DataAssetsVersionHeader from 'components/DataAssets/DataAssetsVersionHeader/DataAssetsVersionHeader'; +import EntityVersionTimeLine from 'components/EntityVersionTimeLine/EntityVersionTimeLine'; +import Loader from 'components/Loader/Loader'; import TabsLabel from 'components/TabsLabel/TabsLabel.component'; import TagsContainerV2 from 'components/Tag/TagsContainerV2/TagsContainerV2'; +import VersionTable from 'components/VersionTable/VersionTable.component'; import { getVersionPathWithTab } from 'constants/constants'; import { EntityField } from 'constants/Feeds.constants'; import { ERROR_PLACEHOLDER_TYPE } from 'enums/common.enum'; @@ -42,9 +45,6 @@ import { getEntityVersionByField, getEntityVersionTags, } from '../../utils/EntityVersionUtils'; -import EntityVersionTimeLine from '../EntityVersionTimeLine/EntityVersionTimeLine'; -import Loader from '../Loader/Loader'; -import VersionTable from '../VersionTable/VersionTable.component'; import { ContainerVersionProp } from './ContainerVersion.interface'; const ContainerVersion: React.FC = ({ diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ContainerVersion/ContainerVersion.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/ContainerVersion/ContainerVersion.test.tsx new file mode 100644 index 00000000000..ff8b673ac2c --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/components/ContainerVersion/ContainerVersion.test.tsx @@ -0,0 +1,201 @@ +/* + * Copyright 2023 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 } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; +import { DEFAULT_ENTITY_PERMISSION } from 'utils/PermissionsUtils'; +import { containerVersionMockProps } from '../../mocks/ContainerVersion.mock'; +import ContainerVersion from './ContainerVersion.component'; + +const mockPush = jest.fn(); + +jest.mock( + 'components/DataAssets/DataAssetsVersionHeader/DataAssetsVersionHeader', + () => jest.fn().mockImplementation(() =>
DataAssetsVersionHeader
) +); + +jest.mock('components/TabsLabel/TabsLabel.component', () => + jest.fn().mockImplementation(({ name }) =>
{name}
) +); + +jest.mock('components/Tag/TagsContainerV2/TagsContainerV2', () => + jest.fn().mockImplementation(() =>
TagsContainerV2
) +); + +jest.mock('components/common/CustomPropertyTable/CustomPropertyTable', () => ({ + CustomPropertyTable: jest + .fn() + .mockImplementation(() =>
CustomPropertyTable
), +})); + +jest.mock('components/common/description/DescriptionV1', () => + jest.fn().mockImplementation(() =>
DescriptionV1
) +); + +jest.mock('components/common/error-with-placeholder/ErrorPlaceHolder', () => + jest.fn().mockImplementation(() =>
ErrorPlaceHolder
) +); + +jest.mock('components/EntityVersionTimeLine/EntityVersionTimeLine', () => + jest.fn().mockImplementation(() =>
EntityVersionTimeLine
) +); + +jest.mock('components/VersionTable/VersionTable.component', () => + jest.fn().mockImplementation(() =>
VersionTable
) +); + +jest.mock('components/Loader/Loader', () => + jest.fn().mockImplementation(() =>
Loader
) +); + +jest.mock('react-router-dom', () => ({ + useHistory: jest.fn().mockImplementation(() => ({ + push: mockPush, + })), + useParams: jest.fn().mockReturnValue({ + tab: 'container', + }), +})); + +describe('ContainerVersion tests', () => { + it('Should render component properly if not loading', async () => { + await act(async () => { + render(); + }); + + const dataAssetsVersionHeader = screen.getByText('DataAssetsVersionHeader'); + const description = screen.getByText('DescriptionV1'); + const schemaTabLabel = screen.getByText('label.schema'); + const customPropertyTabLabel = screen.getByText( + 'label.custom-property-plural' + ); + const entityVersionTimeLine = screen.getByText('EntityVersionTimeLine'); + const versionTable = screen.getByText('VersionTable'); + + expect(dataAssetsVersionHeader).toBeInTheDocument(); + expect(description).toBeInTheDocument(); + expect(schemaTabLabel).toBeInTheDocument(); + expect(customPropertyTabLabel).toBeInTheDocument(); + expect(entityVersionTimeLine).toBeInTheDocument(); + expect(versionTable).toBeInTheDocument(); + }); + + it('Should display Loader if isVersionLoading is true', async () => { + await act(async () => { + render( + + ); + }); + + const loader = screen.getByText('Loader'); + const entityVersionTimeLine = screen.getByText('EntityVersionTimeLine'); + const dataAssetsVersionHeader = screen.queryByText( + 'DataAssetsVersionHeader' + ); + const schemaTabLabel = screen.queryByText('label.schema'); + const customPropertyTabLabel = screen.queryByText( + 'label.custom-property-plural' + ); + const versionTable = screen.queryByText('VersionTable'); + + expect(loader).toBeInTheDocument(); + expect(entityVersionTimeLine).toBeInTheDocument(); + expect(dataAssetsVersionHeader).toBeNull(); + expect(schemaTabLabel).toBeNull(); + expect(customPropertyTabLabel).toBeNull(); + expect(versionTable).toBeNull(); + }); + + it('Should display ErrorPlaceholder if no viewing permission', async () => { + await act(async () => { + render( + + ); + }); + + const errorPlaceHolder = screen.getByText('ErrorPlaceHolder'); + const loader = screen.queryByText('Loader'); + const dataAssetsVersionHeader = screen.queryByText( + 'DataAssetsVersionHeader' + ); + const schemaTabLabel = screen.queryByText('label.schema'); + const customPropertyTabLabel = screen.queryByText( + 'label.custom-property-plural' + ); + const entityVersionTimeLine = screen.queryByText('EntityVersionTimeLine'); + const versionTable = screen.queryByText('VersionTable'); + + expect(errorPlaceHolder).toBeInTheDocument(); + expect(loader).toBeNull(); + expect(entityVersionTimeLine).toBeNull(); + expect(dataAssetsVersionHeader).toBeNull(); + expect(schemaTabLabel).toBeNull(); + expect(customPropertyTabLabel).toBeNull(); + expect(versionTable).toBeNull(); + }); + + it('Should update url on click of tab', async () => { + await act(async () => { + render(); + }); + + const customPropertyTabLabel = screen.getByText( + 'label.custom-property-plural' + ); + const versionTable = screen.getByText('VersionTable'); + + expect(customPropertyTabLabel).toBeInTheDocument(); + expect(versionTable).toBeInTheDocument(); + + await act(async () => { + userEvent.click(customPropertyTabLabel); + }); + + expect(mockPush).toHaveBeenCalledWith( + '/container/sample_data.ecommerce_db.shopify.raw_product_catalog/versions/0.3/custom_properties' + ); + }); + + it('Should display ErrorPlaceholder in Custom Property tab if no "viewAll" permission', async () => { + await act(async () => { + render( + + ); + }); + + const customPropertyTabLabel = screen.getByText( + 'label.custom-property-plural' + ); + const versionTable = screen.getByText('VersionTable'); + let errorPlaceHolder = screen.queryByText('ErrorPlaceHolder'); + + expect(customPropertyTabLabel).toBeInTheDocument(); + expect(versionTable).toBeInTheDocument(); + expect(errorPlaceHolder).toBeNull(); + + await act(async () => { + userEvent.click(customPropertyTabLabel); + }); + + errorPlaceHolder = screen.getByText('ErrorPlaceHolder'); + + expect(errorPlaceHolder).toBeInTheDocument(); + }); +}); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DashboardVersion/DashboardVersion.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DashboardVersion/DashboardVersion.component.tsx index aeb61680c7b..323326760ba 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DashboardVersion/DashboardVersion.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DashboardVersion/DashboardVersion.component.tsx @@ -19,7 +19,10 @@ import { CustomPropertyTable } from 'components/common/CustomPropertyTable/Custo import { CustomPropertyProps } from 'components/common/CustomPropertyTable/CustomPropertyTable.interface'; import DescriptionV1 from 'components/common/description/DescriptionV1'; import ErrorPlaceHolder from 'components/common/error-with-placeholder/ErrorPlaceHolder'; +import RichTextEditorPreviewer from 'components/common/rich-text-editor/RichTextEditorPreviewer'; import DataAssetsVersionHeader from 'components/DataAssets/DataAssetsVersionHeader/DataAssetsVersionHeader'; +import EntityVersionTimeLine from 'components/EntityVersionTimeLine/EntityVersionTimeLine'; +import Loader from 'components/Loader/Loader'; import TabsLabel from 'components/TabsLabel/TabsLabel.component'; import TagsContainerV2 from 'components/Tag/TagsContainerV2/TagsContainerV2'; import { getVersionPathWithTab } from 'constants/constants'; @@ -41,9 +44,6 @@ import { getEntityVersionByField, getEntityVersionTags, } from '../../utils/EntityVersionUtils'; -import RichTextEditorPreviewer from '../common/rich-text-editor/RichTextEditorPreviewer'; -import EntityVersionTimeLine from '../EntityVersionTimeLine/EntityVersionTimeLine'; -import Loader from '../Loader/Loader'; import { DashboardVersionProp } from './DashboardVersion.interface'; const DashboardVersion: FC = ({ @@ -240,47 +240,43 @@ const DashboardVersion: FC = ({ return ( <> -
- {isVersionLoading ? ( - - ) : ( -
- - - - - - - - -
- )} + {isVersionLoading ? ( + + ) : ( +
+ + + + + + + + +
+ )} - -
+ ); }; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DashboardVersion/DashboardVersion.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DashboardVersion/DashboardVersion.test.tsx index 6286db5a2fb..fbfa00d6922 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DashboardVersion/DashboardVersion.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DashboardVersion/DashboardVersion.test.tsx @@ -11,18 +11,23 @@ * limitations under the License. */ -import { findByTestId, findByText, render } from '@testing-library/react'; -import React, { ReactNode } from 'react'; +import { act, render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { ENTITY_PERMISSIONS } from 'mocks/Permissions.mock'; +import React from 'react'; import { MemoryRouter } from 'react-router-dom'; -import DashboardVersion from './DashboardVersion.component'; -import { DashboardVersionProp } from './DashboardVersion.interface'; +import { DEFAULT_ENTITY_PERMISSION } from 'utils/PermissionsUtils'; import { dashboardVersionProps, mockNoChartData, mockTagChangeVersion, -} from './dashboardVersion.mock'; +} from '../../mocks/dashboardVersion.mock'; +import DashboardVersion from './DashboardVersion.component'; +import { DashboardVersionProp } from './DashboardVersion.interface'; -jest.mock('../common/rich-text-editor/RichTextEditorPreviewer', () => { +const mockPush = jest.fn(); + +jest.mock('components/common/rich-text-editor/RichTextEditorPreviewer', () => { return jest .fn() .mockImplementation(() =>
RichTextEditorPreviewer.component
); @@ -32,54 +37,75 @@ jest.mock('components/common/description/DescriptionV1', () => { return jest.fn().mockImplementation(() =>
Description.component
); }); -jest.mock('../EntityVersionTimeLine/EntityVersionTimeLine', () => { +jest.mock('components/EntityVersionTimeLine/EntityVersionTimeLine', () => { return jest .fn() .mockImplementation(() =>
EntityVersionTimeLine.component
); }); -jest.mock('../Loader/Loader', () => { +jest.mock('components/Loader/Loader', () => { return jest.fn().mockImplementation(() =>
Loader.component
); }); -jest.mock('components/containers/PageLayoutV1', () => { - return jest - .fn() - .mockImplementation(({ children }: { children: ReactNode }) => ( -
{children}
- )); +jest.mock('components/common/error-with-placeholder/ErrorPlaceHolder', () => { + return jest.fn().mockImplementation(() =>
ErrorPlaceHolder
); }); +jest.mock( + 'components/DataAssets/DataAssetsVersionHeader/DataAssetsVersionHeader', + () => jest.fn().mockImplementation(() =>
DataAssetsVersionHeader
) +); + +jest.mock('components/TabsLabel/TabsLabel.component', () => + jest.fn().mockImplementation(({ name }) =>
{name}
) +); + +jest.mock('components/Tag/TagsContainerV2/TagsContainerV2', () => + jest.fn().mockImplementation(() =>
TagsContainerV2
) +); + +jest.mock('components/Tag/TagsViewer/tags-viewer', () => + jest.fn().mockImplementation(() =>
TagsViewer
) +); + +jest.mock('components/common/CustomPropertyTable/CustomPropertyTable', () => ({ + CustomPropertyTable: jest + .fn() + .mockImplementation(() =>
CustomPropertyTable
), +})); + +jest.mock('react-router-dom', () => ({ + useHistory: jest.fn().mockImplementation(() => ({ + push: mockPush, + })), + useParams: jest.fn().mockReturnValue({ + tab: 'dashboard', + }), + Link: jest.fn().mockImplementation(() =>
Link
), +})); + JSON.parse = jest.fn().mockReturnValue([]); -describe('Test DashboardVersion page', () => { - it('Checks if the page has all the proper components rendered', async () => { - const { container } = render( - , - { +describe('DashboardVersion tests', () => { + it('Should render component properly if not loading', async () => { + await act(async () => { + render(, { wrapper: MemoryRouter, - } - ); + }); + }); - const dashboardVersionContainer = await findByTestId( - container, - 'dashboard-version-container' - ); - const versionData = await findByTestId(container, 'version-data'); - const schemaTable = await findByTestId(container, 'schema-table'); + const versionData = await screen.findByTestId('version-data'); + const schemaTable = await screen.findByTestId('schema-table'); - const entityVersionTimeLine = await findByText( - container, + const entityVersionTimeLine = await screen.findByText( 'EntityVersionTimeLine.component' ); - const tabs = await findByTestId(container, 'tabs'); - const description = await findByText(container, 'Description.component'); - const richTextEditorPreviewer = await findByText( - container, + const tabs = await screen.findByTestId('tabs'); + const description = await screen.findByText('Description.component'); + const richTextEditorPreviewer = await screen.findByText( 'RichTextEditorPreviewer.component' ); - expect(dashboardVersionContainer).toBeInTheDocument(); expect(versionData).toBeInTheDocument(); expect(schemaTable).toBeInTheDocument(); expect(entityVersionTimeLine).toBeInTheDocument(); @@ -88,38 +114,33 @@ describe('Test DashboardVersion page', () => { expect(richTextEditorPreviewer).toBeInTheDocument(); }); - it('Checks if the page has all the proper components rendered, if change version is related to tags', async () => { - const { container } = render( - { + await act(async () => { + render( + , + { + wrapper: MemoryRouter, } - />, - { - wrapper: MemoryRouter, - } - ); + ); + }); - const dashboardVersionContainer = await findByTestId( - container, - 'dashboard-version-container' - ); - const versionData = await findByTestId(container, 'version-data'); - const schemaTable = await findByTestId(container, 'schema-table'); + const versionData = await screen.findByTestId('version-data'); + const schemaTable = await screen.findByTestId('schema-table'); - const entityVersionTimeLine = await findByText( - container, + const entityVersionTimeLine = await screen.findByText( 'EntityVersionTimeLine.component' ); - const tabs = await findByTestId(container, 'tabs'); - const description = await findByText(container, 'Description.component'); - const richTextEditorPreviewer = await findByText( - container, + const tabs = await screen.findByTestId('tabs'); + const description = await screen.findByText('Description.component'); + const richTextEditorPreviewer = await screen.findByText( 'RichTextEditorPreviewer.component' ); - expect(dashboardVersionContainer).toBeInTheDocument(); expect(versionData).toBeInTheDocument(); expect(schemaTable).toBeInTheDocument(); expect(entityVersionTimeLine).toBeInTheDocument(); @@ -128,52 +149,109 @@ describe('Test DashboardVersion page', () => { expect(richTextEditorPreviewer).toBeInTheDocument(); }); - it('Checks if the page has all the proper components rendered, if the dashboard deleted is undefined', async () => { - const { container } = render( - , - { - wrapper: MemoryRouter, - } - ); + it('Should render component properly if "deleted" field for dashboard is undefined', async () => { + await act(async () => { + render( + , + { + wrapper: MemoryRouter, + } + ); + }); - const dashboardVersionContainer = await findByTestId( - container, - 'dashboard-version-container' - ); - const versionData = await findByTestId(container, 'version-data'); - const entityVersionTimeLine = await findByText( - container, + const versionData = await screen.findByTestId('version-data'); + const entityVersionTimeLine = await screen.findByText( 'EntityVersionTimeLine.component' ); - const tabs = await findByTestId(container, 'tabs'); - const description = await findByText(container, 'Description.component'); + const tabs = await screen.findByTestId('tabs'); + const description = await screen.findByText('Description.component'); - expect(dashboardVersionContainer).toBeInTheDocument(); expect(versionData).toBeInTheDocument(); expect(entityVersionTimeLine).toBeInTheDocument(); expect(tabs).toBeInTheDocument(); expect(description).toBeInTheDocument(); }); - it('If version is loading it should show loading component', async () => { - const { container } = render( - , - { + it('Should display Loader if isVersionLoading is true', async () => { + await act(async () => { + render(, { wrapper: MemoryRouter, - } - ); + }); + }); - const dashboardVersionContainer = await findByTestId( - container, - 'dashboard-version-container' + const entityVersionTimeLine = await screen.findByText( + 'EntityVersionTimeLine.component' ); - const loader = await findByText(container, 'Loader.component'); + const loader = await screen.findByText('Loader.component'); - expect(dashboardVersionContainer).toBeInTheDocument(); + expect(entityVersionTimeLine).toBeInTheDocument(); expect(loader).toBeInTheDocument(); }); + + it('Should update url on click of tab', async () => { + await act(async () => { + render( + , + { + wrapper: MemoryRouter, + } + ); + }); + + const customPropertyTabLabel = screen.getByText( + 'label.custom-property-plural' + ); + + expect(customPropertyTabLabel).toBeInTheDocument(); + + await act(async () => { + userEvent.click(customPropertyTabLabel); + }); + + expect(mockPush).toHaveBeenCalledWith( + '/dashboard/sample_superset.eta_predictions_performance/versions/0.3/custom_properties' + ); + }); + + it('Should display ErrorPlaceholder if no viewing permission', async () => { + await act(async () => { + render( + , + { + wrapper: MemoryRouter, + } + ); + }); + + const versionData = screen.queryByTestId('version-data'); + const schemaTable = screen.queryByTestId('schema-table'); + + const tabs = screen.queryByTestId('tabs'); + const description = screen.queryByText('Description.component'); + const richTextEditorPreviewer = screen.queryByText( + 'RichTextEditorPreviewer.component' + ); + const entityVersionTimeLine = screen.queryByText( + 'EntityVersionTimeLine.component' + ); + const errorPlaceHolder = screen.getByText('ErrorPlaceHolder'); + + expect(entityVersionTimeLine).toBeNull(); + expect(versionData).toBeNull(); + expect(schemaTable).toBeNull(); + expect(tabs).toBeNull(); + expect(description).toBeNull(); + expect(richTextEditorPreviewer).toBeNull(); + expect(errorPlaceHolder).toBeInTheDocument(); + }); }); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataAssets/DataAssetsHeader/DataAssetsHeader.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataAssets/DataAssetsHeader/DataAssetsHeader.component.tsx index bab3868b1f7..3788aaae565 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataAssets/DataAssetsHeader/DataAssetsHeader.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataAssets/DataAssetsHeader/DataAssetsHeader.component.tsx @@ -361,6 +361,7 @@ export const DataAssetsHeader = ({