mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-02 05:33:49 +00:00
322 lines
9.5 KiB
JavaScript
322 lines
9.5 KiB
JavaScript
/*
|
|
* 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.
|
|
*/
|
|
import {
|
|
interceptURL,
|
|
toastNotification,
|
|
verifyResponseStatusCode,
|
|
visitEntityDetailsPage,
|
|
} from '../../common/common';
|
|
import { createEntityTable, hardDeleteService } from '../../common/EntityUtils';
|
|
import {
|
|
DATA_ASSETS,
|
|
INVALID_NAMES,
|
|
NAME_MAX_LENGTH_VALIDATION_ERROR,
|
|
NAME_VALIDATION_ERROR,
|
|
uuid,
|
|
} from '../../constants/constants';
|
|
import { DATABASE_SERVICE } from '../../constants/EntityConstant';
|
|
import { SERVICE_CATEGORIES } from '../../constants/service.constants';
|
|
|
|
// eslint-disable-next-line spaced-comment
|
|
/// <reference types="Cypress" />
|
|
|
|
const TABLE_CUSTOM_METRIC = {
|
|
name: `tableCustomMetric-${uuid()}`,
|
|
expression: `SELECT * FROM ${DATABASE_SERVICE.entity.name}`,
|
|
};
|
|
const COLUMN_CUSTOM_METRIC = {
|
|
name: `tableCustomMetric-${uuid()}`,
|
|
column: DATABASE_SERVICE.entity.columns[0].name,
|
|
expression: `SELECT * FROM ${DATABASE_SERVICE.entity.name}`,
|
|
};
|
|
|
|
const validateForm = (isColumnMetric = false) => {
|
|
// error messages
|
|
cy.get('#name_help').scrollIntoView().should('contain', 'Name is required');
|
|
|
|
cy.get('#expression_help')
|
|
.scrollIntoView()
|
|
.should('contain', 'SQL Query is required');
|
|
if (isColumnMetric) {
|
|
cy.get('#columnName_help')
|
|
.scrollIntoView()
|
|
.should('contain', 'Column is required');
|
|
}
|
|
|
|
// max length validation
|
|
cy.get('#name').scrollIntoView().type(INVALID_NAMES.MAX_LENGTH);
|
|
cy.get('#name_help').should('contain', NAME_MAX_LENGTH_VALIDATION_ERROR);
|
|
|
|
// with special char validation
|
|
cy.get('#name')
|
|
.should('be.visible')
|
|
.clear()
|
|
.type(INVALID_NAMES.WITH_SPECIAL_CHARS);
|
|
cy.get('#name_help').should('contain', NAME_VALIDATION_ERROR);
|
|
cy.get('#name').clear();
|
|
};
|
|
|
|
const createCustomMetric = ({
|
|
term,
|
|
serviceName,
|
|
entity,
|
|
isColumnMetric = false,
|
|
metric,
|
|
}) => {
|
|
interceptURL('PUT', '/api/v1/tables/*/customMetric', 'createCustomMetric');
|
|
interceptURL(
|
|
'GET',
|
|
'/api/v1/tables/name/*?fields=customMetrics,columns&include=all',
|
|
'getCustomMetric'
|
|
);
|
|
visitEntityDetailsPage({
|
|
term,
|
|
serviceName,
|
|
entity,
|
|
});
|
|
// Click on create custom metric button
|
|
cy.get('[data-testid="profiler"]').click();
|
|
verifyResponseStatusCode('@getCustomMetric', 200);
|
|
if (isColumnMetric) {
|
|
cy.get('[data-testid="profiler-tab-left-panel"]')
|
|
.contains('Column Profile')
|
|
.click();
|
|
}
|
|
cy.get('[data-testid="profiler-add-table-test-btn"]').click();
|
|
cy.get('[data-testid="custom-metric"]').click();
|
|
|
|
// validate redirection and cancel button
|
|
cy.get('[data-testid="heading"]').should('be.visible');
|
|
cy.get(
|
|
`[data-testid=${
|
|
isColumnMetric
|
|
? 'profiler-tab-container'
|
|
: 'table-profiler-chart-container'
|
|
}]`
|
|
).should('be.visible');
|
|
cy.get('[data-testid="cancel-button"]').click();
|
|
verifyResponseStatusCode('@getCustomMetric', 200);
|
|
cy.url().should('include', 'profiler');
|
|
cy.get('[data-testid="heading"]')
|
|
.invoke('text')
|
|
.should('equal', isColumnMetric ? 'Column Profile' : 'Table Profile');
|
|
|
|
// Click on create custom metric button
|
|
cy.get('[data-testid="profiler-add-table-test-btn"]').click();
|
|
cy.get('[data-testid="custom-metric"]').click();
|
|
cy.get('[data-testid="submit-button"]').click();
|
|
|
|
validateForm(isColumnMetric);
|
|
|
|
// fill form and submit
|
|
cy.get('#name').type(metric.name);
|
|
if (isColumnMetric) {
|
|
cy.get('#columnName').click();
|
|
cy.get(`[title="${metric.column}"]`).click();
|
|
}
|
|
cy.get('.CodeMirror-scroll').click().type(metric.expression);
|
|
cy.get('[data-testid="submit-button"]').click();
|
|
verifyResponseStatusCode('@createCustomMetric', 200);
|
|
toastNotification(`${metric.name} created successfully.`);
|
|
verifyResponseStatusCode('@getCustomMetric', 200);
|
|
|
|
// verify the created custom metric
|
|
cy.url().should('include', 'profiler');
|
|
cy.get('[data-testid="heading"]')
|
|
.invoke('text')
|
|
.should('equal', isColumnMetric ? 'Column Profile' : 'Table Profile');
|
|
cy.get(`[data-testid="${metric.name}-custom-metrics"]`)
|
|
.scrollIntoView()
|
|
.should('be.visible');
|
|
};
|
|
|
|
const editCustomMetric = ({
|
|
term,
|
|
serviceName,
|
|
entity,
|
|
isColumnMetric = false,
|
|
metric,
|
|
}) => {
|
|
interceptURL(
|
|
'GET',
|
|
'/api/v1/tables/name/*?fields=customMetrics,columns&include=all',
|
|
'getCustomMetric'
|
|
);
|
|
interceptURL('PUT', '/api/v1/tables/*/customMetric', 'editCustomMetric');
|
|
visitEntityDetailsPage({
|
|
term,
|
|
serviceName,
|
|
entity,
|
|
});
|
|
cy.get('[data-testid="profiler"]').click();
|
|
verifyResponseStatusCode('@getCustomMetric', 200);
|
|
if (isColumnMetric) {
|
|
cy.get('[data-testid="profiler-tab-left-panel"]')
|
|
.contains('Column Profile')
|
|
.click();
|
|
cy.get('[data-row-key="user_id"]').contains(metric.column).click();
|
|
}
|
|
cy.get(`[data-testid="${metric.name}-custom-metrics"]`)
|
|
.scrollIntoView()
|
|
.should('be.visible');
|
|
cy.get(`[data-testid="${metric.name}-custom-metrics-menu"]`).click();
|
|
cy.get(`[data-menu-id*="edit"]`).click();
|
|
|
|
// validate cancel button
|
|
cy.get('.ant-modal-content').should('be.visible');
|
|
cy.get('.ant-modal-footer').contains('Cancel').click();
|
|
cy.get('.ant-modal-content').should('not.exist');
|
|
|
|
// edit expression and submit
|
|
cy.get(`[data-testid="${metric.name}-custom-metrics-menu"]`).click();
|
|
cy.get(`[data-menu-id*="edit"]`).click();
|
|
cy.get('.CodeMirror-scroll').click().type('updated');
|
|
cy.get('.ant-modal-footer').contains('Save').click();
|
|
cy.wait('@editCustomMetric').then(({ request }) => {
|
|
expect(request.body.expression).to.have.string('updated');
|
|
});
|
|
toastNotification(`${metric.name} updated successfully.`);
|
|
};
|
|
const deleteCustomMetric = ({
|
|
term,
|
|
serviceName,
|
|
entity,
|
|
metric,
|
|
isColumnMetric = false,
|
|
}) => {
|
|
interceptURL(
|
|
'GET',
|
|
'/api/v1/tables/name/*?fields=customMetrics,columns&include=all',
|
|
'getCustomMetric'
|
|
);
|
|
interceptURL(
|
|
'DELETE',
|
|
isColumnMetric
|
|
? `/api/v1/tables/*/customMetric/${metric.column}/${metric.name}`
|
|
: `/api/v1/tables/*/customMetric/${metric.name}`,
|
|
'deleteCustomMetric'
|
|
);
|
|
visitEntityDetailsPage({
|
|
term,
|
|
serviceName,
|
|
entity,
|
|
});
|
|
cy.get('[data-testid="profiler"]').click();
|
|
verifyResponseStatusCode('@getCustomMetric', 200);
|
|
if (isColumnMetric) {
|
|
cy.get('[data-testid="profiler-tab-left-panel"]')
|
|
.contains('Column Profile')
|
|
.click();
|
|
cy.get('[data-row-key="user_id"]').contains(metric.column).click();
|
|
}
|
|
cy.get(`[data-testid="${metric.name}-custom-metrics"]`)
|
|
.scrollIntoView()
|
|
.should('be.visible');
|
|
cy.get(`[data-testid="${metric.name}-custom-metrics-menu"]`).click();
|
|
cy.get(`[data-menu-id*="delete"]`).click();
|
|
cy.get('.ant-modal-header').should('contain', `Delete ${metric.name}`);
|
|
cy.get('[data-testid="confirmation-text-input"]').type('DELETE');
|
|
cy.get('[data-testid="confirm-button"]').click();
|
|
verifyResponseStatusCode('@deleteCustomMetric', 200);
|
|
toastNotification(`${metric.name} deleted successfully!`);
|
|
};
|
|
|
|
describe('Custom Metric', () => {
|
|
before(() => {
|
|
cy.login();
|
|
cy.getAllLocalStorage().then((data) => {
|
|
const token = Object.values(data)[0].oidcIdToken;
|
|
|
|
createEntityTable({
|
|
token,
|
|
...DATABASE_SERVICE,
|
|
tables: [DATABASE_SERVICE.entity],
|
|
});
|
|
});
|
|
});
|
|
|
|
after(() => {
|
|
cy.login();
|
|
cy.getAllLocalStorage().then((data) => {
|
|
const token = Object.values(data)[0].oidcIdToken;
|
|
|
|
hardDeleteService({
|
|
token,
|
|
serviceFqn: DATABASE_SERVICE.service.name,
|
|
serviceType: SERVICE_CATEGORIES.DATABASE_SERVICES,
|
|
});
|
|
});
|
|
});
|
|
|
|
beforeEach(() => {
|
|
cy.login();
|
|
});
|
|
|
|
it('Create table custom metric', () => {
|
|
createCustomMetric({
|
|
term: DATABASE_SERVICE.entity.name,
|
|
serviceName: DATABASE_SERVICE.service.name,
|
|
entity: DATA_ASSETS.tables,
|
|
metric: TABLE_CUSTOM_METRIC,
|
|
});
|
|
});
|
|
|
|
it("Edit table custom metric's expression", () => {
|
|
editCustomMetric({
|
|
term: DATABASE_SERVICE.entity.name,
|
|
serviceName: DATABASE_SERVICE.service.name,
|
|
entity: DATA_ASSETS.tables,
|
|
metric: TABLE_CUSTOM_METRIC,
|
|
});
|
|
});
|
|
|
|
it('Delete table custom metric', () => {
|
|
deleteCustomMetric({
|
|
term: DATABASE_SERVICE.entity.name,
|
|
serviceName: DATABASE_SERVICE.service.name,
|
|
entity: DATA_ASSETS.tables,
|
|
metric: TABLE_CUSTOM_METRIC,
|
|
});
|
|
});
|
|
|
|
it('Create column custom metric', () => {
|
|
createCustomMetric({
|
|
term: DATABASE_SERVICE.entity.name,
|
|
serviceName: DATABASE_SERVICE.service.name,
|
|
entity: DATA_ASSETS.tables,
|
|
metric: COLUMN_CUSTOM_METRIC,
|
|
isColumnMetric: true,
|
|
});
|
|
});
|
|
|
|
it("Edit column custom metric's expression", () => {
|
|
editCustomMetric({
|
|
term: DATABASE_SERVICE.entity.name,
|
|
serviceName: DATABASE_SERVICE.service.name,
|
|
entity: DATA_ASSETS.tables,
|
|
metric: COLUMN_CUSTOM_METRIC,
|
|
isColumnMetric: true,
|
|
});
|
|
});
|
|
|
|
it('Delete column custom metric', () => {
|
|
deleteCustomMetric({
|
|
term: DATABASE_SERVICE.entity.name,
|
|
serviceName: DATABASE_SERVICE.service.name,
|
|
entity: DATA_ASSETS.tables,
|
|
metric: COLUMN_CUSTOM_METRIC,
|
|
isColumnMetric: true,
|
|
});
|
|
});
|
|
});
|