mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-12-13 16:46:59 +00:00
fetch domains before any widget is loaded (#17695)
* fix domain init ordering * move domains call at the beginning * fix tests * fix tests * fix flaky tests * fix flaky tests (cherry picked from commit 1dc15bc49376d2c117dcc297c05f120f1f595bad)
This commit is contained in:
parent
32a85c0c96
commit
d46540ea0f
@ -1,442 +0,0 @@
|
||||
/*
|
||||
* 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 {
|
||||
addTableFieldTags,
|
||||
deleteEntity,
|
||||
interceptURL,
|
||||
removeTableFieldTags,
|
||||
updateTableFieldDescription,
|
||||
verifyResponseStatusCode,
|
||||
} from '../../common/common';
|
||||
import {
|
||||
createSingleLevelEntity,
|
||||
hardDeleteService,
|
||||
} from '../../common/EntityUtils';
|
||||
import { visitEntityDetailsPage } from '../../common/Utils/Entity';
|
||||
import { getToken } from '../../common/Utils/LocalStorage';
|
||||
import { BASE_URL } from '../../constants/constants';
|
||||
import { EntityType } from '../../constants/Entity.interface';
|
||||
import {
|
||||
POLICY_DETAILS,
|
||||
ROLE_DETAILS,
|
||||
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST,
|
||||
SEARCH_INDEX_DISPLAY_NAME,
|
||||
SEARCH_SERVICE_DETAILS,
|
||||
TAG_1,
|
||||
UPDATE_FIELD_DESCRIPTION,
|
||||
USER_CREDENTIALS,
|
||||
} from '../../constants/SearchIndexDetails.constants';
|
||||
|
||||
const performCommonOperations = () => {
|
||||
// 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 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');
|
||||
};
|
||||
|
||||
describe(
|
||||
'SearchIndexDetails page should work properly for data consumer role',
|
||||
{ tags: 'DataAssets' },
|
||||
() => {
|
||||
const data = { user: { id: '' } };
|
||||
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.getAllLocalStorage().then((storageData) => {
|
||||
const token = getToken(storageData);
|
||||
|
||||
// Create search index entity
|
||||
createSingleLevelEntity({
|
||||
token,
|
||||
...SEARCH_SERVICE_DETAILS,
|
||||
});
|
||||
|
||||
// Create a new user
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `/api/v1/users/signup`,
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
body: USER_CREDENTIALS,
|
||||
}).then((response) => {
|
||||
data.user = response.body;
|
||||
});
|
||||
|
||||
cy.logout();
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.login();
|
||||
|
||||
cy.getAllLocalStorage().then((storageData) => {
|
||||
const token = getToken(storageData);
|
||||
|
||||
// Delete search index
|
||||
hardDeleteService({
|
||||
token,
|
||||
serviceFqn: SEARCH_SERVICE_DETAILS.service.name,
|
||||
serviceType: SEARCH_SERVICE_DETAILS.serviceType,
|
||||
});
|
||||
|
||||
// Delete created user
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
url: `/api/v1/users/${data.user.id}?hardDelete=true&recursive=false`,
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// Login with the created user
|
||||
cy.login(USER_CREDENTIALS.email, USER_CREDENTIALS.password);
|
||||
|
||||
cy.url().should('eq', `${BASE_URL}/my-data`);
|
||||
});
|
||||
|
||||
it('All permissible actions on search index details page should work properly', () => {
|
||||
visitEntityDetailsPage({
|
||||
term: SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.name,
|
||||
serviceName: SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.service,
|
||||
entity: EntityType.SearchIndex,
|
||||
});
|
||||
|
||||
// Edit domain option should not be available
|
||||
cy.get(
|
||||
`[data-testid="entity-page-header"] [data-testid="add-domain"]`
|
||||
).should('not.exist');
|
||||
|
||||
// Manage button should not be visible on service page
|
||||
cy.get(
|
||||
'[data-testid="asset-header-btn-group"] [data-testid="manage-button"]'
|
||||
).should('not.exist');
|
||||
|
||||
performCommonOperations();
|
||||
|
||||
cy.logout();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
describe('SearchIndexDetails page should work properly for data steward role', () => {
|
||||
const data = {
|
||||
user: { id: '' },
|
||||
policy: { id: '' },
|
||||
role: { id: '', name: '' },
|
||||
};
|
||||
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.getAllLocalStorage().then((storageData) => {
|
||||
const token = getToken(storageData);
|
||||
|
||||
// Create search index entity
|
||||
createSingleLevelEntity({
|
||||
token,
|
||||
...SEARCH_SERVICE_DETAILS,
|
||||
});
|
||||
|
||||
// Create Data Steward Policy
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `/api/v1/policies`,
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
body: POLICY_DETAILS,
|
||||
}).then((policyResponse) => {
|
||||
data.policy = policyResponse.body;
|
||||
|
||||
// Create Data Steward Role
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `/api/v1/roles`,
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
body: ROLE_DETAILS,
|
||||
}).then((roleResponse) => {
|
||||
data.role = roleResponse.body;
|
||||
|
||||
// Create a new user
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `/api/v1/users/signup`,
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
body: USER_CREDENTIALS,
|
||||
}).then((userResponse) => {
|
||||
data.user = userResponse.body;
|
||||
|
||||
// Assign data steward role to the user
|
||||
cy.request({
|
||||
method: 'PATCH',
|
||||
url: `/api/v1/users/${data.user.id}`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json-patch+json',
|
||||
},
|
||||
body: [
|
||||
{
|
||||
op: 'add',
|
||||
path: '/roles/0',
|
||||
value: {
|
||||
id: data.role.id,
|
||||
type: 'role',
|
||||
name: data.role.name,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
cy.logout();
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.login();
|
||||
|
||||
cy.getAllLocalStorage().then((storageData) => {
|
||||
const token = getToken(storageData);
|
||||
|
||||
// Delete created user
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
url: `/api/v1/users/${data.user.id}?hardDelete=true&recursive=false`,
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
|
||||
// Delete policy
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
url: `/api/v1/policies/${data.policy.id}?hardDelete=true&recursive=false`,
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
|
||||
// Delete role
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
url: `/api/v1/roles/${data.role.id}?hardDelete=true&recursive=false`,
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
|
||||
// Delete search index
|
||||
hardDeleteService({
|
||||
token,
|
||||
serviceFqn: SEARCH_SERVICE_DETAILS.service.name,
|
||||
serviceType: SEARCH_SERVICE_DETAILS.serviceType,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// Login with the created user
|
||||
cy.login(USER_CREDENTIALS.email, USER_CREDENTIALS.password);
|
||||
|
||||
cy.url().should('eq', `${BASE_URL}/my-data`);
|
||||
});
|
||||
|
||||
it('All permissible actions on search index details page should work properly', () => {
|
||||
visitEntityDetailsPage({
|
||||
term: SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.name,
|
||||
serviceName: SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.service,
|
||||
entity: EntityType.SearchIndex,
|
||||
});
|
||||
|
||||
// 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/*`, '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', () => {
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.getAllLocalStorage().then((storageData) => {
|
||||
const token = getToken(storageData);
|
||||
|
||||
// Create search index entity
|
||||
createSingleLevelEntity({
|
||||
token,
|
||||
...SEARCH_SERVICE_DETAILS,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
cy.login();
|
||||
|
||||
cy.getAllLocalStorage().then((storageData) => {
|
||||
const token = getToken(storageData);
|
||||
|
||||
// Delete search index
|
||||
hardDeleteService({
|
||||
token,
|
||||
serviceFqn: SEARCH_SERVICE_DETAILS.service.name,
|
||||
serviceType: SEARCH_SERVICE_DETAILS.serviceType,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
});
|
||||
|
||||
it('All permissible actions on search index details page should work properly', () => {
|
||||
visitEntityDetailsPage({
|
||||
term: SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.name,
|
||||
serviceName: SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.service,
|
||||
entity: EntityType.SearchIndex,
|
||||
});
|
||||
performCommonOperations();
|
||||
});
|
||||
|
||||
it('Soft delete workflow should work properly', () => {
|
||||
visitEntityDetailsPage({
|
||||
term: SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.name,
|
||||
serviceName: SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.service,
|
||||
entity: EntityType.SearchIndex,
|
||||
});
|
||||
deleteEntity(
|
||||
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.name,
|
||||
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.service,
|
||||
EntityType.SearchIndex,
|
||||
'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="add-domain"]').should('not.exist');
|
||||
cy.get('[data-testid="edit-owner"]').should('not.exist');
|
||||
cy.get('[data-testid="edit-tier"]').should('not.exist');
|
||||
|
||||
// Edit description button should not be visible
|
||||
cy.get('[data-testid="edit-description"]').should('not.exist');
|
||||
|
||||
// Edit tags button should not be visible
|
||||
cy.get(
|
||||
`[data-testid="entity-right-panel"] [data-testid="tags-container"] [data-testid="add-tag"]`
|
||||
).should('not.exist');
|
||||
|
||||
// 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', () => {
|
||||
visitEntityDetailsPage({
|
||||
term: SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.name,
|
||||
serviceName: SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.service,
|
||||
entity: EntityType.SearchIndex,
|
||||
});
|
||||
deleteEntity(
|
||||
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.name,
|
||||
SEARCH_INDEX_DETAILS_FOR_DETAILS_PAGE_TEST.service,
|
||||
EntityType.SearchIndex,
|
||||
'Search Index'
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -181,12 +181,13 @@ test.describe('Domains', () => {
|
||||
await afterAction();
|
||||
});
|
||||
|
||||
test('Switch domain from navbar and check domain query call warp in quotes', async ({
|
||||
test('Switch domain from navbar and check domain query call wrap in quotes', async ({
|
||||
page,
|
||||
}) => {
|
||||
const { afterAction, apiContext } = await getApiContext(page);
|
||||
const domain = new Domain();
|
||||
await domain.create(apiContext);
|
||||
await page.reload();
|
||||
await page.getByTestId('domain-dropdown').click();
|
||||
await page
|
||||
.locator(
|
||||
@ -217,8 +218,8 @@ test.describe('Domains', () => {
|
||||
const { assets, assetCleanup } = await setupAssetsForDomain(page);
|
||||
const domain = new Domain();
|
||||
await domain.create(apiContext);
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
await page.reload();
|
||||
await sidebarClick(page, SidebarItem.DOMAIN);
|
||||
await addAssetsToDomain(page, domain.data, assets);
|
||||
await page.getByTestId('documentation').click();
|
||||
const updatedDomainName = 'PW Domain Updated';
|
||||
@ -275,10 +276,12 @@ test.describe('Domains Rbac', () => {
|
||||
|
||||
test.beforeAll('Setup pre-requests', async ({ browser }) => {
|
||||
const { apiContext, afterAction, page } = await performAdminLogin(browser);
|
||||
await domain1.create(apiContext);
|
||||
await domain2.create(apiContext);
|
||||
await domain3.create(apiContext);
|
||||
await user1.create(apiContext);
|
||||
await Promise.all([
|
||||
domain1.create(apiContext),
|
||||
domain2.create(apiContext),
|
||||
domain3.create(apiContext),
|
||||
user1.create(apiContext),
|
||||
]);
|
||||
|
||||
const domainPayload: Operation[] = [
|
||||
{
|
||||
@ -322,6 +325,8 @@ test.describe('Domains Rbac', () => {
|
||||
});
|
||||
|
||||
test('Domain Rbac', async ({ browser }) => {
|
||||
test.slow(true);
|
||||
|
||||
const { page, afterAction, apiContext } = await performAdminLogin(browser);
|
||||
const { page: userPage, afterAction: afterActionUser1 } =
|
||||
await performUserLogin(browser, user1);
|
||||
@ -363,6 +368,19 @@ test.describe('Domains Rbac', () => {
|
||||
.locator('span')
|
||||
).toBeVisible();
|
||||
|
||||
// Visit explore page and verify if domain is passed in the query
|
||||
const queryRes = userPage.waitForResponse(
|
||||
'/api/v1/search/query?*index=dataAsset*'
|
||||
);
|
||||
await sidebarClick(userPage, SidebarItem.EXPLORE);
|
||||
await queryRes.then(async (res) => {
|
||||
const queryString = new URL(res.request().url()).search;
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
const qParam = urlParams.get('q');
|
||||
|
||||
await expect(qParam).toContain(`domain.fullyQualifiedName:`);
|
||||
});
|
||||
|
||||
for (const asset of domainAssset2) {
|
||||
const fqn = encodeURIComponent(
|
||||
get(asset, 'entityResponseData.fullyQualifiedName', '')
|
||||
@ -384,10 +402,13 @@ test.describe('Domains Rbac', () => {
|
||||
await afterActionUser1();
|
||||
});
|
||||
|
||||
await domain1.delete(apiContext);
|
||||
await domain2.delete(apiContext);
|
||||
await domain3.delete(apiContext);
|
||||
await user1.delete(apiContext);
|
||||
await Promise.all([
|
||||
domain1.delete(apiContext),
|
||||
domain2.delete(apiContext),
|
||||
domain3.delete(apiContext),
|
||||
user1.delete(apiContext),
|
||||
]);
|
||||
|
||||
await assetCleanup1();
|
||||
await assetCleanup2();
|
||||
await afterAction();
|
||||
|
||||
@ -179,6 +179,10 @@ entities.forEach((EntityClass) => {
|
||||
await entity.followUnfollowEntity(page, entityName);
|
||||
});
|
||||
|
||||
test(`Update displayName`, async ({ page }) => {
|
||||
await entity.renameEntity(page, entity.entity.name);
|
||||
});
|
||||
|
||||
test.afterAll('Cleanup', async ({ browser }) => {
|
||||
const { apiContext, afterAction } = await performAdminLogin(browser);
|
||||
await user.delete(apiContext);
|
||||
|
||||
@ -182,7 +182,7 @@ export const fillRule = async (
|
||||
}
|
||||
|
||||
await page
|
||||
.locator(`.ant-select-dropdown [title="${searchData}"]`)
|
||||
.locator(`.ant-select-dropdown:visible [title="${searchData}"]`)
|
||||
.click();
|
||||
}
|
||||
|
||||
|
||||
@ -299,7 +299,10 @@ export const addAssetsToDomain = async (
|
||||
const searchRes = page.waitForResponse(
|
||||
`/api/v1/search/query?q=${name}&index=all&from=0&size=25&*`
|
||||
);
|
||||
await page.getByTestId('searchbar').fill(name);
|
||||
await page
|
||||
.getByTestId('asset-selection-modal')
|
||||
.getByTestId('searchbar')
|
||||
.fill(name);
|
||||
await searchRes;
|
||||
|
||||
await page.locator(`[data-testid="table-data-card_${fqn}"] input`).check();
|
||||
@ -380,14 +383,18 @@ export const setupAssetsForDomain = async (page: Page) => {
|
||||
const table = new TableClass();
|
||||
const topic = new TopicClass();
|
||||
const dashboard = new DashboardClass();
|
||||
await table.create(apiContext);
|
||||
await topic.create(apiContext);
|
||||
await dashboard.create(apiContext);
|
||||
await Promise.all([
|
||||
table.create(apiContext),
|
||||
topic.create(apiContext),
|
||||
dashboard.create(apiContext),
|
||||
]);
|
||||
|
||||
const assetCleanup = async () => {
|
||||
await table.create(apiContext);
|
||||
await topic.create(apiContext);
|
||||
await dashboard.create(apiContext);
|
||||
await Promise.all([
|
||||
table.delete(apiContext),
|
||||
topic.delete(apiContext),
|
||||
dashboard.delete(apiContext),
|
||||
]);
|
||||
await afterAction();
|
||||
};
|
||||
|
||||
|
||||
@ -13,7 +13,6 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { getDomainList } from '../../rest/domainAPI';
|
||||
import { getLimitConfig } from '../../rest/limitsAPI';
|
||||
import applicationsClassBase from '../Settings/Applications/AppDetails/ApplicationsClassBase';
|
||||
import AppContainer from './AppContainer';
|
||||
@ -85,14 +84,4 @@ describe('AppContainer', () => {
|
||||
|
||||
expect(getLimitConfig).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call domain list to cache domains', () => {
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<AppContainer />
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
expect(getDomainList).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@ -15,11 +15,8 @@ import { Layout } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import React, { useCallback, useEffect, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ES_MAX_PAGE_SIZE } from '../../constants/constants';
|
||||
import { useLimitStore } from '../../context/LimitsProvider/useLimitsStore';
|
||||
import { useApplicationStore } from '../../hooks/useApplicationStore';
|
||||
import { useDomainStore } from '../../hooks/useDomainStore';
|
||||
import { getDomainList } from '../../rest/domainAPI';
|
||||
import { getLimitConfig } from '../../rest/limitsAPI';
|
||||
import applicationRoutesClass from '../../utils/ApplicationRoutesClassBase';
|
||||
import Appbar from '../AppBar/Appbar';
|
||||
@ -32,27 +29,11 @@ const AppContainer = () => {
|
||||
const { i18n } = useTranslation();
|
||||
const { Header, Sider, Content } = Layout;
|
||||
const { currentUser } = useApplicationStore();
|
||||
const { updateDomains, updateDomainLoading } = useDomainStore();
|
||||
const AuthenticatedRouter = applicationRoutesClass.getRouteElements();
|
||||
const ApplicationExtras = applicationsClassBase.getApplicationExtension();
|
||||
const isDirectionRTL = useMemo(() => i18n.dir() === 'rtl', [i18n]);
|
||||
const { setConfig, bannerDetails } = useLimitStore();
|
||||
|
||||
const fetchDomainList = useCallback(async () => {
|
||||
try {
|
||||
updateDomainLoading(true);
|
||||
const { data } = await getDomainList({
|
||||
limit: ES_MAX_PAGE_SIZE,
|
||||
fields: 'parent',
|
||||
});
|
||||
updateDomains(data);
|
||||
} catch (error) {
|
||||
// silent fail
|
||||
} finally {
|
||||
updateDomainLoading(false);
|
||||
}
|
||||
}, [currentUser]);
|
||||
|
||||
const fetchLimitConfig = useCallback(async () => {
|
||||
try {
|
||||
const response = await getLimitConfig();
|
||||
@ -65,7 +46,6 @@ const AppContainer = () => {
|
||||
|
||||
useEffect(() => {
|
||||
if (currentUser?.id) {
|
||||
fetchDomainList();
|
||||
fetchLimitConfig();
|
||||
}
|
||||
}, [currentUser?.id]);
|
||||
|
||||
@ -41,6 +41,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import { useHistory, useLocation } from 'react-router-dom';
|
||||
import {
|
||||
DEFAULT_DOMAIN_VALUE,
|
||||
ES_MAX_PAGE_SIZE,
|
||||
REDIRECT_PATHNAME,
|
||||
ROUTES,
|
||||
} from '../../../constants/constants';
|
||||
@ -56,6 +57,7 @@ import { AuthProvider as AuthProviderEnum } from '../../../generated/settings/se
|
||||
import { useApplicationStore } from '../../../hooks/useApplicationStore';
|
||||
import { useDomainStore } from '../../../hooks/useDomainStore';
|
||||
import axiosClient from '../../../rest';
|
||||
import { getDomainList } from '../../../rest/domainAPI';
|
||||
import {
|
||||
fetchAuthenticationConfig,
|
||||
fetchAuthorizerConfig,
|
||||
@ -135,7 +137,7 @@ export const AuthProvider = ({
|
||||
isApplicationLoading,
|
||||
setApplicationLoading,
|
||||
} = useApplicationStore();
|
||||
const { activeDomain } = useDomainStore();
|
||||
const { updateDomains, updateDomainLoading } = useDomainStore();
|
||||
|
||||
const location = useLocation();
|
||||
const history = useHistory();
|
||||
@ -183,6 +185,21 @@ export const AuthProvider = ({
|
||||
return authenticatorRef.current?.renewIdToken();
|
||||
};
|
||||
|
||||
const fetchDomainList = useCallback(async () => {
|
||||
try {
|
||||
updateDomainLoading(true);
|
||||
const { data } = await getDomainList({
|
||||
limit: ES_MAX_PAGE_SIZE,
|
||||
fields: 'parent',
|
||||
});
|
||||
updateDomains(data);
|
||||
} catch (error) {
|
||||
// silent fail
|
||||
} finally {
|
||||
updateDomainLoading(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handledVerifiedUser = () => {
|
||||
if (!isProtectedRoute(location.pathname)) {
|
||||
history.push(ROUTES.HOME);
|
||||
@ -223,6 +240,8 @@ export const AuthProvider = ({
|
||||
if (res) {
|
||||
setCurrentUser(res);
|
||||
setIsAuthenticated(true);
|
||||
// Fetch domains at the start
|
||||
await fetchDomainList();
|
||||
} else {
|
||||
resetUserDetails();
|
||||
}
|
||||
@ -397,6 +416,9 @@ export const AuthProvider = ({
|
||||
setCurrentUser(res);
|
||||
}
|
||||
|
||||
// Fetch domains at the start
|
||||
await fetchDomainList();
|
||||
|
||||
handledVerifiedUser();
|
||||
// Start expiry timer on successful login
|
||||
startTokenExpiryTimer();
|
||||
@ -470,6 +492,7 @@ export const AuthProvider = ({
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const withDomainFilter = (config: InternalAxiosRequestConfig<any>) => {
|
||||
const isGetRequest = config.method === 'get';
|
||||
const activeDomain = useDomainStore.getState().activeDomain;
|
||||
const hasActiveDomain = activeDomain !== DEFAULT_DOMAIN_VALUE;
|
||||
const currentPath = window.location.pathname;
|
||||
const shouldNotIntercept = [
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user