forked from elastic/kibana
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Resolver] Stale query string values are removed when resolver's comp…
…onent instance ID changes. (elastic#74979) The app can show more than 1 Resolver at a time. Each instance has a unique ID called the `resolverComponentInstanceID`. When the user interacts with Resolver it will add values to the query string. The query string values will contain the `resolverComponentInstanceID`. This allows each Resolver to keep its state separate. When resolver unmounts it will remove any query string values related to it. If Resolver's `resolverComponentInstanceID` changes it should remove query string values related to the old instance ID. It does not. This PR fixes that. Note: I don't know if it was possible for this bug to actually happen. I can't make it happen, but depending on how Resolver is mounted by its consumers it *could*
- Loading branch information
Robert Austin
committed
Aug 14, 2020
1 parent
603292c
commit 2e52612
Showing
8 changed files
with
220 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
x-pack/plugins/security_solution/public/resolver/view/query_params.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* 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 { noAncestorsTwoChildren } from '../data_access_layer/mocks/no_ancestors_two_children'; | ||
import { Simulator } from '../test_utilities/simulator'; | ||
// Extend jest with a custom matcher | ||
import '../test_utilities/extend_jest'; | ||
import { urlSearch } from '../test_utilities/url_search'; | ||
|
||
let simulator: Simulator; | ||
let databaseDocumentID: string; | ||
let entityIDs: { origin: string; firstChild: string; secondChild: string }; | ||
|
||
// the resolver component instance ID, used by the react code to distinguish piece of global state from those used by other resolver instances | ||
const resolverComponentInstanceID = 'oldID'; | ||
|
||
describe('Resolver, when analyzing a tree that has no ancestors and 2 children', () => { | ||
beforeEach(async () => { | ||
// create a mock data access layer | ||
const { metadata: dataAccessLayerMetadata, dataAccessLayer } = noAncestorsTwoChildren(); | ||
|
||
// save a reference to the entity IDs exposed by the mock data layer | ||
entityIDs = dataAccessLayerMetadata.entityIDs; | ||
|
||
// save a reference to the `_id` supported by the mock data layer | ||
databaseDocumentID = dataAccessLayerMetadata.databaseDocumentID; | ||
|
||
// create a resolver simulator, using the data access layer and an arbitrary component instance ID | ||
simulator = new Simulator({ databaseDocumentID, dataAccessLayer, resolverComponentInstanceID }); | ||
}); | ||
|
||
describe("when the second child node's first button has been clicked", () => { | ||
beforeEach(async () => { | ||
const node = await simulator.resolveWrapper(() => | ||
simulator.processNodeElements({ entityID: entityIDs.secondChild }).find('button') | ||
); | ||
if (node) { | ||
// Click the first button under the second child element. | ||
node.first().simulate('click'); | ||
} | ||
}); | ||
const expectedSearch = urlSearch(resolverComponentInstanceID, { | ||
selectedEntityID: 'secondChild', | ||
}); | ||
it(`should have a url search of ${expectedSearch}`, async () => { | ||
await expect(simulator.map(() => simulator.historyLocationSearch)).toYieldEqualTo( | ||
urlSearch(resolverComponentInstanceID, { selectedEntityID: 'secondChild' }) | ||
); | ||
}); | ||
describe('when the resolver component gets unmounted', () => { | ||
beforeEach(() => { | ||
simulator.unmount(); | ||
}); | ||
it('should have a history location search of `""`', async () => { | ||
await expect(simulator.map(() => simulator.historyLocationSearch)).toYieldEqualTo(''); | ||
}); | ||
}); | ||
describe('when the resolver component has its component instance ID changed', () => { | ||
const newInstanceID = 'newID'; | ||
beforeEach(() => { | ||
simulator.resolverComponentInstanceID = newInstanceID; | ||
}); | ||
it('should have a history location search of `""`', async () => { | ||
await expect(simulator.map(() => simulator.historyLocationSearch)).toYieldEqualTo(''); | ||
}); | ||
describe("when the user clicks the second child node's button again", () => { | ||
beforeEach(async () => { | ||
const node = await simulator.resolveWrapper(() => | ||
simulator.processNodeElements({ entityID: entityIDs.secondChild }).find('button') | ||
); | ||
if (node) { | ||
// Click the first button under the second child element. | ||
node.first().simulate('click'); | ||
} | ||
}); | ||
it(`should have a url search of ${urlSearch(newInstanceID, { | ||
selectedEntityID: 'secondChild', | ||
})}`, async () => { | ||
await expect(simulator.map(() => simulator.historyLocationSearch)).toYieldEqualTo( | ||
urlSearch(newInstanceID, { selectedEntityID: 'secondChild' }) | ||
); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
x-pack/plugins/security_solution/public/resolver/view/use_query_string_keys.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* | ||
* 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 { useSelector } from 'react-redux'; | ||
import * as selectors from '../store/selectors'; | ||
|
||
/** | ||
* Get the query string keys used by this Resolver instance. | ||
*/ | ||
export function useQueryStringKeys(): { idKey: string; eventKey: string } { | ||
const resolverComponentInstanceID = useSelector(selectors.resolverComponentInstanceID); | ||
const idKey: string = `resolver-${resolverComponentInstanceID}-id`; | ||
const eventKey: string = `resolver-${resolverComponentInstanceID}-event`; | ||
return { | ||
idKey, | ||
eventKey, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.