From e22060668cd19e0bc215ef1893b09bb25bba78d6 Mon Sep 17 00:00:00 2001 From: Ashish Gupta Date: Fri, 22 Mar 2024 00:12:58 +0530 Subject: [PATCH] fix breaking issue in data insight report page after log button click (#15652) * fix breaking issue in data insight report page after log button click * changes as per comments * check page url on page change by click logs --- .../DataInsightReportApplication.spec.ts | 137 +++++++++++++++++ .../e2e/Pages/DataInsightSettings.spec.ts | 4 + .../AppLogsViewer/AppLogsViewer.component.tsx | 142 +++++++++--------- .../AppLogsViewer/AppLogsViewer.test.tsx | 22 +++ 4 files changed, 235 insertions(+), 70 deletions(-) create mode 100644 openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsightReportApplication.spec.ts diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsightReportApplication.spec.ts b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsightReportApplication.spec.ts new file mode 100644 index 00000000000..987e72f2e6e --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsightReportApplication.spec.ts @@ -0,0 +1,137 @@ +/* + * 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 { interceptURL, verifyResponseStatusCode } from '../../common/common'; +import { GlobalSettingOptions } from '../../constants/settings.constant'; + +const visitDataInsightReportApplicationPage = () => { + interceptURL( + 'GET', + '/api/v1/apps/name/DataInsightsReportApplication?fields=*', + 'getDataInsightsReportApplication' + ); + cy.get( + '[data-testid="data-insights-report-application-card"] [data-testid="config-btn"]' + ).click(); + verifyResponseStatusCode('@getDataInsightsReportApplication', 200); +}; + +const logButton = () => { + // check if the button is disabled to perform the click action + cy.get('[data-testid="logs"]').then(($logButton) => { + if ($logButton.is(':enabled')) { + cy.get('[data-testid="logs"]').click(); + cy.get('[data-testid="logs"]').should('be.visible'); + } else { + cy.reload(); + logButton(); + } + }); +}; + +describe('Data Insight Report Application', { tags: 'Settings' }, () => { + beforeEach(() => { + cy.login(); + + interceptURL('GET', '/api/v1/apps?limit=*', 'getApplications'); + + cy.settingClick(GlobalSettingOptions.APPLICATIONS); + + verifyResponseStatusCode('@getApplications', 200); + }); + + it('Install application', () => { + interceptURL('GET', '/api/v1/apps/marketplace?limit=*', 'getMarketPlace'); + interceptURL('POST', '/api/v1/apps', 'installApplication'); + cy.get('[data-testid="add-application"]').click(); + verifyResponseStatusCode('@getMarketPlace', 200); + cy.get( + '[data-testid="data-insights-report-application-card"] [data-testid="config-btn"]' + ).click(); + cy.get('[data-testid="install-application"]').click(); + cy.get('[data-testid="save-button"]').scrollIntoView().click(); + cy.get('[data-testid="submit-btn"]').scrollIntoView().click(); + cy.get('[data-testid="cron-type"]').click(); + // selecting day in week + cy.get('[data-value="5"]').click(); + cy.get('[data-testid="deploy-button"]').click(); + verifyResponseStatusCode('@installApplication', 201); + verifyResponseStatusCode('@getApplications', 200); + cy.get('[data-testid="data-insights-report-application-card"]').should( + 'be.visible' + ); + }); + + it('Edit application', () => { + interceptURL('PATCH', '/api/v1/apps/*', 'updateApplication'); + visitDataInsightReportApplicationPage(); + cy.get('[data-testid="edit-button"]').click(); + cy.get('[data-testid="cron-type"]').click(); + // selecting day in week + cy.get('[data-value="3"]').click(); + cy.get('[data-testid="hour-options"]').click(); + cy.get('[title="01"]').click(); + cy.get('.ant-modal-body [data-testid="deploy-button"]').click(); + verifyResponseStatusCode('@updateApplication', 200); + cy.get('[data-testid="cron-string"]').should('contain', 'At 01:00 AM'); + + cy.get('[data-testid="configuration"]').click(); + + cy.get('#root\\/sendToAdmins').click(); + cy.get('#root\\/sendToTeams').click(); + + cy.get('[data-testid="submit-btn"]').click(); + verifyResponseStatusCode('@updateApplication', 200); + }); + + it('Run application', () => { + interceptURL( + 'GET', + '/api/v1/apps/name/DataInsightsReportApplication?fields=*', + 'getDataInsightReportApplication' + ); + interceptURL( + 'POST', + '/api/v1/apps/trigger/DataInsightsReportApplication', + 'triggerPipeline' + ); + cy.get( + '[data-testid="data-insights-report-application-card"] [data-testid="config-btn"]' + ).click(); + verifyResponseStatusCode('@getDataInsightReportApplication', 200); + cy.get('[data-testid="run-now-button"]').click(); + verifyResponseStatusCode('@triggerPipeline', 200); + + // check the logs in the history table + cy.get('[data-testid="history"]').click(); + + logButton(); + }); + + it('Uninstall application', () => { + interceptURL('GET', '/api/v1/apps?limit=*', 'getApplications'); + interceptURL( + 'DELETE', + '/api/v1/apps/name/DataInsightsReportApplication?hardDelete=true', + 'deleteApplication' + ); + visitDataInsightReportApplicationPage(); + cy.get('[data-testid="manage-button"]').click(); + cy.get('[data-testid="uninstall-button-title"]').click(); + cy.get('[data-testid="save-button"]').click(); + verifyResponseStatusCode('@deleteApplication', 200); + verifyResponseStatusCode('@getApplications', 200); + cy.get('[data-testid="data-insights-report-application-card"]').should( + 'not.exist' + ); + }); +}); diff --git a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsightSettings.spec.ts b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsightSettings.spec.ts index 958e7af0b8a..437886852ab 100644 --- a/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsightSettings.spec.ts +++ b/openmetadata-ui/src/main/resources/ui/cypress/e2e/Pages/DataInsightSettings.spec.ts @@ -12,6 +12,7 @@ */ import { interceptURL, verifyResponseStatusCode } from '../../common/common'; +import { BASE_URL } from '../../constants/constants'; import { GlobalSettingOptions } from '../../constants/settings.constant'; describe( @@ -122,6 +123,9 @@ describe( verifyResponseStatusCode('@getDataInsightDetails', 200); cy.get('[data-testid="run-now-button"]').click(); verifyResponseStatusCode('@triggerPipeline', 200); + + cy.get('[data-testid="logs"]').click(); + cy.url().should('eq', `${BASE_URL}/apps/DataInsightsApplication/logs`); }); } ); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Applications/AppLogsViewer/AppLogsViewer.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Applications/AppLogsViewer/AppLogsViewer.component.tsx index 436a6581f9b..848a871f8f4 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Applications/AppLogsViewer/AppLogsViewer.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Applications/AppLogsViewer/AppLogsViewer.component.tsx @@ -22,7 +22,7 @@ import { Table, Typography, } from 'antd'; -import { isNil } from 'lodash'; +import { isEmpty, isNil } from 'lodash'; import React, { useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { LazyLog } from 'react-lazylog'; @@ -91,7 +91,7 @@ const AppLogsViewer = ({ data }: AppLogsViewerProps) => { const statsRender = useCallback( (jobStats: JobStats) => ( - + @@ -163,75 +163,77 @@ const AppLogsViewer = ({ data }: AppLogsViewerProps) => { const tableColumn = useMemo(() => { const entityTotalJobStatsData = - successContext?.stats.jobStats || failureContext?.stats.jobStats; + successContext?.stats?.jobStats || failureContext?.stats?.jobStats; - return [ - { - title: t('label.name'), - dataIndex: 'name', - key: 'name', - }, - { - title: ( -
- - {t('label.entity-record-plural', { - entity: t('label.total'), - })}{' '} - - -
- ), - dataIndex: 'totalRecords', - key: 'totalRecords', - render: (text: string) => ( - {text} - ), - }, - { - title: ( -
- - {t('label.entity-record-plural', { - entity: t('label.success'), - })}{' '} - - -
- ), - dataIndex: 'successRecords', - key: 'successRecords', - render: (text: string) => ( - {text} - ), - }, - { - title: ( -
- - {t('label.entity-record-plural', { - entity: t('label.failed'), - })}{' '} - - -
- ), - dataIndex: 'failedRecords', - key: 'failedRecords', - render: (text: string) => ( - {text} - ), - }, - ]; + return isEmpty(entityTotalJobStatsData) + ? [] + : [ + { + title: t('label.name'), + dataIndex: 'name', + key: 'name', + }, + { + title: ( +
+ + {t('label.entity-record-plural', { + entity: t('label.total'), + })}{' '} + + +
+ ), + dataIndex: 'totalRecords', + key: 'totalRecords', + render: (text: string) => ( + {text} + ), + }, + { + title: ( +
+ + {t('label.entity-record-plural', { + entity: t('label.success'), + })}{' '} + + +
+ ), + dataIndex: 'successRecords', + key: 'successRecords', + render: (text: string) => ( + {text} + ), + }, + { + title: ( +
+ + {t('label.entity-record-plural', { + entity: t('label.failed'), + })}{' '} + + +
+ ), + dataIndex: 'failedRecords', + key: 'failedRecords', + render: (text: string) => ( + {text} + ), + }, + ]; }, [successContext, failureContext]); const entityStatsRenderer = useCallback( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Applications/AppLogsViewer/AppLogsViewer.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Applications/AppLogsViewer/AppLogsViewer.test.tsx index d6bca1d8d2b..88257deee68 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Applications/AppLogsViewer/AppLogsViewer.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Applications/AppLogsViewer/AppLogsViewer.test.tsx @@ -143,6 +143,18 @@ const mockProps4 = { }, }; +const mockProps5 = { + data: { + ...mockProps1.data, + successContext: { + stats: null, + }, + failureContext: { + stats: null, + }, + }, +}; + describe('AppLogsViewer component', () => { it('should contain all necessary elements', () => { render(); @@ -211,4 +223,14 @@ describe('AppLogsViewer component', () => { expect(screen.getByText('270-AppBadge')).toBeInTheDocument(); expect(screen.getByText('4-AppBadge')).toBeInTheDocument(); }); + + it('should not render stats and entityStats component if successContext and failureContext stats is empty', () => { + render(); + + expect(screen.queryByTestId('stats-component')).not.toBeInTheDocument(); + + expect( + screen.queryByTestId('app-entity-stats-history-table') + ).not.toBeInTheDocument(); + }); });