diff --git a/public/apps/access-error-component.tsx b/public/apps/configuration/access-error-component.tsx similarity index 100% rename from public/apps/access-error-component.tsx rename to public/apps/configuration/access-error-component.tsx diff --git a/public/apps/configuration/panels/audit-logging/audit-logging.tsx b/public/apps/configuration/panels/audit-logging/audit-logging.tsx index fd04dd78e..eb32183d2 100644 --- a/public/apps/configuration/panels/audit-logging/audit-logging.tsx +++ b/public/apps/configuration/panels/audit-logging/audit-logging.tsx @@ -22,6 +22,8 @@ import { EuiForm, EuiFormRow, EuiHorizontalRule, + EuiLoadingContent, + EuiPageHeader, EuiPanel, EuiSpacer, EuiSwitch, @@ -46,7 +48,7 @@ import { ViewSettingGroup } from './view-setting-group'; import { DocLinks } from '../../constants'; import { DataSourceContext } from '../../app-router'; import { SecurityPluginTopNavMenu } from '../../top-nav-menu'; -import { AccessErrorComponent } from '../../../access-error-component'; +import { AccessErrorComponent } from '../../access-error-component'; interface AuditLoggingProps extends AppDependencies { fromType: string; @@ -55,10 +57,6 @@ interface AuditLoggingProps extends AppDependencies { function renderStatusPanel(onSwitchChange: () => void, auditLoggingEnabled: boolean) { return ( - -

Audit logging

-
- Storage location} className="described-form-group"> @@ -97,13 +95,11 @@ function renderStatusPanel(onSwitchChange: () => void, auditLoggingEnabled: bool function renderAccessErrorPanel(loading: boolean, dataSource: DataSourceOption) { return ( - - -

Audit logging

-
- - -
+ ); } @@ -201,7 +197,6 @@ export function AuditLogging(props: AuditLoggingProps) { <> {statusPanel} - @@ -262,7 +257,13 @@ export function AuditLogging(props: AuditLoggingProps) { setDataSource={setDataSource} selectedDataSource={dataSource} /> - {content} + + +

Audit Logging

+
+
+ + {loading ? : content} ); } diff --git a/public/apps/configuration/panels/audit-logging/test/__snapshots__/audit-logging.test.tsx.snap b/public/apps/configuration/panels/audit-logging/test/__snapshots__/audit-logging.test.tsx.snap index 9fdee791a..e44012a64 100644 --- a/public/apps/configuration/panels/audit-logging/test/__snapshots__/audit-logging.test.tsx.snap +++ b/public/apps/configuration/panels/audit-logging/test/__snapshots__/audit-logging.test.tsx.snap @@ -256,15 +256,17 @@ exports[`Audit logs render when AuditLoggingSettings.enabled is true 1`] = ` } setDataSource={[MockFunction]} /> - - -

- Audit logging -

+ + +

+ Audit Logging +

- +
+ + `; + +exports[`Audit logs should load access error component 1`] = ` +
+ + + +

+ Audit Logging +

+
+
+ + +
+`; diff --git a/public/apps/configuration/panels/audit-logging/test/audit-logging.test.tsx b/public/apps/configuration/panels/audit-logging/test/audit-logging.test.tsx index 0a560bbd3..dfe2ab3f4 100644 --- a/public/apps/configuration/panels/audit-logging/test/audit-logging.test.tsx +++ b/public/apps/configuration/panels/audit-logging/test/audit-logging.test.tsx @@ -187,4 +187,17 @@ describe('Audit logs', () => { buildHashUrl(ResourceType.auditLogging) + SUB_URL_FOR_COMPLIANCE_SETTINGS_EDIT ); }); + + it('should load access error component', () => { + const auditLoggingSettings = { enabled: true }; + jest + .spyOn(React, 'useState') + .mockImplementationOnce(() => [auditLoggingSettings, setState]) + .mockImplementationOnce(() => [false, jest.fn()]) + .mockImplementationOnce(() => [true, jest.fn()]); + const component = shallow( + + ); + expect(component).toMatchSnapshot(); + }); }); diff --git a/public/apps/configuration/panels/auth-view/auth-view.tsx b/public/apps/configuration/panels/auth-view/auth-view.tsx index ba1e9aa72..a34a0d67a 100644 --- a/public/apps/configuration/panels/auth-view/auth-view.tsx +++ b/public/apps/configuration/panels/auth-view/auth-view.tsx @@ -13,8 +13,8 @@ * permissions and limitations under the License. */ -import React, { useContext, useState } from 'react'; -import { EuiPageHeader, EuiSpacer, EuiTitle } from '@elastic/eui'; +import React, { useContext } from 'react'; +import { EuiLoadingContent, EuiPageHeader, EuiSpacer, EuiTitle } from '@elastic/eui'; import { isEmpty } from 'lodash'; import { AuthenticationSequencePanel } from './authentication-sequence-panel'; import { AuthorizationPanel } from './authorization-panel'; @@ -25,12 +25,12 @@ import { getSecurityConfig } from '../../utils/auth-view-utils'; import { InstructionView } from './instruction-view'; import { DataSourceContext } from '../../app-router'; import { SecurityPluginTopNavMenu } from '../../top-nav-menu'; -import { AccessErrorComponent } from '../../../access-error-component'; +import { AccessErrorComponent } from '../../access-error-component'; export function AuthView(props: AppDependencies) { const [authentication, setAuthentication] = React.useState([]); const [authorization, setAuthorization] = React.useState([]); - const [loading, setLoading] = useState(false); + const [loading, setLoading] = React.useState(false); const { dataSource, setDataSource } = useContext(DataSourceContext)!; const [errorFlag, setErrorFlag] = React.useState(false); const [accessErrorFlag, setAccessErrorFlag] = React.useState(false); @@ -59,7 +59,7 @@ export function AuthView(props: AppDependencies) { fetchData(); }, [props.coreStart.http, dataSource]); - if (isEmpty(authentication)) { + if (isEmpty(authentication) && !loading) { return ( <>

Authentication and authorization

- {!errorFlag && props.config.ui.backend_configurable && ( + {!loading && !errorFlag && props.config.ui.backend_configurable && ( )} - {accessErrorFlag ? ( + {loading ? ( + + ) : accessErrorFlag ? ( ) : ( <> diff --git a/public/apps/configuration/panels/auth-view/test/__snapshots__/auth-view.test.tsx.snap b/public/apps/configuration/panels/auth-view/test/__snapshots__/auth-view.test.tsx.snap new file mode 100644 index 000000000..aff22a5fb --- /dev/null +++ b/public/apps/configuration/panels/auth-view/test/__snapshots__/auth-view.test.tsx.snap @@ -0,0 +1,31 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Auth view should load access error component 1`] = ` + + + +

+ Authentication and authorization +

+
+ +
+`; diff --git a/public/apps/configuration/panels/auth-view/test/auth-view.test.tsx b/public/apps/configuration/panels/auth-view/test/auth-view.test.tsx index b26640131..5643f86fa 100644 --- a/public/apps/configuration/panels/auth-view/test/auth-view.test.tsx +++ b/public/apps/configuration/panels/auth-view/test/auth-view.test.tsx @@ -29,38 +29,37 @@ describe('Auth view', () => { const mockCoreStart = { http: 1, }; + const config = { + authc: { + basic_internal_auth_domain: { + authentication_backend: { + type: 'intern', + config: {}, + }, + }, + }, + authz: { + ldap: { + http_enabled: true, + }, + }, + }; const setState = jest.fn(); beforeEach(() => { - // jest.spyOn(React, 'useState').mockImplementation((initialValue) => [initialValue, setState]); jest.spyOn(React, 'useState').mockRestore(); jest .spyOn(React, 'useState') .mockImplementationOnce(() => [[], setState]) .mockImplementationOnce(() => [[], setState]) .mockImplementationOnce(() => [false, jest.fn()]) + .mockImplementationOnce(() => [false, jest.fn()]) .mockImplementationOnce(() => [false, jest.fn()]); jest.spyOn(React, 'useEffect').mockImplementationOnce((f) => f()); }); it('valid data', (done) => { - const config = { - authc: { - basic_internal_auth_domain: { - authentication_backend: { - type: 'intern', - config: {}, - }, - }, - }, - authz: { - ldap: { - http_enabled: true, - }, - }, - }; - mockAuthViewUtils.getSecurityConfig = jest.fn().mockReturnValue(config); shallow(); @@ -92,4 +91,20 @@ describe('Auth view', () => { done(); }); }); + + it('should load access error component', async () => { + jest.spyOn(React, 'useState').mockRestore(); + jest + .spyOn(React, 'useState') + .mockImplementationOnce(() => [[], setState]) + .mockImplementationOnce(() => [[], setState]) + .mockImplementationOnce(() => [false, jest.fn()]) + .mockImplementationOnce(() => [false, jest.fn()]) + .mockImplementationOnce(() => [true, jest.fn()]); + mockAuthViewUtils.getSecurityConfig = jest + .fn() + .mockRejectedValue({ response: { status: 403 } }); + const component = shallow(); + expect(component).toMatchSnapshot(); + }); }); diff --git a/public/apps/configuration/panels/permission-list/permission-list.tsx b/public/apps/configuration/panels/permission-list/permission-list.tsx index e753b1379..9925ab69d 100644 --- a/public/apps/configuration/panels/permission-list/permission-list.tsx +++ b/public/apps/configuration/panels/permission-list/permission-list.tsx @@ -32,6 +32,7 @@ import { RIGHT_ALIGNMENT, EuiButtonEmpty, Query, + EuiLoadingContent, } from '@elastic/eui'; import { difference } from 'lodash'; import React, { @@ -63,7 +64,7 @@ import { generateResourceName } from '../../utils/resource-utils'; import { DocLinks } from '../../constants'; import { SecurityPluginTopNavMenu } from '../../top-nav-menu'; import { DataSourceContext } from '../../app-router'; -import { AccessErrorComponent } from '../../../access-error-component'; +import { AccessErrorComponent } from '../../access-error-component'; export function renderBooleanToCheckMark(value: boolean): React.ReactNode { return value ? : ''; @@ -367,7 +368,9 @@ export function PermissionList(props: AppDependencies) {

Permissions

- {accessErrorFlag ? ( + {loading ? ( + + ) : accessErrorFlag ? ( ) : ( diff --git a/public/apps/configuration/panels/role-list.tsx b/public/apps/configuration/panels/role-list.tsx index f0a8b0f19..00f5fd6e8 100644 --- a/public/apps/configuration/panels/role-list.tsx +++ b/public/apps/configuration/panels/role-list.tsx @@ -30,6 +30,7 @@ import { EuiButtonEmpty, EuiSearchBarProps, Query, + EuiLoadingContent, } from '@elastic/eui'; import { difference } from 'lodash'; import { AppDependencies } from '../../types'; @@ -56,7 +57,7 @@ import { useContextMenuState } from '../utils/context-menu'; import { DocLinks } from '../constants'; import { DataSourceContext } from '../app-router'; import { SecurityPluginTopNavMenu } from '../top-nav-menu'; -import { AccessErrorComponent } from '../../access-error-component'; +import { AccessErrorComponent } from '../access-error-component'; const columns: Array> = [ { @@ -271,7 +272,9 @@ export function RoleList(props: AppDependencies) {

Roles

- {accessErrorFlag ? ( + {loading ? ( + + ) : accessErrorFlag ? ( ) : ( diff --git a/public/apps/configuration/panels/service-account-list.tsx b/public/apps/configuration/panels/service-account-list.tsx index dc66b7a43..ee5745635 100644 --- a/public/apps/configuration/panels/service-account-list.tsx +++ b/public/apps/configuration/panels/service-account-list.tsx @@ -20,6 +20,7 @@ import { EuiFlexItem, EuiInMemoryTable, EuiLink, + EuiLoadingContent, EuiPageBody, EuiPageContent, EuiPageContentHeader, @@ -44,7 +45,7 @@ import { showTableStatusMessage } from '../utils/loading-spinner-utils'; import { buildHashUrl } from '../utils/url-builder'; import { LocalCluster } from '../app-router'; import { SecurityPluginTopNavMenu } from '../top-nav-menu'; -import { AccessErrorComponent } from '../../access-error-component'; +import { AccessErrorComponent } from '../access-error-component'; export function dictView(items: Dictionary) { if (isEmpty(items)) { @@ -183,7 +184,9 @@ export function ServiceAccountList(props: AppDependencies) {

Service accounts

- {accessErrorFlag ? ( + {loading ? ( + + ) : accessErrorFlag ? ( ) : ( diff --git a/public/apps/configuration/panels/tenant-list/configure_tab1.tsx b/public/apps/configuration/panels/tenant-list/configure_tab1.tsx index f7bf23b1a..2eeef783b 100644 --- a/public/apps/configuration/panels/tenant-list/configure_tab1.tsx +++ b/public/apps/configuration/panels/tenant-list/configure_tab1.tsx @@ -32,6 +32,7 @@ import { EuiBottomBar, EuiComboBox, EuiIcon, + EuiLoadingContent, } from '@elastic/eui'; import React, { ReactNode, useState } from 'react'; import { SaveChangesModalGenerator } from './save_changes_modal'; @@ -50,7 +51,7 @@ import { } from '../../utils/toast-utils'; import { getDashboardsInfo } from '../../../../utils/dashboards-info-utils'; import { LOCAL_CLUSTER_ID } from '../../../../../common'; -import { AccessErrorComponent } from '../../../access-error-component'; +import { AccessErrorComponent } from '../../access-error-component'; import { LocalCluster } from '../../app-router'; export function ConfigureTab1(props: AppDependencies) { @@ -79,6 +80,7 @@ export function ConfigureTab1(props: AppDependencies) { const [toasts, addToast, removeToast] = useToastState(); const [selectedComboBoxOptions, setSelectedComboBoxOptions] = useState(); const [accessErrorFlag, setAccessErrorFlag] = React.useState(false); + const [loading, setLoading] = React.useState(false); const discardChangesFunction = async () => { await setUpdatedConfiguration(originalConfiguration); @@ -179,20 +181,23 @@ export function ConfigureTab1(props: AppDependencies) { React.useEffect(() => { const fetchData = async () => { try { + setLoading(true); + const dashboardsInfo = await getDashboardsInfo(props.coreStart.http); + const { + multitenancy_enabled: multitenancyEnabled = false, + private_tenant_enabled: privateTenantEnabled = false, + default_tenant: defaultTenant = '', + } = dashboardsInfo; await setOriginalConfiguration({ - multitenancy_enabled: (await getDashboardsInfo(props.coreStart.http)) - .multitenancy_enabled, - private_tenant_enabled: (await getDashboardsInfo(props.coreStart.http)) - .private_tenant_enabled, - default_tenant: (await getDashboardsInfo(props.coreStart.http)).default_tenant, + multitenancy_enabled: multitenancyEnabled, + private_tenant_enabled: privateTenantEnabled, + default_tenant: defaultTenant, }); await setUpdatedConfiguration({ - multitenancy_enabled: (await getDashboardsInfo(props.coreStart.http)) - .multitenancy_enabled, - private_tenant_enabled: (await getDashboardsInfo(props.coreStart.http)) - .private_tenant_enabled, - default_tenant: (await getDashboardsInfo(props.coreStart.http)).default_tenant, + multitenancy_enabled: multitenancyEnabled, + private_tenant_enabled: privateTenantEnabled, + default_tenant: defaultTenant, }); const rawTenantData = await fetchTenants(props.coreStart.http, LOCAL_CLUSTER_ID); @@ -205,6 +210,8 @@ export function ConfigureTab1(props: AppDependencies) { if (e.response && e.response.status === 403) { setAccessErrorFlag(true); } + } finally { + setLoading(false); } }; fetchData(); @@ -314,6 +321,9 @@ export function ConfigureTab1(props: AppDependencies) { ); + if (loading) { + return ; + } if (accessErrorFlag) { return ( ; + } if (accessErrorFlag) { return ( +`; + +exports[`Tenant list AccessError component should load access error component: manage tab 1`] = ` + +`; + exports[`Tenant list Action menu click Duplicate click 1`] = ` diff --git a/public/apps/configuration/panels/tenant-list/test/tenant-list.test.tsx b/public/apps/configuration/panels/tenant-list/test/tenant-list.test.tsx index 5e7a63fd4..ca4081fce 100644 --- a/public/apps/configuration/panels/tenant-list/test/tenant-list.test.tsx +++ b/public/apps/configuration/panels/tenant-list/test/tenant-list.test.tsx @@ -21,6 +21,7 @@ import { useDeleteConfirmState } from '../../../utils/delete-confirm-modal-utils import { Tenant } from '../../../types'; import { TenantEditModal } from '../edit-modal'; import { getDashboardsInfo } from '../../../../../utils/dashboards-info-utils'; +import { ConfigureTab1 } from '../configure_tab1'; jest.mock('../../../utils/tenant-utils'); jest.mock('../../../../../utils/auth-info-utils'); @@ -457,4 +458,50 @@ describe('Tenant list', () => { expect(mockTenantUtils.selectTenant).toHaveBeenCalled(); }); }); + + describe('AccessError component', () => { + let component; + beforeEach(() => { + jest.spyOn(React, 'useState').mockRestore(); + jest + .spyOn(React, 'useState') + .mockImplementationOnce(() => [[], jest.fn()]) + .mockImplementationOnce(() => [false, jest.fn()]) + .mockImplementationOnce(() => [true, jest.fn()]) + .mockImplementationOnce(() => [[], jest.fn()]) + .mockImplementationOnce(() => ['', jest.fn()]) + .mockImplementationOnce(() => ['', jest.fn()]) + .mockImplementationOnce(() => [null, jest.fn()]) + .mockImplementationOnce(() => [false, jest.fn()]) + .mockImplementationOnce(() => [null, jest.fn()]) + .mockImplementationOnce(() => [false, jest.fn()]) + .mockImplementationOnce(() => [false, jest.fn()]) + .mockImplementationOnce(() => ['', jest.fn()]) + .mockImplementationOnce(() => [false, jest.fn()]); + }); + + it('should load access error component: manage tab', () => { + component = shallow( + + ); + expect(component).toMatchSnapshot(); + }); + + it('should load access error component: configure tab', () => { + component = shallow( + + ); + expect(component).toMatchSnapshot(); + }); + }); }); diff --git a/public/apps/configuration/panels/test/__snapshots__/role-list.test.tsx.snap b/public/apps/configuration/panels/test/__snapshots__/role-list.test.tsx.snap index 346ab0454..4e4035617 100644 --- a/public/apps/configuration/panels/test/__snapshots__/role-list.test.tsx.snap +++ b/public/apps/configuration/panels/test/__snapshots__/role-list.test.tsx.snap @@ -1,5 +1,169 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Role list AccessError component should load access error component 1`] = ` + + + + +

+ Roles +

+
+
+ + + + +

+ Roles + + + ( + 0 + ) + +

+
+ + Roles are the core way of controlling access to your cluster. Roles contain any combination of cluster-wide permission, index-specific permissions, document- and field-level security, and tenants. Then you map users to these roles so that users gain those permissions. + + +
+ + + + + Edit + + + Duplicate + + + Delete + + + + + Create role + + + + +
+ + + +
+
+`; + exports[`Role list Render columns render Customization column 1`] = ` + + + +

+ Service accounts +

+
+
+ +
+`; diff --git a/public/apps/configuration/panels/test/__snapshots__/user-list.test.tsx.snap b/public/apps/configuration/panels/test/__snapshots__/user-list.test.tsx.snap new file mode 100644 index 000000000..82f4af425 --- /dev/null +++ b/public/apps/configuration/panels/test/__snapshots__/user-list.test.tsx.snap @@ -0,0 +1,39 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`User list AccessError component should load access error component 1`] = ` + + + + +

+ Internal users +

+
+
+ +
+`; diff --git a/public/apps/configuration/panels/test/role-list.test.tsx b/public/apps/configuration/panels/test/role-list.test.tsx index 61211d052..c5f693633 100644 --- a/public/apps/configuration/panels/test/role-list.test.tsx +++ b/public/apps/configuration/panels/test/role-list.test.tsx @@ -270,4 +270,30 @@ describe('Role list', () => { expect(result).toMatchSnapshot(); }); }); + + describe('AccessError component', () => { + let component; + beforeEach(() => { + jest.spyOn(React, 'useState').mockRestore(); + jest + .spyOn(React, 'useState') + .mockImplementationOnce(() => [[], jest.fn()]) + .mockImplementationOnce(() => [false, jest.fn()]) + .mockImplementationOnce(() => [[], jest.fn()]) + .mockImplementationOnce(() => [false, jest.fn()]) + .mockImplementationOnce(() => [true, jest.fn()]); + component = shallow( + + ); + }); + + it('should load access error component', () => { + expect(component).toMatchSnapshot(); + }); + }); }); diff --git a/public/apps/configuration/panels/test/service-account-list.test.tsx b/public/apps/configuration/panels/test/service-account-list.test.tsx index 54595d235..45417ad53 100644 --- a/public/apps/configuration/panels/test/service-account-list.test.tsx +++ b/public/apps/configuration/panels/test/service-account-list.test.tsx @@ -179,4 +179,35 @@ describe('Service Account list', () => { ); }); }); + + describe('AccessError component', () => { + let component; + const mockCoreStart = { + http: 1, + }; + beforeEach(() => { + jest.spyOn(React, 'useState').mockRestore(); + jest + .spyOn(React, 'useState') + .mockImplementationOnce(() => [[], jest.fn()]) + .mockImplementationOnce(() => [[], jest.fn()]) + .mockImplementationOnce(() => [false, jest.fn()]) + .mockImplementationOnce(() => [true, jest.fn()]) + .mockImplementationOnce(() => ['', jest.fn()]) + .mockImplementationOnce(() => [false, jest.fn()]) + .mockImplementationOnce(() => [null, jest.fn()]); + }); + + it('should load access error component', () => { + component = shallow( + + ); + expect(component).toMatchSnapshot(); + }); + }); }); diff --git a/public/apps/configuration/panels/test/user-list.test.tsx b/public/apps/configuration/panels/test/user-list.test.tsx index 59003f7e6..980e8d21c 100644 --- a/public/apps/configuration/panels/test/user-list.test.tsx +++ b/public/apps/configuration/panels/test/user-list.test.tsx @@ -236,4 +236,39 @@ describe('User list', () => { ); }); }); + + describe('AccessError component', () => { + const mockCoreStart = { + http: { + basePath: { + serverBasePath: '', + }, + }, + }; + let component; + beforeEach(() => { + jest.spyOn(React, 'useState').mockRestore(); + jest + .spyOn(React, 'useState') + .mockImplementationOnce(() => [[], jest.fn()]) + .mockImplementationOnce(() => [false, jest.fn()]) + .mockImplementationOnce(() => [[true], jest.fn()]) + .mockImplementationOnce(() => [[], jest.fn()]) + .mockImplementationOnce(() => ['', jest.fn()]) + .mockImplementationOnce(() => [false, jest.fn()]) + .mockImplementationOnce(() => [null, jest.fn()]); + component = shallow( + + ); + }); + + it('should load access error component', () => { + expect(component).toMatchSnapshot(); + }); + }); }); diff --git a/public/apps/configuration/panels/user-list.tsx b/public/apps/configuration/panels/user-list.tsx index 8a388611c..550c2e07e 100644 --- a/public/apps/configuration/panels/user-list.tsx +++ b/public/apps/configuration/panels/user-list.tsx @@ -21,6 +21,7 @@ import { EuiFlexItem, EuiInMemoryTable, EuiLink, + EuiLoadingContent, EuiPageBody, EuiPageContent, EuiPageContentHeader, @@ -50,7 +51,7 @@ import { showTableStatusMessage } from '../utils/loading-spinner-utils'; import { buildHashUrl } from '../utils/url-builder'; import { DataSourceContext } from '../app-router'; import { SecurityPluginTopNavMenu } from '../top-nav-menu'; -import { AccessErrorComponent } from '../../access-error-component'; +import { AccessErrorComponent } from '../access-error-component'; export function dictView(items: Dictionary) { if (isEmpty(items)) { @@ -219,7 +220,9 @@ export function UserList(props: AppDependencies) {

Internal users

- {accessErrorFlag ? ( + {loading ? ( + + ) : accessErrorFlag ? ( ) : ( diff --git a/public/apps/configuration/test/__snapshots__/access-error-component.test.tsx.snap b/public/apps/configuration/test/__snapshots__/access-error-component.test.tsx.snap new file mode 100644 index 000000000..48012118e --- /dev/null +++ b/public/apps/configuration/test/__snapshots__/access-error-component.test.tsx.snap @@ -0,0 +1,15 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AccessErrorComponent should display custom message prefix once loading is complete 1`] = ` + + Custom message prefix for Test-cluster. + +`; + +exports[`AccessErrorComponent should display default message prefix once loading is complete 1`] = ` + + You do not have permissions to view this data for Test-cluster. + +`; + +exports[`AccessErrorComponent should render loading when loading the content 1`] = ``; diff --git a/public/apps/configuration/test/access-error-component.test.tsx b/public/apps/configuration/test/access-error-component.test.tsx new file mode 100644 index 000000000..20572ce60 --- /dev/null +++ b/public/apps/configuration/test/access-error-component.test.tsx @@ -0,0 +1,48 @@ +/* + * Copyright OpenSearch Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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 { shallow } from 'enzyme'; +import React from 'react'; +import { AccessErrorComponent } from '../access-error-component'; + +describe('AccessErrorComponent', () => { + it('should render loading when loading the content', () => { + const props = { + dataSourceLabel: 'Test-cluster', + loading: true, + }; + const component = shallow(); + expect(component).toMatchSnapshot(); + }); + + it('should display default message prefix once loading is complete', () => { + const props = { + loading: false, + dataSourceLabel: 'Test-cluster', + }; + const component = shallow(); + expect(component).toMatchSnapshot(); + }); + + it('should display custom message prefix once loading is complete', () => { + const props = { + loading: false, + dataSourceLabel: 'Test-cluster', + message: 'Custom message prefix', + }; + const component = shallow(); + expect(component).toMatchSnapshot(); + }); +});