Minor: cleanup test case details page (#15108)

* Minor: cleanup test case details page

* fixed failing cypress
This commit is contained in:
Shailesh Parmar 2024-02-09 11:06:19 +05:30 committed by GitHub
parent 7cff09d968
commit c635cbe44f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 13 additions and 324 deletions

View File

@ -307,13 +307,6 @@ const EditRulePage = withSuspenseFallback(
)
);
const TestCaseDetailsPage = withSuspenseFallback(
React.lazy(
() =>
import('../../pages/TestCaseDetailsPage/TestCaseDetailsPage.component')
)
);
const LogsViewer = withSuspenseFallback(
React.lazy(() => import('../../pages/LogsViewer/LogsViewer.component'))
);
@ -1081,15 +1074,6 @@ const AuthenticatedAppRouter: FunctionComponent = () => {
path={ROUTES.EDIT_OBSERVABILITY_ALERTS}
/>
<AdminProtectedRoute
exact
component={TestCaseDetailsPage}
hasPermission={userPermissions.hasViewPermissions(
ResourceEntity.TEST_CASE,
permissions
)}
path={ROUTES.TEST_CASE_DETAILS}
/>
<Route exact component={DataInsightPage} path={ROUTES.DATA_INSIGHT} />
<Route
exact

View File

@ -198,7 +198,7 @@ const TestCaseResultTab = ({
{testCaseData && (
<Col className="test-case-result-tab-graph" span={24}>
<TestSummary showExpandIcon showOnlyGraph data={testCaseData} />
<TestSummary showOnlyGraph data={testCaseData} />
</Col>
)}

View File

@ -11,7 +11,6 @@
* limitations under the License.
*/
import { queryByAttribute, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import {
MOCK_SQL_TEST_CASE,
@ -94,9 +93,6 @@ describe('TestSummary component', () => {
expect(
await screen.findByTestId('test-summary-container')
).toBeInTheDocument();
expect(
await screen.findByTestId('test-case-expand-button')
).toBeInTheDocument();
expect(await screen.findByTestId('params-container')).toBeInTheDocument();
expect(graphContainer).toBeInTheDocument();
expect(graph).toBeInTheDocument();
@ -125,9 +121,6 @@ describe('TestSummary component', () => {
expect(
await screen.findByText('ErrorPlaceHolder.component')
).toBeInTheDocument();
expect(
await screen.findByTestId('test-case-expand-button')
).toBeInTheDocument();
expect(await screen.findByTestId('params-container')).toBeInTheDocument();
expect(await screen.findAllByTestId('parameter-value')).toHaveLength(
@ -143,30 +136,6 @@ describe('TestSummary component', () => {
).toBeInTheDocument();
});
it('full screen button click should work', async () => {
render(<TestSummary data={MOCK_SQL_TEST_CASE} />);
const fullScreenBtn = await screen.findByTestId('test-case-expand-button');
expect(fullScreenBtn).toBeInTheDocument();
userEvent.click(fullScreenBtn);
expect(mockHistory.push).toHaveBeenCalled();
});
it('minimize screen button click should work', async () => {
render(<TestSummary data={MOCK_SQL_TEST_CASE} showExpandIcon={false} />);
const fullScreenBtn = await screen.findByTestId('test-case-expand-button');
expect(fullScreenBtn).toBeInTheDocument();
userEvent.click(fullScreenBtn);
expect(mockHistory.goBack).toHaveBeenCalled();
});
it('default time range should be 30 days', async () => {
const MockGetEpochMillisForPastDays =
getEpochMillisForPastDays as jest.Mock;

View File

@ -11,7 +11,7 @@
* limitations under the License.
*/
import { Button, Col, Row, Space, Typography } from 'antd';
import { Col, Row, Space, Typography } from 'antd';
import { AxiosError } from 'axios';
import { t } from 'i18next';
import {
@ -25,7 +25,6 @@ import {
uniqueId,
} from 'lodash';
import { DateRangeObject } from 'Models';
import Qs from 'qs';
import React, {
ReactElement,
useCallback,
@ -33,7 +32,6 @@ import React, {
useMemo,
useState,
} from 'react';
import { useHistory } from 'react-router-dom';
import {
CartesianGrid,
Legend,
@ -48,8 +46,6 @@ import {
YAxis,
} from 'recharts';
import { Payload } from 'recharts/types/component/DefaultLegendContent';
import { ReactComponent as ExitFullScreen } from '../../../assets/svg/exit-full-screen.svg';
import { ReactComponent as FullScreen } from '../../../assets/svg/full-screen.svg';
import { ReactComponent as FilterPlaceHolderIcon } from '../../../assets/svg/no-search-placeholder.svg';
import {
GREEN_3,
@ -81,7 +77,6 @@ import {
getCurrentMillis,
getEpochMillisForPastDays,
} from '../../../utils/date-time/DateTimeUtils';
import { getTestCaseDetailsPath } from '../../../utils/RouterUtils';
import { showErrorToast } from '../../../utils/ToastUtils';
import { useActivityFeedProvider } from '../../ActivityFeed/ActivityFeedProvider/ActivityFeedProvider';
import ErrorPlaceHolder from '../../common/ErrorWithPlaceholder/ErrorPlaceHolder';
@ -101,9 +96,8 @@ type ChartDataType = {
const TestSummary: React.FC<TestSummaryProps> = ({
data,
showOnlyGraph = false,
showExpandIcon = true,
}) => {
const { entityThread } = useActivityFeedProvider();
const { entityThread = [] } = useActivityFeedProvider();
const defaultRange = useMemo(
() => ({
@ -118,7 +112,6 @@ const TestSummary: React.FC<TestSummaryProps> = ({
}),
[]
);
const history = useHistory();
const [results, setResults] = useState<TestCaseResult[]>([]);
const [dateRangeObject, setDateRangeObject] = useState<DateRangeObject>(
defaultRange.initialRange
@ -254,7 +247,7 @@ const TestSummary: React.FC<TestSummaryProps> = ({
setIsGraphLoading(true);
try {
const { data: chartData } = await getListTestCaseResults(
data.fullyQualifiedName || '',
data.fullyQualifiedName ?? '',
pick(dateRangeObj, ['startTs', 'endTs'])
);
@ -436,29 +429,11 @@ const TestSummary: React.FC<TestSummaryProps> = ({
}
};
const handleExpandClick = () => {
if (data.fullyQualifiedName) {
if (showExpandIcon) {
history.push({
search: Qs.stringify({ testCaseData: data }),
pathname: getTestCaseDetailsPath(data.fullyQualifiedName),
});
} else {
history.goBack();
}
}
};
const showParameters = useMemo(
() =>
!isUndefined(parameterValuesWithoutSqlExpression) &&
!isEmpty(parameterValuesWithoutSqlExpression) &&
showExpandIcon,
[
parameterValuesWithSqlExpression,
parameterValuesWithoutSqlExpression,
showExpandIcon,
]
!isEmpty(parameterValuesWithoutSqlExpression),
[parameterValuesWithSqlExpression, parameterValuesWithoutSqlExpression]
);
const handleSelectedTimeRange = useCallback((range: string) => {
@ -472,31 +447,13 @@ const TestSummary: React.FC<TestSummaryProps> = ({
<Loader />
) : (
<Row gutter={[16, 16]}>
<Col span={24}>
<Row gutter={16} justify="end">
<Col>
<DatePickerMenu
showSelectedCustomRange
defaultDateRange={pick(defaultRange, ['key', 'title'])}
handleDateRangeChange={handleDateRangeChange}
handleSelectedTimeRange={handleSelectedTimeRange}
/>
</Col>
<Col>
<Button
className="flex justify-center items-center bg-white"
data-testid="test-case-expand-button"
icon={
showExpandIcon ? (
<FullScreen height={16} width={16} />
) : (
<ExitFullScreen height={16} width={16} />
)
}
onClick={handleExpandClick}
/>
</Col>
</Row>
<Col className="d-flex justify-end" span={24}>
<DatePickerMenu
showSelectedCustomRange
defaultDateRange={pick(defaultRange, ['key', 'title'])}
handleDateRangeChange={handleDateRangeChange}
handleSelectedTimeRange={handleSelectedTimeRange}
/>
</Col>
<Col data-testid="graph-container" span={24}>
{getGraph}

View File

@ -118,7 +118,6 @@ export interface DataQualityTabProps {
export interface TestSummaryProps {
data: TestCase;
showOnlyGraph?: boolean;
showExpandIcon?: boolean;
}
export interface ProfilerLatestValueProps {

View File

@ -265,7 +265,6 @@ export const ROUTES = {
// Query Routes
QUERY_FULL_SCREEN_VIEW: `/query-view/${PLACEHOLDER_ROUTE_FQN}/${PLACEHOLDER_ROUTE_QUERY_ID}`,
TEST_CASE_DETAILS: `/test-case/${PLACEHOLDER_ROUTE_FQN}`,
ADD_QUERY: `/query/${PLACEHOLDER_ROUTE_FQN}/add-query`,
// Tasks Routes

View File

@ -1,184 +0,0 @@
/*
* 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 { Col, Layout, Row, Typography } from 'antd';
import { AxiosError } from 'axios';
import { has, isEmpty, isUndefined } from 'lodash';
import React, { useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import ErrorPlaceHolder from '../../components/common/ErrorWithPlaceholder/ErrorPlaceHolder';
import TitleBreadcrumb from '../../components/common/TitleBreadcrumb/TitleBreadcrumb.component';
import TestSummary from '../../components/ProfilerDashboard/component/TestSummary';
import { TestCase } from '../../generated/tests/testCase';
import { useFqn } from '../../hooks/useFqn';
import { DataQualityPageTabs } from '../../pages/DataQuality/DataQualityPage.interface';
import { getTestCaseByFqn } from '../../rest/testAPI';
import { formatDateTime } from '../../utils/date-time/DateTimeUtils';
import { getEntityName } from '../../utils/EntityUtils';
import { getDataQualityPagePath } from '../../utils/RouterUtils';
import { showErrorToast } from '../../utils/ToastUtils';
import './test-case-details-page.style.less';
function TestCaseDetailsPage() {
const { fqn: testCaseFQN } = useFqn();
const { t } = useTranslation();
const [testCaseData, setTestCaseData] = useState<TestCase>();
const fetchTestCaseData = async () => {
try {
const response = await getTestCaseByFqn(testCaseFQN, {
fields: ['testSuite', 'testCaseResult'],
});
setTestCaseData(response);
} catch (error) {
showErrorToast(
error as AxiosError,
t('server.entity-fetch-error', { entity: t('label.test-case') })
);
}
};
const breadcrumb = useMemo(() => {
if (has(testCaseData, 'testSuite')) {
return [
{
name: t('label.test-case-plural'),
url: getDataQualityPagePath(DataQualityPageTabs.TEST_CASES),
},
{
name: testCaseData?.name ?? '',
url: '',
activeTitle: true,
},
];
} else {
return [];
}
}, [testCaseData]);
const parameterValuesWithoutSqlExpression = useMemo(
() =>
testCaseData?.parameterValues && testCaseData.parameterValues.length > 0
? testCaseData.parameterValues.filter(
(param) => param.name !== 'sqlExpression'
)
: undefined,
[testCaseData?.parameterValues]
);
useEffect(() => {
fetchTestCaseData();
}, [testCaseFQN]);
if (isUndefined(testCaseData)) {
return <ErrorPlaceHolder />;
}
return (
<Layout
className="test-case-details-page-container"
style={{ height: '100vh' }}>
<Layout.Content className="p-lg">
<TitleBreadcrumb className="m-b-md" titleLinks={breadcrumb} />
<TestSummary data={testCaseData} showExpandIcon={false} />
</Layout.Content>
<Layout.Sider className="test-case-details-page-right-panel" width={360}>
<Row className="p-sm" gutter={[0, 32]}>
<Col className="m-0" span={24}>
<Typography.Title level={5}>
{getEntityName(testCaseData)}
</Typography.Title>
</Col>
<Col className="m-0" span={24}>
<Row gutter={[16, 8]}>
<Col span={10}>
<Typography.Text className="text-grey-muted">
{`${t('label.last-run-result')}:`}
</Typography.Text>
</Col>
<Col span={14}>
<Typography.Text>
{testCaseData.testCaseResult?.testCaseStatus ?? '--'}
</Typography.Text>
</Col>
<Col span={10}>
<Typography.Text className="text-grey-muted">
{`${t('label.last-run')}:`}
</Typography.Text>
</Col>
<Col span={14}>
<Typography.Text>
{testCaseData.testCaseResult?.timestamp
? formatDateTime(testCaseData.testCaseResult?.timestamp)
: '--'}
</Typography.Text>
</Col>
</Row>
</Col>
<Col span={24}>
<Row className="m-0">
<Col className="p-0" span={24}>
<Typography.Text className="text-grey-muted">
{t('label.description')}
</Typography.Text>
</Col>
<Col className="p-0" span={24}>
<Typography.Text>
{testCaseData.description
? testCaseData.description
: t('label.no-description')}
</Typography.Text>
</Col>
</Row>
</Col>
<Col span={24}>
<Row className="m-0">
<Col className="p-0" span={24}>
<Typography.Text className="text-grey-muted">
{t('label.parameter')}
</Typography.Text>
</Col>
<Col className="p-0" span={24}>
{!isEmpty(parameterValuesWithoutSqlExpression) &&
!isUndefined(parameterValuesWithoutSqlExpression) ? (
<Row
className="parameter-value-container m-0"
gutter={[16, 4]}>
{parameterValuesWithoutSqlExpression.map((param) => (
<Col key={param.name} span={24}>
<Typography.Text className="text-grey-muted">
{`${param.name}:`}{' '}
</Typography.Text>
<Typography.Text>{param.value}</Typography.Text>
</Col>
))}
</Row>
) : (
<Typography.Text type="secondary">
{t('label.no-parameter-available')}
</Typography.Text>
)}
</Col>
</Row>
</Col>
</Row>
</Layout.Sider>
</Layout>
);
}
export default TestCaseDetailsPage;

View File

@ -1,27 +0,0 @@
/*
* 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 url('../../styles/variables.less');
.test-case-details-page-container {
height: 100vh;
background-color: @white;
.test-case-details-page-right-panel {
background-color: @white;
border-left: @global-border;
padding: 0px;
overflow-y: auto;
width: 360px;
}
}

View File

@ -534,14 +534,6 @@ export const getGlossaryTermsVersionsPath = (
return path;
};
export const getTestCaseDetailsPath = (testCaseFqn: string) => {
let path = ROUTES.TEST_CASE_DETAILS;
path = path.replace(PLACEHOLDER_ROUTE_FQN, getEncodedFqn(testCaseFqn));
return path;
};
export const getDataQualityPagePath = (tab?: DataQualityPageTabs) => {
let path = tab ? ROUTES.DATA_QUALITY_WITH_TAB : ROUTES.DATA_QUALITY;