mirror of
				https://github.com/open-metadata/OpenMetadata.git
				synced 2025-10-30 18:17:53 +00:00 
			
		
		
		
	test(ui): table details component (#12278)
* test(ui): table details component * fix merge conflicts * address commnets
This commit is contained in:
		
							parent
							
								
									fe7f2828b2
								
							
						
					
					
						commit
						916d9c1d1f
					
				| @ -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.
 | ||||
|  | ||||
| @ -275,16 +275,14 @@ const TopicSchemaFields: FC<TopicSchemaFieldsProps> = ({ | ||||
| 
 | ||||
|   return ( | ||||
|     <Row className="mt-4" gutter={[16, 16]}> | ||||
|       {messageSchema?.schemaType && ( | ||||
|         <Col> | ||||
|         <Space> | ||||
|           <Typography.Text type="secondary"> | ||||
|             {t('label.schema')} | ||||
|           </Typography.Text> | ||||
|           {schemaTypePlaceholder ?? ( | ||||
|             <Tag>{messageSchema?.schemaType ?? ''}</Tag> | ||||
|           )} | ||||
|         </Space> | ||||
|           {schemaTypePlaceholder ?? <Tag>{messageSchema.schemaType}</Tag>} | ||||
|         </Col> | ||||
|       )} | ||||
|       {isEmpty(messageSchema?.schemaFields) && | ||||
|       isEmpty(messageSchema?.schemaText) ? ( | ||||
|         <ErrorPlaceHolder /> | ||||
|  | ||||
| @ -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(); | ||||
|   }); | ||||
| }); | ||||
| @ -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}`; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Chirag Madlani
						Chirag Madlani