mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-16 11:18:33 +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 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} />
|
||||||
|
@ -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;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -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(() => {
|
||||||
|
@ -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),
|
||||||
|
@ -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 });
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
@ -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,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user