mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-12-02 10:36:29 +00:00
fix(ui): Domain dp fixes (#24422)
* fix data products redirect path * do not show unprocessed status * fix domain issue * fix tests * add playwright tests
This commit is contained in:
parent
f6fc36e615
commit
c92b3e0d4d
@ -812,6 +812,45 @@ test.describe('Domains', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('Verify redirect path on data product delete', async ({ page }) => {
|
||||
const { afterAction, apiContext } = await getApiContext(page);
|
||||
const domain = new Domain();
|
||||
const dataProduct = new DataProduct([domain]);
|
||||
|
||||
await domain.create(apiContext);
|
||||
await dataProduct.create(apiContext);
|
||||
|
||||
await page.reload();
|
||||
await redirectToHomePage(page);
|
||||
|
||||
await sidebarClick(page, SidebarItem.DATA_PRODUCT);
|
||||
await selectDataProduct(page, dataProduct.data);
|
||||
|
||||
await page.getByTestId('manage-button').click();
|
||||
await page.getByTestId('delete-button-title').click();
|
||||
|
||||
await page.getByTestId('confirmation-text-input').click();
|
||||
await page.getByTestId('confirmation-text-input').fill('DELETE');
|
||||
|
||||
const dpListRes = page.waitForResponse(
|
||||
'/api/v1/search/query?q=&index=data_product_search_index*'
|
||||
);
|
||||
const deleteRes = page.waitForResponse('/api/v1/dataProducts/*');
|
||||
|
||||
await page.getByTestId('confirm-button').click();
|
||||
|
||||
await deleteRes;
|
||||
await dpListRes;
|
||||
|
||||
await expect(
|
||||
page.getByText(`"Data Product" deleted successfully!`)
|
||||
).toBeVisible();
|
||||
|
||||
await expect(page.getByTestId('add-entity-button')).toBeVisible();
|
||||
|
||||
await afterAction();
|
||||
});
|
||||
|
||||
test('Verify duplicate domain creation', async ({ page }) => {
|
||||
const { afterAction, apiContext } = await getApiContext(page);
|
||||
const domain = new Domain();
|
||||
|
||||
@ -18,6 +18,7 @@ import { toString } from 'lodash';
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { ROUTES } from '../../../constants/constants';
|
||||
import { ERROR_PLACEHOLDER_TYPE } from '../../../enums/common.enum';
|
||||
import { EntityType, TabSpecificField } from '../../../enums/entity.enum';
|
||||
import { DataProduct } from '../../../generated/entity/domains/dataProduct';
|
||||
@ -104,8 +105,7 @@ const DataProductsPage = () => {
|
||||
entity: t('label.data-product'),
|
||||
})
|
||||
);
|
||||
const domainPath = getDomainPath();
|
||||
navigate(domainPath);
|
||||
navigate(ROUTES.DATA_PRODUCT);
|
||||
} catch (err) {
|
||||
showErrorToast(
|
||||
err as AxiosError,
|
||||
|
||||
@ -24,6 +24,11 @@ export const EntityStatusBadge = ({
|
||||
status,
|
||||
showDivider = true,
|
||||
}: EntityStatusBadgeProps) => {
|
||||
// Do not show badge for 'Unprocessed' status
|
||||
if (status === EntityStatus.Unprocessed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Space>
|
||||
{showDivider && <Divider className="m-x-xs h-6" type="vertical" />}
|
||||
|
||||
@ -10,8 +10,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { EntityType } from '../enums/entity.enum';
|
||||
import { Domain, DomainType } from '../generated/entity/domains/domain';
|
||||
import { getDomainOptions, isDomainExist } from '../utils/DomainUtils';
|
||||
import {
|
||||
getDomainOptions,
|
||||
getQueryFilterToIncludeDomain,
|
||||
isDomainExist,
|
||||
} from '../utils/DomainUtils';
|
||||
|
||||
describe('getDomainOptions function', () => {
|
||||
const domains = [
|
||||
@ -146,4 +151,126 @@ describe('isDomainExist', () => {
|
||||
|
||||
expect(isDomainExist(domain, 'parent.child.grandchild')).toBe(true);
|
||||
});
|
||||
|
||||
describe('getQueryFilterToIncludeDomain', () => {
|
||||
it('should return correct query filter structure with domain and data product fqns', () => {
|
||||
const domainFqn = 'testDomain';
|
||||
const dataProductFqn = 'testDataProduct';
|
||||
|
||||
const result = getQueryFilterToIncludeDomain(domainFqn, dataProductFqn);
|
||||
|
||||
expect(result).toEqual({
|
||||
query: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
'domains.fullyQualifiedName': domainFqn,
|
||||
},
|
||||
},
|
||||
{
|
||||
bool: {
|
||||
must_not: [
|
||||
{
|
||||
term: {
|
||||
'dataProducts.fullyQualifiedName': dataProductFqn,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
bool: {
|
||||
must_not: [
|
||||
{
|
||||
terms: {
|
||||
entityType: [
|
||||
EntityType.DATA_PRODUCT,
|
||||
EntityType.TEST_SUITE,
|
||||
EntityType.QUERY,
|
||||
EntityType.TEST_CASE,
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should create filter with nested domain fqn', () => {
|
||||
const domainFqn = 'parent.child.grandchild';
|
||||
const dataProductFqn = 'product.subproduct';
|
||||
|
||||
const result = getQueryFilterToIncludeDomain(domainFqn, dataProductFqn);
|
||||
|
||||
const firstMust = result.query.bool.must[0] as {
|
||||
term: { 'domains.fullyQualifiedName': string };
|
||||
};
|
||||
|
||||
expect(firstMust.term['domains.fullyQualifiedName']).toBe(domainFqn);
|
||||
|
||||
const secondMust = result.query.bool.must[1] as {
|
||||
bool: {
|
||||
must_not: Array<{
|
||||
term: { 'dataProducts.fullyQualifiedName': string };
|
||||
}>;
|
||||
};
|
||||
};
|
||||
|
||||
expect(
|
||||
secondMust.bool.must_not[0].term['dataProducts.fullyQualifiedName']
|
||||
).toBe(dataProductFqn);
|
||||
});
|
||||
|
||||
it('should exclude specific entity types', () => {
|
||||
const domainFqn = 'testDomain';
|
||||
const dataProductFqn = 'testDataProduct';
|
||||
|
||||
const result = getQueryFilterToIncludeDomain(domainFqn, dataProductFqn);
|
||||
|
||||
const thirdMust = result.query.bool.must[2] as {
|
||||
bool: {
|
||||
must_not: Array<{
|
||||
terms: { entityType: EntityType[] };
|
||||
}>;
|
||||
};
|
||||
};
|
||||
const excludedEntityTypes = thirdMust.bool.must_not[0].terms.entityType;
|
||||
|
||||
expect(excludedEntityTypes).toContain(EntityType.DATA_PRODUCT);
|
||||
expect(excludedEntityTypes).toContain(EntityType.TEST_SUITE);
|
||||
expect(excludedEntityTypes).toContain(EntityType.QUERY);
|
||||
expect(excludedEntityTypes).toContain(EntityType.TEST_CASE);
|
||||
expect(excludedEntityTypes).toHaveLength(4);
|
||||
});
|
||||
|
||||
it('should handle empty string parameters', () => {
|
||||
const domainFqn = '';
|
||||
const dataProductFqn = '';
|
||||
|
||||
const result = getQueryFilterToIncludeDomain(domainFqn, dataProductFqn);
|
||||
|
||||
const firstMust = result.query.bool.must[0] as {
|
||||
term: { 'domains.fullyQualifiedName': string };
|
||||
};
|
||||
|
||||
expect(firstMust.term['domains.fullyQualifiedName']).toBe('');
|
||||
|
||||
const secondMust = result.query.bool.must[1] as {
|
||||
bool: {
|
||||
must_not: Array<{
|
||||
term: { 'dataProducts.fullyQualifiedName': string };
|
||||
}>;
|
||||
};
|
||||
};
|
||||
|
||||
expect(
|
||||
secondMust.bool.must_not[0].term['dataProducts.fullyQualifiedName']
|
||||
).toBe('');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -103,8 +103,13 @@ export const getQueryFilterToIncludeDomain = (
|
||||
bool: {
|
||||
must_not: [
|
||||
{
|
||||
term: {
|
||||
entityType: 'dataProduct',
|
||||
terms: {
|
||||
entityType: [
|
||||
EntityType.DATA_PRODUCT,
|
||||
EntityType.TEST_SUITE,
|
||||
EntityType.QUERY,
|
||||
EntityType.TEST_CASE,
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user