Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Endpoint] Policy list support for URL pagination state #63291

Merged

Conversation

paul-tavares
Copy link
Contributor

Summary

Drive pagination for the Policy List (page index + page size) via URL search params (page_index=1&page_size=10). This enables a user to click the browser back/forward buttons and be shown the correct set of data on the Policy list view.

This PR also includes a Redux "spy" middleware test utility to avoid having to use setTimeout based sleeps in Unit Test cases. With this in place:

🤞

Checklist

Delete any items that are not applicable to this PR.

@paul-tavares paul-tavares added v8.0.0 release_note:skip Skip the PR/issue when compiling release notes Team:Endpoint Management Feature:Endpoint Elastic Endpoint feature v7.8.0 labels Apr 10, 2020
@paul-tavares paul-tavares requested a review from a team as a code owner April 10, 2020 21:01
@paul-tavares paul-tavares self-assigned this Apr 10, 2020
@elasticmachine
Copy link
Contributor

Pinging @elastic/endpoint-management (Team:Endpoint Management)

@elasticmachine
Copy link
Contributor

Pinging @elastic/endpoint-app-team (Feature:Endpoint)

* // do assertion
* });
*/
export const createSpyMiddleware = <S = GlobalState>(): MiddlewareActionSpyHelper<S> => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@parkiino , @kevinlog , @oatkiller , @peluja1012 , @dplumlee , @bkimmel , @kqualters-elastic - FYI. If you find that you have the same need for this type of utility while creating test cases for middleware or views that trigger middleware, we can elevate this utility to be in a higher level folder and re-use it. Its currently built in a generic way, so it should adopt to other middleware testing cases.

@oatkiller - I'm going to try to jest.fn() on the middleware idea next. Did not include it here because I did not have a need currently for it. 😃

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI - I made the middleware dispatch function a jest mocked function and exposed its mock object via the dispatchSpy property in the returned object.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is greatttt

const timeout = setTimeout(() => {
watchers.delete(watch);
reject(err);
}, 4500);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it ever make sense to make this timeout configurable? Not necessary now, but wondering if we would ever adjust jest's default.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, for sure the createSpyMiddleware factory can be improved in the future to take in the timeout. I actually looked to see if there was a way to access Jest's timeout value at runtime so that I could use it, but was not able to find it (there is one to set it, but not retrieve it).

…st-url-pagination-redo

# Conflicts:
#	x-pack/plugins/endpoint/public/applications/endpoint/store/policy_list/middleware.ts
#	x-pack/plugins/endpoint/public/applications/endpoint/store/routing/action.ts
#	x-pack/plugins/endpoint/public/applications/endpoint/view/use_page_id.ts
@paul-tavares
Copy link
Contributor Author

jenkins test this

return state.location?.pathname === '/policy';
};

export const routeLocation = (state: PolicyListState) => state.location;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could drop export if you'd like

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. I will remove it in next commit

*
* @param actionType
*/
waitForAction: (actionType: Pick<AppAction, 'type'>['type']) => Promise<void>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should be able to write AppAction['type'] here and get the same behavior

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks. Will simplify it. (not sure why I decided to go the long/hard way on this one).

