mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-19 04:41:02 +00:00
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:
parent
8cfe720877
commit
e22060668c
@ -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'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
@ -12,6 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { interceptURL, verifyResponseStatusCode } from '../../common/common';
|
import { interceptURL, verifyResponseStatusCode } from '../../common/common';
|
||||||
|
import { BASE_URL } from '../../constants/constants';
|
||||||
import { GlobalSettingOptions } from '../../constants/settings.constant';
|
import { GlobalSettingOptions } from '../../constants/settings.constant';
|
||||||
|
|
||||||
describe(
|
describe(
|
||||||
@ -122,6 +123,9 @@ describe(
|
|||||||
verifyResponseStatusCode('@getDataInsightDetails', 200);
|
verifyResponseStatusCode('@getDataInsightDetails', 200);
|
||||||
cy.get('[data-testid="run-now-button"]').click();
|
cy.get('[data-testid="run-now-button"]').click();
|
||||||
verifyResponseStatusCode('@triggerPipeline', 200);
|
verifyResponseStatusCode('@triggerPipeline', 200);
|
||||||
|
|
||||||
|
cy.get('[data-testid="logs"]').click();
|
||||||
|
cy.url().should('eq', `${BASE_URL}/apps/DataInsightsApplication/logs`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -22,7 +22,7 @@ import {
|
|||||||
Table,
|
Table,
|
||||||
Typography,
|
Typography,
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import { isNil } from 'lodash';
|
import { isEmpty, isNil } from 'lodash';
|
||||||
import React, { useCallback, useMemo } from 'react';
|
import React, { useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { LazyLog } from 'react-lazylog';
|
import { LazyLog } from 'react-lazylog';
|
||||||
@ -91,7 +91,7 @@ const AppLogsViewer = ({ data }: AppLogsViewerProps) => {
|
|||||||
|
|
||||||
const statsRender = useCallback(
|
const statsRender = useCallback(
|
||||||
(jobStats: JobStats) => (
|
(jobStats: JobStats) => (
|
||||||
<Card size="small">
|
<Card data-testid="stats-component" size="small">
|
||||||
<Row gutter={[16, 8]}>
|
<Row gutter={[16, 8]}>
|
||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
<Space wrap direction="horizontal" size={0}>
|
<Space wrap direction="horizontal" size={0}>
|
||||||
@ -163,75 +163,77 @@ const AppLogsViewer = ({ data }: AppLogsViewerProps) => {
|
|||||||
|
|
||||||
const tableColumn = useMemo(() => {
|
const tableColumn = useMemo(() => {
|
||||||
const entityTotalJobStatsData =
|
const entityTotalJobStatsData =
|
||||||
successContext?.stats.jobStats || failureContext?.stats.jobStats;
|
successContext?.stats?.jobStats || failureContext?.stats?.jobStats;
|
||||||
|
|
||||||
return [
|
return isEmpty(entityTotalJobStatsData)
|
||||||
{
|
? []
|
||||||
title: t('label.name'),
|
: [
|
||||||
dataIndex: 'name',
|
{
|
||||||
key: 'name',
|
title: t('label.name'),
|
||||||
},
|
dataIndex: 'name',
|
||||||
{
|
key: 'name',
|
||||||
title: (
|
},
|
||||||
<div className="d-flex items-center">
|
{
|
||||||
<Typography.Text>
|
title: (
|
||||||
{t('label.entity-record-plural', {
|
<div className="d-flex items-center">
|
||||||
entity: t('label.total'),
|
<Typography.Text>
|
||||||
})}{' '}
|
{t('label.entity-record-plural', {
|
||||||
</Typography.Text>
|
entity: t('label.total'),
|
||||||
<AppBadge
|
})}{' '}
|
||||||
className="entity-stats total m-l-sm"
|
</Typography.Text>
|
||||||
label={entityTotalJobStatsData.totalRecords}
|
<AppBadge
|
||||||
/>
|
className="entity-stats total m-l-sm"
|
||||||
</div>
|
label={entityTotalJobStatsData.totalRecords}
|
||||||
),
|
/>
|
||||||
dataIndex: 'totalRecords',
|
</div>
|
||||||
key: 'totalRecords',
|
),
|
||||||
render: (text: string) => (
|
dataIndex: 'totalRecords',
|
||||||
<Typography.Text className="text-primary">{text}</Typography.Text>
|
key: 'totalRecords',
|
||||||
),
|
render: (text: string) => (
|
||||||
},
|
<Typography.Text className="text-primary">{text}</Typography.Text>
|
||||||
{
|
),
|
||||||
title: (
|
},
|
||||||
<div className="d-flex items-center">
|
{
|
||||||
<Typography.Text>
|
title: (
|
||||||
{t('label.entity-record-plural', {
|
<div className="d-flex items-center">
|
||||||
entity: t('label.success'),
|
<Typography.Text>
|
||||||
})}{' '}
|
{t('label.entity-record-plural', {
|
||||||
</Typography.Text>
|
entity: t('label.success'),
|
||||||
<AppBadge
|
})}{' '}
|
||||||
className="entity-stats success m-l-sm"
|
</Typography.Text>
|
||||||
label={entityTotalJobStatsData.successRecords}
|
<AppBadge
|
||||||
/>
|
className="entity-stats success m-l-sm"
|
||||||
</div>
|
label={entityTotalJobStatsData.successRecords}
|
||||||
),
|
/>
|
||||||
dataIndex: 'successRecords',
|
</div>
|
||||||
key: 'successRecords',
|
),
|
||||||
render: (text: string) => (
|
dataIndex: 'successRecords',
|
||||||
<Typography.Text className="text-success">{text}</Typography.Text>
|
key: 'successRecords',
|
||||||
),
|
render: (text: string) => (
|
||||||
},
|
<Typography.Text className="text-success">{text}</Typography.Text>
|
||||||
{
|
),
|
||||||
title: (
|
},
|
||||||
<div className="d-flex items-center">
|
{
|
||||||
<Typography.Text>
|
title: (
|
||||||
{t('label.entity-record-plural', {
|
<div className="d-flex items-center">
|
||||||
entity: t('label.failed'),
|
<Typography.Text>
|
||||||
})}{' '}
|
{t('label.entity-record-plural', {
|
||||||
</Typography.Text>
|
entity: t('label.failed'),
|
||||||
<AppBadge
|
})}{' '}
|
||||||
className="entity-stats failure m-l-sm"
|
</Typography.Text>
|
||||||
label={entityTotalJobStatsData.failedRecords}
|
<AppBadge
|
||||||
/>
|
className="entity-stats failure m-l-sm"
|
||||||
</div>
|
label={entityTotalJobStatsData.failedRecords}
|
||||||
),
|
/>
|
||||||
dataIndex: 'failedRecords',
|
</div>
|
||||||
key: 'failedRecords',
|
),
|
||||||
render: (text: string) => (
|
dataIndex: 'failedRecords',
|
||||||
<Typography.Text className="text-failure">{text}</Typography.Text>
|
key: 'failedRecords',
|
||||||
),
|
render: (text: string) => (
|
||||||
},
|
<Typography.Text className="text-failure">{text}</Typography.Text>
|
||||||
];
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
}, [successContext, failureContext]);
|
}, [successContext, failureContext]);
|
||||||
|
|
||||||
const entityStatsRenderer = useCallback(
|
const entityStatsRenderer = useCallback(
|
||||||
|
@ -143,6 +143,18 @@ const mockProps4 = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mockProps5 = {
|
||||||
|
data: {
|
||||||
|
...mockProps1.data,
|
||||||
|
successContext: {
|
||||||
|
stats: null,
|
||||||
|
},
|
||||||
|
failureContext: {
|
||||||
|
stats: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
describe('AppLogsViewer component', () => {
|
describe('AppLogsViewer component', () => {
|
||||||
it('should contain all necessary elements', () => {
|
it('should contain all necessary elements', () => {
|
||||||
render(<AppLogsViewer {...mockProps1} />);
|
render(<AppLogsViewer {...mockProps1} />);
|
||||||
@ -211,4 +223,14 @@ describe('AppLogsViewer component', () => {
|
|||||||
expect(screen.getByText('270-AppBadge')).toBeInTheDocument();
|
expect(screen.getByText('270-AppBadge')).toBeInTheDocument();
|
||||||
expect(screen.getByText('4-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();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user