mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-11-11 08:23:40 +00:00
This commit is contained in:
parent
6d91757e3e
commit
dc02fbb358
@ -53,7 +53,7 @@ const testSuite = {
|
|||||||
name: `${tableFqn}.testSuite`,
|
name: `${tableFqn}.testSuite`,
|
||||||
executableEntityReference: tableFqn,
|
executableEntityReference: tableFqn,
|
||||||
};
|
};
|
||||||
const testCase = {
|
const testCase1 = {
|
||||||
name: `user_tokens_table_column_name_to_exist_${uuid()}`,
|
name: `user_tokens_table_column_name_to_exist_${uuid()}`,
|
||||||
entityLink: `<#E::table::${testSuite.executableEntityReference}>`,
|
entityLink: `<#E::table::${testSuite.executableEntityReference}>`,
|
||||||
parameterValues: [{ name: 'columnName', value: 'id' }],
|
parameterValues: [{ name: 'columnName', value: 'id' }],
|
||||||
@ -61,6 +61,16 @@ const testCase = {
|
|||||||
description: 'test case description',
|
description: 'test case description',
|
||||||
testSuite: testSuite.name,
|
testSuite: testSuite.name,
|
||||||
};
|
};
|
||||||
|
const testCase2 = {
|
||||||
|
name: `email_column_values_to_be_in_set_${uuid()}`,
|
||||||
|
entityLink: `<#E::table::${testSuite.executableEntityReference}::columns::email>`,
|
||||||
|
parameterValues: [
|
||||||
|
{ name: 'allowedValues', value: '["gmail","yahoo","collate"]' },
|
||||||
|
],
|
||||||
|
testDefinition: 'columnValuesToBeInSet',
|
||||||
|
testSuite: testSuite.name,
|
||||||
|
};
|
||||||
|
|
||||||
let testCaseId = '';
|
let testCaseId = '';
|
||||||
|
|
||||||
const OWNER1 = 'Aaron Johnson';
|
const OWNER1 = 'Aaron Johnson';
|
||||||
@ -139,10 +149,16 @@ describe('Data Quality and Profiler should work properly', () => {
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: `/api/v1/dataQuality/testCases`,
|
url: `/api/v1/dataQuality/testCases`,
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
body: testCase,
|
body: testCase1,
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
testCaseId = response.body.id;
|
testCaseId = response.body.id;
|
||||||
});
|
});
|
||||||
|
cy.request({
|
||||||
|
method: 'POST',
|
||||||
|
url: `/api/v1/dataQuality/testCases`,
|
||||||
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
|
body: testCase2,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -797,6 +813,55 @@ describe('Data Quality and Profiler should work properly', () => {
|
|||||||
.contains(sqlQuery);
|
.contains(sqlQuery);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Array params value should be visible while editing the test case', () => {
|
||||||
|
const tableName = DATABASE_SERVICE.entity.name;
|
||||||
|
interceptURL(
|
||||||
|
'GET',
|
||||||
|
`api/v1/tables/name/${DATABASE_SERVICE.service.name}.*.${tableName}?fields=*&include=all`,
|
||||||
|
'waitForPageLoad'
|
||||||
|
);
|
||||||
|
interceptURL(
|
||||||
|
'GET',
|
||||||
|
'/api/v1/dataQuality/testDefinitions/*',
|
||||||
|
'testCaseDefinition'
|
||||||
|
);
|
||||||
|
visitEntityDetailsPage({
|
||||||
|
term: tableName,
|
||||||
|
serviceName: DATABASE_SERVICE.service.name,
|
||||||
|
entity: DATA_ASSETS.tables,
|
||||||
|
});
|
||||||
|
verifyResponseStatusCode('@waitForPageLoad', 200);
|
||||||
|
cy.get('[data-testid="entity-header-display-name"]').should(
|
||||||
|
'contain',
|
||||||
|
tableName
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.get('[data-testid="profiler"]').click();
|
||||||
|
interceptURL('GET', '/api/v1/dataQuality/testCases?fields=*', 'testCase');
|
||||||
|
cy.get('[data-testid="profiler-tab-left-panel"]')
|
||||||
|
.contains('Data Quality')
|
||||||
|
.click();
|
||||||
|
verifyResponseStatusCode('@testCase', 200);
|
||||||
|
cy.get(`[data-testid="${testCase2.name}"]`)
|
||||||
|
.scrollIntoView()
|
||||||
|
.should('be.visible');
|
||||||
|
cy.get(`[data-testid="edit-${testCase2.name}"]`)
|
||||||
|
.should('be.visible')
|
||||||
|
.click();
|
||||||
|
|
||||||
|
verifyResponseStatusCode('@testCaseDefinition', 200);
|
||||||
|
|
||||||
|
cy.get('#tableTestForm_params_allowedValues_0_value')
|
||||||
|
.scrollIntoView()
|
||||||
|
.should('have.value', 'gmail');
|
||||||
|
cy.get('#tableTestForm_params_allowedValues_1_value')
|
||||||
|
.scrollIntoView()
|
||||||
|
.should('have.value', 'yahoo');
|
||||||
|
cy.get('#tableTestForm_params_allowedValues_2_value')
|
||||||
|
.scrollIntoView()
|
||||||
|
.should('have.value', 'collate');
|
||||||
|
});
|
||||||
|
|
||||||
it('Update displayName of test case', () => {
|
it('Update displayName of test case', () => {
|
||||||
interceptURL('GET', '/api/v1/dataQuality/testCases?*', 'getTestCase');
|
interceptURL('GET', '/api/v1/dataQuality/testCases?*', 'getTestCase');
|
||||||
|
|
||||||
@ -812,23 +877,23 @@ describe('Data Quality and Profiler should work properly', () => {
|
|||||||
verifyResponseStatusCode('@getTestCase', 200);
|
verifyResponseStatusCode('@getTestCase', 200);
|
||||||
interceptURL(
|
interceptURL(
|
||||||
'GET',
|
'GET',
|
||||||
`/api/v1/search/query?q=*${testCase.name}*&index=test_case_search_index*`,
|
`/api/v1/search/query?q=*${testCase1.name}*&index=test_case_search_index*`,
|
||||||
'searchTestCase'
|
'searchTestCase'
|
||||||
);
|
);
|
||||||
cy.get(
|
cy.get(
|
||||||
'[data-testid="test-case-container"] [data-testid="searchbar"]'
|
'[data-testid="test-case-container"] [data-testid="searchbar"]'
|
||||||
).type(testCase.name);
|
).type(testCase1.name);
|
||||||
verifyResponseStatusCode('@searchTestCase', 200);
|
verifyResponseStatusCode('@searchTestCase', 200);
|
||||||
cy.get(`[data-testid="${testCase.name}"]`)
|
cy.get(`[data-testid="${testCase1.name}"]`)
|
||||||
.scrollIntoView()
|
.scrollIntoView()
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
cy.get(`[data-testid="edit-${testCase.name}"]`).click();
|
cy.get(`[data-testid="edit-${testCase1.name}"]`).click();
|
||||||
cy.get('.ant-modal-body').should('be.visible');
|
cy.get('.ant-modal-body').should('be.visible');
|
||||||
cy.get('#tableTestForm_displayName').type('Table test case display name');
|
cy.get('#tableTestForm_displayName').type('Table test case display name');
|
||||||
interceptURL('PATCH', '/api/v1/dataQuality/testCases/*', 'updateTestCase');
|
interceptURL('PATCH', '/api/v1/dataQuality/testCases/*', 'updateTestCase');
|
||||||
cy.get('.ant-modal-footer').contains('Submit').click();
|
cy.get('.ant-modal-footer').contains('Submit').click();
|
||||||
verifyResponseStatusCode('@updateTestCase', 200);
|
verifyResponseStatusCode('@updateTestCase', 200);
|
||||||
cy.get(`[data-testid="${testCase.name}"]`)
|
cy.get(`[data-testid="${testCase1.name}"]`)
|
||||||
.scrollIntoView()
|
.scrollIntoView()
|
||||||
.invoke('text')
|
.invoke('text')
|
||||||
.then((text) => {
|
.then((text) => {
|
||||||
|
|||||||
@ -16,7 +16,7 @@ import Modal from 'antd/lib/modal/Modal';
|
|||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import { compare } from 'fast-json-patch';
|
import { compare } from 'fast-json-patch';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ENTITY_NAME_REGEX } from '../../constants/regex.constants';
|
import { ENTITY_NAME_REGEX } from '../../constants/regex.constants';
|
||||||
import { Table } from '../../generated/entity/data/table';
|
import { Table } from '../../generated/entity/data/table';
|
||||||
@ -50,6 +50,10 @@ const EditTestCaseModal: React.FC<EditTestCaseModalProps> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
const tableFqn = useMemo(
|
||||||
|
() => getEntityFqnFromEntityLink(testCase?.entityLink ?? ''),
|
||||||
|
[testCase]
|
||||||
|
);
|
||||||
const [selectedDefinition, setSelectedDefinition] =
|
const [selectedDefinition, setSelectedDefinition] =
|
||||||
useState<TestDefinition>();
|
useState<TestDefinition>();
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
@ -80,27 +84,13 @@ const EditTestCaseModal: React.FC<EditTestCaseModalProps> = ({
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const GenerateParamsField = useCallback(() => {
|
const paramsField = useMemo(() => {
|
||||||
if (selectedDefinition?.parameterDefinition) {
|
if (selectedDefinition?.parameterDefinition) {
|
||||||
return <ParameterForm definition={selectedDefinition} table={table} />;
|
return <ParameterForm definition={selectedDefinition} table={table} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return <></>;
|
||||||
}, [testCase, selectedDefinition, table]);
|
}, [selectedDefinition, table]);
|
||||||
|
|
||||||
const fetchTestDefinitionById = async () => {
|
|
||||||
setIsLoading(true);
|
|
||||||
try {
|
|
||||||
const definition = await getTestDefinitionById(
|
|
||||||
testCase.testDefinition.id || ''
|
|
||||||
);
|
|
||||||
setSelectedDefinition(definition);
|
|
||||||
} catch (error) {
|
|
||||||
showErrorToast(error as AxiosError);
|
|
||||||
} finally {
|
|
||||||
setIsLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const createTestCaseObj = (value: {
|
const createTestCaseObj = (value: {
|
||||||
testName: string;
|
testName: string;
|
||||||
@ -161,7 +151,7 @@ const EditTestCaseModal: React.FC<EditTestCaseModalProps> = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getParamsValue = () => {
|
const getParamsValue = (selectedDefinition: TestDefinition) => {
|
||||||
return testCase?.parameterValues?.reduce(
|
return testCase?.parameterValues?.reduce(
|
||||||
(acc, curr) => ({
|
(acc, curr) => ({
|
||||||
...acc,
|
...acc,
|
||||||
@ -186,21 +176,34 @@ const EditTestCaseModal: React.FC<EditTestCaseModalProps> = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
const fetchTestDefinitionById = async () => {
|
||||||
if (testCase) {
|
setIsLoading(true);
|
||||||
fetchTestDefinitionById();
|
try {
|
||||||
const tableFqn = getEntityFqnFromEntityLink(testCase?.entityLink);
|
const definition = await getTestDefinitionById(
|
||||||
|
testCase.testDefinition.id || ''
|
||||||
|
);
|
||||||
form.setFieldsValue({
|
form.setFieldsValue({
|
||||||
name: testCase?.name,
|
name: testCase?.name,
|
||||||
testDefinition: testCase?.testDefinition?.name,
|
testDefinition: testCase?.testDefinition?.name,
|
||||||
displayName: testCase?.displayName,
|
displayName: testCase?.displayName,
|
||||||
params: getParamsValue(),
|
params: getParamsValue(definition),
|
||||||
table: getNameFromFQN(tableFqn),
|
table: getNameFromFQN(tableFqn),
|
||||||
column: getNameFromFQN(
|
column: getNameFromFQN(
|
||||||
getEntityFqnFromEntityLink(testCase?.entityLink, isColumn)
|
getEntityFqnFromEntityLink(testCase?.entityLink, isColumn)
|
||||||
),
|
),
|
||||||
computePassedFailedRowCount: testCase?.computePassedFailedRowCount,
|
computePassedFailedRowCount: testCase?.computePassedFailedRowCount,
|
||||||
});
|
});
|
||||||
|
setSelectedDefinition(definition);
|
||||||
|
} catch (error) {
|
||||||
|
showErrorToast(error as AxiosError);
|
||||||
|
} finally {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (testCase) {
|
||||||
|
fetchTestDefinitionById();
|
||||||
|
|
||||||
const isContainsColumnName = testCase.parameterValues?.find(
|
const isContainsColumnName = testCase.parameterValues?.find(
|
||||||
(value) => value.name === 'columnName'
|
(value) => value.name === 'columnName'
|
||||||
@ -281,7 +284,7 @@ const EditTestCaseModal: React.FC<EditTestCaseModalProps> = ({
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{GenerateParamsField()}
|
{paramsField}
|
||||||
|
|
||||||
{!showOnlyParameter && (
|
{!showOnlyParameter && (
|
||||||
<>
|
<>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user