* Also - do not hold on to references to this property value if `jest.clearAllMocks()` or
* `jest.resetAllMocks()` is called between usages of the value.
*/
dispatchSpy: jest.Mock<Dispatch<AppAction>>['mock'];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this isn't always set, maybe make the property dispatchSpy? instead? that way we'll check for validity before using it (and hopefully avoid an error.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, thats another alternative. But would that be a worst developer experience? It would imply that we would need to either check the property every time we try to use it (utils!.dispatchSpy) or in destructing it, like dispatchSpy = utils!.dispatchUtils which could lead to an error if done prior to store creation.


actionSpyMiddleware: api => {
return next => {
spyDispatch = jest.fn(action => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you create jest.fn where it is defined and here do

spyDispatch.mockImplementation(action => {
  // ...
})

would that allow you to remove the comment about an error occurring if you access the mock calls out of sequence?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was my initial thought (in order to avoid the check in the dispatchSpy property getter), but dispatch needs access to next() thus it needs to be defined within this context.

spyDispatch = jest.fn(action => {
next(action);
// If we have action watchers, then loop through them and call them with this action
if (watchers.size > 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would this work the same if you didn't have if (watchers.size > 0)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh - good point. I'll remove the condition and have only the for loop

watch(action);
}
}
return action;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you using this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not using it, but needed to satisfy the type defined by jest.Mock<>. Without it, I got type errors

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@paul-tavares paul-tavares merged commit 48fd5c0 into elastic:master Apr 13, 2020
@paul-tavares paul-tavares deleted the EMT-182-policy-list-url-pagination-redo branch April 13, 2020 20:26
paul-tavares added a commit that referenced this pull request Apr 13, 2020
)

* store changes to support pagination via url

* Fix storing location when pagination happens

* Initial set of tests

* Redux spy middleware and async utility

* Add better types to `waitForAction`

* Add more docs

* fix urlSearchParams selector to account for array of values

* full set of tests for policy list store concerns

* More efficient redux spy middleware (no more sleep())

* Set spy middleware `dispatch` to a `jest.fn` and expose `mock` info.

* Fix url param selector to return first param value when it is defined multiple times

* Removed PageId and associated hook

* clean up TODO items

* Fixes post-merge frm `master`

* Address code review comments
gmmorris added a commit to gmmorris/kibana that referenced this pull request Apr 14, 2020
* master: (132 commits)
  document code splitting for client code (elastic#62593)
  Escape single quotes surrounded by double quotes (elastic#63229)
  [Endpoint] Update cli mapping to match endpoint package (elastic#63372)
  update in-app links to metricbeat configuration docs (elastic#63295)
  investigation notes field (documentation / metadata) (elastic#63386)
  [Maps] fix bug where toggling Scaling type does not re-fetch data (elastic#63326)
  [Alerting] set correct parameter for unauthented email action (elastic#63086)
  [Telemetry] force staging urls in tests (elastic#63356)
  Migrate legacy maps service to NP & update refs (elastic#60942)
  Fix task manager query to return tasks to retry (elastic#63360)
  [Endpoint] Policy list support for URL pagination state (elastic#63291)
  [Canvas] Migrate saved object mappings and migrations to Kibana Platform (elastic#58891)
  [DOCS] Add ILM tutorial (elastic#59502)
  [Maps] Add SOURCE_TYPES enumeration (elastic#62975)
  [Maps] update geospatial filters to use geo_shape query for geo_point fields (elastic#62966)
  Move away from npStart for embeddables in canvas (elastic#62680)
  Use MapInput type from Maps plugin (elastic#61539)
  Update to pagination for workpad and templates (elastic#62050)
  [SIEM] Fix AlertsTable id (elastic#63368)
  Consistent terminology around cypress test data (elastic#63279)
  ...
gmmorris added a commit to gmmorris/kibana that referenced this pull request Apr 14, 2020
* master:
  document code splitting for client code (elastic#62593)
  Escape single quotes surrounded by double quotes (elastic#63229)
  [Endpoint] Update cli mapping to match endpoint package (elastic#63372)
  update in-app links to metricbeat configuration docs (elastic#63295)
  investigation notes field (documentation / metadata) (elastic#63386)
  [Maps] fix bug where toggling Scaling type does not re-fetch data (elastic#63326)
  [Alerting] set correct parameter for unauthented email action (elastic#63086)
  [Telemetry] force staging urls in tests (elastic#63356)
  Migrate legacy maps service to NP & update refs (elastic#60942)
  Fix task manager query to return tasks to retry (elastic#63360)
  [Endpoint] Policy list support for URL pagination state (elastic#63291)
  [Canvas] Migrate saved object mappings and migrations to Kibana Platform (elastic#58891)
  [DOCS] Add ILM tutorial (elastic#59502)
  [Maps] Add SOURCE_TYPES enumeration (elastic#62975)
  [Maps] update geospatial filters to use geo_shape query for geo_point fields (elastic#62966)
  Move away from npStart for embeddables in canvas (elastic#62680)
wayneseymour pushed a commit that referenced this pull request Apr 15, 2020
* store changes to support pagination via url

* Fix storing location when pagination happens

* Initial set of tests

* Redux spy middleware and async utility

* Add better types to `waitForAction`

* Add more docs

* fix urlSearchParams selector to account for array of values

* full set of tests for policy list store concerns

* More efficient redux spy middleware (no more sleep())

* Set spy middleware `dispatch` to a `jest.fn` and expose `mock` info.

* Fix url param selector to return first param value when it is defined multiple times

* Removed PageId and associated hook

* clean up TODO items

* Fixes post-merge frm `master`

* Address code review comments
@aisantos
Copy link

Regressed test cases for url pagination state for Policy List:

  • Policy List displays displays default page_index and page_size when no url params T5737
  • Policy List display correct page when using url params directly T5739
  • Policy List url params accepts only positive numbers for page_index and page_size T5740
  • Policy List url params accepts only a value of 10, 20 or 50 for page_size T5741
  • Policy List url params ignores unknown search params T5472
  • Policy List url params uses only last param value if multiple values are present T5473
  • Policy List url params uses defaults for any missing search params T5744
  • Policy List url params uses an invalid page_index value T5916
  • Policy List url params has a page_index with a value that is more than total pagination T5917

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment