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
This commit is contained in:
Ashish Gupta 2024-03-22 00:12:58 +05:30 committed by GitHub
parent 8cfe720877
commit e22060668c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 235 additions and 70 deletions

View File

@ -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'
);
});
});

View File

@ -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`);
});
}
);

View File

@ -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) => (
<Card size="small">
<Card data-testid="stats-component" size="small">
<Row gutter={[16, 8]}>
<Col span={24}>
<Space wrap direction="horizontal" size={0}>
@ -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: (
<div className="d-flex items-center">
<Typography.Text>
{t('label.entity-record-plural', {
entity: t('label.total'),
})}{' '}
</Typography.Text>
<AppBadge
className="entity-stats total m-l-sm"
label={entityTotalJobStatsData.totalRecords}
/>
</div>
),
dataIndex: 'totalRecords',
key: 'totalRecords',
render: (text: string) => (
<Typography.Text className="text-primary">{text}</Typography.Text>
),
},
{
title: (
<div className="d-flex items-center">
<Typography.Text>
{t('label.entity-record-plural', {
entity: t('label.success'),
})}{' '}
</Typography.Text>
<AppBadge
className="entity-stats success m-l-sm"
label={entityTotalJobStatsData.successRecords}
/>
</div>
),
dataIndex: 'successRecords',
key: 'successRecords',
render: (text: string) => (
<Typography.Text className="text-success">{text}</Typography.Text>
),
},
{
title: (
<div className="d-flex items-center">
<Typography.Text>
{t('label.entity-record-plural', {
entity: t('label.failed'),
})}{' '}
</Typography.Text>
<AppBadge
className="entity-stats failure m-l-sm"
label={entityTotalJobStatsData.failedRecords}
/>
</div>
),
dataIndex: 'failedRecords',
key: 'failedRecords',
render: (text: string) => (
<Typography.Text className="text-failure">{text}</Typography.Text>
),
},
];
return isEmpty(entityTotalJobStatsData)
? []
: [
{
title: t('label.name'),
dataIndex: 'name',
key: 'name',
},
{
title: (
<div className="d-flex items-center">
<Typography.Text>
{t('label.entity-record-plural', {
entity: t('label.total'),
})}{' '}
</Typography.Text>
<AppBadge
className="entity-stats total m-l-sm"
label={entityTotalJobStatsData.totalRecords}
/>
</div>
),
dataIndex: 'totalRecords',
key: 'totalRecords',
render: (text: string) => (
<Typography.Text className="text-primary">{text}</Typography.Text>
),
},
{
title: (
<div className="d-flex items-center">
<Typography.Text>
{t('label.entity-record-plural', {
entity: t('label.success'),
})}{' '}
</Typography.Text>
<AppBadge
className="entity-stats success m-l-sm"
label={entityTotalJobStatsData.successRecords}
/>
</div>
),
dataIndex: 'successRecords',
key: 'successRecords',
render: (text: string) => (
<Typography.Text className="text-success">{text}</Typography.Text>
),
},
{
title: (
<div className="d-flex items-center">
<Typography.Text>
{t('label.entity-record-plural', {
entity: t('label.failed'),
})}{' '}
</Typography.Text>
<AppBadge
className="entity-stats failure m-l-sm"
label={entityTotalJobStatsData.failedRecords}
/>
</div>
),
dataIndex: 'failedRecords',
key: 'failedRecords',
render: (text: string) => (
<Typography.Text className="text-failure">{text}</Typography.Text>
),
},
];
}, [successContext, failureContext]);
const entityStatsRenderer = useCallback(

View File

@ -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(<AppLogsViewer {...mockProps1} />);
@ -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(<AppLogsViewer {...mockProps5} />);
expect(screen.queryByTestId('stats-component')).not.toBeInTheDocument();
expect(
screen.queryByTestId('app-entity-stats-history-table')
).not.toBeInTheDocument();
});
});