From 48b9c1e4f282d96581577e3655188e31174364e2 Mon Sep 17 00:00:00 2001 From: Constance Chen Date: Fri, 18 Jun 2021 09:14:26 -0700 Subject: [PATCH 1/3] Convert Settings to new page template + add missing ability check around route --- .../log_retention/log_retention_panel.tsx | 14 ++++++++++--- .../components/settings/settings.test.tsx | 4 ++-- .../components/settings/settings.tsx | 20 +++++-------------- .../applications/app_search/index.test.tsx | 15 ++++++++++++++ .../public/applications/app_search/index.tsx | 10 ++++++---- 5 files changed, 39 insertions(+), 24 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.tsx index 76fdcdac58ad4..fb4b503c7e62c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.tsx @@ -9,7 +9,15 @@ import React, { useEffect } from 'react'; import { useActions, useValues } from 'kea'; -import { EuiLink, EuiSpacer, EuiSwitch, EuiText, EuiTextColor, EuiTitle } from '@elastic/eui'; +import { + EuiPanel, + EuiLink, + EuiSpacer, + EuiSwitch, + EuiText, + EuiTextColor, + EuiTitle, +} from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { DOCS_PREFIX } from '../../../routes'; @@ -30,7 +38,7 @@ export const LogRetentionPanel: React.FC = () => { }, []); return ( -
+

{i18n.translate('xpack.enterpriseSearch.appSearch.settings.logRetention.title', { @@ -104,6 +112,6 @@ export const LogRetentionPanel: React.FC = () => { data-test-subj="LogRetentionPanelAPISwitch" /> -

+ ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.test.tsx index 41d446b8e36fc..1ad12856a92e1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.test.tsx @@ -9,13 +9,13 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { EuiPageContentBody } from '@elastic/eui'; +import { LogRetentionPanel } from './log_retention'; import { Settings } from './settings'; describe('Settings', () => { it('renders', () => { const wrapper = shallow(); - expect(wrapper.find(EuiPageContentBody)).toHaveLength(1); + expect(wrapper.find(LogRetentionPanel)).toHaveLength(1); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.tsx index 2d5dd08f81288..ddbf046d75ec1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.tsx @@ -7,10 +7,7 @@ import React from 'react'; -import { EuiPageHeader, EuiPageContent, EuiPageContentBody } from '@elastic/eui'; - -import { FlashMessages } from '../../../shared/flash_messages'; -import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; +import { AppSearchPageTemplate } from '../layout'; import { LogRetentionPanel, LogRetentionConfirmationModal } from './log_retention'; @@ -18,16 +15,9 @@ import { SETTINGS_TITLE } from './'; export const Settings: React.FC = () => { return ( - <> - - - - - - - - - - + + + + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx index 4d8ff80326715..12bc5931f50b7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx @@ -31,6 +31,7 @@ import { ErrorConnecting } from './components/error_connecting'; import { Library } from './components/library'; import { MetaEngineCreation } from './components/meta_engine_creation'; import { RoleMappings } from './components/role_mappings'; +import { Settings } from './components/settings'; import { SetupGuide } from './components/setup_guide'; import { AppSearch, AppSearchUnconfigured, AppSearchConfigured, AppSearchNav } from './'; @@ -104,6 +105,20 @@ describe('AppSearchConfigured', () => { }); describe('ability checks', () => { + describe('canViewSettings', () => { + it('renders Settings when user canViewSettings is true', () => { + setMockValues({ myRole: { canViewSettings: true } }); + rerender(wrapper); + expect(wrapper.find(Settings)).toHaveLength(1); + }); + + it('does not render Settings when user canViewSettings is false', () => { + setMockValues({ myRole: { canViewSettings: false } }); + rerender(wrapper); + expect(wrapper.find(Settings)).toHaveLength(0); + }); + }); + describe('canViewRoleMappings', () => { it('renders RoleMappings when canViewRoleMappings is true', () => { setMockValues({ myRole: { canViewRoleMappings: true } }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx index caf0f805e8ca7..a3c9c10898341 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx @@ -76,7 +76,7 @@ export const AppSearchUnconfigured: React.FC = () => ( export const AppSearchConfigured: React.FC> = (props) => { const { - myRole: { canManageEngines, canManageMetaEngines, canViewRoleMappings }, + myRole: { canManageEngines, canManageMetaEngines, canViewSettings, canViewRoleMappings }, } = useValues(AppLogic(props)); const { renderHeaderActions } = useValues(KibanaLogic); const { readOnlyMode } = useValues(HttpLogic); @@ -92,6 +92,11 @@ export const AppSearchConfigured: React.FC> = (props) = )} + {canViewSettings && ( + + + + )} {canViewRoleMappings && ( @@ -109,9 +114,6 @@ export const AppSearchConfigured: React.FC> = (props) = - - - From bf5aee3d977cd01b7afab12f4ef35d1b222c2a72 Mon Sep 17 00:00:00 2001 From: Constance Chen Date: Fri, 18 Jun 2021 09:26:15 -0700 Subject: [PATCH 2/3] Convert Credentials to new page template + add missing ability check around route --- .../credentials/credentials.test.tsx | 5 +- .../components/credentials/credentials.tsx | 133 +++++++++--------- .../applications/app_search/index.test.tsx | 15 ++ .../public/applications/app_search/index.tsx | 16 ++- 4 files changed, 94 insertions(+), 75 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.test.tsx index 286658c011002..737908752911d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.test.tsx @@ -12,7 +12,7 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { EuiCopy, EuiLoadingContent, EuiPageContentBody } from '@elastic/eui'; +import { EuiCopy, EuiLoadingContent } from '@elastic/eui'; import { DEFAULT_META } from '../../../shared/constants'; import { externalUrl } from '../../../shared/enterprise_search_url'; @@ -20,6 +20,7 @@ import { externalUrl } from '../../../shared/enterprise_search_url'; import { Credentials } from './credentials'; import { CredentialsFlyout } from './credentials_flyout'; +import { CredentialsList } from './credentials_list'; describe('Credentials', () => { // Kea mocks @@ -42,7 +43,7 @@ describe('Credentials', () => { it('renders', () => { const wrapper = shallow(); - expect(wrapper.find(EuiPageContentBody)).toHaveLength(1); + expect(wrapper.find(CredentialsList)).toHaveLength(1); }); it('fetches data on mount', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.tsx index 8918445982ea6..f81d8d64737df 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials.tsx @@ -10,9 +10,7 @@ import React, { useEffect } from 'react'; import { useActions, useValues } from 'kea'; import { - EuiPageHeader, EuiTitle, - EuiPageContentBody, EuiPanel, EuiCopy, EuiButtonIcon, @@ -25,8 +23,7 @@ import { import { i18n } from '@kbn/i18n'; import { externalUrl } from '../../../shared/enterprise_search_url/external_url'; -import { FlashMessages } from '../../../shared/flash_messages'; -import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; +import { AppSearchPageTemplate } from '../layout'; import { CREDENTIALS_TITLE } from './constants'; import { CredentialsFlyout } from './credentials_flyout'; @@ -52,74 +49,72 @@ export const Credentials: React.FC = () => { }, []); return ( - <> - - - - {shouldShowCredentialsForm && } - - + + {shouldShowCredentialsForm && } + + +

+ {i18n.translate('xpack.enterpriseSearch.appSearch.credentials.apiEndpoint', { + defaultMessage: 'Endpoint', + })} +

+
+ + {(copy) => ( + <> + + {externalUrl.enterpriseSearchUrl} + + )} + +
+ + + +

- {i18n.translate('xpack.enterpriseSearch.appSearch.credentials.apiEndpoint', { - defaultMessage: 'Endpoint', + {i18n.translate('xpack.enterpriseSearch.appSearch.credentials.apiKeys', { + defaultMessage: 'API Keys', })}

- - {(copy) => ( - <> - - {externalUrl.enterpriseSearchUrl} - - )} - -
- - - - -

- {i18n.translate('xpack.enterpriseSearch.appSearch.credentials.apiKeys', { - defaultMessage: 'API Keys', - })} -

-
-
- - {!dataLoading && ( - showCredentialsForm()} - > - {i18n.translate('xpack.enterpriseSearch.appSearch.credentials.createKey', { - defaultMessage: 'Create a key', - })} - - )} - -
- - - - {!!dataLoading ? : } - -
- + + + {!dataLoading && ( + showCredentialsForm()} + > + {i18n.translate('xpack.enterpriseSearch.appSearch.credentials.createKey', { + defaultMessage: 'Create a key', + })} + + )} + + + + + {!!dataLoading ? : } + + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx index 12bc5931f50b7..01b1f0f9d3b01 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx @@ -24,6 +24,7 @@ import { rerender } from '../test_helpers'; jest.mock('./app_logic', () => ({ AppLogic: jest.fn() })); import { AppLogic } from './app_logic'; +import { Credentials } from './components/credentials'; import { EngineRouter, EngineNav } from './components/engine'; import { EngineCreation } from './components/engine_creation'; import { EnginesOverview } from './components/engines'; @@ -119,6 +120,20 @@ describe('AppSearchConfigured', () => { }); }); + describe('canViewAccountCredentials', () => { + it('renders Credentials when user canViewAccountCredentials is true', () => { + setMockValues({ myRole: { canViewAccountCredentials: true } }); + rerender(wrapper); + expect(wrapper.find(Credentials)).toHaveLength(1); + }); + + it('does not render Credentials when user canViewAccountCredentials is false', () => { + setMockValues({ myRole: { canViewAccountCredentials: false } }); + rerender(wrapper); + expect(wrapper.find(Credentials)).toHaveLength(0); + }); + }); + describe('canViewRoleMappings', () => { it('renders RoleMappings when canViewRoleMappings is true', () => { setMockValues({ myRole: { canViewRoleMappings: true } }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx index a3c9c10898341..b6d959acecc36 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx @@ -76,7 +76,13 @@ export const AppSearchUnconfigured: React.FC = () => ( export const AppSearchConfigured: React.FC> = (props) => { const { - myRole: { canManageEngines, canManageMetaEngines, canViewSettings, canViewRoleMappings }, + myRole: { + canManageEngines, + canManageMetaEngines, + canViewSettings, + canViewAccountCredentials, + canViewRoleMappings, + }, } = useValues(AppLogic(props)); const { renderHeaderActions } = useValues(KibanaLogic); const { readOnlyMode } = useValues(HttpLogic); @@ -97,6 +103,11 @@ export const AppSearchConfigured: React.FC> = (props) =
)} + {canViewAccountCredentials && ( + + + + )} {canViewRoleMappings && ( @@ -114,9 +125,6 @@ export const AppSearchConfigured: React.FC> = (props) = - - - {canManageEngines && ( From b7009bcc2fedf9e863b6b55253a33185ad7b2a9b Mon Sep 17 00:00:00 2001 From: Constance Chen Date: Fri, 18 Jun 2021 09:56:04 -0700 Subject: [PATCH 3/3] [Tests refactor] DRY out repeated ability tests to a helper --- .../applications/app_search/index.test.tsx | 92 ++++--------------- 1 file changed, 20 insertions(+), 72 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx index 01b1f0f9d3b01..2402a6ecc6401 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx @@ -105,80 +105,28 @@ describe('AppSearchConfigured', () => { expect(wrapper.find(Layout).first().prop('readOnlyMode')).toEqual(true); }); - describe('ability checks', () => { - describe('canViewSettings', () => { - it('renders Settings when user canViewSettings is true', () => { - setMockValues({ myRole: { canViewSettings: true } }); - rerender(wrapper); - expect(wrapper.find(Settings)).toHaveLength(1); + describe('routes with ability checks', () => { + const runRouteAbilityCheck = (routeAbility: string, View: React.FC) => { + describe(View.name, () => { + it(`renders ${View.name} when user ${routeAbility} is true`, () => { + setMockValues({ myRole: { [routeAbility]: true } }); + rerender(wrapper); + expect(wrapper.find(View)).toHaveLength(1); + }); + + it(`does not render ${View.name} when user ${routeAbility} is false`, () => { + setMockValues({ myRole: { [routeAbility]: false } }); + rerender(wrapper); + expect(wrapper.find(View)).toHaveLength(0); + }); }); + }; - it('does not render Settings when user canViewSettings is false', () => { - setMockValues({ myRole: { canViewSettings: false } }); - rerender(wrapper); - expect(wrapper.find(Settings)).toHaveLength(0); - }); - }); - - describe('canViewAccountCredentials', () => { - it('renders Credentials when user canViewAccountCredentials is true', () => { - setMockValues({ myRole: { canViewAccountCredentials: true } }); - rerender(wrapper); - expect(wrapper.find(Credentials)).toHaveLength(1); - }); - - it('does not render Credentials when user canViewAccountCredentials is false', () => { - setMockValues({ myRole: { canViewAccountCredentials: false } }); - rerender(wrapper); - expect(wrapper.find(Credentials)).toHaveLength(0); - }); - }); - - describe('canViewRoleMappings', () => { - it('renders RoleMappings when canViewRoleMappings is true', () => { - setMockValues({ myRole: { canViewRoleMappings: true } }); - rerender(wrapper); - expect(wrapper.find(RoleMappings)).toHaveLength(1); - }); - - it('does not render RoleMappings when user canViewRoleMappings is false', () => { - setMockValues({ myRole: { canManageEngines: false } }); - rerender(wrapper); - expect(wrapper.find(RoleMappings)).toHaveLength(0); - }); - }); - - describe('canManageEngines', () => { - it('renders EngineCreation when user canManageEngines is true', () => { - setMockValues({ myRole: { canManageEngines: true } }); - rerender(wrapper); - - expect(wrapper.find(EngineCreation)).toHaveLength(1); - }); - - it('does not render EngineCreation when user canManageEngines is false', () => { - setMockValues({ myRole: { canManageEngines: false } }); - rerender(wrapper); - - expect(wrapper.find(EngineCreation)).toHaveLength(0); - }); - }); - - describe('canManageMetaEngines', () => { - it('renders MetaEngineCreation when user canManageMetaEngines is true', () => { - setMockValues({ myRole: { canManageMetaEngines: true } }); - rerender(wrapper); - - expect(wrapper.find(MetaEngineCreation)).toHaveLength(1); - }); - - it('does not render MetaEngineCreation when user canManageMetaEngines is false', () => { - setMockValues({ myRole: { canManageMetaEngines: false } }); - rerender(wrapper); - - expect(wrapper.find(MetaEngineCreation)).toHaveLength(0); - }); - }); + runRouteAbilityCheck('canViewSettings', Settings); + runRouteAbilityCheck('canViewAccountCredentials', Credentials); + runRouteAbilityCheck('canViewRoleMappings', RoleMappings); + runRouteAbilityCheck('canManageEngines', EngineCreation); + runRouteAbilityCheck('canManageMetaEngines', MetaEngineCreation); }); describe('library', () => {