Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GEN-706 Feat: Introducing incident tab in table details page #17860

Merged
merged 9 commits into from
Sep 24, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -388,4 +388,155 @@ test.describe('Incident Manager', () => {
);
});
});

test('Validate Incident Tab in Entity details page', async ({ page }) => {
const testCases = table1.testCasesResponseData;
await table1.visitEntityPage(page);
const incidentListResponse = page.waitForResponse(
`/api/v1/dataQuality/testCases/testCaseIncidentStatus?*originEntityFQN=${table1.entityResponseData?.['fullyQualifiedName']}*`
);

await page.click('[data-testid="incidents"]');
await incidentListResponse;

for (const testCase of testCases) {
await expect(
page.locator(`[data-testid="test-case-${testCase?.['name']}"]`)
).toBeVisible();
}
const lineageResponse = page.waitForResponse(
`/api/v1/lineage/getLineage?*fqn=${table1.entityResponseData?.['fullyQualifiedName']}*`
);
const incidentCountResponse = page.waitForResponse(
`/api/v1/dataQuality/testCases/testCaseIncidentStatus?*originEntityFQN=${table1.entityResponseData?.['fullyQualifiedName']}*limit=0*`
);
await page.click('[data-testid="lineage"]');
await lineageResponse;
await incidentCountResponse;

await page.waitForSelector("[role='dialog']", { state: 'visible' });

await expect(page.getByTestId('Incidents-label')).toBeVisible();
await expect(page.getByTestId('Incidents-value')).toContainText('3');

const incidentResponse = page.waitForResponse(
`/api/v1/dataQuality/testCases/testCaseIncidentStatus?*originEntityFQN=${table1.entityResponseData?.['fullyQualifiedName']}*`
);
await page.getByTestId('Incidents-value').click();
await incidentResponse;

for (const testCase of testCases) {
await expect(
page.locator(`[data-testid="test-case-${testCase?.['name']}"]`)
).toBeVisible();
}
});

