chore(ui): search index details and version cypress (#13287)

* Added cypress for search index version page
Added cypress checks for domains on version pages

* Added cypress for search index details page with different roles

* worked on comments

* fixed comment
This commit is contained in:
Aniket Katkar 2023-09-26 17:46:28 +05:30 committed by GitHub
parent 9900764961
commit 82b06b1a79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 1215 additions and 162 deletions

View File

@ -14,6 +14,11 @@
// eslint-disable-next-line spaced-comment
/// <reference types="cypress" />
import {
customFormatDateTime,
getCurrentMillis,
getEpochMillisForFutureDays,
} from '../../src/utils/date-time/DateTimeUtils';
import {
CUSTOM_PROPERTY_INVALID_NAMES,
CUSTOM_PROPERTY_NAME_VALIDATION_ERROR,
@ -538,8 +543,10 @@ export const visitEntityDetailsPage = (
cy.get('[data-testid="searchBox"]').type('{enter}');
verifyResponseStatusCode('@explorePageSearch', 200);
cy.get(`[data-testid="${entity}-tab"]`).should('be.visible').click();
cy.get(`[data-testid="${entity}-tab"]`).should('be.visible');
const tabName = entity === 'searchIndexes' ? 'search indexes' : entity;
cy.get(`[data-testid="${tabName}-tab"]`).should('be.visible').click();
cy.get(`[data-testid="${tabName}-tab"]`).should('be.visible');
verifyResponseStatusCode('@explorePageTabSearch', 200);
cy.get(`[data-testid="${id}"]`).scrollIntoView().click();
@ -1168,6 +1175,8 @@ export const addTier = (tier, entity) => {
cy.clickOutside();
cy.get('[data-testid="Tier"]').should('contain', tier);
cy.get('.tier-card-popover').clickOutside();
};
export const removeTier = (entity) => {
@ -1178,6 +1187,8 @@ export const removeTier = (entity) => {
verifyResponseStatusCode('@patchTier', 200);
cy.get('[data-testid="Tier"]').should('contain', 'No Tier');
cy.get('.tier-card-popover').clickOutside();
};
export const deleteEntity = (
@ -1216,7 +1227,7 @@ export const deleteEntity = (
cy.get('[data-testid="confirm-button"]').click();
verifyResponseStatusCode(`@${deletionType}DeleteTable`, 200);
toastNotification(`${successMessageEntityName} deleted successfully!`, false);
toastNotification(`${successMessageEntityName} deleted successfully!`);
};
export const visitServiceDetailsPage = (
@ -1301,3 +1312,247 @@ export const visitDataModelPage = (dataModelFQN, dataModelName) => {
verifyResponseStatusCode('@getDataModelDetails', 200);
};
export const createAnnouncement = (title, startDate, endDate, description) => {
cy.get('[data-testid="add-announcement"]').should('be.visible').click();
cy.get('.ant-modal-header').contains('Make an announcement');
cy.get('#title').type(title);
cy.get('#startTime').click().type(`${startDate}{enter}`);
cy.clickOutside();
cy.get('#endTime').click().type(`${endDate}{enter}`);
cy.clickOutside();
cy.get(descriptionBox).type(description);
cy.get('[id="announcement-submit"]').scrollIntoView().click();
};
export const addAnnouncement = (value) => {
interceptURL('GET', '/api/v1/permissions/*/name/*', 'entityPermission');
interceptURL('GET', '/api/v1/feed/count?entityLink=*', 'entityFeed');
interceptURL('GET', `/api/v1/${value.entity}/name/*`, 'getEntityDetails');
interceptURL('POST', '/api/v1/feed', 'waitForAnnouncement');
interceptURL(
'GET',
'/api/v1/feed?entityLink=*type=Announcement',
'announcementFeed'
);
visitEntityDetailsPage(value.term, value.serviceName, value.entity);
cy.get('[data-testid="manage-button"]').click();
cy.get('[data-testid="announcement-button"]').click();
cy.wait('@announcementFeed').then((res) => {
const data = res.response.body.data;
if (data.length > 0) {
const token = localStorage.getItem('oidcIdToken');
data.map((feed) => {
cy.request({
method: 'DELETE',
url: `/api/v1/feed/${feed.id}`,
headers: { Authorization: `Bearer ${token}` },
}).then((response) => {
expect(response.status).to.eq(200);
});
});
cy.reload();
cy.get('[data-testid="manage-button"]').click();
cy.get('[data-testid="announcement-button"]').click();
}
const startDate = customFormatDateTime(getCurrentMillis(), 'yyyy-MM-dd');
const endDate = customFormatDateTime(
getEpochMillisForFutureDays(5),
'yyyy-MM-dd'
);
cy.get('[data-testid="announcement-error"]')
.should('be.visible')
.contains('No Announcements, Click on add announcement to add one.');
// Create Active Announcement
createAnnouncement(
'Announcement Title',
startDate,
endDate,
'Announcement Description'
);
// wait time for success toast message
verifyResponseStatusCode('@waitForAnnouncement', 201);
cy.get('.Toastify__close-button >').should('be.visible').click();
// Create InActive Announcement
const InActiveStartDate = customFormatDateTime(
getEpochMillisForFutureDays(6),
'yyyy-MM-dd'
);
const InActiveEndDate = customFormatDateTime(
getEpochMillisForFutureDays(11),
'yyyy-MM-dd'
);
createAnnouncement(
'InActive Announcement Title',
InActiveStartDate,
InActiveEndDate,
'InActive Announcement Description'
);
// wait time for success toast message
verifyResponseStatusCode('@waitForAnnouncement', 201);
cy.get('.Toastify__close-button >').should('be.visible').click();
// check for inActive-announcement
cy.get('[data-testid="inActive-announcements"]').should('be.visible');
// close announcement drawer
cy.get('[data-testid="title"] .anticon-close').should('be.visible').click();
// reload page to get the active announcement card
cy.reload();
verifyResponseStatusCode('@entityPermission', 200);
verifyResponseStatusCode('@getEntityDetails', 200);
verifyResponseStatusCode('@entityFeed', 200);
// check for announcement card on entity page
cy.get('[data-testid="announcement-card"]').should('be.visible');
});
};
export const addTags = (classificationName, tagName, entity) => {
cy.get(
'[data-testid="entity-right-panel"] [data-testid="tags-container"] [data-testid="add-tag"]'
).click();
cy.get('[data-testid="tag-selector"] #tagsForm_tags').type(tagName);
cy.get(`[data-testid="tag-${classificationName}.${tagName}"]`).click();
interceptURL('PATCH', `/api/v1/${entity}/*`, 'patchTag');
cy.get('[data-testid="saveAssociatedTag"]').click();
verifyResponseStatusCode('@patchTag', 200);
cy.get(
`[data-testid="entity-right-panel"] [data-testid="tags-container"] [data-testid="tag-${classificationName}.${tagName}"]`
)
.scrollIntoView()
.should('be.visible');
};
export const removeTags = (classificationName, tagName, entity) => {
cy.get(
'[data-testid="entity-right-panel"] [data-testid="tags-container"] [data-testid="edit-button"]'
).click();
cy.get(
`[data-testid="selected-tag-${classificationName}.${tagName}"] [data-testid="remove-tags"]`
).click();
interceptURL('PATCH', `/api/v1/${entity}/*`, `patchTag`);
cy.get('[data-testid="saveAssociatedTag"]').click();
verifyResponseStatusCode(`@patchTag`, 200);
cy.get(
'[data-testid="entity-right-panel"] [data-testid="tags-container"]'
).then(($body) => {
const manageButton = $body.find(
`[data-testid="tag-${classificationName}.${tagName}"]`
);
expect(manageButton.length).to.equal(0);
});
};
export const addTableFieldTags = (
dataRowKey,
classificationName,
tagName,
entity
) => {
cy.get(
`[data-row-key="${dataRowKey}"] [data-testid="tags-container"] [data-testid="add-tag"]`
).click();
cy.get('[data-testid="tag-selector"] #tagsForm_tags').type(tagName);
cy.get(`[data-testid="tag-${classificationName}.${tagName}"]`).click();
interceptURL('PATCH', `/api/v1/${entity}/*`, 'patchTag');
cy.get('[data-testid="saveAssociatedTag"]').click();
verifyResponseStatusCode('@patchTag', 200);
cy.get(
`[data-row-key="${dataRowKey}"] [data-testid="tag-${classificationName}.${tagName}"]`
)
.scrollIntoView()
.should('be.visible');
};
export const removeTableFieldTags = (
dataRowKey,
classificationName,
tagName,
entity
) => {
cy.get(
`[data-row-key="${dataRowKey}"] [data-testid="tags-container"] [data-testid="edit-button"]`
).click();
cy.get(
`[data-testid="selected-tag-${classificationName}.${tagName}"] [data-testid="remove-tags"]`
).click();
interceptURL('PATCH', `/api/v1/${entity}/*`, `patchTag`);
cy.get('[data-testid="saveAssociatedTag"]').click();
verifyResponseStatusCode(`@patchTag`, 200);
cy.get(`[data-row-key="${dataRowKey}"]`).then(($body) => {
const manageButton = $body.find(
`[data-testid="tag-${classificationName}.${tagName}"]`
);
expect(manageButton.length).to.equal(0);
});
};
export const updateDescription = (description, entity) => {
cy.get(
'[data-testid="asset-description-container"] [data-testid="edit-description"]'
).click();
cy.get(descriptionBox).should('be.visible').click().clear().type(description);
interceptURL('PATCH', `/api/v1/${entity}/*`, 'updateDescription');
cy.get('[data-testid="save"]').click();
verifyResponseStatusCode('@updateDescription', 200);
};
export const updateTableFieldDescription = (
dataRowKey,
description,
entity
) => {
cy.get(
`[data-row-key="${dataRowKey}"] [data-testid="description"] [data-testid="edit-button"]`
).click();
cy.get(descriptionBox).should('be.visible').click().clear().type(description);
interceptURL('PATCH', `/api/v1/${entity}/*`, 'updateDescription');
cy.get('[data-testid="save"]').click();
verifyResponseStatusCode('@updateDescription', 200);
};

View File

@ -0,0 +1,113 @@
/*
* Copyright 2023 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// / <reference types="Cypress" />
import { uuid } from '../common/common';
export const TIER = 'Tier1';
export const TAG_1 = {
classification: 'PersonalData',
tag: 'SpecialCategory',
};
export const UPDATE_DESCRIPTION = 'Updated description for search index.';
export const UPDATE_FIELD_DESCRIPTION =
'Updated description for search index field.';
export const USER_FIRST_NAME = `USER_FIRST_NAME_${uuid()}`;
export const USER_LAST_NAME = `USER_LAST_NAME_${uuid()}`;
export const USER_NAME = `test_user${uuid()}`;
export const USER_EMAIL = `${USER_NAME}@openmetadata.org`;
export const SEARCH_INDEX_NAME = `search_index-${uuid()}`;
export const SEARCH_INDEX_DISPLAY_NAME = `${SEARCH_INDEX_NAME}_display_name`;
export const USER_CREDENTIALS = {
firstName: USER_FIRST_NAME,
lastName: USER_LAST_NAME,
email: USER_EMAIL,
password: 'User@OMD123',
};
export const SEARCH_INDEX_DETAILS_FOR_ANNOUNCEMENT = {
term: SEARCH_INDEX_NAME,
displayName: SEARCH_INDEX_DISPLAY_NAME,
entity: 'searchIndexes',
serviceName: 'elasticsearch_sample',
entityType: 'Search Index',
};
export const SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST = {
name: SEARCH_INDEX_NAME,
service: 'elasticsearch_sample',
fields: [
{
name: 'name',
dataType: 'TEXT',
dataTypeDisplay: 'text',
fullyQualifiedName: `elasticsearch_sample.${SEARCH_INDEX_NAME}.name`,
tags: [],
},
{
name: 'displayName',
dataType: 'TEXT',
dataTypeDisplay: 'text',
description: 'Description for field displayName',
fullyQualifiedName: `elasticsearch_sample.${SEARCH_INDEX_NAME}.displayName`,
tags: [],
},
{
name: 'description',
dataType: 'TEXT',
dataTypeDisplay: 'text',
fullyQualifiedName: `elasticsearch_sample.${SEARCH_INDEX_NAME}.description`,
tags: [],
},
{
name: 'columns',
dataType: 'NESTED',
dataTypeDisplay: 'nested',
fullyQualifiedName: `elasticsearch_sample.${SEARCH_INDEX_NAME}.columns`,
tags: [],
children: [
{
name: 'name',
dataType: 'TEXT',
dataTypeDisplay: 'text',
fullyQualifiedName: `elasticsearch_sample.${SEARCH_INDEX_NAME}.columns.name`,
tags: [],
},
{
name: 'displayName',
dataType: 'TEXT',
dataTypeDisplay: 'text',
fullyQualifiedName: `elasticsearch_sample.${SEARCH_INDEX_NAME}.columns.displayName`,
tags: [],
},
{
name: 'description',
dataType: 'TEXT',
dataTypeDisplay: 'text',
fullyQualifiedName: `elasticsearch_sample.${SEARCH_INDEX_NAME}.columns.description`,
tags: [],
},
],
},
{
name: 'databaseSchema',
dataType: 'TEXT',
dataTypeDisplay: 'text',
description: 'Database Schema that this table belongs to.',
fullyQualifiedName: `elasticsearch_sample.${SEARCH_INDEX_NAME}.databaseSchema`,
tags: [],
},
],
tags: [],
};

View File

@ -18,15 +18,25 @@ export const OWNER = 'Amber Green';
export const REVIEWER = 'Amanda York';
export const TIER = 'Tier1';
const DOMAIN_NAME = `cypress_version_test_domain-${uuid()}`;
const TABLE_NAME = `cypress_version_table-${uuid()}`;
const TOPIC_NAME = `cypress_version_topic-${uuid()}`;
const DASHBOARD_NAME = `cypress_version_dashboard-${uuid()}`;
const PIPELINE_NAME = `cypress_version_pipeline-${uuid()}`;
const ML_MODEL_NAME = `cypress_version_ml_model-${uuid()}`;
const CONTAINER_NAME = `cypress_version_container-${uuid()}`;
const SEARCH_INDEX_NAME = `cypress_version_search_index-${uuid()}`;
const STORED_PROCEDURE_NAME = `cypress_version_stored_procedure-${uuid()}`;
const DATA_MODEL_NAME = `cypress_version_data_model_${uuid()}`;
export const DOMAIN_CREATION_DETAILS = {
name: DOMAIN_NAME,
description: `Description for ${DOMAIN_NAME}`,
domainType: 'Aggregate',
experts: [],
};
const TABLE_DETAILS_FOR_VERSION_TEST = {
name: TABLE_NAME,
columns: [
@ -135,29 +145,26 @@ const TOPIC_DETAILS_FOR_VERSION_TEST = {
{
name: 'default',
dataType: 'RECORD',
fullyQualifiedName: 'sample_kafka.cypress_version_test_topic.default',
fullyQualifiedName: `sample_kafka.${TOPIC_NAME}.default`,
tags: [],
children: [
{
name: 'name',
dataType: 'RECORD',
fullyQualifiedName:
'sample_kafka.cypress_version_test_topic.default.name',
fullyQualifiedName: `sample_kafka.${TOPIC_NAME}.default.name`,
tags: [],
children: [
{
name: 'first_name',
dataType: 'STRING',
description: 'Description for schema field first_name',
fullyQualifiedName:
'sample_kafka.cypress_version_test_topic.default.name.first_name',
fullyQualifiedName: `sample_kafka.${TOPIC_NAME}.default.name.first_name`,
tags: [],
},
{
name: 'last_name',
dataType: 'STRING',
fullyQualifiedName:
'sample_kafka.cypress_version_test_topic.default.name.last_name',
fullyQualifiedName: `sample_kafka.${TOPIC_NAME}.default.name.last_name`,
tags: [],
},
],
@ -165,15 +172,13 @@ const TOPIC_DETAILS_FOR_VERSION_TEST = {
{
name: 'age',
dataType: 'INT',
fullyQualifiedName:
'sample_kafka.cypress_version_test_topic.default.age',
fullyQualifiedName: `sample_kafka.${TOPIC_NAME}.default.age`,
tags: [],
},
{
name: 'club_name',
dataType: 'STRING',
fullyQualifiedName:
'sample_kafka.cypress_version_test_topic.default.club_name',
fullyQualifiedName: `sample_kafka.${TOPIC_NAME}.default.club_name`,
tags: [],
},
],
@ -259,8 +264,7 @@ const PIPELINE_DETAILS_FOR_VERSION_TEST = {
{
name: 'cypress_task_1',
displayName: 'cypress_task_1',
fullyQualifiedName:
'sample_airflow.cypress_version_test_pipeline.cypress_task_1',
fullyQualifiedName: `sample_airflow.${PIPELINE_NAME}.cypress_task_1`,
sourceUrl:
'http://localhost:8080/taskinstance/list/?flt1_dag_id_equals=assert_table_exists',
downstreamTasks: [],
@ -270,8 +274,7 @@ const PIPELINE_DETAILS_FOR_VERSION_TEST = {
{
name: 'cypress_task_2',
displayName: 'cypress_task_2',
fullyQualifiedName:
'sample_airflow.cypress_version_test_pipeline.cypress_task_2',
fullyQualifiedName: `sample_airflow.${PIPELINE_NAME}.cypress_task_2`,
description: 'Description for task cypress_task_2',
sourceUrl:
'http://localhost:8080/taskinstance/list/?flt1_dag_id_equals=assert_table_exists',
@ -282,8 +285,7 @@ const PIPELINE_DETAILS_FOR_VERSION_TEST = {
{
name: 'cypress_task_3',
displayName: 'cypress_task_3',
fullyQualifiedName:
'sample_airflow.cypress_version_test_pipeline.cypress_task_3',
fullyQualifiedName: `sample_airflow.${PIPELINE_NAME}.cypress_task_3`,
sourceUrl:
'http://localhost:8080/taskinstance/list/?flt1_dag_id_equals=assert_table_exists',
downstreamTasks: [],
@ -348,7 +350,7 @@ const ML_MODEL_DETAILS_FOR_VERSION_TEST = {
{
name: 'feature_1',
dataType: 'numerical',
fullyQualifiedName: 'mlflow_svc.cypress_version_test_ml_model.feature_1',
fullyQualifiedName: `mlflow_svc.${ML_MODEL_NAME}.feature_1`,
featureSources: [],
tags: [],
},
@ -356,13 +358,13 @@ const ML_MODEL_DETAILS_FOR_VERSION_TEST = {
name: 'feature_2',
dataType: 'numerical',
description: 'Description for mlFeature feature_2',
fullyQualifiedName: 'mlflow_svc.cypress_version_test_ml_model.feature_2',
fullyQualifiedName: `mlflow_svc.${ML_MODEL_NAME}.feature_2`,
featureSources: [],
},
{
name: 'feature_3',
dataType: 'numerical',
fullyQualifiedName: 'mlflow_svc.cypress_version_test_ml_model.feature_3',
fullyQualifiedName: `mlflow_svc.${ML_MODEL_NAME}.feature_3`,
featureSources: [],
},
],
@ -427,8 +429,7 @@ const CONTAINER_DETAILS_FOR_VERSION_TEST = {
name: 'column_1',
dataType: 'NUMERIC',
dataTypeDisplay: 'numeric',
fullyQualifiedName:
's3_storage_sample.departments.finance.cypress_version_test_container.column_1',
fullyQualifiedName: `s3_storage_sample.departments.finance.${CONTAINER_NAME}.column_1`,
tags: [],
ordinalPosition: 1,
},
@ -437,8 +438,7 @@ const CONTAINER_DETAILS_FOR_VERSION_TEST = {
dataType: 'BOOLEAN',
dataTypeDisplay: 'boolean',
description: 'Description for column column_2',
fullyQualifiedName:
's3_storage_sample.departments.finance.cypress_version_test_container.column_2',
fullyQualifiedName: `s3_storage_sample.departments.finance.${CONTAINER_NAME}.column_2`,
tags: [],
ordinalPosition: 2,
},
@ -446,8 +446,7 @@ const CONTAINER_DETAILS_FOR_VERSION_TEST = {
name: 'column_3',
dataType: 'BOOLEAN',
dataTypeDisplay: 'boolean',
fullyQualifiedName:
's3_storage_sample.departments.finance.cypress_version_test_container.column_3',
fullyQualifiedName: `s3_storage_sample.departments.finance.${CONTAINER_NAME}.column_3`,
tags: [],
ordinalPosition: 3,
},
@ -455,8 +454,7 @@ const CONTAINER_DETAILS_FOR_VERSION_TEST = {
name: 'column_4',
dataType: 'NUMERIC',
dataTypeDisplay: 'numeric',
fullyQualifiedName:
's3_storage_sample.departments.finance.cypress_version_test_container.column_4',
fullyQualifiedName: `s3_storage_sample.departments.finance.${CONTAINER_NAME}.column_4`,
tags: [],
ordinalPosition: 4,
},
@ -512,6 +510,121 @@ const CONTAINER_PATCH_PAYLOAD = [
},
];
const SEARCH_INDEX_DETAILS_FOR_VERSION_TEST = {
name: SEARCH_INDEX_NAME,
service: 'elasticsearch_sample',
fields: [
{
name: 'name',
dataType: 'TEXT',
dataTypeDisplay: 'text',
fullyQualifiedName: `elasticsearch_sample.${SEARCH_INDEX_NAME}.name`,
tags: [],
},
{
name: 'displayName',
dataType: 'TEXT',
dataTypeDisplay: 'text',
description: 'Description for field displayName',
fullyQualifiedName: `elasticsearch_sample.${SEARCH_INDEX_NAME}.displayName`,
tags: [],
},
{
name: 'description',
dataType: 'TEXT',
dataTypeDisplay: 'text',
fullyQualifiedName: `elasticsearch_sample.${SEARCH_INDEX_NAME}.description`,
tags: [],
},
{
name: 'columns',
dataType: 'NESTED',
dataTypeDisplay: 'nested',
fullyQualifiedName: `elasticsearch_sample.${SEARCH_INDEX_NAME}.columns`,
tags: [],
children: [
{
name: 'name',
dataType: 'TEXT',
dataTypeDisplay: 'text',
fullyQualifiedName: `elasticsearch_sample.${SEARCH_INDEX_NAME}.columns.name`,
tags: [],
},
{
name: 'displayName',
dataType: 'TEXT',
dataTypeDisplay: 'text',
fullyQualifiedName: `elasticsearch_sample.${SEARCH_INDEX_NAME}.columns.displayName`,
tags: [],
},
{
name: 'description',
dataType: 'TEXT',
dataTypeDisplay: 'text',
fullyQualifiedName: `elasticsearch_sample.${SEARCH_INDEX_NAME}.columns.description`,
tags: [],
},
],
},
{
name: 'databaseSchema',
dataType: 'TEXT',
dataTypeDisplay: 'text',
description: 'Database Schema that this table belongs to.',
fullyQualifiedName: `elasticsearch_sample.${SEARCH_INDEX_NAME}.databaseSchema`,
tags: [],
},
],
tags: [],
};
const SEARCH_INDEX_PATCH_PAYLOAD = [
{
op: 'add',
path: '/tags/0',
value: {
labelType: 'Manual',
state: 'Confirmed',
source: 'Classification',
tagFQN: 'PersonalData.SpecialCategory',
},
},
{
op: 'add',
path: '/fields/2/description',
value: 'Description for field description',
},
{
op: 'remove',
path: '/fields/1/description',
},
{
op: 'add',
path: '/fields/0/tags/0',
value: {
labelType: 'Manual',
state: 'Confirmed',
source: 'Classification',
tagFQN: 'PersonalData.Personal',
},
},
{
op: 'add',
path: '/fields/0/tags/1',
value: {
labelType: 'Manual',
state: 'Confirmed',
source: 'Classification',
tagFQN: 'PII.Sensitive',
},
},
{
op: 'add',
path: '/description',
value: `Description for ${SEARCH_INDEX_NAME}`,
},
];
const STORED_PROCEDURE_DETAILS_FOR_VERSION_TEST = {
name: STORED_PROCEDURE_NAME,
databaseSchema: 'sample_data.ecommerce_db.shopify',
@ -624,6 +737,7 @@ export const DATA_MODEL_PATCH_PAYLOAD = [
value: `Description for ${DATA_MODEL_NAME}`,
},
];
export const ENTITY_DETAILS_FOR_VERSION_TEST = {
Table: {
name: TABLE_NAME,
@ -700,6 +814,19 @@ export const ENTITY_DETAILS_FOR_VERSION_TEST = {
entityChildRemovedDescription: 'Description for column column_2',
entityChildAddedDescription: 'Description for column column_3',
},
'Search Index': {
name: SEARCH_INDEX_NAME,
serviceName: 'elasticsearch_sample',
entity: 'searchIndexes',
entityCreationDetails: SEARCH_INDEX_DETAILS_FOR_VERSION_TEST,
entityPatchPayload: SEARCH_INDEX_PATCH_PAYLOAD,
isChildrenExist: true,
childSelector: 'data-row-key',
entityAddedDescription: `Description for ${SEARCH_INDEX_NAME}`,
updatedTagEntityChildName: 'name',
entityChildRemovedDescription: 'Description for field displayName',
entityChildAddedDescription: 'Description for field description',
},
'Stored Procedure': {
name: STORED_PROCEDURE_NAME,
serviceName: 'sample_data',

View File

@ -12,12 +12,7 @@
*/
import {
customFormatDateTime,
getCurrentMillis,
getEpochMillisForFutureDays,
} from '../../../src/utils/date-time/DateTimeUtils';
import {
descriptionBox,
addAnnouncement,
interceptURL,
verifyResponseStatusCode,
visitEntityDetailsPage,
@ -29,116 +24,6 @@ describe('Entity Announcement', () => {
cy.login();
});
const createAnnouncement = (title, startDate, endDate, description) => {
cy.get('[data-testid="add-announcement"]').should('be.visible').click();
cy.get('.ant-modal-header').contains('Make an announcement');
cy.get('#title').type(title);
cy.get('#startTime').click().type(`${startDate}{enter}`);
cy.clickOutside();
cy.get('#endTime').click().type(`${endDate}{enter}`);
cy.clickOutside();
cy.get(descriptionBox).type(description);
cy.get('[id="announcement-submit"]').scrollIntoView().click();
};
const addAnnouncement = (value) => {
interceptURL('GET', '/api/v1/permissions/*/name/*', 'entityPermission');
interceptURL('GET', '/api/v1/feed/count?entityLink=*', 'entityFeed');
interceptURL('GET', `/api/v1/${value.entity}/name/*`, 'getEntityDetails');
interceptURL('POST', '/api/v1/feed', 'waitForAnnouncement');
interceptURL(
'GET',
'/api/v1/feed?entityLink=*type=Announcement',
'announcementFeed'
);
visitEntityDetailsPage(value.term, value.serviceName, value.entity);
cy.get('[data-testid="manage-button"]').click();
cy.get('[data-testid="announcement-button"]').click();
cy.wait('@announcementFeed').then((res) => {
const data = res.response.body.data;
if (data.length > 0) {
const token = localStorage.getItem('oidcIdToken');
data.map((feed) => {
cy.request({
method: 'DELETE',
url: `/api/v1/feed/${feed.id}`,
headers: { Authorization: `Bearer ${token}` },
}).then((response) => {
expect(response.status).to.eq(200);
});
});
cy.reload();
cy.get('[data-testid="manage-button"]').click();
cy.get('[data-testid="announcement-button"]').click();
}
const startDate = customFormatDateTime(getCurrentMillis(), 'yyyy-MM-dd');
const endDate = customFormatDateTime(
getEpochMillisForFutureDays(5),
'yyyy-MM-dd'
);
cy.get('[data-testid="announcement-error"]')
.should('be.visible')
.contains('No Announcements, Click on add announcement to add one.');
// Create Active Announcement
createAnnouncement(
'Announcement Title',
startDate,
endDate,
'Announcement Description'
);
// wait time for success toast message
verifyResponseStatusCode('@waitForAnnouncement', 201);
cy.get('.Toastify__close-button >').should('be.visible').click();
// Create InActive Announcement
const InActiveStartDate = customFormatDateTime(
getEpochMillisForFutureDays(6),
'yyyy-MM-dd'
);
const InActiveEndDate = customFormatDateTime(
getEpochMillisForFutureDays(11),
'yyyy-MM-dd'
);
createAnnouncement(
'InActive Announcement Title',
InActiveStartDate,
InActiveEndDate,
'InActive Announcement Description'
);
// wait time for success toast message
verifyResponseStatusCode('@waitForAnnouncement', 201);
cy.get('.Toastify__close-button >').should('be.visible').click();
// check for inActive-announcement
cy.get('[data-testid="inActive-announcements"]').should('be.visible');
// close announcement drawer
cy.get('[data-testid="title"] .anticon-close')
.should('be.visible')
.click();
// reload page to get the active announcement card
cy.reload();
verifyResponseStatusCode('@entityPermission', 200);
verifyResponseStatusCode('@getEntityDetails', 200);
verifyResponseStatusCode('@entityFeed', 200);
// check for announcement card on entity page
cy.get('[data-testid="announcement-card"]').should('be.visible');
});
};
ANNOUNCEMENT_ENTITIES.forEach((entity) => {
it(`Add announcement and verify the active announcement for ${entity.entity}`, () => {
addAnnouncement(entity);

View File

@ -10,6 +10,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// / <reference types="Cypress" />
import {
addOwner,
@ -27,6 +28,7 @@ import {
COMMON_UPDATED_DESCRIPTION,
DATABASE_DETAILS_FOR_VERSION_TEST,
DATABASE_SCHEMA_DETAILS_FOR_VERSION_TEST,
DOMAIN_CREATION_DETAILS,
OWNER,
SERVICE_DETAILS_FOR_VERSION_TEST,
TIER,
@ -34,6 +36,29 @@ import {
const serviceDetails = SERVICE_DETAILS_FOR_VERSION_TEST.Database;
let domainId;
describe('Common prerequisite for database schema version test', () => {
beforeEach(() => {
cy.login();
});
it('Domain creation for database schema version test', () => {
const token = localStorage.getItem('oidcIdToken');
cy.request({
method: 'PUT',
url: `/api/v1/domains`,
headers: { Authorization: `Bearer ${token}` },
body: DOMAIN_CREATION_DETAILS,
}).then((response) => {
expect(response.status).to.eq(201);
domainId = response.body.id;
});
});
});
describe(`Database schema version page should work properly`, () => {
let databaseId;
let databaseSchemaId;
@ -87,7 +112,19 @@ describe(`Database schema version page should work properly`, () => {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json-patch+json',
},
body: COMMON_PATCH_PAYLOAD,
body: [
...COMMON_PATCH_PAYLOAD,
{
op: 'add',
path: '/domain',
value: {
id: domainId,
type: 'domain',
name: DOMAIN_CREATION_DETAILS.name,
description: DOMAIN_CREATION_DETAILS.description,
},
},
],
}).then((response) => {
expect(response.status).to.eq(200);
});
@ -131,6 +168,12 @@ describe(`Database schema version page should work properly`, () => {
verifyResponseStatusCode('@getVersionsList', 200);
verifyResponseStatusCode('@getSelectedVersionDetails', 200);
cy.get(
`[data-testid="domain-link"] [data-testid="diff-added-${DOMAIN_CREATION_DETAILS.name}"]`
)
.scrollIntoView()
.should('be.visible');
cy.get(`[data-testid="diff-added-${COMMON_UPDATED_DESCRIPTION}"]`)
.scrollIntoView()
.should('be.visible');
@ -382,3 +425,21 @@ describe(`Database schema version page should work properly`, () => {
).should('not.exist');
});
});
describe('Common cleanup for database schema version test', () => {
beforeEach(() => {
cy.login();
});
it('Domain deletion for database schema version test', () => {
const token = localStorage.getItem('oidcIdToken');
cy.request({
method: 'DELETE',
url: `/api/v1/domains/name/${DOMAIN_CREATION_DETAILS.name}`,
headers: { Authorization: `Bearer ${token}` },
}).then((response) => {
expect(response.status).to.eq(200);
});
});
});

View File

@ -10,6 +10,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// / <reference types="Cypress" />
import {
addOwner,
@ -26,6 +27,7 @@ import {
COMMON_PATCH_PAYLOAD,
COMMON_UPDATED_DESCRIPTION,
DATABASE_DETAILS_FOR_VERSION_TEST,
DOMAIN_CREATION_DETAILS,
OWNER,
SERVICE_DETAILS_FOR_VERSION_TEST,
TIER,
@ -33,6 +35,29 @@ import {
const serviceDetails = SERVICE_DETAILS_FOR_VERSION_TEST.Database;
let domainId;
describe('Common prerequisite for database version test', () => {
beforeEach(() => {
cy.login();
});
it('Domain creation for database version test', () => {
const token = localStorage.getItem('oidcIdToken');
cy.request({
method: 'PUT',
url: `/api/v1/domains`,
headers: { Authorization: `Bearer ${token}` },
body: DOMAIN_CREATION_DETAILS,
}).then((response) => {
expect(response.status).to.eq(201);
domainId = response.body.id;
});
});
});
describe(`Database version page should work properly`, () => {
let databaseId;
let databaseFQN;
@ -73,7 +98,19 @@ describe(`Database version page should work properly`, () => {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json-patch+json',
},
body: COMMON_PATCH_PAYLOAD,
body: [
...COMMON_PATCH_PAYLOAD,
{
op: 'add',
path: '/domain',
value: {
id: domainId,
type: 'domain',
name: DOMAIN_CREATION_DETAILS.name,
description: DOMAIN_CREATION_DETAILS.description,
},
},
],
}).then((response) => {
expect(response.status).to.eq(200);
});
@ -113,6 +150,12 @@ describe(`Database version page should work properly`, () => {
verifyResponseStatusCode('@getVersionsList', 200);
verifyResponseStatusCode('@getSelectedVersionDetails', 200);
cy.get(
`[data-testid="domain-link"] [data-testid="diff-added-${DOMAIN_CREATION_DETAILS.name}"]`
)
.scrollIntoView()
.should('be.visible');
cy.get(`[data-testid="diff-added-${COMMON_UPDATED_DESCRIPTION}"]`)
.scrollIntoView()
.should('be.visible');
@ -344,3 +387,21 @@ describe(`Database version page should work properly`, () => {
).should('not.exist');
});
});
describe('Common cleanup for database version test', () => {
beforeEach(() => {
cy.login();
});
it('Domain deletion for database version test', () => {
const token = localStorage.getItem('oidcIdToken');
cy.request({
method: 'DELETE',
url: `/api/v1/domains/name/${DOMAIN_CREATION_DETAILS.name}`,
headers: { Authorization: `Bearer ${token}` },
}).then((response) => {
expect(response.status).to.eq(200);
});
});
});

View File

@ -24,11 +24,35 @@ import {
} from '../../common/common';
import { visitEntityDetailsVersionPage } from '../../common/VersionUtils';
import {
DOMAIN_CREATION_DETAILS,
ENTITY_DETAILS_FOR_VERSION_TEST,
OWNER,
TIER,
} from '../../constants/Version.constants';
let domainId;
describe('Common prerequisite for entity version test', () => {
beforeEach(() => {
cy.login();
});
it('Domain creation for entity version test', () => {
const token = localStorage.getItem('oidcIdToken');
cy.request({
method: 'PUT',
url: `/api/v1/domains`,
headers: { Authorization: `Bearer ${token}` },
body: DOMAIN_CREATION_DETAILS,
}).then((response) => {
expect(response.status).to.eq(201);
domainId = response.body.id;
});
});
});
Object.entries(ENTITY_DETAILS_FOR_VERSION_TEST).map(
([entityType, entityDetails]) => {
describe(`${entityType} version page should work properly`, () => {
@ -62,7 +86,19 @@ Object.entries(ENTITY_DETAILS_FOR_VERSION_TEST).map(
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json-patch+json',
},
body: entityDetails.entityPatchPayload,
body: [
...entityDetails.entityPatchPayload,
{
op: 'add',
path: '/domain',
value: {
id: domainId,
type: 'domain',
name: DOMAIN_CREATION_DETAILS.name,
description: DOMAIN_CREATION_DETAILS.description,
},
},
],
}).then((response) => {
expect(response.status).to.eq(200);
});
@ -76,6 +112,13 @@ Object.entries(ENTITY_DETAILS_FOR_VERSION_TEST).map(
entityFQN,
'0.2'
);
cy.get(
`[data-testid="domain-link"] [data-testid="diff-added-${DOMAIN_CREATION_DETAILS.name}"]`
)
.scrollIntoView()
.should('be.visible');
cy.get(
`[data-testid="diff-added-${entityDetails.entityAddedDescription}"]`
)
@ -287,3 +330,21 @@ Object.entries(ENTITY_DETAILS_FOR_VERSION_TEST).map(
});
}
);
describe('Common cleanup for entity version test', () => {
beforeEach(() => {
cy.login();
});
it('Domain deletion for entity version test', () => {
const token = localStorage.getItem('oidcIdToken');
cy.request({
method: 'DELETE',
url: `/api/v1/domains/name/${DOMAIN_CREATION_DETAILS.name}`,
headers: { Authorization: `Bearer ${token}` },
}).then((response) => {
expect(response.status).to.eq(200);
});
});
});

View File

@ -0,0 +1,419 @@
/*
* Copyright 2023 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// / <reference types="Cypress" />
import {
addAnnouncement,
addOwner,
addTableFieldTags,
addTags,
addTier,
deleteEntity,
interceptURL,
login,
removeOwner,
removeTableFieldTags,
removeTags,
removeTier,
updateDescription,
updateTableFieldDescription,
verifyResponseStatusCode,
visitEntityDetailsPage,
} from '../../common/common';
import { BASE_URL } from '../../constants/constants';
import {
SEARCH_INDEX_DETAILS_FOR_ANNOUNCEMENT,
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST,
SEARCH_INDEX_DISPLAY_NAME,
TAG_1,
TIER,
UPDATE_DESCRIPTION,
UPDATE_FIELD_DESCRIPTION,
USER_CREDENTIALS,
USER_NAME,
} from '../../constants/SearchIndexDetails.constants';
const performCommonOperations = () => {
// Add and remove tier flow should work properly
addTier(TIER, 'searchIndexes');
removeTier('searchIndexes');
// Add and remove tags flow should work properly
addTags(TAG_1.classification, TAG_1.tag, 'searchIndexes');
removeTags(TAG_1.classification, TAG_1.tag, 'searchIndexes');
// User should be able to edit search index field tags
addTableFieldTags(
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.fields[0].fullyQualifiedName,
TAG_1.classification,
TAG_1.tag,
'searchIndexes'
);
removeTableFieldTags(
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.fields[0].fullyQualifiedName,
TAG_1.classification,
TAG_1.tag,
'searchIndexes'
);
// User should be able to edit search index description
updateDescription(UPDATE_DESCRIPTION, 'searchIndexes');
cy.get('[data-testid="asset-description-container"]').contains(
UPDATE_DESCRIPTION
);
updateDescription(' ', 'searchIndexes');
cy.get('[data-testid="asset-description-container"]').contains(
'No description'
);
// User should be able to edit search index field description
updateTableFieldDescription(
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.fields[0].fullyQualifiedName,
UPDATE_FIELD_DESCRIPTION,
'searchIndexes'
);
cy.get(
`[data-row-key="${SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.fields[0].fullyQualifiedName}"] [data-testid="description"]`
).contains(UPDATE_FIELD_DESCRIPTION);
updateTableFieldDescription(
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.fields[0].fullyQualifiedName,
' ',
'searchIndexes'
);
cy.get(
`[data-row-key="${SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.fields[0].fullyQualifiedName}"] [data-testid="description"]`
).contains('No Description');
// Add and remove owner flow should work properly
addOwner(
`${USER_CREDENTIALS.firstName}${USER_CREDENTIALS.lastName}`,
'searchIndexes'
);
removeOwner('searchIndexes');
};
describe('Prerequisite for search index details page test', () => {
before(() => {
cy.login();
});
it('Prerequisites', () => {
const token = localStorage.getItem('oidcIdToken');
// Create search index entity
cy.request({
method: 'PUT',
url: `/api/v1/searchIndexes`,
headers: { Authorization: `Bearer ${token}` },
body: SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST,
}).then((response) => {
expect(response.status).to.eq(201);
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.id = response.body.id;
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.fullyQualifiedName =
response.body.fullyQualifiedName;
});
// Create a new user
cy.request({
method: 'POST',
url: `/api/v1/users/signup`,
headers: { Authorization: `Bearer ${token}` },
body: USER_CREDENTIALS,
}).then((response) => {
expect(response.status).to.eq(201);
USER_CREDENTIALS.id = response.body.id;
});
});
});
describe('SearchIndexDetails page should work properly for data consumer role', () => {
beforeEach(() => {
// Login with the created user
login(USER_CREDENTIALS.email, USER_CREDENTIALS.password);
cy.goToHomePage(true);
cy.url().should('eq', `${BASE_URL}/my-data`);
});
it('All permissible actions on search index details page should work properly', () => {
visitEntityDetailsPage(
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.name,
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.service,
'searchIndexes',
undefined,
'Search Index'
);
// Edit domain option should not be available
cy.get(`[data-testid="entity-page-header"]`).then(($body) => {
const editDomain = $body.find(`[data-testid="add-domain"]`);
expect(editDomain.length).to.equal(0);
});
// Manage button should not be visible on service page
cy.get('[data-testid="asset-header-btn-group"]').then(($body) => {
const manageButton = $body.find(`[data-testid="manage-button"]`);
expect(manageButton.length).to.equal(0);
});
performCommonOperations();
});
});
describe('Prerequisite for data steward role tests', () => {
it('Add data steward role to the user', () => {
cy.login();
// Assign data steward role to the created user
cy.get('[data-testid="app-bar-item-settings"]').click();
interceptURL('GET', `/api/v1/users?*`, 'getUsersList');
cy.get('[data-testid="settings-left-panel"]').contains('Users').click();
verifyResponseStatusCode('@getUsersList', 200);
cy.get('[data-testid="searchbar"]').type(
`${USER_CREDENTIALS.firstName}${USER_CREDENTIALS.lastName}`
);
interceptURL('GET', `/api/v1/users/name/${USER_NAME}*`, 'getUserDetails');
cy.get(
`[data-row-key="${USER_CREDENTIALS.id}"] [data-testid="${USER_NAME}"]`
).click();
verifyResponseStatusCode('@getUserDetails', 200);
cy.get('[data-testid="edit-roles"]').click();
cy.get('[data-testid="inline-edit-container"] #select-role').click();
cy.get('[title="Data Steward"]').click();
cy.clickOutside();
interceptURL('PATCH', `/api/v1/users/${USER_CREDENTIALS.id}`, 'updateRole');
cy.get('[data-testid="inline-save-btn"]').click();
verifyResponseStatusCode('@updateRole', 200);
});
});
describe('SearchIndexDetails page should work properly for data steward role', () => {
beforeEach(() => {
// Login with the created user
login(USER_CREDENTIALS.email, USER_CREDENTIALS.password);
cy.goToHomePage(true);
cy.url().should('eq', `${BASE_URL}/my-data`);
});
it('All permissible actions on search index details page should work properly', () => {
visitEntityDetailsPage(
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.name,
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.service,
'searchIndexes',
undefined,
'Search Index'
);
// Edit domain option should not be available
cy.get(`[data-testid="entity-page-header"]`).then(($body) => {
const editDomain = $body.find(`[data-testid="add-domain"]`);
expect(editDomain.length).to.equal(0);
});
// Manage button should be visible on service page
cy.get('[data-testid="manage-button"]').click();
// Announcement and Delete options should not be visible
cy.get('.manage-dropdown-list-container').then(($body) => {
const announcementButton = $body.find(
`[data-testid="announcement-button"]`
);
const deleteButton = $body.find(`[data-testid="delete-button"]`);
expect(announcementButton.length).to.equal(0);
expect(deleteButton.length).to.equal(0);
});
// Rename search index flow should work properly
cy.get('[data-testid="rename-button"]').click({ waitForAnimations: true });
cy.get('#displayName').clear().type(SEARCH_INDEX_DISPLAY_NAME);
interceptURL(
'PATCH',
`/api/v1/searchIndexes/${SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.id}`,
'updateDisplayName'
);
cy.get('[data-testid="save-button"]').click();
verifyResponseStatusCode('@updateDisplayName', 200);
cy.get('[data-testid="entity-header-display-name"]').contains(
SEARCH_INDEX_DISPLAY_NAME
);
performCommonOperations();
});
});
describe('SearchIndexDetails page should work properly for admin role', () => {
beforeEach(() => {
cy.login();
});
it('All permissible actions on search index details page should work properly', () => {
// Add announcement workflow should work properly
addAnnouncement(SEARCH_INDEX_DETAILS_FOR_ANNOUNCEMENT);
// Rename search index flow should work properly
cy.get('[data-testid="manage-button"]').click();
cy.get('[data-testid="rename-button"]').click({ waitForAnimations: true });
cy.get('#displayName').clear().type(SEARCH_INDEX_DISPLAY_NAME);
interceptURL(
'PATCH',
`/api/v1/searchIndexes/${SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.id}`,
'updateDisplayName'
);
cy.get('[data-testid="save-button"]').click();
verifyResponseStatusCode('@updateDisplayName', 200);
cy.get('[data-testid="entity-header-display-name"]').contains(
SEARCH_INDEX_DISPLAY_NAME
);
performCommonOperations();
});
it('Soft delete workflow should work properly', () => {
deleteEntity(
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.name,
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.service,
'searchIndexes',
'Search Index',
'Search Index',
'soft'
);
cy.get('[data-testid="deleted-badge"]').should('be.visible');
// Edit options for domain owner and tier should not be visible
cy.get(`[data-testid="entity-page-header"]`).then(($body) => {
const editDomain = $body.find(`[data-testid="add-domain"]`);
const editOwner = $body.find(`[data-testid="edit-owner"]`);
const editTier = $body.find(`[data-testid="edit-tier"]`);
expect(editDomain.length).to.equal(0);
expect(editOwner.length).to.equal(0);
expect(editTier.length).to.equal(0);
});
// Edit description button should not be visible
cy.get(`[data-testid="asset-description-container"]`).then(($body) => {
const editDescription = $body.find(`[data-testid="edit-description"]`);
expect(editDescription.length).to.equal(0);
});
// Edit tags button should not be visible
cy.get(
`[data-testid="entity-right-panel"] [data-testid="tags-container"]`
).then(($body) => {
const addTag = $body.find(`[data-testid="add-tag"]`);
expect(addTag.length).to.equal(0);
});
// Edit description and tags button for fields should not be visible
cy.get(
`[data-row-key="${SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.fields[0].fullyQualifiedName}"]`
).then(($body) => {
const addTag = $body.find(
`[data-testid="tags-container"] [data-testid="add-tag"]`
);
const editDescription = $body.find(
`[data-testid="description"] [data-testid="edit-button"]`
);
expect(addTag.length).to.equal(0);
expect(editDescription.length).to.equal(0);
// Restore search index flow should work properly
cy.get('[data-testid="manage-button"]').click();
cy.get('[data-testid="restore-button"]').click();
interceptURL(
'PUT',
`/api/v1/searchIndexes/restore`,
'restoreSearchIndex'
);
cy.get('[data-testid="restore-asset-modal"] .ant-btn-primary')
.contains('Restore')
.click();
verifyResponseStatusCode('@restoreSearchIndex', 200);
});
});
it('Hard delete workflow should work properly', () => {
deleteEntity(
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.name,
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.service,
'searchIndexes',
'Search Index',
'Search Index'
);
});
});
describe('Cleanup', () => {
before(() => {
Cypress.session.clearAllSavedSessions();
cy.login();
});
it('Delete search index and user', () => {
const token = localStorage.getItem('oidcIdToken');
// Delete created user
cy.request({
method: 'DELETE',
url: `/api/v1/users/${USER_CREDENTIALS.id}?hardDelete=true&recursive=false`,
headers: { Authorization: `Bearer ${token}` },
}).then((response) => {
expect(response.status).to.eq(200);
});
});
});

View File

@ -10,6 +10,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// eslint-disable-next-line spaced-comment
/// <reference types="Cypress" />
import {
addOwner,
@ -24,11 +26,35 @@ import {
import { DELETE_TERM } from '../../constants/constants';
import {
COMMON_UPDATED_DESCRIPTION,
DOMAIN_CREATION_DETAILS,
OWNER,
SERVICE_DETAILS_FOR_VERSION_TEST,
TIER,
} from '../../constants/Version.constants';
let domainId;
describe('Common prerequisite for service version test', () => {
beforeEach(() => {
cy.login();
});
it('Domain creation for service version test', () => {
const token = localStorage.getItem('oidcIdToken');
cy.request({
method: 'PUT',
url: `/api/v1/domains`,
headers: { Authorization: `Bearer ${token}` },
body: DOMAIN_CREATION_DETAILS,
}).then((response) => {
expect(response.status).to.eq(201);
domainId = response.body.id;
});
});
});
Object.entries(SERVICE_DETAILS_FOR_VERSION_TEST).map(
([serviceType, serviceDetails]) => {
describe(`${serviceType} service version page`, () => {
@ -60,7 +86,19 @@ Object.entries(SERVICE_DETAILS_FOR_VERSION_TEST).map(
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json-patch+json',
},
body: serviceDetails.entityPatchPayload,
body: [
...serviceDetails.entityPatchPayload,
{
op: 'add',
path: '/domain',
value: {
id: domainId,
type: 'domain',
name: DOMAIN_CREATION_DETAILS.name,
description: DOMAIN_CREATION_DETAILS.description,
},
},
],
}).then((response) => {
expect(response.status).to.eq(200);
});
@ -97,6 +135,12 @@ Object.entries(SERVICE_DETAILS_FOR_VERSION_TEST).map(
verifyResponseStatusCode('@getVersionsList', 200);
verifyResponseStatusCode('@getSelectedVersionDetails', 200);
cy.get(
`[data-testid="domain-link"] [data-testid="diff-added-${DOMAIN_CREATION_DETAILS.name}"]`
)
.scrollIntoView()
.should('be.visible');
cy.get(`[data-testid="diff-added-${COMMON_UPDATED_DESCRIPTION}"]`)
.scrollIntoView()
.should('be.visible');
@ -323,3 +367,21 @@ Object.entries(SERVICE_DETAILS_FOR_VERSION_TEST).map(
});
}
);
describe('Common cleanup for service version test', () => {
beforeEach(() => {
cy.login();
});
it('Domain deletion for service version test', () => {
const token = localStorage.getItem('oidcIdToken');
cy.request({
method: 'DELETE',
url: `/api/v1/domains/name/${DOMAIN_CREATION_DETAILS.name}`,
headers: { Authorization: `Bearer ${token}` },
}).then((response) => {
expect(response.status).to.eq(200);
});
});
});

View File

@ -313,6 +313,18 @@ export const DataAssetsHeader = ({
onUpdateVote?.(data, dataAsset.id ?? '');
};
const { editDomainPermission, editOwnerPermission, editTierPermission } =
useMemo(
() => ({
editDomainPermission: permissions.EditAll && !dataAsset.deleted,
editOwnerPermission:
(permissions.EditAll || permissions.EditOwner) && !dataAsset.deleted,
editTierPermission:
(permissions.EditAll || permissions.EditTags) && !dataAsset.deleted,
}),
[permissions, dataAsset]
);
return (
<>
<Row gutter={[8, 12]}>
@ -344,13 +356,13 @@ export const DataAssetsHeader = ({
entityFqn={dataAsset.fullyQualifiedName ?? ''}
entityId={dataAsset.id ?? ''}
entityType={entityType}
hasPermission={permissions.EditAll}
hasPermission={editDomainPermission}
/>
<Divider className="self-center m-x-sm" type="vertical" />
</>
)}
<OwnerLabel
hasPermission={permissions.EditAll || permissions.EditOwner}
hasPermission={editOwnerPermission}
owner={dataAsset?.owner}
onUpdate={onOwnerUpdate}
/>
@ -369,13 +381,10 @@ export const DataAssetsHeader = ({
</span>
)}
{(permissions.EditAll || permissions.EditTags) && (
{editTierPermission && (
<Button
className="flex-center p-0"
data-testid="edit-tier"
disabled={
!(permissions.EditAll || permissions.EditTags)
}
icon={<EditIcon color={DE_ACTIVE_COLOR} width="14px" />}
size="small"
type="text"
@ -392,7 +401,7 @@ export const DataAssetsHeader = ({
<Col span={6}>
<Space className="items-end w-full" direction="vertical" size={16}>
<Space>
<ButtonGroup size="small">
<ButtonGroup data-testid="asset-header-btn-group" size="small">
{onUpdateVote && (
<Voting
disabled={deleted}

View File

@ -101,7 +101,7 @@ export const DomainLabel = ({
) : (
<Typography.Text
className="font-medium text-xs"
data-testid="domain-link">
data-testid="no-domain-text">
{t('label.no-entity', { entity: t('label.domain') })}
</Typography.Text>
)}

View File

@ -125,9 +125,7 @@ const DomainSelectableList = ({
trigger="click"
onOpenChange={setPopupVisible}
{...popoverProps}>
{children ? (
children
) : (
{children ?? (
<Tooltip
placement="topRight"
title={hasPermission ? '' : NO_PERMISSION_FOR_ACTION}>

View File

@ -157,6 +157,7 @@ const DescriptionV1 = ({
<>
<Space
className="schema-description d-flex"
data-testid="asset-description-container"
direction="vertical"
size={16}>
<Space size="middle">

View File

@ -285,6 +285,7 @@ const ManageButton: FC<Props> = ({
}}
className="reactive-modal"
closable={false}
data-testid="restore-asset-modal"
maskClosable={false}
okText={t('label.restore')}
open={showReactiveModal}