Minor: Added Ai learning banner if data is not accurate (#17198)

* Minor: Added Ai learning banner if data is not accurate

* fixed failing test cases
This commit is contained in:
Shailesh Parmar 2024-07-27 10:31:52 +05:30 committed by GitHub
parent a681c5184b
commit 10040a2e8d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 96 additions and 4 deletions

View File

@ -45,7 +45,11 @@ import testCaseResultTabClassBase from './TestCaseResultTabClassBase';
const TestCaseResultTab = () => { const TestCaseResultTab = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const { testCase: testCaseData, setTestCase } = useTestCaseStore(); const {
testCase: testCaseData,
setTestCase,
showAILearningBanner,
} = useTestCaseStore();
const additionalComponent = const additionalComponent =
testCaseResultTabClassBase.getAdditionalComponents(); testCaseResultTabClassBase.getAdditionalComponents();
const [isDescriptionEdit, setIsDescriptionEdit] = useState<boolean>(false); const [isDescriptionEdit, setIsDescriptionEdit] = useState<boolean>(false);
@ -116,6 +120,11 @@ const TestCaseResultTab = () => {
[] []
); );
const AlertComponent = useMemo(
() => testCaseResultTabClassBase.getAlertBanner(),
[]
);
const testCaseParams = useMemo(() => { const testCaseParams = useMemo(() => {
if (testCaseData?.useDynamicAssertion) { if (testCaseData?.useDynamicAssertion) {
return ( return (
@ -224,6 +233,13 @@ const TestCaseResultTab = () => {
</Col> </Col>
) : null} ) : null}
{showAILearningBanner &&
testCaseData?.useDynamicAssertion &&
AlertComponent && (
<Col span={24}>
<AlertComponent />
</Col>
)}
{testCaseData && ( {testCaseData && (
<Col className="test-case-result-tab-graph" span={24}> <Col className="test-case-result-tab-graph" span={24}>
<TestSummary data={testCaseData} /> <TestSummary data={testCaseData} />

View File

@ -22,7 +22,7 @@ import { TestCase } from '../../../../generated/tests/testCase';
import { checkPermission } from '../../../../utils/PermissionsUtils'; import { checkPermission } from '../../../../utils/PermissionsUtils';
import TestCaseResultTab from './TestCaseResultTab.component'; import TestCaseResultTab from './TestCaseResultTab.component';
const mockTestCaseData = { const mockTestCaseData: TestCase = {
id: '1b748634-d24b-4879-9791-289f2f90fc3c', id: '1b748634-d24b-4879-9791-289f2f90fc3c',
name: 'table_column_count_equals', name: 'table_column_count_equals',
fullyQualifiedName: fullyQualifiedName:
@ -68,6 +68,7 @@ const mockTestCaseData = {
const mockUseTestCaseStore = { const mockUseTestCaseStore = {
testCase: mockTestCaseData, testCase: mockTestCaseData,
setTestCase: jest.fn(), setTestCase: jest.fn(),
showAILearningBanner: false,
}; };
jest.mock( jest.mock(
@ -76,6 +77,11 @@ jest.mock(
useTestCaseStore: jest.fn().mockImplementation(() => mockUseTestCaseStore), useTestCaseStore: jest.fn().mockImplementation(() => mockUseTestCaseStore),
}) })
); );
const mockBannerComponent = () => <div>BannerComponent</div>;
jest.mock('./TestCaseResultTabClassBase', () => ({
getAdditionalComponents: jest.fn().mockReturnValue([]),
getAlertBanner: jest.fn().mockImplementation(() => mockBannerComponent),
}));
jest.mock('../../../common/EntityDescription/DescriptionV1', () => { jest.mock('../../../common/EntityDescription/DescriptionV1', () => {
return jest.fn().mockImplementation(() => <div>DescriptionV1</div>); return jest.fn().mockImplementation(() => <div>DescriptionV1</div>);
}); });
@ -189,4 +195,32 @@ describe('TestCaseResultTab', () => {
mockUseTestCaseStore.testCase.useDynamicAssertion = false; mockUseTestCaseStore.testCase.useDynamicAssertion = false;
}); });
it('Should show banner if banner component is available, useDynamicAssertion and showAILearningBanner is true', async () => {
mockTestCaseData.useDynamicAssertion = true;
mockUseTestCaseStore.showAILearningBanner = true;
render(<TestCaseResultTab />);
const bannerComponent = await screen.findByText('BannerComponent');
expect(bannerComponent).toBeInTheDocument();
mockTestCaseData.useDynamicAssertion = false;
mockUseTestCaseStore.showAILearningBanner = false;
});
it('Should not show banner if banner component is available, useDynamicAssertion is false and showAILearningBanner is true', async () => {
mockTestCaseData.useDynamicAssertion = false;
mockUseTestCaseStore.showAILearningBanner = true;
render(<TestCaseResultTab />);
const bannerComponent = screen.queryByText('BannerComponent');
expect(bannerComponent).not.toBeInTheDocument();
mockTestCaseData.useDynamicAssertion = false;
mockUseTestCaseStore.showAILearningBanner = false;
});
}); });

View File

@ -21,6 +21,10 @@ class TestCaseResultTabClassBase {
public getAdditionalComponents(): Array<AdditionalComponentInterface> { public getAdditionalComponents(): Array<AdditionalComponentInterface> {
return []; return [];
} }
public getAlertBanner(): React.FC | null {
return null;
}
} }
const testCaseResultTabClassBase = new TestCaseResultTabClassBase(); const testCaseResultTabClassBase = new TestCaseResultTabClassBase();

View File

@ -150,6 +150,15 @@ jest.mock(
})), })),
}) })
); );
const mockSetShowAILearningBanner = jest.fn();
jest.mock(
'../../../../pages/IncidentManager/IncidentManagerDetailPage/useTestCase.store',
() => ({
useTestCaseStore: jest.fn().mockImplementation(() => ({
setShowAILearningBanner: mockSetShowAILearningBanner,
})),
})
);
describe('TestSummaryGraph', () => { describe('TestSummaryGraph', () => {
it('should display error placeholder when the result data is empty', () => { it('should display error placeholder when the result data is empty', () => {
@ -214,4 +223,10 @@ describe('TestSummaryGraph', () => {
expect(minLineChart).toBeInTheDocument(); expect(minLineChart).toBeInTheDocument();
expect(maxLineChart).toBeInTheDocument(); expect(maxLineChart).toBeInTheDocument();
}); });
it('should call mockSetShowAILearningBanner', () => {
render(<TestSummaryGraph {...mockProps} />);
expect(mockSetShowAILearningBanner).toHaveBeenCalledWith(false);
});
}); });

View File

@ -51,6 +51,7 @@ import {
ThreadTaskStatus, ThreadTaskStatus,
} from '../../../../generated/entity/feed/thread'; } from '../../../../generated/entity/feed/thread';
import { TestCaseStatus } from '../../../../generated/tests/testCase'; import { TestCaseStatus } from '../../../../generated/tests/testCase';
import { useTestCaseStore } from '../../../../pages/IncidentManager/IncidentManagerDetailPage/useTestCase.store';
import { import {
axisTickFormatter, axisTickFormatter,
updateActiveChartFilter, updateActiveChartFilter,
@ -72,6 +73,7 @@ function TestSummaryGraph({
}: Readonly<TestSummaryGraphProps>) { }: Readonly<TestSummaryGraphProps>) {
const { t } = useTranslation(); const { t } = useTranslation();
const { entityThread = [] } = useActivityFeedProvider(); const { entityThread = [] } = useActivityFeedProvider();
const { setShowAILearningBanner } = useTestCaseStore();
const chartRef = useRef(null); const chartRef = useRef(null);
const [chartMouseEvent, setChartMouseEvent] = const [chartMouseEvent, setChartMouseEvent] =
useState<CategoricalChartState>(); useState<CategoricalChartState>();
@ -91,11 +93,14 @@ function TestSummaryGraph({
}, [chartRef, chartMouseEvent]); }, [chartRef, chartMouseEvent]);
const chartData = useMemo(() => { const chartData = useMemo(() => {
return prepareChartData({ const data = prepareChartData({
testCaseParameterValue: testCaseParameterValue ?? [], testCaseParameterValue: testCaseParameterValue ?? [],
testCaseResults, testCaseResults,
entityThread, entityThread,
}); });
setShowAILearningBanner(data.showAILearningBanner);
return data;
}, [testCaseResults, entityThread, testCaseParameterValue]); }, [testCaseResults, entityThread, testCaseParameterValue]);
const incidentData = useMemo(() => { const incidentData = useMemo(() => {

View File

@ -76,6 +76,8 @@ const mockUseTestCase: UseTestCaseStoreInterface = {
isLoading: false, isLoading: false,
setIsLoading: jest.fn(), setIsLoading: jest.fn(),
reset: jest.fn(), reset: jest.fn(),
showAILearningBanner: false,
setShowAILearningBanner: jest.fn(),
}; };
jest.mock('./useTestCase.store', () => ({ jest.mock('./useTestCase.store', () => ({
useTestCaseStore: jest.fn().mockImplementation(() => mockUseTestCase), useTestCaseStore: jest.fn().mockImplementation(() => mockUseTestCase),

View File

@ -16,20 +16,26 @@ import { TestCase } from '../../../generated/tests/testCase';
export interface UseTestCaseStoreInterface { export interface UseTestCaseStoreInterface {
testCase: TestCase | undefined; testCase: TestCase | undefined;
isLoading: boolean; isLoading: boolean;
showAILearningBanner: boolean;
setTestCase: (testCase: TestCase) => void; setTestCase: (testCase: TestCase) => void;
setIsLoading: (isLoading: boolean) => void; setIsLoading: (isLoading: boolean) => void;
setShowAILearningBanner: (showBanner: boolean) => void;
reset: () => void; reset: () => void;
} }
export const useTestCaseStore = create<UseTestCaseStoreInterface>()((set) => ({ export const useTestCaseStore = create<UseTestCaseStoreInterface>()((set) => ({
testCase: undefined, testCase: undefined,
isLoading: true, isLoading: true,
showAILearningBanner: false,
setTestCase: (testCase: TestCase) => { setTestCase: (testCase: TestCase) => {
set({ testCase }); set({ testCase });
}, },
setIsLoading: (isLoading: boolean) => { setIsLoading: (isLoading: boolean) => {
set({ isLoading }); set({ isLoading });
}, },
setShowAILearningBanner: (showAILearningBanner: boolean) => {
set({ showAILearningBanner });
},
reset: () => { reset: () => {
set({ testCase: undefined, isLoading: true }); set({ testCase: undefined, isLoading: true, showAILearningBanner: false });
}, },
})); }));

View File

@ -96,6 +96,7 @@ describe('prepareChartData', () => {
label: 'max', label: 'max',
}, },
], ],
showAILearningBanner: false,
}); });
}); });
@ -185,6 +186,7 @@ describe('prepareChartData', () => {
label: 'max', label: 'max',
}, },
], ],
showAILearningBanner: true,
}); });
}); });
@ -230,6 +232,7 @@ describe('prepareChartData', () => {
label: 'max', label: 'max',
}, },
], ],
showAILearningBanner: false,
}); });
}); });
@ -254,6 +257,7 @@ describe('prepareChartData', () => {
expect(result).toEqual({ expect(result).toEqual({
data: [], data: [],
information: [], information: [],
showAILearningBanner: false,
}); });
}); });
}); });

