mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-24 17:08:28 +00:00
Tests #19066: Playwright coverage for ViewAll rule with matchAnyTag() and isOwner() condition (#19374)
* Modify the setup for the tests and add teardown to reset the organization policies * Fix the loader shown in case of no permission * Add playwright tests to cover the viewAll permission with conditions * Add description for the commented code
This commit is contained in:
parent
d8e6219200
commit
7fea955338
@ -63,6 +63,11 @@ export default defineConfig({
|
|||||||
{
|
{
|
||||||
name: 'setup',
|
name: 'setup',
|
||||||
testMatch: '**/*.setup.ts',
|
testMatch: '**/*.setup.ts',
|
||||||
|
teardown: 'restore-policies',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'restore-policies',
|
||||||
|
testMatch: '**/auth.teardown.ts',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'chromium',
|
name: 'chromium',
|
||||||
|
@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 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 { PolicyClass } from '../support/access-control/PoliciesClass';
|
||||||
|
import { RolesClass } from '../support/access-control/RolesClass';
|
||||||
|
import { ApiCollectionClass } from '../support/entity/ApiCollectionClass';
|
||||||
|
import { ContainerClass } from '../support/entity/ContainerClass';
|
||||||
|
import { DashboardClass } from '../support/entity/DashboardClass';
|
||||||
|
import { MlModelClass } from '../support/entity/MlModelClass';
|
||||||
|
import { PipelineClass } from '../support/entity/PipelineClass';
|
||||||
|
import { SearchIndexClass } from '../support/entity/SearchIndexClass';
|
||||||
|
import { TableClass } from '../support/entity/TableClass';
|
||||||
|
import { TopicClass } from '../support/entity/TopicClass';
|
||||||
|
import { EntityData } from '../support/interfaces/ConditionalPermissions.interface';
|
||||||
|
import { UserClass } from '../support/user/UserClass';
|
||||||
|
import { ServiceTypes } from './settings';
|
||||||
|
|
||||||
|
export const isOwnerPolicy = new PolicyClass();
|
||||||
|
export const matchAnyTagPolicy = new PolicyClass();
|
||||||
|
export const isOwnerRole = new RolesClass();
|
||||||
|
export const matchAnyTagRole = new RolesClass();
|
||||||
|
export const userWithOwnerPermission = new UserClass();
|
||||||
|
export const userWithTagPermission = new UserClass();
|
||||||
|
export const apiCollectionWithOwner = new ApiCollectionClass();
|
||||||
|
export const apiCollectionWithTag = new ApiCollectionClass();
|
||||||
|
export const containerWithOwner = new ContainerClass();
|
||||||
|
export const containerWithTag = new ContainerClass();
|
||||||
|
export const dashboardWithOwner = new DashboardClass();
|
||||||
|
export const dashboardWithTag = new DashboardClass();
|
||||||
|
export const mlModelWithOwner = new MlModelClass();
|
||||||
|
export const mlModelWithTag = new MlModelClass();
|
||||||
|
export const pipelineWithOwner = new PipelineClass();
|
||||||
|
export const pipelineWithTag = new PipelineClass();
|
||||||
|
export const searchIndexWithOwner = new SearchIndexClass();
|
||||||
|
export const searchIndexWithTag = new SearchIndexClass();
|
||||||
|
export const tableWithOwner = new TableClass();
|
||||||
|
export const tableWithTag = new TableClass();
|
||||||
|
export const topicWithOwner = new TopicClass();
|
||||||
|
export const topicWithTag = new TopicClass();
|
||||||
|
|
||||||
|
const withOwner = {
|
||||||
|
apiCollectionWithOwner,
|
||||||
|
containerWithOwner,
|
||||||
|
dashboardWithOwner,
|
||||||
|
mlModelWithOwner,
|
||||||
|
pipelineWithOwner,
|
||||||
|
searchIndexWithOwner,
|
||||||
|
tableWithOwner,
|
||||||
|
topicWithOwner,
|
||||||
|
};
|
||||||
|
|
||||||
|
const withTag = {
|
||||||
|
apiCollectionWithTag,
|
||||||
|
containerWithTag,
|
||||||
|
dashboardWithTag,
|
||||||
|
mlModelWithTag,
|
||||||
|
pipelineWithTag,
|
||||||
|
searchIndexWithTag,
|
||||||
|
tableWithTag,
|
||||||
|
topicWithTag,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const assetsData = [
|
||||||
|
{
|
||||||
|
asset: ServiceTypes.API_SERVICES,
|
||||||
|
withOwner: apiCollectionWithOwner,
|
||||||
|
withTag: apiCollectionWithTag,
|
||||||
|
childTabId: 'collections',
|
||||||
|
assetOwnerUrl: `/service/${apiCollectionWithOwner.serviceType}`,
|
||||||
|
assetTagUrl: `/service/${apiCollectionWithTag.serviceType}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
asset: ServiceTypes.STORAGE_SERVICES,
|
||||||
|
withOwner: containerWithOwner,
|
||||||
|
withTag: containerWithTag,
|
||||||
|
childTabId: 'containers',
|
||||||
|
assetOwnerUrl: `/service/${containerWithOwner.serviceType}`,
|
||||||
|
assetTagUrl: `/service/${containerWithTag.serviceType}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
asset: ServiceTypes.DASHBOARD_SERVICES,
|
||||||
|
withOwner: dashboardWithOwner,
|
||||||
|
withTag: dashboardWithTag,
|
||||||
|
childTabId: 'dashboards',
|
||||||
|
childTabId2: 'data-model',
|
||||||
|
childTableId2: 'data-models-table',
|
||||||
|
assetOwnerUrl: `/service/${dashboardWithOwner.serviceType}`,
|
||||||
|
assetTagUrl: `/service/${dashboardWithTag.serviceType}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
asset: ServiceTypes.ML_MODEL_SERVICES,
|
||||||
|
withOwner: mlModelWithOwner,
|
||||||
|
withTag: mlModelWithTag,
|
||||||
|
childTabId: 'ml models',
|
||||||
|
assetOwnerUrl: `/service/${mlModelWithOwner.serviceType}`,
|
||||||
|
assetTagUrl: `/service/${mlModelWithTag.serviceType}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
asset: ServiceTypes.PIPELINE_SERVICES,
|
||||||
|
withOwner: pipelineWithOwner,
|
||||||
|
withTag: pipelineWithTag,
|
||||||
|
childTabId: 'pipelines',
|
||||||
|
assetOwnerUrl: `/service/${pipelineWithOwner.serviceType}`,
|
||||||
|
assetTagUrl: `/service/${pipelineWithTag.serviceType}`,
|
||||||
|
},
|
||||||
|
// TODO: Uncomment when search index permission issue is fixed
|
||||||
|
// {
|
||||||
|
// asset: ServiceTypes.SEARCH_SERVICES,
|
||||||
|
// withOwner: searchIndexWithOwner,
|
||||||
|
// withTag: searchIndexWithTag,
|
||||||
|
// childTabId: 'search indexes',
|
||||||
|
// assetOwnerUrl: `/service/${searchIndexWithOwner.serviceType}`,
|
||||||
|
// assetTagUrl: `/service/${searchIndexWithTag.serviceType}`,
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
asset: ServiceTypes.DATABASE_SERVICES,
|
||||||
|
withOwner: tableWithOwner,
|
||||||
|
withTag: tableWithTag,
|
||||||
|
childTabId: 'databases',
|
||||||
|
assetOwnerUrl: `/service/${tableWithOwner.serviceType}`,
|
||||||
|
assetTagUrl: `/service/${tableWithTag.serviceType}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
asset: ServiceTypes.MESSAGING_SERVICES,
|
||||||
|
withOwner: topicWithOwner,
|
||||||
|
withTag: topicWithTag,
|
||||||
|
childTabId: 'topics',
|
||||||
|
assetOwnerUrl: `/service/${topicWithOwner.serviceType}`,
|
||||||
|
assetTagUrl: `/service/${topicWithTag.serviceType}`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
asset: 'database',
|
||||||
|
withOwner: tableWithOwner,
|
||||||
|
withTag: tableWithTag,
|
||||||
|
childTabId: 'schema',
|
||||||
|
assetOwnerUrl: `/database`,
|
||||||
|
assetTagUrl: `/database`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
asset: 'databaseSchema',
|
||||||
|
withOwner: tableWithOwner,
|
||||||
|
withTag: tableWithTag,
|
||||||
|
childTabId: 'table',
|
||||||
|
assetOwnerUrl: `/databaseSchema`,
|
||||||
|
assetTagUrl: `/databaseSchema`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
asset: 'container',
|
||||||
|
withOwner: containerWithOwner,
|
||||||
|
withTag: containerWithTag,
|
||||||
|
childTabId: 'children',
|
||||||
|
assetOwnerUrl: `/container`,
|
||||||
|
assetTagUrl: `/container`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const conditionalPermissionsEntityData: EntityData = {
|
||||||
|
isOwnerPolicy,
|
||||||
|
matchAnyTagPolicy,
|
||||||
|
isOwnerRole,
|
||||||
|
matchAnyTagRole,
|
||||||
|
userWithOwnerPermission,
|
||||||
|
userWithTagPermission,
|
||||||
|
withOwner,
|
||||||
|
withTag,
|
||||||
|
};
|
@ -77,6 +77,36 @@ export const DATA_CONSUMER_RULES: PolicyRulesType[] = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const VIEW_ALL_RULE: PolicyRulesType[] = [
|
||||||
|
{
|
||||||
|
name: 'OrganizationPolicy-ViewAll-Rule',
|
||||||
|
description: 'Allow all users to view all metadata',
|
||||||
|
resources: ['All'],
|
||||||
|
operations: ['ViewAll'],
|
||||||
|
effect: 'allow',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const VIEW_ALL_WITH_IS_OWNER: PolicyRulesType[] = [
|
||||||
|
{
|
||||||
|
name: 'viewAll-IsOwner',
|
||||||
|
resources: ['All'],
|
||||||
|
operations: ['ViewAll'],
|
||||||
|
effect: 'allow',
|
||||||
|
condition: 'isOwner()',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const VIEW_ALL_WITH_MATCH_TAG_CONDITION: PolicyRulesType[] = [
|
||||||
|
{
|
||||||
|
name: 'viewAll-MatchTag',
|
||||||
|
resources: ['All'],
|
||||||
|
operations: ['ViewAll'],
|
||||||
|
effect: 'allow',
|
||||||
|
condition: "matchAnyTag('PersonalData.Personal')",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
export const EDIT_USER_FOR_TEAM_RULES: PolicyRulesType[] = [
|
export const EDIT_USER_FOR_TEAM_RULES: PolicyRulesType[] = [
|
||||||
{
|
{
|
||||||
name: 'EditUserTeams-EditRule',
|
name: 'EditUserTeams-EditRule',
|
||||||
@ -104,13 +134,6 @@ export const ORGANIZATION_POLICY_RULES: PolicyRulesType[] = [
|
|||||||
resources: ['All'],
|
resources: ['All'],
|
||||||
condition: 'isOwner()',
|
condition: 'isOwner()',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'OrganizationPolicy-ViewAll-Rule',
|
|
||||||
description: 'Allow all users to discover data assets.',
|
|
||||||
effect: 'allow',
|
|
||||||
operations: ['ViewAll'],
|
|
||||||
resources: ['All'],
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export const GLOBAL_SETTING_PERMISSIONS: Record<
|
export const GLOBAL_SETTING_PERMISSIONS: Record<
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { uuid } from '../utils/common';
|
import { uuid } from '../utils/common';
|
||||||
import { GlobalSettingOptions } from './settings';
|
import { GlobalSettingOptions, ServiceTypes } from './settings';
|
||||||
|
|
||||||
export const SERVICE_TYPE = {
|
export const SERVICE_TYPE = {
|
||||||
Database: GlobalSettingOptions.DATABASES,
|
Database: GlobalSettingOptions.DATABASES,
|
||||||
@ -26,49 +26,38 @@ export const SERVICE_TYPE = {
|
|||||||
ApiService: GlobalSettingOptions.APIS,
|
ApiService: GlobalSettingOptions.APIS,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SERVICE_CATEGORIES = {
|
|
||||||
DATABASE_SERVICES: 'databaseServices',
|
|
||||||
MESSAGING_SERVICES: 'messagingServices',
|
|
||||||
PIPELINE_SERVICES: 'pipelineServices',
|
|
||||||
DASHBOARD_SERVICES: 'dashboardServices',
|
|
||||||
ML_MODEL_SERVICES: 'mlmodelServices',
|
|
||||||
STORAGE_SERVICES: 'storageServices',
|
|
||||||
METADATA_SERVICES: 'metadataServices',
|
|
||||||
SEARCH_SERVICES: 'searchServices',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const VISIT_SERVICE_PAGE_DETAILS = {
|
export const VISIT_SERVICE_PAGE_DETAILS = {
|
||||||
[SERVICE_TYPE.Database]: {
|
[SERVICE_TYPE.Database]: {
|
||||||
settingsMenuId: GlobalSettingOptions.DATABASES,
|
settingsMenuId: GlobalSettingOptions.DATABASES,
|
||||||
serviceCategory: SERVICE_CATEGORIES.DATABASE_SERVICES,
|
serviceCategory: ServiceTypes.DATABASE_SERVICES,
|
||||||
},
|
},
|
||||||
[SERVICE_TYPE.Messaging]: {
|
[SERVICE_TYPE.Messaging]: {
|
||||||
settingsMenuId: GlobalSettingOptions.MESSAGING,
|
settingsMenuId: GlobalSettingOptions.MESSAGING,
|
||||||
serviceCategory: SERVICE_CATEGORIES.MESSAGING_SERVICES,
|
serviceCategory: ServiceTypes.MESSAGING_SERVICES,
|
||||||
},
|
},
|
||||||
[SERVICE_TYPE.Dashboard]: {
|
[SERVICE_TYPE.Dashboard]: {
|
||||||
settingsMenuId: GlobalSettingOptions.DASHBOARDS,
|
settingsMenuId: GlobalSettingOptions.DASHBOARDS,
|
||||||
serviceCategory: SERVICE_CATEGORIES.DASHBOARD_SERVICES,
|
serviceCategory: ServiceTypes.DASHBOARD_SERVICES,
|
||||||
},
|
},
|
||||||
[SERVICE_TYPE.Pipeline]: {
|
[SERVICE_TYPE.Pipeline]: {
|
||||||
settingsMenuId: GlobalSettingOptions.PIPELINES,
|
settingsMenuId: GlobalSettingOptions.PIPELINES,
|
||||||
serviceCategory: SERVICE_CATEGORIES.PIPELINE_SERVICES,
|
serviceCategory: ServiceTypes.PIPELINE_SERVICES,
|
||||||
},
|
},
|
||||||
[SERVICE_TYPE.MLModels]: {
|
[SERVICE_TYPE.MLModels]: {
|
||||||
settingsMenuId: GlobalSettingOptions.MLMODELS,
|
settingsMenuId: GlobalSettingOptions.MLMODELS,
|
||||||
serviceCategory: SERVICE_CATEGORIES.ML_MODEL_SERVICES,
|
serviceCategory: ServiceTypes.ML_MODEL_SERVICES,
|
||||||
},
|
},
|
||||||
[SERVICE_TYPE.Storage]: {
|
[SERVICE_TYPE.Storage]: {
|
||||||
settingsMenuId: GlobalSettingOptions.STORAGES,
|
settingsMenuId: GlobalSettingOptions.STORAGES,
|
||||||
serviceCategory: SERVICE_CATEGORIES.STORAGE_SERVICES,
|
serviceCategory: ServiceTypes.STORAGE_SERVICES,
|
||||||
},
|
},
|
||||||
[SERVICE_TYPE.Search]: {
|
[SERVICE_TYPE.Search]: {
|
||||||
settingsMenuId: GlobalSettingOptions.SEARCH,
|
settingsMenuId: GlobalSettingOptions.SEARCH,
|
||||||
serviceCategory: SERVICE_CATEGORIES.SEARCH_SERVICES,
|
serviceCategory: ServiceTypes.SEARCH_SERVICES,
|
||||||
},
|
},
|
||||||
[SERVICE_TYPE.Metadata]: {
|
[SERVICE_TYPE.Metadata]: {
|
||||||
settingsMenuId: GlobalSettingOptions.METADATA,
|
settingsMenuId: GlobalSettingOptions.METADATA,
|
||||||
serviceCategory: SERVICE_CATEGORIES.METADATA_SERVICES,
|
serviceCategory: ServiceTypes.METADATA_SERVICES,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,6 +21,18 @@ export enum GlobalSettingsMenuCategory {
|
|||||||
APPLICATIONS = 'apps',
|
APPLICATIONS = 'apps',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ServiceTypes {
|
||||||
|
API_SERVICES = 'apiServices',
|
||||||
|
DATABASE_SERVICES = 'databaseServices',
|
||||||
|
MESSAGING_SERVICES = 'messagingServices',
|
||||||
|
PIPELINE_SERVICES = 'pipelineServices',
|
||||||
|
DASHBOARD_SERVICES = 'dashboardServices',
|
||||||
|
ML_MODEL_SERVICES = 'mlmodelServices',
|
||||||
|
STORAGE_SERVICES = 'storageServices',
|
||||||
|
METADATA_SERVICES = 'metadataServices',
|
||||||
|
SEARCH_SERVICES = 'searchServices',
|
||||||
|
}
|
||||||
|
|
||||||
export enum GlobalSettingOptions {
|
export enum GlobalSettingOptions {
|
||||||
USERS = 'users',
|
USERS = 'users',
|
||||||
ADMINS = 'admins',
|
ADMINS = 'admins',
|
||||||
@ -80,6 +92,10 @@ export enum GlobalSettingOptions {
|
|||||||
export const SETTINGS_OPTIONS_PATH = {
|
export const SETTINGS_OPTIONS_PATH = {
|
||||||
// Services
|
// Services
|
||||||
|
|
||||||
|
[GlobalSettingOptions.API_COLLECTIONS]: [
|
||||||
|
GlobalSettingsMenuCategory.SERVICES,
|
||||||
|
`${GlobalSettingsMenuCategory.SERVICES}.${GlobalSettingOptions.API_COLLECTIONS}`,
|
||||||
|
],
|
||||||
[GlobalSettingOptions.DATABASES]: [
|
[GlobalSettingOptions.DATABASES]: [
|
||||||
GlobalSettingsMenuCategory.SERVICES,
|
GlobalSettingsMenuCategory.SERVICES,
|
||||||
`${GlobalSettingsMenuCategory.SERVICES}.${GlobalSettingOptions.DATABASES}`,
|
`${GlobalSettingsMenuCategory.SERVICES}.${GlobalSettingOptions.DATABASES}`,
|
||||||
|
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 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 { Page, test as base } from '@playwright/test';
|
||||||
|
import { startCase } from 'lodash';
|
||||||
|
import {
|
||||||
|
assetsData,
|
||||||
|
userWithOwnerPermission,
|
||||||
|
userWithTagPermission,
|
||||||
|
} from '../../constant/conditionalPermissions';
|
||||||
|
import { performAdminLogin } from '../../utils/admin';
|
||||||
|
import {
|
||||||
|
checkViewAllPermission,
|
||||||
|
conditionalPermissionsCleanup,
|
||||||
|
conditionalPermissionsPrerequisites,
|
||||||
|
getEntityFQN,
|
||||||
|
} from '../../utils/conditionalPermissions';
|
||||||
|
|
||||||
|
const test = base.extend<{
|
||||||
|
user1Page: Page;
|
||||||
|
user2Page: Page;
|
||||||
|
}>({
|
||||||
|
user1Page: async ({ browser }, use) => {
|
||||||
|
const page = await browser.newPage();
|
||||||
|
await userWithOwnerPermission.login(page);
|
||||||
|
await use(page);
|
||||||
|
await page.close();
|
||||||
|
},
|
||||||
|
user2Page: async ({ browser }, use) => {
|
||||||
|
const page = await browser.newPage();
|
||||||
|
await userWithTagPermission.login(page);
|
||||||
|
await use(page);
|
||||||
|
await page.close();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
test.beforeAll(async ({ browser }) => {
|
||||||
|
test.slow();
|
||||||
|
|
||||||
|
const { apiContext, afterAction } = await performAdminLogin(browser);
|
||||||
|
await conditionalPermissionsPrerequisites(apiContext);
|
||||||
|
await afterAction();
|
||||||
|
});
|
||||||
|
|
||||||
|
test.afterAll(async ({ browser }) => {
|
||||||
|
test.slow();
|
||||||
|
|
||||||
|
const { apiContext, afterAction } = await performAdminLogin(browser);
|
||||||
|
await conditionalPermissionsCleanup(apiContext);
|
||||||
|
await afterAction();
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const serviceData of assetsData) {
|
||||||
|
const {
|
||||||
|
asset,
|
||||||
|
withOwner,
|
||||||
|
withTag,
|
||||||
|
assetOwnerUrl,
|
||||||
|
assetTagUrl,
|
||||||
|
childTabId,
|
||||||
|
childTabId2,
|
||||||
|
childTableId2,
|
||||||
|
} = serviceData;
|
||||||
|
|
||||||
|
test(`User with owner permission can only view owned ${startCase(
|
||||||
|
asset
|
||||||
|
)}`, async ({ user1Page: page }) => {
|
||||||
|
// Get the FQNs of both assets
|
||||||
|
const ownerAssetName = getEntityFQN(asset, withOwner);
|
||||||
|
const tagAssetName = getEntityFQN(asset, withTag);
|
||||||
|
|
||||||
|
const ownerAssetURL = `${assetOwnerUrl}/${ownerAssetName}`;
|
||||||
|
const tagAssetURL = `${assetTagUrl}/${tagAssetName}`;
|
||||||
|
|
||||||
|
await checkViewAllPermission({
|
||||||
|
page,
|
||||||
|
url1: ownerAssetURL,
|
||||||
|
url2: tagAssetURL,
|
||||||
|
childTabId,
|
||||||
|
childTabId2,
|
||||||
|
childTableId2,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`User with matchAnyTag permission can only view ${startCase(
|
||||||
|
asset
|
||||||
|
)} with the tag`, async ({ user2Page: page }) => {
|
||||||
|
// Get the FQNs of both assets
|
||||||
|
const ownerAssetName = getEntityFQN(asset, withOwner);
|
||||||
|
const tagAssetName = getEntityFQN(asset, withTag);
|
||||||
|
|
||||||
|
const ownerAssetURL = `${assetOwnerUrl}/${ownerAssetName}`;
|
||||||
|
const tagAssetURL = `${assetTagUrl}/${tagAssetName}`;
|
||||||
|
|
||||||
|
await checkViewAllPermission({
|
||||||
|
page,
|
||||||
|
url1: tagAssetURL,
|
||||||
|
url2: ownerAssetURL,
|
||||||
|
childTabId,
|
||||||
|
childTabId2,
|
||||||
|
childTableId2,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 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 { test as teardown } from '@playwright/test';
|
||||||
|
import { AdminClass } from '../support/user/AdminClass';
|
||||||
|
import { resetPolicyChanges } from '../utils/authTeardown';
|
||||||
|
|
||||||
|
teardown('restore the organization roles and policies', async ({ page }) => {
|
||||||
|
const admin = new AdminClass();
|
||||||
|
|
||||||
|
// Reset the default organization roles and policies
|
||||||
|
await resetPolicyChanges(page, admin);
|
||||||
|
});
|
@ -13,6 +13,7 @@
|
|||||||
import { APIRequestContext, Page } from '@playwright/test';
|
import { APIRequestContext, Page } from '@playwright/test';
|
||||||
import { Operation } from 'fast-json-patch';
|
import { Operation } from 'fast-json-patch';
|
||||||
import { SERVICE_TYPE } from '../../constant/service';
|
import { SERVICE_TYPE } from '../../constant/service';
|
||||||
|
import { ServiceTypes } from '../../constant/settings';
|
||||||
import { uuid } from '../../utils/common';
|
import { uuid } from '../../utils/common';
|
||||||
import { visitEntityPage } from '../../utils/entity';
|
import { visitEntityPage } from '../../utils/entity';
|
||||||
import { visitServiceDetailsPage } from '../../utils/service';
|
import { visitServiceDetailsPage } from '../../utils/service';
|
||||||
@ -149,6 +150,8 @@ export class ApiCollectionClass extends EntityClass {
|
|||||||
|
|
||||||
constructor(name?: string) {
|
constructor(name?: string) {
|
||||||
super(EntityTypeEndpoint.API_COLLECTION);
|
super(EntityTypeEndpoint.API_COLLECTION);
|
||||||
|
this.serviceCategory = SERVICE_TYPE.ApiService;
|
||||||
|
this.serviceType = ServiceTypes.API_SERVICES;
|
||||||
this.service.name = name ?? this.service.name;
|
this.service.name = name ?? this.service.name;
|
||||||
this.type = 'Api Collection';
|
this.type = 'Api Collection';
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
import { APIRequestContext, Page } from '@playwright/test';
|
import { APIRequestContext, Page } from '@playwright/test';
|
||||||
import { Operation } from 'fast-json-patch';
|
import { Operation } from 'fast-json-patch';
|
||||||
import { SERVICE_TYPE } from '../../constant/service';
|
import { SERVICE_TYPE } from '../../constant/service';
|
||||||
|
import { ServiceTypes } from '../../constant/settings';
|
||||||
import { uuid } from '../../utils/common';
|
import { uuid } from '../../utils/common';
|
||||||
import { visitEntityPage } from '../../utils/entity';
|
import { visitEntityPage } from '../../utils/entity';
|
||||||
import {
|
import {
|
||||||
@ -153,6 +154,7 @@ export class ApiEndpointClass extends EntityClass {
|
|||||||
super(EntityTypeEndpoint.API_ENDPOINT);
|
super(EntityTypeEndpoint.API_ENDPOINT);
|
||||||
this.service.name = name ?? this.service.name;
|
this.service.name = name ?? this.service.name;
|
||||||
this.serviceCategory = SERVICE_TYPE.ApiService;
|
this.serviceCategory = SERVICE_TYPE.ApiService;
|
||||||
|
this.serviceType = ServiceTypes.API_SERVICES;
|
||||||
this.type = 'ApiEndpoint';
|
this.type = 'ApiEndpoint';
|
||||||
this.childrenTabId = 'schema';
|
this.childrenTabId = 'schema';
|
||||||
this.childrenSelectorId = this.children[0].name;
|
this.childrenSelectorId = this.children[0].name;
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
import { APIRequestContext, Page } from '@playwright/test';
|
import { APIRequestContext, Page } from '@playwright/test';
|
||||||
import { Operation } from 'fast-json-patch';
|
import { Operation } from 'fast-json-patch';
|
||||||
import { SERVICE_TYPE } from '../../constant/service';
|
import { SERVICE_TYPE } from '../../constant/service';
|
||||||
|
import { ServiceTypes } from '../../constant/settings';
|
||||||
import { uuid } from '../../utils/common';
|
import { uuid } from '../../utils/common';
|
||||||
import { visitEntityPage } from '../../utils/entity';
|
import { visitEntityPage } from '../../utils/entity';
|
||||||
import {
|
import {
|
||||||
@ -24,6 +25,7 @@ import { EntityClass } from './EntityClass';
|
|||||||
|
|
||||||
export class ContainerClass extends EntityClass {
|
export class ContainerClass extends EntityClass {
|
||||||
private containerName = `pw-container-${uuid()}`;
|
private containerName = `pw-container-${uuid()}`;
|
||||||
|
private childContainerName = `pw-container-${uuid()}`;
|
||||||
service = {
|
service = {
|
||||||
name: `pw-storage-service-${uuid()}`,
|
name: `pw-storage-service-${uuid()}`,
|
||||||
serviceType: 'S3',
|
serviceType: 'S3',
|
||||||
@ -45,14 +47,21 @@ export class ContainerClass extends EntityClass {
|
|||||||
displayName: this.containerName,
|
displayName: this.containerName,
|
||||||
service: this.service.name,
|
service: this.service.name,
|
||||||
};
|
};
|
||||||
|
childContainer = {
|
||||||
|
name: this.childContainerName,
|
||||||
|
displayName: this.childContainerName,
|
||||||
|
service: this.service.name,
|
||||||
|
};
|
||||||
|
|
||||||
serviceResponseData: ResponseDataType = {} as ResponseDataType;
|
serviceResponseData: ResponseDataType = {} as ResponseDataType;
|
||||||
entityResponseData: ResponseDataWithServiceType =
|
entityResponseData: ResponseDataWithServiceType =
|
||||||
{} as ResponseDataWithServiceType;
|
{} as ResponseDataWithServiceType;
|
||||||
|
childResponseData: ResponseDataType = {} as ResponseDataType;
|
||||||
|
|
||||||
constructor(name?: string) {
|
constructor(name?: string) {
|
||||||
super(EntityTypeEndpoint.Container);
|
super(EntityTypeEndpoint.Container);
|
||||||
this.service.name = name ?? this.service.name;
|
this.service.name = name ?? this.service.name;
|
||||||
|
this.serviceType = ServiceTypes.STORAGE_SERVICES;
|
||||||
this.type = 'Container';
|
this.type = 'Container';
|
||||||
this.serviceCategory = SERVICE_TYPE.Storage;
|
this.serviceCategory = SERVICE_TYPE.Storage;
|
||||||
}
|
}
|
||||||
@ -71,6 +80,20 @@ export class ContainerClass extends EntityClass {
|
|||||||
this.serviceResponseData = await serviceResponse.json();
|
this.serviceResponseData = await serviceResponse.json();
|
||||||
this.entityResponseData = await entityResponse.json();
|
this.entityResponseData = await entityResponse.json();
|
||||||
|
|
||||||
|
const childContainer = {
|
||||||
|
...this.childContainer,
|
||||||
|
parent: {
|
||||||
|
id: this.entityResponseData.id,
|
||||||
|
type: 'container',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const childResponse = await apiContext.post('/api/v1/containers', {
|
||||||
|
data: childContainer,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.childResponseData = await childResponse.json();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
service: serviceResponse.body,
|
service: serviceResponse.body,
|
||||||
entity: entityResponse.body,
|
entity: entityResponse.body,
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
import { APIRequestContext, Page } from '@playwright/test';
|
import { APIRequestContext, Page } from '@playwright/test';
|
||||||
import { Operation } from 'fast-json-patch';
|
import { Operation } from 'fast-json-patch';
|
||||||
import { SERVICE_TYPE } from '../../constant/service';
|
import { SERVICE_TYPE } from '../../constant/service';
|
||||||
|
import { ServiceTypes } from '../../constant/settings';
|
||||||
import { uuid } from '../../utils/common';
|
import { uuid } from '../../utils/common';
|
||||||
import { visitEntityPage } from '../../utils/entity';
|
import { visitEntityPage } from '../../utils/entity';
|
||||||
import {
|
import {
|
||||||
@ -24,6 +25,7 @@ import { EntityClass } from './EntityClass';
|
|||||||
|
|
||||||
export class DashboardClass extends EntityClass {
|
export class DashboardClass extends EntityClass {
|
||||||
private dashboardName = `pw-dashboard-${uuid()}`;
|
private dashboardName = `pw-dashboard-${uuid()}`;
|
||||||
|
private dashboardDataModelName = `pw-dashboard-data-model-${uuid()}`;
|
||||||
service = {
|
service = {
|
||||||
name: `pw-dashboard-service-${uuid()}`,
|
name: `pw-dashboard-service-${uuid()}`,
|
||||||
serviceType: 'Superset',
|
serviceType: 'Superset',
|
||||||
@ -50,10 +52,28 @@ export class DashboardClass extends EntityClass {
|
|||||||
displayName: this.dashboardName,
|
displayName: this.dashboardName,
|
||||||
service: this.service.name,
|
service: this.service.name,
|
||||||
};
|
};
|
||||||
|
children = [
|
||||||
|
{
|
||||||
|
name: 'country_name',
|
||||||
|
dataType: 'VARCHAR',
|
||||||
|
dataLength: 256,
|
||||||
|
dataTypeDisplay: 'varchar',
|
||||||
|
description: 'Name of the country.',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
dataModel = {
|
||||||
|
name: this.dashboardDataModelName,
|
||||||
|
displayName: this.dashboardDataModelName,
|
||||||
|
service: this.service.name,
|
||||||
|
columns: this.children,
|
||||||
|
dataModelType: 'SupersetDataModel',
|
||||||
|
};
|
||||||
|
|
||||||
serviceResponseData: ResponseDataType = {} as ResponseDataType;
|
serviceResponseData: ResponseDataType = {} as ResponseDataType;
|
||||||
entityResponseData: ResponseDataWithServiceType =
|
entityResponseData: ResponseDataWithServiceType =
|
||||||
{} as ResponseDataWithServiceType;
|
{} as ResponseDataWithServiceType;
|
||||||
|
dataModelResponseData: ResponseDataWithServiceType =
|
||||||
|
{} as ResponseDataWithServiceType;
|
||||||
chartsResponseData: ResponseDataType = {} as ResponseDataType;
|
chartsResponseData: ResponseDataType = {} as ResponseDataType;
|
||||||
|
|
||||||
constructor(name?: string) {
|
constructor(name?: string) {
|
||||||
@ -61,6 +81,7 @@ export class DashboardClass extends EntityClass {
|
|||||||
this.service.name = name ?? this.service.name;
|
this.service.name = name ?? this.service.name;
|
||||||
this.type = 'Dashboard';
|
this.type = 'Dashboard';
|
||||||
this.serviceCategory = SERVICE_TYPE.Dashboard;
|
this.serviceCategory = SERVICE_TYPE.Dashboard;
|
||||||
|
this.serviceType = ServiceTypes.DASHBOARD_SERVICES;
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(apiContext: APIRequestContext) {
|
async create(apiContext: APIRequestContext) {
|
||||||
@ -80,9 +101,16 @@ export class DashboardClass extends EntityClass {
|
|||||||
charts: [`${this.service.name}.${this.charts.name}`],
|
charts: [`${this.service.name}.${this.charts.name}`],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const dataModelResponse = await apiContext.post(
|
||||||
|
'/api/v1/dashboard/datamodels',
|
||||||
|
{
|
||||||
|
data: this.dataModel,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
this.serviceResponseData = await serviceResponse.json();
|
this.serviceResponseData = await serviceResponse.json();
|
||||||
this.chartsResponseData = await chartsResponse.json();
|
this.chartsResponseData = await chartsResponse.json();
|
||||||
|
this.dataModelResponseData = await dataModelResponse.json();
|
||||||
this.entityResponseData = await entityResponse.json();
|
this.entityResponseData = await entityResponse.json();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
import { APIRequestContext, Page } from '@playwright/test';
|
import { APIRequestContext, Page } from '@playwright/test';
|
||||||
import { Operation } from 'fast-json-patch';
|
import { Operation } from 'fast-json-patch';
|
||||||
import { SERVICE_TYPE } from '../../constant/service';
|
import { SERVICE_TYPE } from '../../constant/service';
|
||||||
|
import { ServiceTypes } from '../../constant/settings';
|
||||||
import { uuid } from '../../utils/common';
|
import { uuid } from '../../utils/common';
|
||||||
import { visitEntityPage } from '../../utils/entity';
|
import { visitEntityPage } from '../../utils/entity';
|
||||||
import {
|
import {
|
||||||
@ -70,6 +71,7 @@ export class DashboardDataModelClass extends EntityClass {
|
|||||||
this.childrenTabId = 'model';
|
this.childrenTabId = 'model';
|
||||||
this.childrenSelectorId = this.children[0].name;
|
this.childrenSelectorId = this.children[0].name;
|
||||||
this.serviceCategory = SERVICE_TYPE.Dashboard;
|
this.serviceCategory = SERVICE_TYPE.Dashboard;
|
||||||
|
this.serviceType = ServiceTypes.DASHBOARD_SERVICES;
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(apiContext: APIRequestContext) {
|
async create(apiContext: APIRequestContext) {
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
import { APIRequestContext, expect, Page } from '@playwright/test';
|
import { APIRequestContext, expect, Page } from '@playwright/test';
|
||||||
import { Operation } from 'fast-json-patch';
|
import { Operation } from 'fast-json-patch';
|
||||||
import { SERVICE_TYPE } from '../../constant/service';
|
import { SERVICE_TYPE } from '../../constant/service';
|
||||||
|
import { ServiceTypes } from '../../constant/settings';
|
||||||
import {
|
import {
|
||||||
assignDomain,
|
assignDomain,
|
||||||
removeDomain,
|
removeDomain,
|
||||||
@ -127,6 +128,7 @@ export class DatabaseClass extends EntityClass {
|
|||||||
super(EntityTypeEndpoint.Database);
|
super(EntityTypeEndpoint.Database);
|
||||||
this.service.name = name ?? this.service.name;
|
this.service.name = name ?? this.service.name;
|
||||||
this.type = 'Database';
|
this.type = 'Database';
|
||||||
|
this.serviceType = ServiceTypes.DATABASE_SERVICES;
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(apiContext: APIRequestContext) {
|
async create(apiContext: APIRequestContext) {
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
import { APIRequestContext, Page } from '@playwright/test';
|
import { APIRequestContext, Page } from '@playwright/test';
|
||||||
import { Operation } from 'fast-json-patch';
|
import { Operation } from 'fast-json-patch';
|
||||||
import { SERVICE_TYPE } from '../../constant/service';
|
import { SERVICE_TYPE } from '../../constant/service';
|
||||||
|
import { ServiceTypes } from '../../constant/settings';
|
||||||
import { uuid } from '../../utils/common';
|
import { uuid } from '../../utils/common';
|
||||||
import { visitServiceDetailsPage } from '../../utils/service';
|
import { visitServiceDetailsPage } from '../../utils/service';
|
||||||
import {
|
import {
|
||||||
@ -61,6 +62,7 @@ export class DatabaseSchemaClass extends EntityClass {
|
|||||||
super(EntityTypeEndpoint.DatabaseSchema);
|
super(EntityTypeEndpoint.DatabaseSchema);
|
||||||
this.service.name = name ?? this.service.name;
|
this.service.name = name ?? this.service.name;
|
||||||
this.type = 'Database Schema';
|
this.type = 'Database Schema';
|
||||||
|
this.serviceType = ServiceTypes.DATABASE_SERVICES;
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(apiContext: APIRequestContext) {
|
async create(apiContext: APIRequestContext) {
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
import { APIRequestContext, Page } from '@playwright/test';
|
import { APIRequestContext, Page } from '@playwright/test';
|
||||||
import { CustomPropertySupportedEntityList } from '../../constant/customProperty';
|
import { CustomPropertySupportedEntityList } from '../../constant/customProperty';
|
||||||
import { GlobalSettingOptions } from '../../constant/settings';
|
import { GlobalSettingOptions, ServiceTypes } from '../../constant/settings';
|
||||||
import { assignDomain, removeDomain, updateDomain } from '../../utils/common';
|
import { assignDomain, removeDomain, updateDomain } from '../../utils/common';
|
||||||
import {
|
import {
|
||||||
createCustomPropertyForEntity,
|
createCustomPropertyForEntity,
|
||||||
@ -56,6 +56,7 @@ import { EntityTypeEndpoint, ENTITY_PATH } from './Entity.interface';
|
|||||||
export class EntityClass {
|
export class EntityClass {
|
||||||
type = '';
|
type = '';
|
||||||
serviceCategory?: GlobalSettingOptions;
|
serviceCategory?: GlobalSettingOptions;
|
||||||
|
serviceType?: ServiceTypes;
|
||||||
childrenTabId?: string;
|
childrenTabId?: string;
|
||||||
childrenSelectorId?: string;
|
childrenSelectorId?: string;
|
||||||
endpoint: EntityTypeEndpoint;
|
endpoint: EntityTypeEndpoint;
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
import { APIRequestContext, Page } from '@playwright/test';
|
import { APIRequestContext, Page } from '@playwright/test';
|
||||||
import { Operation } from 'fast-json-patch';
|
import { Operation } from 'fast-json-patch';
|
||||||
import { SERVICE_TYPE } from '../../constant/service';
|
import { SERVICE_TYPE } from '../../constant/service';
|
||||||
|
import { ServiceTypes } from '../../constant/settings';
|
||||||
import { uuid } from '../../utils/common';
|
import { uuid } from '../../utils/common';
|
||||||
import { visitEntityPage } from '../../utils/entity';
|
import { visitEntityPage } from '../../utils/entity';
|
||||||
import {
|
import {
|
||||||
@ -64,6 +65,7 @@ export class MlModelClass extends EntityClass {
|
|||||||
this.childrenTabId = 'features';
|
this.childrenTabId = 'features';
|
||||||
this.childrenSelectorId = `feature-card-${this.children[0].name}`;
|
this.childrenSelectorId = `feature-card-${this.children[0].name}`;
|
||||||
this.serviceCategory = SERVICE_TYPE.MLModels;
|
this.serviceCategory = SERVICE_TYPE.MLModels;
|
||||||
|
this.serviceType = ServiceTypes.ML_MODEL_SERVICES;
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(apiContext: APIRequestContext) {
|
async create(apiContext: APIRequestContext) {
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
import { APIRequestContext, Page } from '@playwright/test';
|
import { APIRequestContext, Page } from '@playwright/test';
|
||||||
import { Operation } from 'fast-json-patch';
|
import { Operation } from 'fast-json-patch';
|
||||||
import { SERVICE_TYPE } from '../../constant/service';
|
import { SERVICE_TYPE } from '../../constant/service';
|
||||||
|
import { ServiceTypes } from '../../constant/settings';
|
||||||
import { uuid } from '../../utils/common';
|
import { uuid } from '../../utils/common';
|
||||||
import { visitEntityPage } from '../../utils/entity';
|
import { visitEntityPage } from '../../utils/entity';
|
||||||
import {
|
import {
|
||||||
@ -59,6 +60,7 @@ export class PipelineClass extends EntityClass {
|
|||||||
this.childrenTabId = 'tasks';
|
this.childrenTabId = 'tasks';
|
||||||
this.childrenSelectorId = this.children[0].name;
|
this.childrenSelectorId = this.children[0].name;
|
||||||
this.serviceCategory = SERVICE_TYPE.Pipeline;
|
this.serviceCategory = SERVICE_TYPE.Pipeline;
|
||||||
|
this.serviceType = ServiceTypes.PIPELINE_SERVICES;
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(apiContext: APIRequestContext) {
|
async create(apiContext: APIRequestContext) {
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
import { APIRequestContext, Page } from '@playwright/test';
|
import { APIRequestContext, Page } from '@playwright/test';
|
||||||
import { Operation } from 'fast-json-patch';
|
import { Operation } from 'fast-json-patch';
|
||||||
import { SERVICE_TYPE } from '../../constant/service';
|
import { SERVICE_TYPE } from '../../constant/service';
|
||||||
|
import { ServiceTypes } from '../../constant/settings';
|
||||||
import { uuid } from '../../utils/common';
|
import { uuid } from '../../utils/common';
|
||||||
import { visitEntityPage } from '../../utils/entity';
|
import { visitEntityPage } from '../../utils/entity';
|
||||||
import {
|
import {
|
||||||
@ -105,6 +106,7 @@ export class SearchIndexClass extends EntityClass {
|
|||||||
this.childrenTabId = 'fields';
|
this.childrenTabId = 'fields';
|
||||||
this.childrenSelectorId = this.children[0].fullyQualifiedName;
|
this.childrenSelectorId = this.children[0].fullyQualifiedName;
|
||||||
this.serviceCategory = SERVICE_TYPE.Search;
|
this.serviceCategory = SERVICE_TYPE.Search;
|
||||||
|
this.serviceType = ServiceTypes.SEARCH_SERVICES;
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(apiContext: APIRequestContext) {
|
async create(apiContext: APIRequestContext) {
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
import { APIRequestContext, Page } from '@playwright/test';
|
import { APIRequestContext, Page } from '@playwright/test';
|
||||||
import { Operation } from 'fast-json-patch';
|
import { Operation } from 'fast-json-patch';
|
||||||
import { SERVICE_TYPE } from '../../constant/service';
|
import { SERVICE_TYPE } from '../../constant/service';
|
||||||
|
import { ServiceTypes } from '../../constant/settings';
|
||||||
import { uuid } from '../../utils/common';
|
import { uuid } from '../../utils/common';
|
||||||
import { visitEntityPage } from '../../utils/entity';
|
import { visitEntityPage } from '../../utils/entity';
|
||||||
import {
|
import {
|
||||||
@ -71,6 +72,7 @@ export class StoredProcedureClass extends EntityClass {
|
|||||||
this.service.name = name ?? this.service.name;
|
this.service.name = name ?? this.service.name;
|
||||||
this.serviceCategory = SERVICE_TYPE.Database;
|
this.serviceCategory = SERVICE_TYPE.Database;
|
||||||
this.type = 'Store Procedure';
|
this.type = 'Store Procedure';
|
||||||
|
this.serviceType = ServiceTypes.DATABASE_SERVICES;
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(apiContext: APIRequestContext) {
|
async create(apiContext: APIRequestContext) {
|
||||||
|
@ -14,6 +14,7 @@ import { APIRequestContext, Page } from '@playwright/test';
|
|||||||
import { Operation } from 'fast-json-patch';
|
import { Operation } from 'fast-json-patch';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
import { SERVICE_TYPE } from '../../constant/service';
|
import { SERVICE_TYPE } from '../../constant/service';
|
||||||
|
import { ServiceTypes } from '../../constant/settings';
|
||||||
import { uuid } from '../../utils/common';
|
import { uuid } from '../../utils/common';
|
||||||
import { visitEntityPage } from '../../utils/entity';
|
import { visitEntityPage } from '../../utils/entity';
|
||||||
import {
|
import {
|
||||||
@ -125,6 +126,7 @@ export class TableClass extends EntityClass {
|
|||||||
super(EntityTypeEndpoint.Table);
|
super(EntityTypeEndpoint.Table);
|
||||||
this.service.name = name ?? this.service.name;
|
this.service.name = name ?? this.service.name;
|
||||||
this.serviceCategory = SERVICE_TYPE.Database;
|
this.serviceCategory = SERVICE_TYPE.Database;
|
||||||
|
this.serviceType = ServiceTypes.DATABASE_SERVICES;
|
||||||
this.type = 'Table';
|
this.type = 'Table';
|
||||||
this.childrenTabId = 'schema';
|
this.childrenTabId = 'schema';
|
||||||
this.childrenSelectorId = `${this.entity.databaseSchema}.${this.entity.name}.${this.children[0].name}`;
|
this.childrenSelectorId = `${this.entity.databaseSchema}.${this.entity.name}.${this.children[0].name}`;
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
import { APIRequestContext, Page } from '@playwright/test';
|
import { APIRequestContext, Page } from '@playwright/test';
|
||||||
import { Operation } from 'fast-json-patch';
|
import { Operation } from 'fast-json-patch';
|
||||||
import { SERVICE_TYPE } from '../../constant/service';
|
import { SERVICE_TYPE } from '../../constant/service';
|
||||||
|
import { ServiceTypes } from '../../constant/settings';
|
||||||
import { uuid } from '../../utils/common';
|
import { uuid } from '../../utils/common';
|
||||||
import { visitEntityPage } from '../../utils/entity';
|
import { visitEntityPage } from '../../utils/entity';
|
||||||
import {
|
import {
|
||||||
@ -107,6 +108,7 @@ export class TopicClass extends EntityClass {
|
|||||||
this.childrenTabId = 'schema';
|
this.childrenTabId = 'schema';
|
||||||
this.childrenSelectorId = this.children[0].name;
|
this.childrenSelectorId = this.children[0].name;
|
||||||
this.serviceCategory = SERVICE_TYPE.Messaging;
|
this.serviceCategory = SERVICE_TYPE.Messaging;
|
||||||
|
this.serviceType = ServiceTypes.MESSAGING_SERVICES;
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(apiContext: APIRequestContext) {
|
async create(apiContext: APIRequestContext) {
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 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 { PolicyClass } from '../access-control/PoliciesClass';
|
||||||
|
import { RolesClass } from '../access-control/RolesClass';
|
||||||
|
import { ApiCollectionClass } from '../entity/ApiCollectionClass';
|
||||||
|
import { ContainerClass } from '../entity/ContainerClass';
|
||||||
|
import { DashboardClass } from '../entity/DashboardClass';
|
||||||
|
import { MlModelClass } from '../entity/MlModelClass';
|
||||||
|
import { PipelineClass } from '../entity/PipelineClass';
|
||||||
|
import { SearchIndexClass } from '../entity/SearchIndexClass';
|
||||||
|
import { TableClass } from '../entity/TableClass';
|
||||||
|
import { TopicClass } from '../entity/TopicClass';
|
||||||
|
import { UserClass } from '../user/UserClass';
|
||||||
|
|
||||||
|
export interface EntityData {
|
||||||
|
isOwnerPolicy: PolicyClass;
|
||||||
|
matchAnyTagPolicy: PolicyClass;
|
||||||
|
isOwnerRole: RolesClass;
|
||||||
|
matchAnyTagRole: RolesClass;
|
||||||
|
userWithOwnerPermission: UserClass;
|
||||||
|
userWithTagPermission: UserClass;
|
||||||
|
withOwner: {
|
||||||
|
apiCollectionWithOwner: ApiCollectionClass;
|
||||||
|
containerWithOwner: ContainerClass;
|
||||||
|
dashboardWithOwner: DashboardClass;
|
||||||
|
mlModelWithOwner: MlModelClass;
|
||||||
|
pipelineWithOwner: PipelineClass;
|
||||||
|
searchIndexWithOwner: SearchIndexClass;
|
||||||
|
tableWithOwner: TableClass;
|
||||||
|
topicWithOwner: TopicClass;
|
||||||
|
};
|
||||||
|
withTag: {
|
||||||
|
apiCollectionWithTag: ApiCollectionClass;
|
||||||
|
containerWithTag: ContainerClass;
|
||||||
|
dashboardWithTag: DashboardClass;
|
||||||
|
mlModelWithTag: MlModelClass;
|
||||||
|
pipelineWithTag: PipelineClass;
|
||||||
|
searchIndexWithTag: SearchIndexClass;
|
||||||
|
tableWithTag: TableClass;
|
||||||
|
topicWithTag: TopicClass;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AssetTypes =
|
||||||
|
| ApiCollectionClass
|
||||||
|
| ContainerClass
|
||||||
|
| DashboardClass
|
||||||
|
| MlModelClass
|
||||||
|
| PipelineClass
|
||||||
|
| TableClass
|
||||||
|
| TopicClass;
|
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 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 { APIRequestContext, Page } from '@playwright/test';
|
||||||
|
import {
|
||||||
|
ORGANIZATION_POLICY_RULES,
|
||||||
|
VIEW_ALL_RULE,
|
||||||
|
} from '../constant/permission';
|
||||||
|
import { AdminClass } from '../support/user/AdminClass';
|
||||||
|
import { getApiContext } from './common';
|
||||||
|
|
||||||
|
export const restoreOrganizationDefaultRole = async (
|
||||||
|
apiContext: APIRequestContext
|
||||||
|
) => {
|
||||||
|
const organizationTeamResponse = await apiContext
|
||||||
|
.get(`/api/v1/teams/name/Organization`)
|
||||||
|
.then((res) => res.json());
|
||||||
|
|
||||||
|
const dataConsumerRoleResponse = await apiContext
|
||||||
|
.get('/api/v1/roles/name/DataConsumer')
|
||||||
|
.then((res) => res.json());
|
||||||
|
|
||||||
|
await apiContext.patch(`/api/v1/teams/${organizationTeamResponse.id}`, {
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
op: 'replace',
|
||||||
|
path: '/defaultRoles',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
id: dataConsumerRoleResponse.id,
|
||||||
|
type: 'role',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json-patch+json',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateDefaultOrganizationPolicy = async (
|
||||||
|
apiContext: APIRequestContext
|
||||||
|
) => {
|
||||||
|
const orgPolicyResponse = await apiContext
|
||||||
|
.get('/api/v1/policies/name/OrganizationPolicy')
|
||||||
|
.then((response) => response.json());
|
||||||
|
|
||||||
|
await apiContext.patch(`/api/v1/policies/${orgPolicyResponse.id}`, {
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
op: 'replace',
|
||||||
|
path: '/rules',
|
||||||
|
value: [...ORGANIZATION_POLICY_RULES, ...VIEW_ALL_RULE],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json-patch+json',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const restoreRolesAndPolicies = async (page: Page) => {
|
||||||
|
const { apiContext, afterAction } = await getApiContext(page);
|
||||||
|
// Remove organization policy and role
|
||||||
|
await restoreOrganizationDefaultRole(apiContext);
|
||||||
|
// update default Organization policy
|
||||||
|
await updateDefaultOrganizationPolicy(apiContext);
|
||||||
|
|
||||||
|
await afterAction();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const resetPolicyChanges = async (page: Page, admin: AdminClass) => {
|
||||||
|
await admin.login(page);
|
||||||
|
await page.waitForURL('**/my-data');
|
||||||
|
await restoreRolesAndPolicies(page);
|
||||||
|
await admin.logout(page);
|
||||||
|
await page.waitForURL('**/signin');
|
||||||
|
};
|
@ -0,0 +1,304 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 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 { APIRequestContext, expect, Page } from '@playwright/test';
|
||||||
|
import { conditionalPermissionsEntityData } from '../constant/conditionalPermissions';
|
||||||
|
import {
|
||||||
|
VIEW_ALL_WITH_IS_OWNER,
|
||||||
|
VIEW_ALL_WITH_MATCH_TAG_CONDITION,
|
||||||
|
} from '../constant/permission';
|
||||||
|
import { TableClass } from '../support/entity/TableClass';
|
||||||
|
import { AssetTypes } from '../support/interfaces/ConditionalPermissions.interface';
|
||||||
|
import { redirectToHomePage } from './common';
|
||||||
|
|
||||||
|
export const conditionalPermissionsPrerequisites = async (
|
||||||
|
apiContext: APIRequestContext
|
||||||
|
) => {
|
||||||
|
const {
|
||||||
|
isOwnerPolicy,
|
||||||
|
matchAnyTagPolicy,
|
||||||
|
isOwnerRole,
|
||||||
|
matchAnyTagRole,
|
||||||
|
userWithOwnerPermission,
|
||||||
|
userWithTagPermission,
|
||||||
|
withOwner,
|
||||||
|
withTag,
|
||||||
|
} = conditionalPermissionsEntityData;
|
||||||
|
await userWithOwnerPermission.create(apiContext);
|
||||||
|
await userWithTagPermission.create(apiContext);
|
||||||
|
await withOwner.apiCollectionWithOwner.create(apiContext);
|
||||||
|
await withTag.apiCollectionWithTag.create(apiContext);
|
||||||
|
await withOwner.containerWithOwner.create(apiContext);
|
||||||
|
await withTag.containerWithTag.create(apiContext);
|
||||||
|
await withOwner.dashboardWithOwner.create(apiContext);
|
||||||
|
await withTag.dashboardWithTag.create(apiContext);
|
||||||
|
await withOwner.mlModelWithOwner.create(apiContext);
|
||||||
|
await withTag.mlModelWithTag.create(apiContext);
|
||||||
|
await withOwner.pipelineWithOwner.create(apiContext);
|
||||||
|
await withTag.pipelineWithTag.create(apiContext);
|
||||||
|
await withOwner.searchIndexWithOwner.create(apiContext);
|
||||||
|
await withTag.searchIndexWithTag.create(apiContext);
|
||||||
|
await withOwner.tableWithOwner.create(apiContext);
|
||||||
|
await withTag.tableWithTag.create(apiContext);
|
||||||
|
await withOwner.topicWithOwner.create(apiContext);
|
||||||
|
await withTag.topicWithTag.create(apiContext);
|
||||||
|
|
||||||
|
const isOwnerPolicyResponse = await isOwnerPolicy.create(
|
||||||
|
apiContext,
|
||||||
|
VIEW_ALL_WITH_IS_OWNER
|
||||||
|
);
|
||||||
|
const matchAnyTagPolicyResponse = await matchAnyTagPolicy.create(
|
||||||
|
apiContext,
|
||||||
|
VIEW_ALL_WITH_MATCH_TAG_CONDITION
|
||||||
|
);
|
||||||
|
|
||||||
|
const isOwnerRoleResponse = await isOwnerRole.create(apiContext, [
|
||||||
|
isOwnerPolicyResponse.fullyQualifiedName,
|
||||||
|
]);
|
||||||
|
const matchAnyTagRoleResponse = await matchAnyTagRole.create(apiContext, [
|
||||||
|
matchAnyTagPolicyResponse.fullyQualifiedName,
|
||||||
|
]);
|
||||||
|
|
||||||
|
await userWithOwnerPermission.patch({
|
||||||
|
apiContext,
|
||||||
|
patchData: [
|
||||||
|
{
|
||||||
|
op: 'replace',
|
||||||
|
path: '/roles',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
id: isOwnerRoleResponse.id,
|
||||||
|
type: 'role',
|
||||||
|
name: isOwnerRoleResponse.name,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
await userWithTagPermission.patch({
|
||||||
|
apiContext,
|
||||||
|
patchData: [
|
||||||
|
{
|
||||||
|
op: 'replace',
|
||||||
|
path: '/roles',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
id: matchAnyTagRoleResponse.id,
|
||||||
|
type: 'role',
|
||||||
|
name: matchAnyTagRoleResponse.name,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const ownerPatchData = {
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
op: 'replace',
|
||||||
|
path: '/owners',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
id: userWithOwnerPermission.responseData.id,
|
||||||
|
type: 'user',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json-patch+json',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const tagPatchData = {
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
op: 'replace',
|
||||||
|
path: '/tags',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
tagFQN: 'PersonalData.Personal',
|
||||||
|
source: 'Classification',
|
||||||
|
labelType: 'Manual',
|
||||||
|
name: 'Personal',
|
||||||
|
state: 'Confirmed',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json-patch+json',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const entity of Object.values(withOwner)) {
|
||||||
|
await apiContext.patch(
|
||||||
|
`/api/v1/services/${entity.serviceType}/${entity.serviceResponseData.id}`,
|
||||||
|
ownerPatchData
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await apiContext.patch(
|
||||||
|
`/api/v1/databases/${withOwner.tableWithOwner.databaseResponseData.id}`,
|
||||||
|
ownerPatchData
|
||||||
|
);
|
||||||
|
|
||||||
|
await apiContext.patch(
|
||||||
|
`/api/v1/databaseSchemas/${withOwner.tableWithOwner.schemaResponseData.id}`,
|
||||||
|
ownerPatchData
|
||||||
|
);
|
||||||
|
|
||||||
|
await apiContext.patch(
|
||||||
|
`/api/v1/containers/${withOwner.containerWithOwner.entityResponseData.id}`,
|
||||||
|
ownerPatchData
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const entity of Object.values(withTag)) {
|
||||||
|
await apiContext.patch(
|
||||||
|
`/api/v1/services/${entity.serviceType}/${entity.serviceResponseData.id}`,
|
||||||
|
tagPatchData
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await apiContext.patch(
|
||||||
|
`/api/v1/databases/${withTag.tableWithTag.databaseResponseData.id}`,
|
||||||
|
tagPatchData
|
||||||
|
);
|
||||||
|
|
||||||
|
await apiContext.patch(
|
||||||
|
`/api/v1/databaseSchemas/${withTag.tableWithTag.schemaResponseData.id}`,
|
||||||
|
tagPatchData
|
||||||
|
);
|
||||||
|
|
||||||
|
await apiContext.patch(
|
||||||
|
`/api/v1/containers/${withTag.containerWithTag.entityResponseData.id}`,
|
||||||
|
tagPatchData
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const conditionalPermissionsCleanup = async (
|
||||||
|
apiContext: APIRequestContext
|
||||||
|
) => {
|
||||||
|
const {
|
||||||
|
isOwnerPolicy,
|
||||||
|
matchAnyTagPolicy,
|
||||||
|
isOwnerRole,
|
||||||
|
matchAnyTagRole,
|
||||||
|
userWithOwnerPermission,
|
||||||
|
userWithTagPermission,
|
||||||
|
withOwner: {
|
||||||
|
apiCollectionWithOwner,
|
||||||
|
containerWithOwner,
|
||||||
|
dashboardWithOwner,
|
||||||
|
mlModelWithOwner,
|
||||||
|
pipelineWithOwner,
|
||||||
|
searchIndexWithOwner,
|
||||||
|
tableWithOwner,
|
||||||
|
topicWithOwner,
|
||||||
|
},
|
||||||
|
withTag: {
|
||||||
|
apiCollectionWithTag,
|
||||||
|
containerWithTag,
|
||||||
|
dashboardWithTag,
|
||||||
|
mlModelWithTag,
|
||||||
|
pipelineWithTag,
|
||||||
|
searchIndexWithTag,
|
||||||
|
tableWithTag,
|
||||||
|
topicWithTag,
|
||||||
|
},
|
||||||
|
} = conditionalPermissionsEntityData;
|
||||||
|
await isOwnerRole.delete(apiContext);
|
||||||
|
await matchAnyTagRole.delete(apiContext);
|
||||||
|
await isOwnerPolicy.delete(apiContext);
|
||||||
|
await matchAnyTagPolicy.delete(apiContext);
|
||||||
|
await userWithOwnerPermission.delete(apiContext);
|
||||||
|
await userWithTagPermission.delete(apiContext);
|
||||||
|
await apiCollectionWithOwner.delete(apiContext);
|
||||||
|
await apiCollectionWithTag.delete(apiContext);
|
||||||
|
await containerWithOwner.delete(apiContext);
|
||||||
|
await containerWithTag.delete(apiContext);
|
||||||
|
await dashboardWithOwner.delete(apiContext);
|
||||||
|
await dashboardWithTag.delete(apiContext);
|
||||||
|
await mlModelWithOwner.delete(apiContext);
|
||||||
|
await mlModelWithTag.delete(apiContext);
|
||||||
|
await pipelineWithOwner.delete(apiContext);
|
||||||
|
await pipelineWithTag.delete(apiContext);
|
||||||
|
await searchIndexWithOwner.delete(apiContext);
|
||||||
|
await searchIndexWithTag.delete(apiContext);
|
||||||
|
await tableWithOwner.delete(apiContext);
|
||||||
|
await tableWithTag.delete(apiContext);
|
||||||
|
await topicWithOwner.delete(apiContext);
|
||||||
|
await topicWithTag.delete(apiContext);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getEntityFQN = (assetName: string, asset: AssetTypes) => {
|
||||||
|
if (assetName === 'database') {
|
||||||
|
return (asset as TableClass).databaseResponseData.fullyQualifiedName;
|
||||||
|
}
|
||||||
|
if (assetName === 'databaseSchema') {
|
||||||
|
return (asset as TableClass).schemaResponseData.fullyQualifiedName;
|
||||||
|
}
|
||||||
|
if (assetName === 'container') {
|
||||||
|
return asset.entityResponseData.fullyQualifiedName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return asset.serviceResponseData.fullyQualifiedName;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const checkViewAllPermission = async ({
|
||||||
|
page,
|
||||||
|
url1,
|
||||||
|
url2,
|
||||||
|
childTabId,
|
||||||
|
childTabId2,
|
||||||
|
childTableId2,
|
||||||
|
}: {
|
||||||
|
page: Page;
|
||||||
|
url1: string;
|
||||||
|
url2: string;
|
||||||
|
childTabId: string;
|
||||||
|
childTabId2?: string;
|
||||||
|
childTableId2?: string;
|
||||||
|
}) => {
|
||||||
|
await redirectToHomePage(page);
|
||||||
|
|
||||||
|
// visit the page of the asset with permission
|
||||||
|
await page.goto(url1);
|
||||||
|
|
||||||
|
// Check if the details are shown properly
|
||||||
|
await expect(page.getByTestId('data-assets-header')).toBeAttached();
|
||||||
|
|
||||||
|
await page.waitForSelector(`[data-testid="${childTabId}"]`);
|
||||||
|
|
||||||
|
await page.click(`[data-testid="${childTabId}"]`);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page
|
||||||
|
.getByTestId('service-children-table')
|
||||||
|
.getByTestId('no-data-placeholder')
|
||||||
|
).not.toBeAttached();
|
||||||
|
|
||||||
|
if (childTabId2) {
|
||||||
|
await page.click(`[data-testid="${childTabId2}"]`);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByTestId(childTableId2 ?? '').getByTestId('no-data-placeholder')
|
||||||
|
).not.toBeAttached();
|
||||||
|
}
|
||||||
|
|
||||||
|
// visit the page of the asset without permission
|
||||||
|
await page.goto(url2);
|
||||||
|
|
||||||
|
// Check if the no permissions placeholder is shown
|
||||||
|
await expect(page.getByTestId('permission-error-placeholder')).toBeAttached();
|
||||||
|
};
|
@ -355,6 +355,8 @@ const DatabaseDetails: FunctionComponent = () => {
|
|||||||
if (databasePermission.ViewAll || databasePermission.ViewBasic) {
|
if (databasePermission.ViewAll || databasePermission.ViewBasic) {
|
||||||
getDetailsByFQN();
|
getDetailsByFQN();
|
||||||
fetchDatabaseSchemaCount();
|
fetchDatabaseSchemaCount();
|
||||||
|
} else {
|
||||||
|
setIsDatabaseDetailsLoading(false);
|
||||||
}
|
}
|
||||||
}, [databasePermission, decodedDatabaseFQN]);
|
}, [databasePermission, decodedDatabaseFQN]);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user