test(ui): table details component (#12278)

* test(ui): table details component

* fix merge conflicts

* address commnets
This commit is contained in:
Chirag Madlani 2023-09-04 19:20:18 +05:30 committed by GitHub
parent fe7f2828b2
commit 916d9c1d1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 329 additions and 12 deletions

View File

@ -137,7 +137,7 @@ const ActivityFeedProvider = ({ children, user }: Props) => {
setLoading(false);
}
},
[]
[currentUser, user]
);
// Here value is the post message and id can be thread id or post id.

View File

@ -275,16 +275,14 @@ const TopicSchemaFields: FC<TopicSchemaFieldsProps> = ({
return (
<Row className="mt-4" gutter={[16, 16]}>
<Col>
<Space>
{messageSchema?.schemaType && (
<Col>
<Typography.Text type="secondary">
{t('label.schema')}
</Typography.Text>
{schemaTypePlaceholder ?? (
<Tag>{messageSchema?.schemaType ?? ''}</Tag>
)}
</Space>
</Col>
{schemaTypePlaceholder ?? <Tag>{messageSchema.schemaType}</Tag>}
</Col>
)}
{isEmpty(messageSchema?.schemaFields) &&
isEmpty(messageSchema?.schemaText) ? (
<ErrorPlaceHolder />

View File

@ -0,0 +1,320 @@
/*
* 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 { usePermissionProvider } from 'components/PermissionProvider/PermissionProvider';
import React from 'react';
import { getTableDetailsByFQN } from 'rest/tableAPI';
import { DEFAULT_ENTITY_PERMISSION } from 'utils/PermissionsUtils';
import TableDetailsPageV1 from './TableDetailsPageV1';
const mockEntityPermissionByFqn = jest
.fn()
.mockImplementation(() => DEFAULT_ENTITY_PERMISSION);
jest.mock('components/PermissionProvider/PermissionProvider', () => ({
usePermissionProvider: jest.fn().mockImplementation(() => ({
getEntityPermissionByFqn: mockEntityPermissionByFqn,
})),
}));
jest.mock('rest/tableAPI', () => ({
getTableDetailsByFQN: jest.fn().mockImplementation(() =>
Promise.resolve({
name: 'test',
id: '123',
})
),
addFollower: jest.fn(),
patchTableDetails: jest.fn(),
removeFollower: jest.fn(),
restoreTable: jest.fn(),
}));
jest.mock('utils/CommonUtils', () => ({
getCurrentUserId: jest.fn(),
getFeedCounts: jest.fn(),
getPartialNameFromTableFQN: jest.fn().mockImplementation(() => 'fqn'),
getTableFQNFromColumnFQN: jest.fn(),
refreshPage: jest.fn(),
sortTagsCaseInsensitive: jest.fn(),
}));
jest.mock('rest/queryAPI', () => ({
getQueriesList: jest.fn(),
}));
jest.mock(
'components/ActivityFeed/ActivityFeedTab/ActivityFeedTab.component',
() => ({
ActivityFeedTab: jest
.fn()
.mockImplementation(() => <p>testActivityFeedTab</p>),
})
);
jest.mock(
'components/ActivityFeed/ActivityThreadPanel/ActivityThreadPanel',
() => {
return jest.fn().mockImplementation(() => <p>testActivityThreadPanel</p>);
}
);
jest.mock('components/common/description/DescriptionV1', () => {
return jest.fn().mockImplementation(() => <p>testDescriptionV1</p>);
});
jest.mock('components/common/error-with-placeholder/ErrorPlaceHolder', () => {
return jest.fn().mockImplementation(() => <p>testErrorPlaceHolder</p>);
});
jest.mock('components/common/QueryViewer/QueryViewer.component', () => {
return jest.fn().mockImplementation(() => <p>testQueryViewer</p>);
});
jest.mock('components/containers/PageLayoutV1', () => {
return jest.fn().mockImplementation(({ children }) => <p>{children}</p>);
});
jest.mock(
'components/DataAssets/DataAssetsHeader/DataAssetsHeader.component',
() => ({
DataAssetsHeader: jest
.fn()
.mockImplementation(() => <p>testDataAssetsHeader</p>),
})
);
jest.mock('components/Entity/EntityLineage/EntityLineage.component', () => {
return jest.fn().mockImplementation(() => <p>testEntityLineage</p>);
});
jest.mock('components/SampleDataTable/SampleDataTable.component', () => {
return jest.fn().mockImplementation(() => <p>testSampleDataTable</p>);
});
jest.mock('components/SchemaTab/SchemaTab.component', () => {
return jest.fn().mockImplementation(() => <p>testSchemaTab</p>);
});
jest.mock('components/TableProfiler/TableProfilerV1', () => {
return jest.fn().mockImplementation(() => <p>testTableProfilerV1</p>);
});
jest.mock('components/TableQueries/TableQueries', () => {
return jest.fn().mockImplementation(() => <p>testTableQueries</p>);
});
jest.mock('components/TabsLabel/TabsLabel.component', () => {
return jest.fn().mockImplementation(({ name }) => <p>{name}</p>);
});
jest.mock('components/Tag/TagsContainerV2/TagsContainerV2', () => {
return jest.fn().mockImplementation(() => <p>testTagsContainerV2</p>);
});
jest.mock('./FrequentlyJoinedTables/FrequentlyJoinedTables.component', () => ({
FrequentlyJoinedTables: jest
.fn()
.mockImplementation(() => <p>testFrequentlyJoinedTables</p>),
}));
jest.mock('./FrequentlyJoinedTables/FrequentlyJoinedTables.component', () => ({
FrequentlyJoinedTables: jest
.fn()
.mockImplementation(() => <p>testFrequentlyJoinedTables</p>),
}));
jest.mock(
'components/ActivityFeed/ActivityFeedProvider/ActivityFeedProvider',
() => ({
useActivityFeedProvider: jest.fn().mockImplementation(() => ({
postFeed: jest.fn(),
deleteFeed: jest.fn(),
updateFeed: jest.fn(),
})),
__esModule: true,
default: 'ActivityFeedProvider',
})
);
jest.mock('react-router-dom', () => ({
useParams: jest
.fn()
.mockImplementation(() => ({ datasetFQN: 'fqn', tab: 'schema' })),
useHistory: jest.fn().mockImplementation(() => ({})),
}));
jest.mock('components/TourProvider/TourProvider', () => ({
useTourProvider: jest.fn().mockImplementation(() => ({
isTourOpen: false,
activeTabForTourDatasetPage: 'schema',
isTourPage: false,
})),
}));
jest.mock('components/Loader/Loader', () => {
return jest.fn().mockImplementation(() => <>testLoader</>);
});
jest.useFakeTimers();
describe('TestDetailsPageV1 component', () => {
it('TableDetailsPageV1 should fetch permissions', () => {
render(<TableDetailsPageV1 />);
expect(mockEntityPermissionByFqn).toHaveBeenCalledWith('table', 'fqn');
});
it('TableDetailsPageV1 should not fetch table details if permission is there', () => {
render(<TableDetailsPageV1 />);
expect(getTableDetailsByFQN).not.toHaveBeenCalled();
});
it('TableDetailsPageV1 should fetch table details with basic fields', async () => {
(usePermissionProvider as jest.Mock).mockImplementationOnce(() => ({
getEntityPermissionByFqn: jest.fn().mockImplementationOnce(() => ({
ViewBasic: true,
})),
}));
await act(async () => {
render(<TableDetailsPageV1 />);
});
expect(getTableDetailsByFQN).toHaveBeenCalledWith(
'fqn',
'columns,followers,joins,tags,owner,dataModel,tableConstraints,extension,viewDefinition'
);
});
it('TableDetailsPageV1 should fetch table details with all the permitted fields', async () => {
(usePermissionProvider as jest.Mock).mockImplementationOnce(() => ({
getEntityPermissionByFqn: jest.fn().mockImplementationOnce(() => ({
ViewAll: true,
ViewBasic: true,
ViewUsage: true,
})),
}));
await act(async () => {
render(<TableDetailsPageV1 />);
});
expect(getTableDetailsByFQN).toHaveBeenCalledWith(
'fqn',
'columns,followers,joins,tags,owner,dataModel,tableConstraints,extension,viewDefinition,usageSummary,testSuite'
);
});
it('TableDetailsPageV1 should render page for ViewBasic permissions', async () => {
(usePermissionProvider as jest.Mock).mockImplementationOnce(() => ({
getEntityPermissionByFqn: jest.fn().mockImplementationOnce(() => ({
ViewBasic: true,
})),
}));
await act(async () => {
render(<TableDetailsPageV1 />);
});
expect(getTableDetailsByFQN).toHaveBeenCalledWith(
'fqn',
'columns,followers,joins,tags,owner,dataModel,tableConstraints,extension,viewDefinition'
);
expect(await screen.findByText('testDataAssetsHeader')).toBeInTheDocument();
expect(await screen.findByText('label.schema')).toBeInTheDocument();
expect(
await screen.findByText('label.activity-feed-and-task-plural')
).toBeInTheDocument();
expect(await screen.findByText('label.sample-data')).toBeInTheDocument();
expect(await screen.findByText('label.query-plural')).toBeInTheDocument();
expect(await screen.findByText('label.lineage')).toBeInTheDocument();
expect(
await screen.findByText('label.custom-property-plural')
).toBeInTheDocument();
expect(
await screen.findByText('label.profiler-amp-data-quality')
).toBeInTheDocument();
});
it('TableDetailsPageV1 should dbt tab if data is present', async () => {
(usePermissionProvider as jest.Mock).mockImplementationOnce(() => ({
getEntityPermissionByFqn: jest.fn().mockImplementationOnce(() => ({
ViewBasic: true,
})),
}));
(getTableDetailsByFQN as jest.Mock).mockImplementationOnce(() =>
Promise.resolve({
name: 'test',
id: '123',
tableFqn: 'fqn',
dataModel: { sql: 'somequery' },
})
);
await act(async () => {
render(<TableDetailsPageV1 />);
});
expect(await screen.findByText('label.dbt-lowercase')).toBeInTheDocument();
expect(screen.queryByText('label.view-definition')).not.toBeInTheDocument();
});
it('TableDetailsPageV1 should render view defination if data is present', async () => {
(usePermissionProvider as jest.Mock).mockImplementationOnce(() => ({
getEntityPermissionByFqn: jest.fn().mockImplementationOnce(() => ({
ViewBasic: true,
})),
}));
(getTableDetailsByFQN as jest.Mock).mockImplementationOnce(() =>
Promise.resolve({
name: 'test',
id: '123',
viewDefinition: 'viewDefinition',
})
);
await act(async () => {
render(<TableDetailsPageV1 />);
});
expect(screen.queryByText('label.dbt-lowercase')).not.toBeInTheDocument();
expect(
await screen.findByText('label.view-definition')
).toBeInTheDocument();
});
it('TableDetailsPageV1 should render schemaTab by default', async () => {
(usePermissionProvider as jest.Mock).mockImplementationOnce(() => ({
getEntityPermissionByFqn: jest.fn().mockImplementationOnce(() => ({
ViewBasic: true,
})),
}));
await act(async () => {
render(<TableDetailsPageV1 />);
});
expect(getTableDetailsByFQN).toHaveBeenCalledWith(
'fqn',
'columns,followers,joins,tags,owner,dataModel,tableConstraints,extension,viewDefinition'
);
expect(await screen.findByText('testSchemaTab')).toBeInTheDocument();
});
});

View File

@ -1,5 +1,5 @@
/*
* Copyright 2022 Collate.
* 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
@ -13,6 +13,5 @@
import { TabSpecificField } from '../enums/entity.enum';
export const defaultFields = `${TabSpecificField.COLUMNS},
${TabSpecificField.FOLLOWERS}, ${TabSpecificField.JOINS}, ${TabSpecificField.TAGS}, ${TabSpecificField.OWNER},
${TabSpecificField.DATAMODEL},${TabSpecificField.TABLE_CONSTRAINTS},${TabSpecificField.EXTENSION},${TabSpecificField.VIEW_DEFINITION}`;
// eslint-disable-next-line max-len
export const defaultFields = `${TabSpecificField.COLUMNS},${TabSpecificField.FOLLOWERS},${TabSpecificField.JOINS},${TabSpecificField.TAGS},${TabSpecificField.OWNER},${TabSpecificField.DATAMODEL},${TabSpecificField.TABLE_CONSTRAINTS},${TabSpecificField.EXTENSION},${TabSpecificField.VIEW_DEFINITION}`;