View File

@ -36,6 +36,7 @@ export const prepareChartData = ({
const yValues = params.reduce((acc, curr, i) => { const yValues = params.reduce((acc, curr, i) => {
return { ...acc, [`y${i + 1}`]: parseInt(curr.value ?? '') }; return { ...acc, [`y${i + 1}`]: parseInt(curr.value ?? '') };
}, {}); }, {});
let showAILearningBanner = false;
testCaseResults.forEach((result) => { testCaseResults.forEach((result) => {
const values = result.testResultValue?.reduce((acc, curr) => { const values = result.testResultValue?.reduce((acc, curr) => {
const value = round(parseFloat(curr.value ?? ''), 2) || 0; const value = round(parseFloat(curr.value ?? ''), 2) || 0;
@ -59,6 +60,10 @@ export const prepareChartData = ({
const y2 = result?.maxBound ?? yValues.y2; const y2 = result?.maxBound ?? yValues.y2;
const boundArea = isUndefined(y1) || isUndefined(y2) ? undefined : [y1, y2]; const boundArea = isUndefined(y1) || isUndefined(y2) ? undefined : [y1, y2];
if (isUndefined(boundArea)) {
showAILearningBanner = true;
}
dataPoints.push({ dataPoints.push({
name: result.timestamp, name: result.timestamp,
status: result.testCaseStatus, status: result.testCaseStatus,
@ -81,5 +86,6 @@ export const prepareChartData = ({
color: COLORS[i], color: COLORS[i],
})) ?? [], })) ?? [],
data: dataPoints, data: dataPoints,
showAILearningBanner,
}; };
}; };