From 85ae4c36b20e18d8c3b378b8330756c67007ba76 Mon Sep 17 00:00:00 2001 From: Yulia Cech Date: Mon, 26 Oct 2020 16:50:56 +0100 Subject: [PATCH 01/10] Fix edit policy page navigation --- .../client_integration/app/app.helpers.tsx | 55 +++++++++++++++ .../client_integration/app/app.test.ts | 69 +++++++++++++++++++ .../edit_policy/constants.ts | 20 ++++++ .../client_integration/helpers/index.ts | 3 + .../public/application/app.tsx | 40 +++++++---- .../public/application/index.tsx | 8 ++- .../edit_policy/edit_policy.container.tsx | 8 ++- .../sections/edit_policy/edit_policy.tsx | 2 +- 8 files changed, 186 insertions(+), 19 deletions(-) create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx create mode 100644 x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx new file mode 100644 index 0000000000000..8b54c408d1eb1 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { act } from 'react-dom/test-utils'; +import { registerTestBed, TestBed, TestBedConfig } from '../../../../../test_utils'; +import { App } from '../../../public/application/app'; +import { TestSubjects } from '../helpers'; + +const getTestBedConfig = (initialEntries: string[]): TestBedConfig => ({ + memoryRouter: { + initialEntries, + }, + defaultProps: { + getUrlForApp: () => {}, + navigateToApp: () => {}, + }, +}); + +const initTestBed = (initialEntries: string[]) => + registerTestBed(App, getTestBedConfig(initialEntries))(); + +export interface AppTestBed extends TestBed { + actions: { + clickPolicyNameLink: () => void; + clickCreatePolicyButton: () => void; + }; +} + +export const setup = async (initialEntries: string[]): Promise => { + const testBed = await initTestBed(initialEntries); + + const clickPolicyNameLink = async () => { + const { component, find } = testBed; + await act(async () => { + find('policyTablePolicyNameLink').simulate('click', { button: 0 }); + }); + component.update(); + }; + + const clickCreatePolicyButton = async () => { + const { component, find } = testBed; + await act(async () => { + find('createPolicyButton').simulate('click', { button: 0 }); + }); + component.update(); + }; + + return { + ...testBed, + actions: { clickPolicyNameLink, clickCreatePolicyButton }, + }; +}; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts new file mode 100644 index 0000000000000..23de2fc847933 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { AppTestBed, setup } from './app.helpers'; +import { setupEnvironment } from '../helpers/setup_environment'; +import { SPECIAL_CHARS_NAME, SPECIAL_CHARS_POLICY } from '../edit_policy/constants'; +import { act } from 'react-dom/test-utils'; + +window.scrollTo = jest.fn(); + +describe('', () => { + let testBed: AppTestBed; + const { server, httpRequestsMockHelpers } = setupEnvironment(); + afterAll(() => { + server.restore(); + }); + + describe('navigation with special characters', () => { + beforeEach(async () => { + httpRequestsMockHelpers.setLoadPolicies([SPECIAL_CHARS_POLICY]); + }); + + test('when clicked on policy name in table', async () => { + await act(async () => { + testBed = await setup(['/']); + }); + + const { component, actions } = testBed; + component.update(); + + await actions.clickPolicyNameLink(); + component.update(); + + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${SPECIAL_CHARS_NAME}` + ); + }); + + test('when creating a new policy', async () => { + await act(async () => { + testBed = await setup(['/']); + }); + + const { component, actions } = testBed; + component.update(); + + await actions.clickCreatePolicyButton(); + component.update(); + + expect(testBed.find('policyTitle').text()).toBe(`Create an index lifecycle policy`); + }); + + test('when loading edit policy page url', async () => { + await act(async () => { + testBed = await setup([`/policies/edit/${encodeURIComponent(SPECIAL_CHARS_NAME)}`]); + }); + + const { component } = testBed; + component.update(); + + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${SPECIAL_CHARS_NAME}` + ); + }); + }); +}); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts index bd845b0a7d9a7..4d7c1903a3aef 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts @@ -7,6 +7,7 @@ import { PolicyFromES } from '../../../common/types'; export const POLICY_NAME = 'my_policy'; +export const SPECIAL_CHARS_NAME = 'test%25'; export const SNAPSHOT_POLICY_NAME = 'my_snapshot_policy'; export const NEW_SNAPSHOT_POLICY_NAME = 'my_new_snapshot_policy'; @@ -60,3 +61,22 @@ export const DELETE_PHASE_POLICY: PolicyFromES = { }, name: POLICY_NAME, }; + +export const SPECIAL_CHARS_POLICY: PolicyFromES = { + version: 1, + modified_date: Date.now().toString(), + policy: { + phases: { + hot: { + min_age: '0ms', + actions: { + rollover: { + max_size: '50gb', + }, + }, + }, + }, + name: SPECIAL_CHARS_NAME, + }, + name: SPECIAL_CHARS_NAME, +}; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts index c6d27ca890b54..11f15699e0395 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/helpers/index.ts @@ -17,4 +17,7 @@ export type TestSubjects = | 'hot-selectedMaxDocuments' | 'hot-selectedMaxAge' | 'hot-selectedMaxAgeUnits' + | 'policyTablePolicyNameLink' + | 'policyTitle' + | 'createPolicyButton' | string; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/app.tsx b/x-pack/plugins/index_lifecycle_management/public/application/app.tsx index f7f8b30324bca..56f41af419fe1 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/app.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/app.tsx @@ -14,7 +14,7 @@ import { EditPolicy } from './sections/edit_policy'; import { PolicyTable } from './sections/policy_table'; import { trackUiMetric } from './services/ui_metric'; -export const App = ({ +export const AppWithRouter = ({ history, navigateToApp, getUrlForApp, @@ -22,23 +22,33 @@ export const App = ({ history: ScopedHistory; navigateToApp: ApplicationStart['navigateToApp']; getUrlForApp: ApplicationStart['getUrlForApp']; +}) => ( + + + +); + +export const App = ({ + navigateToApp, + getUrlForApp, +}: { + navigateToApp: ApplicationStart['navigateToApp']; + getUrlForApp: ApplicationStart['getUrlForApp']; }) => { useEffect(() => trackUiMetric(METRIC_TYPE.LOADED, UIM_APP_LOAD), []); return ( - - - - } - /> - } - /> - - + + + } + /> + } + /> + ); }; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/index.tsx b/x-pack/plugins/index_lifecycle_management/public/application/index.tsx index 7a7fd20e96c63..542b047cdc77f 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/index.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/index.tsx @@ -12,7 +12,7 @@ import { CloudSetup } from '../../../cloud/public'; import { KibanaContextProvider } from '../shared_imports'; -import { App } from './app'; +import { AppWithRouter } from './app'; export const renderApp = ( element: Element, @@ -25,7 +25,11 @@ export const renderApp = ( render( - + , element diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx index dfc3e7194da06..c0dd19ff291ef 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx @@ -76,12 +76,18 @@ export const EditPolicy: React.FunctionComponent ); }; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx index 8f8b0447f378a..860325f66ca08 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx @@ -227,7 +227,7 @@ export const EditPolicy: React.FunctionComponent = ({ verticalPosition="center" horizontalPosition="center" > - +

{isNewPolicy ? i18n.translate('xpack.indexLifecycleMgmt.editPolicy.createPolicyMessage', { From 0577f4a2786ecb0b819b009e7e47eb5707a9aafc Mon Sep 17 00:00:00 2001 From: Yulia Cech Date: Mon, 26 Oct 2020 20:03:04 +0100 Subject: [PATCH 02/10] Fix edit policy page navigation --- .../client_integration/app/app.test.ts | 21 +++++++++-- .../edit_policy/constants.ts | 35 +++++-------------- .../edit_policy/edit_policy.test.ts | 4 +-- .../edit_policy/edit_policy.container.tsx | 10 ++++-- 4 files changed, 36 insertions(+), 34 deletions(-) diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts index 23de2fc847933..5a654518fecaf 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts @@ -6,7 +6,7 @@ import { AppTestBed, setup } from './app.helpers'; import { setupEnvironment } from '../helpers/setup_environment'; -import { SPECIAL_CHARS_NAME, SPECIAL_CHARS_POLICY } from '../edit_policy/constants'; +import { SPECIAL_CHARS_NAME, getDefaultHotPhasePolicy } from '../edit_policy/constants'; import { act } from 'react-dom/test-utils'; window.scrollTo = jest.fn(); @@ -19,8 +19,8 @@ describe('', () => { }); describe('navigation with special characters', () => { - beforeEach(async () => { - httpRequestsMockHelpers.setLoadPolicies([SPECIAL_CHARS_POLICY]); + beforeAll(async () => { + httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy(SPECIAL_CHARS_NAME)]); }); test('when clicked on policy name in table', async () => { @@ -65,5 +65,20 @@ describe('', () => { `Edit index lifecycle policy ${SPECIAL_CHARS_NAME}` ); }); + + test('when loading edit policy page url with double encoding', async () => { + await act(async () => { + testBed = await setup([ + encodeURI(`/policies/edit/${encodeURIComponent(SPECIAL_CHARS_NAME)}`), + ]); + }); + + const { component } = testBed; + component.update(); + + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${SPECIAL_CHARS_NAME}` + ); + }); }); }); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts index 4d7c1903a3aef..af4f0306e3026 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts @@ -7,27 +7,12 @@ import { PolicyFromES } from '../../../common/types'; export const POLICY_NAME = 'my_policy'; -export const SPECIAL_CHARS_NAME = 'test%25'; +// navigation doesn't work for % with other special chars or sequence %25 +// link to kibana issue for explanation +export const SPECIAL_CHARS_NAME = 'test?#'; export const SNAPSHOT_POLICY_NAME = 'my_snapshot_policy'; export const NEW_SNAPSHOT_POLICY_NAME = 'my_new_snapshot_policy'; -export const DEFAULT_POLICY: PolicyFromES = { - version: 1, - modified_date: Date.now().toString(), - policy: { - name: '', - phases: { - hot: { - min_age: '123ms', - actions: { - rollover: {}, - }, - }, - }, - }, - name: '', -}; - export const DELETE_PHASE_POLICY: PolicyFromES = { version: 1, modified_date: Date.now().toString(), @@ -62,21 +47,19 @@ export const DELETE_PHASE_POLICY: PolicyFromES = { name: POLICY_NAME, }; -export const SPECIAL_CHARS_POLICY: PolicyFromES = { +export const getDefaultHotPhasePolicy = (policyName: string): PolicyFromES => ({ version: 1, modified_date: Date.now().toString(), policy: { + name: policyName, phases: { hot: { - min_age: '0ms', + min_age: '123ms', actions: { - rollover: { - max_size: '50gb', - }, + rollover: {}, }, }, }, - name: SPECIAL_CHARS_NAME, }, - name: SPECIAL_CHARS_NAME, -}; + name: policyName, +}); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts index 3cbc2d982566e..9696cf9b8557a 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts @@ -14,7 +14,7 @@ import { DELETE_PHASE_POLICY, NEW_SNAPSHOT_POLICY_NAME, SNAPSHOT_POLICY_NAME, - DEFAULT_POLICY, + getDefaultHotPhasePolicy, } from './constants'; window.scrollTo = jest.fn(); @@ -29,7 +29,7 @@ describe('', () => { describe('hot phase', () => { describe('serialization', () => { beforeEach(async () => { - httpRequestsMockHelpers.setLoadPolicies([DEFAULT_POLICY]); + httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy('test')]); httpRequestsMockHelpers.setLoadSnapshotPolicies([]); await act(async () => { diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx index c0dd19ff291ef..76fbb0baa6e6d 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx @@ -77,9 +77,13 @@ export const EditPolicy: React.FunctionComponent Date: Tue, 27 Oct 2020 13:47:37 +0100 Subject: [PATCH 03/10] Add links to PR for explanation --- .../__jest__/client_integration/edit_policy/constants.ts | 2 +- .../application/sections/edit_policy/edit_policy.container.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts index af4f0306e3026..99400e0056c07 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts @@ -8,7 +8,7 @@ import { PolicyFromES } from '../../../common/types'; export const POLICY_NAME = 'my_policy'; // navigation doesn't work for % with other special chars or sequence %25 -// link to kibana issue for explanation +// https://github.com/elastic/kibana/pull/81664 export const SPECIAL_CHARS_NAME = 'test?#'; export const SNAPSHOT_POLICY_NAME = 'my_snapshot_policy'; export const NEW_SNAPSHOT_POLICY_NAME = 'my_new_snapshot_policy'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx index 76fbb0baa6e6d..e67b03a95f657 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx @@ -82,7 +82,7 @@ export const EditPolicy: React.FunctionComponent Date: Tue, 3 Nov 2020 15:48:44 +0100 Subject: [PATCH 04/10] Added more tests and linked to a github issue about navigation issues --- .../public/url/attempt_to_uri_decode.test.ts | 45 ++++- .../public/url/attempt_to_uri_decode.ts | 4 +- .../client_integration/app/app.test.ts | 181 +++++++++++++++++- .../edit_policy/constants.ts | 3 - .../edit_policy/edit_policy.container.tsx | 13 +- .../public/shared_imports.ts | 2 + 6 files changed, 219 insertions(+), 29 deletions(-) diff --git a/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.test.ts b/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.test.ts index 15750c7667800..bb81c2f33b462 100644 --- a/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.test.ts +++ b/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.test.ts @@ -19,14 +19,47 @@ import { attemptToURIDecode } from './attempt_to_uri_decode'; +// this function doesn't work for % with other special chars or sequence %25 +// known issue https://github.com/elastic/kibana/issues/82440 test('decodes an encoded string', () => { - const encodedString = 'test%3F'; - expect(attemptToURIDecode(encodedString)).toBe('test?'); + const originalName = 'test;,/?:@&=+$#'; + const encodedName = encodeURIComponent(originalName); + // react router v5 automatically decodes route match params + const reactRouterDecoded = decodeURI(encodedName); + + expect(attemptToURIDecode(encodedName)).toBe(originalName); + expect(attemptToURIDecode(reactRouterDecoded)).toBe(originalName); }); -// react router partially decodes %25 sequence to % in match params -// https://github.com/elastic/kibana/pull/81664 test('ignores the error if a string is already decoded', () => { - const decodedString = 'test%'; - expect(attemptToURIDecode(decodedString)).toBe(decodedString); + const originalName = 'test%'; + + const encodedName = encodeURIComponent(originalName); + // react router v5 automatically decodes route match params + const reactRouterDecoded = decodeURI(encodedName); + + expect(attemptToURIDecode(encodedName)).toBe(originalName); + expect(attemptToURIDecode(reactRouterDecoded)).toBe(originalName); +}); + +test('returns wrong decoded value for %25 sequence', () => { + const originalName = 'test%25'; + + const encodedName = encodeURIComponent(originalName); + // react router v5 automatically decodes route match params + const reactRouterDecoded = decodeURI(encodedName); + + expect(attemptToURIDecode(encodedName)).toBe(originalName); + expect(attemptToURIDecode(reactRouterDecoded)).not.toBe(originalName); +}); + +test('returns wrong decoded value for % with other escaped characters', () => { + const originalName = 'test%?#'; + + const encodedName = encodeURIComponent(originalName); + // react router v5 automatically decodes route match params + const reactRouterDecoded = decodeURI(encodedName); + + expect(attemptToURIDecode(encodedName)).toBe(originalName); + expect(attemptToURIDecode(reactRouterDecoded)).not.toBe(originalName); }); diff --git a/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.ts b/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.ts index 65444b83f77bb..47e807b6eafe0 100644 --- a/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.ts +++ b/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.ts @@ -19,7 +19,9 @@ /* * Use this function with any match params coming from react router to safely decode values. - * https://github.com/elastic/kibana/pull/81664 + * After an update to react router v6, this functions should be deprecated. + * Known issue for navigation with special characters in paths + * https://github.com/elastic/kibana/issues/82440 */ export const attemptToURIDecode = (value: string) => { let result = value; diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts index 5a654518fecaf..a225afd0c5f3e 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts @@ -6,9 +6,16 @@ import { AppTestBed, setup } from './app.helpers'; import { setupEnvironment } from '../helpers/setup_environment'; -import { SPECIAL_CHARS_NAME, getDefaultHotPhasePolicy } from '../edit_policy/constants'; +import { getDefaultHotPhasePolicy, POLICY_NAME } from '../edit_policy/constants'; import { act } from 'react-dom/test-utils'; +const SPECIAL_CHARS_NAME = 'test?#$+=&@:'; +const DOLLAR_SIGN_NAME = 'test%'; +// navigation doesn't work for % with other special chars or sequence %25 +// known issue https://github.com/elastic/kibana/issues/82440 +const DOLLAR_SIGN_WITH_OTHER_CHARS_NAME = 'test%#'; +const DOLLAR_SIGN_25_SEQUENCE = 'test%25'; + window.scrollTo = jest.fn(); describe('', () => { @@ -18,6 +25,38 @@ describe('', () => { server.restore(); }); + describe('new policy creation', () => { + test('when there are no policies', async () => { + httpRequestsMockHelpers.setLoadPolicies([]); + await act(async () => { + testBed = await setup(['/']); + }); + + const { component, actions } = testBed; + component.update(); + + await actions.clickCreatePolicyButton(); + component.update(); + + expect(testBed.find('policyTitle').text()).toBe(`Create an index lifecycle policy`); + }); + + test('when there are policies', async () => { + httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy(POLICY_NAME)]); + await act(async () => { + testBed = await setup(['/']); + }); + + const { component, actions } = testBed; + component.update(); + + await actions.clickCreatePolicyButton(); + component.update(); + + expect(testBed.find('policyTitle').text()).toBe(`Create an index lifecycle policy`); + }); + }); + describe('navigation with special characters', () => { beforeAll(async () => { httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy(SPECIAL_CHARS_NAME)]); @@ -39,7 +78,77 @@ describe('', () => { ); }); - test('when creating a new policy', async () => { + test('when loading edit policy page url', async () => { + await act(async () => { + testBed = await setup([`/policies/edit/${encodeURIComponent(SPECIAL_CHARS_NAME)}`]); + }); + + const { component } = testBed; + component.update(); + + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${SPECIAL_CHARS_NAME}` + ); + }); + + test('when loading edit policy page url with double encoding', async () => { + await act(async () => { + testBed = await setup([ + encodeURI(`/policies/edit/${encodeURIComponent(SPECIAL_CHARS_NAME)}`), + ]); + }); + + const { component } = testBed; + component.update(); + + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${SPECIAL_CHARS_NAME}` + ); + }); + }); + + describe('navigation with dollar sign', () => { + beforeAll(async () => { + httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy(DOLLAR_SIGN_NAME)]); + }); + + test('when loading edit policy page url', async () => { + await act(async () => { + testBed = await setup([`/policies/edit/${encodeURIComponent(DOLLAR_SIGN_NAME)}`]); + }); + + const { component } = testBed; + component.update(); + + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${DOLLAR_SIGN_NAME}` + ); + }); + + test('when loading edit policy page url with double encoding', async () => { + await act(async () => { + testBed = await setup([ + encodeURI(`/policies/edit/${encodeURIComponent(DOLLAR_SIGN_NAME)}`), + ]); + }); + + const { component } = testBed; + component.update(); + + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${DOLLAR_SIGN_NAME}` + ); + }); + }); + + describe('navigation with dollar sign with other special characters', () => { + beforeAll(async () => { + httpRequestsMockHelpers.setLoadPolicies([ + getDefaultHotPhasePolicy(DOLLAR_SIGN_WITH_OTHER_CHARS_NAME), + ]); + }); + + test('when clicked on policy name in table', async () => { await act(async () => { testBed = await setup(['/']); }); @@ -47,29 +156,85 @@ describe('', () => { const { component, actions } = testBed; component.update(); - await actions.clickCreatePolicyButton(); + await actions.clickPolicyNameLink(); component.update(); - expect(testBed.find('policyTitle').text()).toBe(`Create an index lifecycle policy`); + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${DOLLAR_SIGN_WITH_OTHER_CHARS_NAME}` + ); }); test('when loading edit policy page url', async () => { await act(async () => { - testBed = await setup([`/policies/edit/${encodeURIComponent(SPECIAL_CHARS_NAME)}`]); + testBed = await setup([ + `/policies/edit/${encodeURIComponent(DOLLAR_SIGN_WITH_OTHER_CHARS_NAME)}`, + ]); + }); + + const { component } = testBed; + component.update(); + + // known issue https://github.com/elastic/kibana/issues/82440 + expect(testBed.find('policyTitle').text()).not.toBe( + `Edit index lifecycle policy ${DOLLAR_SIGN_WITH_OTHER_CHARS_NAME}` + ); + }); + + test('when loading edit policy page url with double encoding', async () => { + await act(async () => { + testBed = await setup([ + encodeURI(`/policies/edit/${encodeURIComponent(DOLLAR_SIGN_WITH_OTHER_CHARS_NAME)}`), + ]); }); const { component } = testBed; component.update(); expect(testBed.find('policyTitle').text()).toBe( - `Edit index lifecycle policy ${SPECIAL_CHARS_NAME}` + `Edit index lifecycle policy ${DOLLAR_SIGN_WITH_OTHER_CHARS_NAME}` + ); + }); + }); + + describe('navigation with %25 sequence', () => { + beforeAll(async () => { + httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy(DOLLAR_SIGN_25_SEQUENCE)]); + }); + + test('when clicked on policy name in table', async () => { + await act(async () => { + testBed = await setup(['/']); + }); + + const { component, actions } = testBed; + component.update(); + + await actions.clickPolicyNameLink(); + component.update(); + + expect(testBed.find('policyTitle').text()).toBe( + `Edit index lifecycle policy ${DOLLAR_SIGN_25_SEQUENCE}` + ); + }); + + test('when loading edit policy page url', async () => { + await act(async () => { + testBed = await setup([`/policies/edit/${encodeURIComponent(DOLLAR_SIGN_25_SEQUENCE)}`]); + }); + + const { component } = testBed; + component.update(); + + // known issue https://github.com/elastic/kibana/issues/82440 + expect(testBed.find('policyTitle').text()).not.toBe( + `Edit index lifecycle policy ${DOLLAR_SIGN_25_SEQUENCE}` ); }); test('when loading edit policy page url with double encoding', async () => { await act(async () => { testBed = await setup([ - encodeURI(`/policies/edit/${encodeURIComponent(SPECIAL_CHARS_NAME)}`), + encodeURI(`/policies/edit/${encodeURIComponent(DOLLAR_SIGN_25_SEQUENCE)}`), ]); }); @@ -77,7 +242,7 @@ describe('', () => { component.update(); expect(testBed.find('policyTitle').text()).toBe( - `Edit index lifecycle policy ${SPECIAL_CHARS_NAME}` + `Edit index lifecycle policy ${DOLLAR_SIGN_25_SEQUENCE}` ); }); }); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts index 45bd405006b17..f675ef2349e34 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts @@ -7,9 +7,6 @@ import { PolicyFromES } from '../../../common/types'; export const POLICY_NAME = 'my_policy'; -// navigation doesn't work for % with other special chars or sequence %25 -// https://github.com/elastic/kibana/pull/81664 -export const SPECIAL_CHARS_NAME = 'test?#'; export const SNAPSHOT_POLICY_NAME = 'my_snapshot_policy'; export const NEW_SNAPSHOT_POLICY_NAME = 'my_new_snapshot_policy'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx index e67b03a95f657..7cf44329e349d 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx @@ -11,6 +11,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { useLoadPoliciesList } from '../../services/api'; import { EditPolicy as PresentationComponent } from './edit_policy'; +import { attemptToURIDecode } from '../../../shared_imports'; interface RouterProps { policyName: string; @@ -76,22 +77,12 @@ export const EditPolicy: React.FunctionComponent ); }; diff --git a/x-pack/plugins/index_lifecycle_management/public/shared_imports.ts b/x-pack/plugins/index_lifecycle_management/public/shared_imports.ts index 023aeba57aa7a..42dd468ed6d97 100644 --- a/x-pack/plugins/index_lifecycle_management/public/shared_imports.ts +++ b/x-pack/plugins/index_lifecycle_management/public/shared_imports.ts @@ -29,6 +29,8 @@ export { SuperSelectField, } from '../../../../src/plugins/es_ui_shared/static/forms/components'; +export { attemptToURIDecode } from '../../../../src/plugins/es_ui_shared/public'; + export { KibanaContextProvider } from '../../../../src/plugins/kibana_react/public'; export const useKibana = () => _useKibana(); From f4015fc5cdb33c0ca4928a8799e988adf44763ae Mon Sep 17 00:00:00 2001 From: Yulia Cech Date: Tue, 3 Nov 2020 16:16:29 +0100 Subject: [PATCH 05/10] Fix decoding function for undefined values --- .../es_ui_shared/public/url/attempt_to_uri_decode.test.ts | 4 ++++ src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.ts | 4 ++-- .../__jest__/client_integration/app/app.test.ts | 2 ++ .../public/application/sections/edit_policy/edit_policy.tsx | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.test.ts b/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.test.ts index bb81c2f33b462..6654611faa18b 100644 --- a/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.test.ts +++ b/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.test.ts @@ -63,3 +63,7 @@ test('returns wrong decoded value for % with other escaped characters', () => { expect(attemptToURIDecode(encodedName)).toBe(originalName); expect(attemptToURIDecode(reactRouterDecoded)).not.toBe(originalName); }); + +test("doesn't convert undefined to a string", () => { + expect(attemptToURIDecode(undefined)).toBeUndefined(); +}); diff --git a/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.ts b/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.ts index 47e807b6eafe0..37e4761106e44 100644 --- a/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.ts +++ b/src/plugins/es_ui_shared/public/url/attempt_to_uri_decode.ts @@ -23,10 +23,10 @@ * Known issue for navigation with special characters in paths * https://github.com/elastic/kibana/issues/82440 */ -export const attemptToURIDecode = (value: string) => { +export const attemptToURIDecode = (value?: string): string | undefined => { let result = value; try { - result = decodeURIComponent(value); + result = value ? decodeURIComponent(value) : value; } catch (e) { // do nothing } diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts index a225afd0c5f3e..b5e35f8ab2970 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts @@ -39,6 +39,7 @@ describe('', () => { component.update(); expect(testBed.find('policyTitle').text()).toBe(`Create an index lifecycle policy`); + expect(testBed.find('policyNameField').props().value).toBe(''); }); test('when there are policies', async () => { @@ -54,6 +55,7 @@ describe('', () => { component.update(); expect(testBed.find('policyTitle').text()).toBe(`Create an index lifecycle policy`); + expect(testBed.find('policyNameField').props().value).toBe(''); }); }); diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx index ffa286c9df278..e152c8c0ee127 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.tsx @@ -71,7 +71,7 @@ import { EditPolicyContextProvider } from './edit_policy_context'; export interface Props { policies: PolicyFromES[]; - policyName: string; + policyName?: string; getUrlForApp: ( appId: string, options?: { From 9acc687ef658c1cf79a7848b1992ca489951161a Mon Sep 17 00:00:00 2001 From: Yulia Cech Date: Tue, 3 Nov 2020 17:16:03 +0100 Subject: [PATCH 06/10] Fix type check issues --- .../component_template_details.tsx | 2 +- .../component_template_list/component_template_list.tsx | 6 +++--- .../component_template_clone/component_template_clone.tsx | 2 +- .../component_template_edit/component_template_edit.tsx | 2 +- .../sections/home/data_stream_list/data_stream_list.tsx | 2 +- .../sections/home/template_list/template_list.tsx | 2 +- .../application/sections/template_clone/template_clone.tsx | 2 +- .../application/sections/template_edit/template_edit.tsx | 2 +- .../sections/pipelines_clone/pipelines_clone.tsx | 2 +- .../application/sections/pipelines_edit/pipelines_edit.tsx | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx index 6d9aa58d6c86b..2fb16874cf943 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_details/component_template_details.tsx @@ -52,7 +52,7 @@ export const ComponentTemplateDetailsFlyoutContent: React.FunctionComponent { const { api } = useComponentTemplatesContext(); - const decodedComponentTemplateName = attemptToURIDecode(componentTemplateName); + const decodedComponentTemplateName = attemptToURIDecode(componentTemplateName)!; const { data: componentTemplateDetails, isLoading, error } = api.useLoadComponentTemplate( decodedComponentTemplateName diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx index 00ea3ebf794ee..e8424ae46c6d2 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_list/component_template_list.tsx @@ -84,7 +84,7 @@ export const ComponentTemplateList: React.FunctionComponent = ({ }), icon: 'pencil', handleActionClick: () => - goToEditComponentTemplate(attemptToURIDecode(componentTemplateName)), + goToEditComponentTemplate(attemptToURIDecode(componentTemplateName)!), }, { name: i18n.translate('xpack.idxMgmt.componentTemplateDetails.cloneActionLabel', { @@ -92,7 +92,7 @@ export const ComponentTemplateList: React.FunctionComponent = ({ }), icon: 'copy', handleActionClick: () => - goToCloneComponentTemplate(attemptToURIDecode(componentTemplateName)), + goToCloneComponentTemplate(attemptToURIDecode(componentTemplateName)!), }, { name: i18n.translate('xpack.idxMgmt.componentTemplateDetails.deleteButtonLabel', { @@ -103,7 +103,7 @@ export const ComponentTemplateList: React.FunctionComponent = ({ details._kbnMeta.usedBy.length > 0, closePopoverOnClick: true, handleActionClick: () => { - setComponentTemplatesToDelete([attemptToURIDecode(componentTemplateName)]); + setComponentTemplatesToDelete([attemptToURIDecode(componentTemplateName)!]); }, }, ]; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_clone/component_template_clone.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_clone/component_template_clone.tsx index 6c03fcf5d9972..e6b403543f4b0 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_clone/component_template_clone.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_clone/component_template_clone.tsx @@ -19,7 +19,7 @@ export interface Params { export const ComponentTemplateClone: FunctionComponent> = (props) => { const { sourceComponentTemplateName } = props.match.params; - const decodedSourceName = attemptToURIDecode(sourceComponentTemplateName); + const decodedSourceName = attemptToURIDecode(sourceComponentTemplateName)!; const { toasts, api } = useComponentTemplatesContext(); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_edit/component_template_edit.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_edit/component_template_edit.tsx index 934f86f7d7590..500c84a97d222 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_edit/component_template_edit.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_edit/component_template_edit.tsx @@ -31,7 +31,7 @@ export const ComponentTemplateEdit: React.FunctionComponent(false); const [saveError, setSaveError] = useState(null); - const decodedName = attemptToURIDecode(name); + const decodedName = attemptToURIDecode(name)!; const { error, data: componentTemplate, isLoading } = api.useLoadComponentTemplate(decodedName); diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_list.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_list.tsx index 19286523055f5..aaf5c5a933ca9 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_list.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_list.tsx @@ -232,7 +232,7 @@ export const DataStreamList: React.FunctionComponent { - const decodedTemplateName = attemptToURIDecode(name); + const decodedTemplateName = attemptToURIDecode(name)!; const isLegacy = getIsLegacyFromQueryParams(location); const [isSaving, setIsSaving] = useState(false); diff --git a/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx b/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx index 3e62f7f880f74..e3cb40b3a36e1 100644 --- a/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx +++ b/x-pack/plugins/index_management/public/application/sections/template_edit/template_edit.tsx @@ -27,7 +27,7 @@ export const TemplateEdit: React.FunctionComponent { - const decodedTemplateName = attemptToURIDecode(name); + const decodedTemplateName = attemptToURIDecode(name)!; const isLegacy = getIsLegacyFromQueryParams(location); const [isSaving, setIsSaving] = useState(false); diff --git a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_clone/pipelines_clone.tsx b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_clone/pipelines_clone.tsx index 9465117b6b589..df60907973156 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_clone/pipelines_clone.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_clone/pipelines_clone.tsx @@ -25,7 +25,7 @@ export const PipelinesClone: FunctionComponent> const { sourceName } = props.match.params; const { services } = useKibana(); - const decodedSourceName = attemptToURIDecode(sourceName); + const decodedSourceName = attemptToURIDecode(sourceName)!; const { error, data: pipeline, isLoading, isInitialRequest } = services.api.useLoadPipeline( decodedSourceName ); diff --git a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_edit/pipelines_edit.tsx b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_edit/pipelines_edit.tsx index 7e2e85ab23fb3..2b53fdb6a6375 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_edit/pipelines_edit.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/sections/pipelines_edit/pipelines_edit.tsx @@ -38,7 +38,7 @@ export const PipelinesEdit: React.FunctionComponent(false); const [saveError, setSaveError] = useState(null); - const decodedPipelineName = attemptToURIDecode(name); + const decodedPipelineName = attemptToURIDecode(name)!; const { error, data: pipeline, isLoading } = services.api.useLoadPipeline(decodedPipelineName); From 05459f2e18d7e61a3f62d05d6dcc4ab3bfe1ef63 Mon Sep 17 00:00:00 2001 From: Yulia Cech Date: Wed, 4 Nov 2020 12:25:55 +0100 Subject: [PATCH 07/10] Renamed dollar sign to percent sign, added a method for (double) encoded paths and better description in test names --- .../client_integration/app/app.helpers.tsx | 6 ++ .../client_integration/app/app.test.ts | 93 ++++++++++--------- 2 files changed, 53 insertions(+), 46 deletions(-) diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx index 8b54c408d1eb1..46548096cef01 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx @@ -53,3 +53,9 @@ export const setup = async (initialEntries: string[]): Promise => { actions: { clickPolicyNameLink, clickCreatePolicyButton }, }; }; + +export const getEncodedPolicyEditPath = (policyName: string): string => + `/policies/edit/${encodeURIComponent(policyName)}`; + +export const getDoubleEncodedPolicyEditPath = (policyName: string): string => + encodeURI(getEncodedPolicyEditPath(policyName)); diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts index b5e35f8ab2970..9052cf2847baa 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.test.ts @@ -4,17 +4,22 @@ * you may not use this file except in compliance with the Elastic License. */ -import { AppTestBed, setup } from './app.helpers'; +import { + AppTestBed, + getDoubleEncodedPolicyEditPath, + getEncodedPolicyEditPath, + setup, +} from './app.helpers'; import { setupEnvironment } from '../helpers/setup_environment'; import { getDefaultHotPhasePolicy, POLICY_NAME } from '../edit_policy/constants'; import { act } from 'react-dom/test-utils'; const SPECIAL_CHARS_NAME = 'test?#$+=&@:'; -const DOLLAR_SIGN_NAME = 'test%'; +const PERCENT_SIGN_NAME = 'test%'; // navigation doesn't work for % with other special chars or sequence %25 // known issue https://github.com/elastic/kibana/issues/82440 -const DOLLAR_SIGN_WITH_OTHER_CHARS_NAME = 'test%#'; -const DOLLAR_SIGN_25_SEQUENCE = 'test%25'; +const PERCENT_SIGN_WITH_OTHER_CHARS_NAME = 'test%#'; +const PERCENT_SIGN_25_SEQUENCE = 'test%25'; window.scrollTo = jest.fn(); @@ -64,7 +69,7 @@ describe('', () => { httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy(SPECIAL_CHARS_NAME)]); }); - test('when clicked on policy name in table', async () => { + test('clicking policy name in the table works', async () => { await act(async () => { testBed = await setup(['/']); }); @@ -80,9 +85,9 @@ describe('', () => { ); }); - test('when loading edit policy page url', async () => { + test('loading edit policy page url works', async () => { await act(async () => { - testBed = await setup([`/policies/edit/${encodeURIComponent(SPECIAL_CHARS_NAME)}`]); + testBed = await setup([getEncodedPolicyEditPath(SPECIAL_CHARS_NAME)]); }); const { component } = testBed; @@ -93,11 +98,11 @@ describe('', () => { ); }); - test('when loading edit policy page url with double encoding', async () => { + // using double encoding to counteract react-router's v5 internal decodeURI call + // when those links are open in a new tab, address bar contains double encoded url + test('loading edit policy page url with double encoding works', async () => { await act(async () => { - testBed = await setup([ - encodeURI(`/policies/edit/${encodeURIComponent(SPECIAL_CHARS_NAME)}`), - ]); + testBed = await setup([getDoubleEncodedPolicyEditPath(SPECIAL_CHARS_NAME)]); }); const { component } = testBed; @@ -109,48 +114,46 @@ describe('', () => { }); }); - describe('navigation with dollar sign', () => { + describe('navigation with percent sign', () => { beforeAll(async () => { - httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy(DOLLAR_SIGN_NAME)]); + httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy(PERCENT_SIGN_NAME)]); }); - test('when loading edit policy page url', async () => { + test('loading edit policy page url works', async () => { await act(async () => { - testBed = await setup([`/policies/edit/${encodeURIComponent(DOLLAR_SIGN_NAME)}`]); + testBed = await setup([getEncodedPolicyEditPath(PERCENT_SIGN_NAME)]); }); const { component } = testBed; component.update(); expect(testBed.find('policyTitle').text()).toBe( - `Edit index lifecycle policy ${DOLLAR_SIGN_NAME}` + `Edit index lifecycle policy ${PERCENT_SIGN_NAME}` ); }); - test('when loading edit policy page url with double encoding', async () => { + test('loading edit policy page url with double encoding works', async () => { await act(async () => { - testBed = await setup([ - encodeURI(`/policies/edit/${encodeURIComponent(DOLLAR_SIGN_NAME)}`), - ]); + testBed = await setup([getDoubleEncodedPolicyEditPath(PERCENT_SIGN_NAME)]); }); const { component } = testBed; component.update(); expect(testBed.find('policyTitle').text()).toBe( - `Edit index lifecycle policy ${DOLLAR_SIGN_NAME}` + `Edit index lifecycle policy ${PERCENT_SIGN_NAME}` ); }); }); - describe('navigation with dollar sign with other special characters', () => { + describe('navigation with percent sign with other special characters', () => { beforeAll(async () => { httpRequestsMockHelpers.setLoadPolicies([ - getDefaultHotPhasePolicy(DOLLAR_SIGN_WITH_OTHER_CHARS_NAME), + getDefaultHotPhasePolicy(PERCENT_SIGN_WITH_OTHER_CHARS_NAME), ]); }); - test('when clicked on policy name in table', async () => { + test('clicking policy name in the table works', async () => { await act(async () => { testBed = await setup(['/']); }); @@ -162,15 +165,13 @@ describe('', () => { component.update(); expect(testBed.find('policyTitle').text()).toBe( - `Edit index lifecycle policy ${DOLLAR_SIGN_WITH_OTHER_CHARS_NAME}` + `Edit index lifecycle policy ${PERCENT_SIGN_WITH_OTHER_CHARS_NAME}` ); }); - test('when loading edit policy page url', async () => { + test("loading edit policy page url doesn't work", async () => { await act(async () => { - testBed = await setup([ - `/policies/edit/${encodeURIComponent(DOLLAR_SIGN_WITH_OTHER_CHARS_NAME)}`, - ]); + testBed = await setup([getEncodedPolicyEditPath(PERCENT_SIGN_WITH_OTHER_CHARS_NAME)]); }); const { component } = testBed; @@ -178,32 +179,32 @@ describe('', () => { // known issue https://github.com/elastic/kibana/issues/82440 expect(testBed.find('policyTitle').text()).not.toBe( - `Edit index lifecycle policy ${DOLLAR_SIGN_WITH_OTHER_CHARS_NAME}` + `Edit index lifecycle policy ${PERCENT_SIGN_WITH_OTHER_CHARS_NAME}` ); }); - test('when loading edit policy page url with double encoding', async () => { + // using double encoding to counteract react-router's v5 internal decodeURI call + // when those links are open in a new tab, address bar contains double encoded url + test('loading edit policy page url with double encoding works', async () => { await act(async () => { - testBed = await setup([ - encodeURI(`/policies/edit/${encodeURIComponent(DOLLAR_SIGN_WITH_OTHER_CHARS_NAME)}`), - ]); + testBed = await setup([getDoubleEncodedPolicyEditPath(PERCENT_SIGN_WITH_OTHER_CHARS_NAME)]); }); const { component } = testBed; component.update(); expect(testBed.find('policyTitle').text()).toBe( - `Edit index lifecycle policy ${DOLLAR_SIGN_WITH_OTHER_CHARS_NAME}` + `Edit index lifecycle policy ${PERCENT_SIGN_WITH_OTHER_CHARS_NAME}` ); }); }); describe('navigation with %25 sequence', () => { beforeAll(async () => { - httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy(DOLLAR_SIGN_25_SEQUENCE)]); + httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy(PERCENT_SIGN_25_SEQUENCE)]); }); - test('when clicked on policy name in table', async () => { + test('clicking policy name in the table works correctly', async () => { await act(async () => { testBed = await setup(['/']); }); @@ -215,13 +216,13 @@ describe('', () => { component.update(); expect(testBed.find('policyTitle').text()).toBe( - `Edit index lifecycle policy ${DOLLAR_SIGN_25_SEQUENCE}` + `Edit index lifecycle policy ${PERCENT_SIGN_25_SEQUENCE}` ); }); - test('when loading edit policy page url', async () => { + test("loading edit policy page url doesn't work", async () => { await act(async () => { - testBed = await setup([`/policies/edit/${encodeURIComponent(DOLLAR_SIGN_25_SEQUENCE)}`]); + testBed = await setup([getEncodedPolicyEditPath(PERCENT_SIGN_25_SEQUENCE)]); }); const { component } = testBed; @@ -229,22 +230,22 @@ describe('', () => { // known issue https://github.com/elastic/kibana/issues/82440 expect(testBed.find('policyTitle').text()).not.toBe( - `Edit index lifecycle policy ${DOLLAR_SIGN_25_SEQUENCE}` + `Edit index lifecycle policy ${PERCENT_SIGN_25_SEQUENCE}` ); }); - test('when loading edit policy page url with double encoding', async () => { + // using double encoding to counteract react-router's v5 internal decodeURI call + // when those links are open in a new tab, address bar contains double encoded url + test('loading edit policy page url with double encoding works', async () => { await act(async () => { - testBed = await setup([ - encodeURI(`/policies/edit/${encodeURIComponent(DOLLAR_SIGN_25_SEQUENCE)}`), - ]); + testBed = await setup([getDoubleEncodedPolicyEditPath(PERCENT_SIGN_25_SEQUENCE)]); }); const { component } = testBed; component.update(); expect(testBed.find('policyTitle').text()).toBe( - `Edit index lifecycle policy ${DOLLAR_SIGN_25_SEQUENCE}` + `Edit index lifecycle policy ${PERCENT_SIGN_25_SEQUENCE}` ); }); }); From 5a735dfe95dcce5c8165eb225d80f3d3e44f05a1 Mon Sep 17 00:00:00 2001 From: Yulia Cech Date: Mon, 9 Nov 2020 15:28:09 +0100 Subject: [PATCH 08/10] Deleted Index Management from required bundles in ILM --- x-pack/plugins/index_lifecycle_management/kibana.json | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/index_lifecycle_management/kibana.json b/x-pack/plugins/index_lifecycle_management/kibana.json index 21e7e7888acb9..90290738e8827 100644 --- a/x-pack/plugins/index_lifecycle_management/kibana.json +++ b/x-pack/plugins/index_lifecycle_management/kibana.json @@ -17,7 +17,6 @@ ], "configPath": ["xpack", "ilm"], "requiredBundles": [ - "indexManagement", "kibanaReact", "esUiShared", "home" From a0a4aafd9415444885ea10090e843da9fcbdf2dd Mon Sep 17 00:00:00 2001 From: Yulia Cech Date: Mon, 9 Nov 2020 17:37:10 +0100 Subject: [PATCH 09/10] Fixed merge conflicts --- .../client_integration/app/app.helpers.tsx | 15 ++++++++++++- .../edit_policy/constants.ts | 7 ++++-- .../edit_policy/edit_policy.test.ts | 2 +- .../public/application/app.tsx | 22 +++++++++---------- .../public/application/index.tsx | 6 ++++- .../edit_policy/edit_policy.container.tsx | 2 +- .../data_stream_list/data_stream_list.tsx | 2 +- 7 files changed, 38 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx index 46548096cef01..de7242a6c5ddf 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/app/app.helpers.tsx @@ -4,10 +4,23 @@ * you may not use this file except in compliance with the Elastic License. */ +import React from 'react'; import { act } from 'react-dom/test-utils'; import { registerTestBed, TestBed, TestBedConfig } from '../../../../../test_utils'; import { App } from '../../../public/application/app'; import { TestSubjects } from '../helpers'; +import { createBreadcrumbsMock } from '../../../public/application/services/breadcrumbs.mock'; +import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public/context'; + +const breadcrumbService = createBreadcrumbsMock(); + +const AppWithContext = (props: any) => { + return ( + + + + ); +}; const getTestBedConfig = (initialEntries: string[]): TestBedConfig => ({ memoryRouter: { @@ -20,7 +33,7 @@ const getTestBedConfig = (initialEntries: string[]): TestBedConfig => ({ }); const initTestBed = (initialEntries: string[]) => - registerTestBed(App, getTestBedConfig(initialEntries))(); + registerTestBed(AppWithContext, getTestBedConfig(initialEntries))(); export interface AppTestBed extends TestBed { actions: { diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts index f675ef2349e34..00c7d705c1f44 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/constants.ts @@ -128,9 +128,12 @@ export const getDefaultHotPhasePolicy = (policyName: string): PolicyFromES => ({ name: policyName, phases: { hot: { - min_age: '123ms', + min_age: '0ms', actions: { - rollover: {}, + rollover: { + max_age: '30d', + max_size: '50gb', + }, }, }, }, diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts index 1b11c2e8f0166..c91ee3e2a1c06 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts @@ -34,7 +34,7 @@ describe('', () => { describe('hot phase', () => { describe('serialization', () => { beforeEach(async () => { - httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy('test')]); + httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy('my_policy')]); httpRequestsMockHelpers.setLoadSnapshotPolicies([]); await act(async () => { diff --git a/x-pack/plugins/index_lifecycle_management/public/application/app.tsx b/x-pack/plugins/index_lifecycle_management/public/application/app.tsx index e3ec212f0afa0..20185b02064bc 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/app.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/app.tsx @@ -40,16 +40,16 @@ export const App = ({ return ( - - } - /> - } - /> - + + } + /> + } + /> + ); }; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/index.tsx b/x-pack/plugins/index_lifecycle_management/public/application/index.tsx index e3b877973684d..bb1a4810ba2d2 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/index.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/index.tsx @@ -28,7 +28,11 @@ export const renderApp = ( render( - + , element diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx index e52ad58746a20..4c0cc2c8957e1 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx @@ -90,7 +90,7 @@ export const EditPolicy: React.FunctionComponent { history.push(`/${Section.DataStreams}`); From ab1c1d91602da7c4e6b4deab807fba34092dc6fc Mon Sep 17 00:00:00 2001 From: Yulia Cech Date: Mon, 9 Nov 2020 17:53:06 +0100 Subject: [PATCH 10/10] Revert "Deleted Index Management from required bundles in ILM" This reverts commit 5a735dfe --- x-pack/plugins/index_lifecycle_management/kibana.json | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/index_lifecycle_management/kibana.json b/x-pack/plugins/index_lifecycle_management/kibana.json index 90290738e8827..21e7e7888acb9 100644 --- a/x-pack/plugins/index_lifecycle_management/kibana.json +++ b/x-pack/plugins/index_lifecycle_management/kibana.json @@ -17,6 +17,7 @@ ], "configPath": ["xpack", "ilm"], "requiredBundles": [ + "indexManagement", "kibanaReact", "esUiShared", "home"