test("Verify filters in Incident Manager's page", async ({ page }) => {
const assigneeTestCase = {
username: user1.data.email.split('@')[0].toLocaleLowerCase(),
userDisplayName: user1.getUserName(),
testCaseName: table1.testCasesResponseData[2]?.['name'],
};
const testCase1 = table1.testCasesResponseData[0]?.['name'];
const incidentDetailsRes = page.waitForResponse(
'/api/v1/dataQuality/testCases/testCaseIncidentStatus?latest=true&startTs=*&endTs=*&limit=*'
);
await sidebarClick(page, SidebarItem.INCIDENT_MANAGER);
await incidentDetailsRes;

await page.click('[data-testid="select-assignee"]');
const searchUserResponse = page.waitForResponse(
`/api/v1/search/query?q=*${assigneeTestCase.userDisplayName}*index=user_search_index*`
);
await page
.getByTestId('select-assignee')
.locator('input')
.fill(assigneeTestCase.userDisplayName);
await searchUserResponse;

const assigneeFilterRes = page.waitForResponse(
`/api/v1/dataQuality/testCases/testCaseIncidentStatus?*assignee=${assigneeTestCase.username}*`
);
await page.click(`[data-testid="${assigneeTestCase.username}"]`);
await assigneeFilterRes;

await expect(
page.locator(`[data-testid="test-case-${assigneeTestCase.testCaseName}"]`)
).toBeVisible();
await expect(
page.locator(`[data-testid="test-case-${testCase1}"]`)
).not.toBeVisible();

const nonAssigneeFilterRes = page.waitForResponse(
'/api/v1/dataQuality/testCases/testCaseIncidentStatus?latest=true&startTs=*&endTs=*&limit=*'
);
await page
.getByTestId('select-assignee')
.getByLabel('close-circle')
.click();
await nonAssigneeFilterRes;

await page.click(`[data-testid="status-select"]`);
const statusFilterRes = page.waitForResponse(
'/api/v1/dataQuality/testCases/testCaseIncidentStatus?*testCaseResolutionStatusType=Assigned*'
);
await page.click(`[title="Assigned"]`);
await statusFilterRes;

await expect(
page.locator(`[data-testid="test-case-${assigneeTestCase.testCaseName}"]`)
).toBeVisible();
await expect(
page.locator(`[data-testid="test-case-${testCase1}"]`)
).not.toBeVisible();

const nonStatusFilterRes = page.waitForResponse(
'/api/v1/dataQuality/testCases/testCaseIncidentStatus?latest=true&startTs=*&endTs=*&limit=*'
);
await page.getByTestId('status-select').getByLabel('close-circle').click();
await nonStatusFilterRes;

await page.click('[data-testid="test-case-select"]');
const testCaseResponse = page.waitForResponse(
`/api/v1/search/query?q=${testCase1}*index=test_case_search_index*`
);
await page.getByTestId('test-case-select').locator('input').fill(testCase1);
await testCaseResponse;

const testCaseFilterRes = page.waitForResponse(
`/api/v1/dataQuality/testCases/testCaseIncidentStatus?*testCaseFQN=*${testCase1}*`
);
await page.click(`[title="${testCase1}"]`);
await testCaseFilterRes;

await expect(
page.locator(`[data-testid="test-case-${assigneeTestCase.testCaseName}"]`)
).not.toBeVisible();
await expect(
page.locator(`[data-testid="test-case-${testCase1}"]`)
).toBeVisible();

const nonTestCaseFilterRes = page.waitForResponse(
'/api/v1/dataQuality/testCases/testCaseIncidentStatus?latest=true&startTs=*&endTs=*&limit=*'
);
await page
.getByTestId('test-case-select')
.getByLabel('close-circle')
.click();
await nonTestCaseFilterRes;

await page.click('[data-testid="date-picker-menu"]');
const timeSeriesFilterRes = page.waitForResponse(
'/api/v1/dataQuality/testCases/testCaseIncidentStatus?latest=true&startTs=*&endTs=*&limit=*'
);
await page.getByRole('menuitem', { name: 'Yesterday' }).click();
await timeSeriesFilterRes;

for (const testCase of table1.testCasesResponseData) {
await expect(
page.locator(`[data-testid="test-case-${testCase?.['name']}"]`)
).toBeVisible();
}
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
import { useTranslation } from 'react-i18next';
import { ROUTES } from '../../../../constants/constants';
import { mockTablePermission } from '../../../../constants/mockTourData.constants';
import { PROFILER_FILTER_RANGE } from '../../../../constants/profiler.constant';
import { usePermissionProvider } from '../../../../context/PermissionProvider/PermissionProvider';
import {
OperationPermission,
Expand All @@ -33,9 +34,14 @@ import { ExplorePageTabs } from '../../../../enums/Explore.enum';
import { Table } from '../../../../generated/entity/data/table';
import { TestSummary } from '../../../../generated/tests/testCase';
import useCustomLocation from '../../../../hooks/useCustomLocation/useCustomLocation';
import { getListTestCaseIncidentStatus } from '../../../../rest/incidentManagerAPI';
import { getLatestTableProfileByFqn } from '../../../../rest/tableAPI';
import { getTestCaseExecutionSummary } from '../../../../rest/testAPI';
import { formTwoDigitNumber } from '../../../../utils/CommonUtils';
import {
getCurrentMillis,
getEpochMillisForPastDays,
} from '../../../../utils/date-time/DateTimeUtils';
import {
getFormattedEntityData,
getSortedTagsWithHighlight,
Expand Down Expand Up @@ -69,6 +75,7 @@ function TableSummary({
const { getEntityPermission } = usePermissionProvider();

const [profileData, setProfileData] = useState<TableProfileDetails>();
const [incidentCount, setIncidentCount] = useState(0);
const [testSuiteSummary, setTestSuiteSummary] = useState<TestSummary>();
const [tablePermissions, setTablePermissions] = useState<OperationPermission>(
DEFAULT_ENTITY_PERMISSION
Expand Down Expand Up @@ -100,6 +107,26 @@ function TableSummary({
}
};

const fetchIncidentCount = async () => {
if (tableDetails?.fullyQualifiedName) {
try {
const { paging } = await getListTestCaseIncidentStatus({
limit: 0,
latest: true,
originEntityFQN: tableDetails?.fullyQualifiedName,
startTs: getEpochMillisForPastDays(
PROFILER_FILTER_RANGE.last30days.days
),
endTs: getCurrentMillis(),
});

setIncidentCount(paging.total);
} catch (error) {
setIncidentCount(0);
}
}
};

const fetchProfilerData = useCallback(async () => {
try {
const { profile, tableConstraints } = await getLatestTableProfileByFqn(
Expand Down Expand Up @@ -165,8 +192,11 @@ function TableSummary({
}, [tableDetails, testSuiteSummary, viewProfilerPermission]);

const entityInfo = useMemo(
() => getEntityOverview(ExplorePageTabs.TABLES, tableDetails),
[tableDetails]
() =>
getEntityOverview(ExplorePageTabs.TABLES, tableDetails, {
incidentCount,
}),
[tableDetails, incidentCount]
);

const formattedColumnsData: BasicEntityInfo[] = useMemo(
Expand Down Expand Up @@ -196,6 +226,7 @@ function TableSummary({
if (shouldFetchProfilerData) {
fetchProfilerData();
fetchAllTests();
fetchIncidentCount();
}
} else {
setTablePermissions(mockTablePermission as OperationPermission);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ jest.mock('../../../../context/PermissionProvider/PermissionProvider', () => ({
describe('TableSummary component tests', () => {
it('Component should render properly, when loaded in the Explore page.', async () => {
await act(async () => {
render(<TableSummary entityDetails={mockTableEntityDetails} />);
render(<TableSummary entityDetails={mockTableEntityDetails} />, {
wrapper: MemoryRouter,
});
});

const profilerHeader = screen.getByTestId('profiler-header');
Expand Down Expand Up @@ -176,7 +178,9 @@ describe('TableSummary component tests', () => {
);

await act(async () => {
render(<TableSummary entityDetails={mockTableEntityDetails} />);
render(<TableSummary entityDetails={mockTableEntityDetails} />, {
wrapper: MemoryRouter,
});
});

const testsPassedLabel = screen.getByTestId('test-passed');
Expand Down Expand Up @@ -209,7 +213,9 @@ describe('TableSummary component tests', () => {
})
);
await act(async () => {
render(<TableSummary entityDetails={mockTableEntityDetails} />);
render(<TableSummary entityDetails={mockTableEntityDetails} />, {
wrapper: MemoryRouter,
});
});
const testsPassedValue = screen.getByTestId('test-passed-value');
const testsAbortedValue = screen.getByTestId('test-aborted-value');
Expand Down
Loading
Loading