mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-15 18:58:32 +00:00
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:
parent
a681c5184b
commit
10040a2e8d
@ -45,7 +45,11 @@ import testCaseResultTabClassBase from './TestCaseResultTabClassBase';
|
||||
|
||||
const TestCaseResultTab = () => {
|
||||
const { t } = useTranslation();
|
||||
const { testCase: testCaseData, setTestCase } = useTestCaseStore();
|
||||
const {
|
||||
testCase: testCaseData,
|
||||
setTestCase,
|
||||
showAILearningBanner,
|
||||
} = useTestCaseStore();
|
||||
const additionalComponent =
|
||||
testCaseResultTabClassBase.getAdditionalComponents();
|
||||
const [isDescriptionEdit, setIsDescriptionEdit] = useState<boolean>(false);
|
||||
@ -116,6 +120,11 @@ const TestCaseResultTab = () => {
|
||||
[]
|
||||
);
|
||||
|
||||
const AlertComponent = useMemo(
|
||||
() => testCaseResultTabClassBase.getAlertBanner(),
|
||||
[]
|
||||
);
|
||||
|
||||
const testCaseParams = useMemo(() => {
|
||||
if (testCaseData?.useDynamicAssertion) {
|
||||
return (
|
||||
@ -224,6 +233,13 @@ const TestCaseResultTab = () => {
|
||||
</Col>
|
||||
) : null}
|
||||
|
||||
{showAILearningBanner &&
|
||||
testCaseData?.useDynamicAssertion &&
|
||||
AlertComponent && (
|
||||
<Col span={24}>
|
||||
<AlertComponent />
|
||||
</Col>
|
||||
)}
|
||||
{testCaseData && (
|
||||
<Col className="test-case-result-tab-graph" span={24}>
|
||||
<TestSummary data={testCaseData} />
|
||||
|
@ -22,7 +22,7 @@ import { TestCase } from '../../../../generated/tests/testCase';
|
||||
import { checkPermission } from '../../../../utils/PermissionsUtils';
|
||||
import TestCaseResultTab from './TestCaseResultTab.component';
|
||||
|
||||
const mockTestCaseData = {
|
||||
const mockTestCaseData: TestCase = {
|
||||
id: '1b748634-d24b-4879-9791-289f2f90fc3c',
|
||||
name: 'table_column_count_equals',
|
||||
fullyQualifiedName:
|
||||
@ -68,6 +68,7 @@ const mockTestCaseData = {
|
||||
const mockUseTestCaseStore = {
|
||||
testCase: mockTestCaseData,
|
||||
setTestCase: jest.fn(),
|
||||
showAILearningBanner: false,
|
||||
};
|
||||
|
||||
jest.mock(
|
||||
@ -76,6 +77,11 @@ jest.mock(
|
||||
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', () => {
|
||||
return jest.fn().mockImplementation(() => <div>DescriptionV1</div>);
|
||||
});
|
||||
@ -189,4 +195,32 @@ describe('TestCaseResultTab', () => {
|
||||
|
||||
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;
|
||||
});
|
||||
});
|
||||
|
@ -21,6 +21,10 @@ class TestCaseResultTabClassBase {
|
||||
public getAdditionalComponents(): Array<AdditionalComponentInterface> {
|
||||
return [];
|
||||
}
|
||||
|
||||
public getAlertBanner(): React.FC | null {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const testCaseResultTabClassBase = new TestCaseResultTabClassBase();
|
||||
|
@ -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', () => {
|
||||
it('should display error placeholder when the result data is empty', () => {
|
||||
@ -214,4 +223,10 @@ describe('TestSummaryGraph', () => {
|
||||
expect(minLineChart).toBeInTheDocument();
|
||||
expect(maxLineChart).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should call mockSetShowAILearningBanner', () => {
|
||||
render(<TestSummaryGraph {...mockProps} />);
|
||||
|
||||
expect(mockSetShowAILearningBanner).toHaveBeenCalledWith(false);
|
||||
});
|
||||
});
|
||||
|
@ -51,6 +51,7 @@ import {
|
||||
ThreadTaskStatus,
|
||||
} from '../../../../generated/entity/feed/thread';
|
||||
import { TestCaseStatus } from '../../../../generated/tests/testCase';
|
||||
import { useTestCaseStore } from '../../../../pages/IncidentManager/IncidentManagerDetailPage/useTestCase.store';
|
||||
import {
|
||||
axisTickFormatter,
|
||||
updateActiveChartFilter,
|
||||
@ -72,6 +73,7 @@ function TestSummaryGraph({
|
||||
}: Readonly<TestSummaryGraphProps>) {
|
||||
const { t } = useTranslation();
|
||||
const { entityThread = [] } = useActivityFeedProvider();
|
||||
const { setShowAILearningBanner } = useTestCaseStore();
|
||||
const chartRef = useRef(null);
|
||||
const [chartMouseEvent, setChartMouseEvent] =
|
||||
useState<CategoricalChartState>();
|
||||
@ -91,11 +93,14 @@ function TestSummaryGraph({
|
||||
}, [chartRef, chartMouseEvent]);
|
||||
|
||||
const chartData = useMemo(() => {
|
||||
return prepareChartData({
|
||||
const data = prepareChartData({
|
||||
testCaseParameterValue: testCaseParameterValue ?? [],
|
||||
testCaseResults,
|
||||
entityThread,
|
||||
});
|
||||
setShowAILearningBanner(data.showAILearningBanner);
|
||||
|
||||
return data;
|
||||
}, [testCaseResults, entityThread, testCaseParameterValue]);
|
||||
|
||||
const incidentData = useMemo(() => {
|
||||
|
@ -76,6 +76,8 @@ const mockUseTestCase: UseTestCaseStoreInterface = {
|
||||
isLoading: false,
|
||||
setIsLoading: jest.fn(),
|
||||
reset: jest.fn(),
|
||||
showAILearningBanner: false,
|
||||
setShowAILearningBanner: jest.fn(),
|
||||
};
|
||||
jest.mock('./useTestCase.store', () => ({
|
||||
useTestCaseStore: jest.fn().mockImplementation(() => mockUseTestCase),
|
||||
|
@ -16,20 +16,26 @@ import { TestCase } from '../../../generated/tests/testCase';
|
||||
export interface UseTestCaseStoreInterface {
|
||||
testCase: TestCase | undefined;
|
||||
isLoading: boolean;
|
||||
showAILearningBanner: boolean;
|
||||
setTestCase: (testCase: TestCase) => void;
|
||||
setIsLoading: (isLoading: boolean) => void;
|
||||
setShowAILearningBanner: (showBanner: boolean) => void;
|
||||
reset: () => void;
|
||||
}
|
||||
export const useTestCaseStore = create<UseTestCaseStoreInterface>()((set) => ({
|
||||
testCase: undefined,
|
||||
isLoading: true,
|
||||
showAILearningBanner: false,
|
||||
setTestCase: (testCase: TestCase) => {
|
||||
set({ testCase });
|
||||
},
|
||||
setIsLoading: (isLoading: boolean) => {
|
||||
set({ isLoading });
|
||||
},
|
||||
setShowAILearningBanner: (showAILearningBanner: boolean) => {
|
||||
set({ showAILearningBanner });
|
||||
},
|
||||
reset: () => {
|
||||
set({ testCase: undefined, isLoading: true });
|
||||
set({ testCase: undefined, isLoading: true, showAILearningBanner: false });
|
||||
},
|
||||
}));
|
||||
|
@ -96,6 +96,7 @@ describe('prepareChartData', () => {
|
||||
label: 'max',
|
||||
},
|
||||
],
|
||||
showAILearningBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
@ -185,6 +186,7 @@ describe('prepareChartData', () => {
|
||||
label: 'max',
|
||||
},
|
||||
],
|
||||
showAILearningBanner: true,
|
||||
});
|
||||
});
|
||||
|
||||
@ -230,6 +232,7 @@ describe('prepareChartData', () => {
|
||||
label: 'max',
|
||||
},
|
||||
],
|
||||
showAILearningBanner: false,
|
||||
});
|
||||
});
|
||||
|
||||
@ -254,6 +257,7 @@ describe('prepareChartData', () => {
|
||||
expect(result).toEqual({
|
||||
data: [],
|
||||
information: [],
|
||||
showAILearningBanner: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -36,6 +36,7 @@ export const prepareChartData = ({
|
||||
const yValues = params.reduce((acc, curr, i) => {
|
||||
return { ...acc, [`y${i + 1}`]: parseInt(curr.value ?? '') };
|
||||
}, {});
|
||||
let showAILearningBanner = false;
|
||||
testCaseResults.forEach((result) => {
|
||||
const values = result.testResultValue?.reduce((acc, curr) => {
|
||||
const value = round(parseFloat(curr.value ?? ''), 2) || 0;
|
||||
@ -59,6 +60,10 @@ export const prepareChartData = ({
|
||||
const y2 = result?.maxBound ?? yValues.y2;
|
||||
const boundArea = isUndefined(y1) || isUndefined(y2) ? undefined : [y1, y2];
|
||||
|
||||
if (isUndefined(boundArea)) {
|
||||
showAILearningBanner = true;
|
||||
}
|
||||
|
||||
dataPoints.push({
|
||||
name: result.timestamp,
|
||||
status: result.testCaseStatus,
|
||||
@ -81,5 +86,6 @@ export const prepareChartData = ({
|
||||
color: COLORS[i],
|
||||
})) ?? [],
|
||||
data: dataPoints,
|
||||
showAILearningBanner,
|
||||
};
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user