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

Migrate base path APIs and UiSettings client to new platform #22694

Merged

Conversation

spalger
Copy link
Contributor

@spalger spalger commented Sep 4, 2018

Fixes #20697

This PR migrates the base path related methods from ui/chrome to core.basePath and the uiSettings to core.uiSettings. The two are not split into separate PRs because I'm kinda cramped for time right now so rather I split the changes up into two commits so that you can review them separately if you like. If you'd like I can submit them as separate PRs but the basePath PR will block the uiSettings PR either way.

There shouldn't be any API changes except one thing, since the existing implementation is so close to what we'd want from the new platform API I made the one change that is inconsistent with what we've been doing so far and moved uiSettings.subscribe() to uiSettings.getUpdate$().subscribe(). This method isn't super commonly used, but it is a breaking change that will likely impact plugins so I'll notify some folks if we decide to move forward this way. I can also make a super-light wrapper for angular that just updates this method if you prefer.

@spalger spalger added Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc Feature:New Platform v7.0.0 v6.5.0 labels Sep 4, 2018
@epixa
Copy link
Contributor

epixa commented Sep 4, 2018

I did a high level review of the code in the base path commit, and it looks pretty good. The modifyUrl code seemed to be the only thing that wasn't completely straightforward, but I figured out that was actually pulled from the legacy world, so it works for me. The code itself wasn't bad or anything, but if it was all net new, I'd want to question some of the decisions with it (e.g. "why standardize on this property instead of that one?"), but that seems beyond the scope of this PR. In the end, that code is working well in production and everyone is fine with the API mechanics, which this PR doesn't change.

@elasticmachine
Copy link
Contributor

💔 Build Failed

@spalger spalger force-pushed the migrate-new-platform/ui-settings-client branch from 23ed10e to df345e1 Compare September 5, 2018 19:36
* under the License.
*/

function mockClass<T>(
Copy link
Contributor Author

@spalger spalger Sep 5, 2018

Choose a reason for hiding this comment

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

@azasypkin Tried making a helper for mocking classes again, and this time I really like how it turned out. Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Paid a little extra attention to make it serialize in snapshots nicely too: https://github.com/elastic/kibana/pull/22694/files#diff-de8d63302459e4f07e8b9f006649574fR17

Copy link
Member

Choose a reason for hiding this comment

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

I like it! We can probably move it to some shared test tools/utils and use it in other tests from now on. Just two things:

  • I can't think of any real use case right now, but it may happen that file/module exports both class and something else that we'd like to mock and we won't be able to use mockClass for that or I'm wrong?

  • Wondering if we can use jest-mock's generateMetadata and generateFromMetadata to mock all class methods at once and then set behavior/return values in setup function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cool, I'll follow up with something like that if/when I need this util again and will investigate how we can support modules with more exports. I've tried using the autoMocks before but found them to be really mysterious and the docs didn't really help me understand what was going on... not opposed to them, but since I've struggled to figure them out til this point I worry they might make the tests harder to understand... but really just don't know.

@spalger spalger force-pushed the migrate-new-platform/ui-settings-client branch from b5eb2eb to 05d9b8e Compare September 5, 2018 20:01
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@spalger spalger requested a review from azasypkin September 5, 2018 22:20
@azasypkin
Copy link
Member

ack: started to look into PR already, will try to finish today, tomorrow is more realistic though.

@legrego
Copy link
Member

legrego commented Sep 6, 2018

@spalger -- I didn't see anything jump out at me in this PR, but the title scared me, so I'm here to ask if this will have any impact on the base path work that Spaces is built on? Specifically, we moved the basePath determination from just using server.basePath to a combination of server.basePath, and the space identifier, which is determined at the request level.

Our implementation is essentially stolen from your previous work on Spaces (thanks!): https://github.com/elastic/kibana/pull/18664/files

@spalger
Copy link
Contributor Author

spalger commented Sep 6, 2018

@legrego This won't have any impact on the server-side handling of base path, it just exposes the basePath information that is currently being injected into the UI via the new platform which is then injected into ui/chrome/apis/base_path to power the existing APIs. It's mostly just shifting around how we expose the basePath client-side without changing anything about the way it's derived. As long as the spaces changes update this then everything should work nicely

@elasticmachine

This comment has been minimized.

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

spalger pushed a commit to spalger/kibana that referenced this pull request Sep 7, 2018
Copy link
Member

@azasypkin azasypkin left a comment

Choose a reason for hiding this comment

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

Looks great, I haven't noticed anything suspicious while testing locally. Left a bunch of questions and minor nits, but nothing that would block this PR.

},

getKibanaVersion: () => {
return this.getKibanaVersion();
Copy link
Member

Choose a reason for hiding this comment

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

note: haha, my IDE mistakenly marks this as a recursive call :)

src/core/public/base_path/base_path_service.ts Outdated Show resolved Hide resolved
src/core/public/utils/modify_url.ts Outdated Show resolved Hide resolved
src/core/public/utils/modify_url.ts Outdated Show resolved Hide resolved
src/core/public/utils/modify_url.ts Outdated Show resolved Hide resolved
}

/**
* Prepares the uiSettingsClient to be discarded, completing any update$ observerables
Copy link
Member

Choose a reason for hiding this comment

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

typo: observables

const declared = this.isDeclared(key);
const defaults = this.defaults;

const oldVal = declared ? this.cache[key].userValue : undefined;
Copy link
Member

Choose a reason for hiding this comment

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

question: do you have any clue why we needed this before?

const newVal = key in defaults && defaults[key].defaultValue === value
      ? null
      : value;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We didn't, I checked the code since it was first introduced and best I can tell defaults[key].defaultValue was never actually defined, so I just got rid of it.

expect(start).toBeInstanceOf(MockUiSettingsClient);
});

it('contstructs UiSettingsClient and UiSettingsApi', () => {
Copy link
Member

Choose a reason for hiding this comment

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

typo: constructs.

* under the License.
*/

function mockClass<T>(
Copy link
Member

Choose a reason for hiding this comment

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

I like it! We can probably move it to some shared test tools/utils and use it in other tests from now on. Just two things:

  • I can't think of any real use case right now, but it may happen that file/module exports both class and something else that we'd like to mock and we won't be able to use mockClass for that or I'm wrong?

  • Wondering if we can use jest-mock's generateMetadata and generateFromMetadata to mock all class methods at once and then set behavior/return values in setup function.

*/

// properties that come from legacyInjectedMetadata.uiSettings.defaults
interface InjectedUiSettingsDefault {
Copy link
Member

Choose a reason for hiding this comment

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

question: where did you get these "schemas" from?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They're really just snapshots of what we get based on what's in the uiExports today. They can absolutely go out of date because they really aren't validated or enforced anywhere, which I plan to fix in #22779

@elasticmachine
Copy link
Contributor

💔 Build Failed

spalger pushed a commit that referenced this pull request Sep 8, 2018
I'd really like to upgrade to Typescript 3 for its `unknown` type, but we need to upgrade to `jest@23` to support a recent version of `ts-jest@23`. 

The [jest changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md) breaks down the breaking changes in 23.x, but I found it to be slightly incomplete so I've broken down the changes that actually caused breaks for us here, and addressed each in individual commits to make review a little easier:

- the `testURL` config default was changed from `about:blank` to `http://localhost`
    - this cause some XHR requests powered by JSdom to start failing. It seems these requests just do nothing in master but start to fail when JSdom is initialized with an actual URL... I think we would ideally stop sending meaningless XHR requests in the tests, but it was a lot easier to just set the config to `about:blank` for now, and we can worry about cleanup later if necessary
- `expect(...).toThrow()` only passes if an actual error was thrown.
     - In two places in the index pattern code we were throwing strings, which broke the assertions. Fortunately/Unfortunately the errors are not being consumed by anything, so I was able to wrap them in `new Error()` without causing any issues.
- snapshots of mock functions now include a `results` array, detailing the return values of the function
- React fragments are now serialized as `<React.Fragment>` instead of `<UNDEFINED>`
- undefined props in React components are now stripped from snapshots
- minor changes to the ordering of mocks, imports resolution, and before hooks caused the uiSettings API tests to start breaking, but I'm replacing them with totally new tests in #22694 so I just deleted them here
- mocks created with `jest.spyOn()` that are restored now have their `mock.calls` reset, so some of the kbn-pm tests stated failing. This was fixed by restoring them with `jest.restoreAllMocks()` rather than trying to do it before the assertions
spalger pushed a commit to spalger/kibana that referenced this pull request Sep 8, 2018
I'd really like to upgrade to Typescript 3 for its `unknown` type, but we need to upgrade to `jest@23` to support a recent version of `ts-jest@23`.

The [jest changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md) breaks down the breaking changes in 23.x, but I found it to be slightly incomplete so I've broken down the changes that actually caused breaks for us here, and addressed each in individual commits to make review a little easier:

- the `testURL` config default was changed from `about:blank` to `http://localhost`
    - this cause some XHR requests powered by JSdom to start failing. It seems these requests just do nothing in master but start to fail when JSdom is initialized with an actual URL... I think we would ideally stop sending meaningless XHR requests in the tests, but it was a lot easier to just set the config to `about:blank` for now, and we can worry about cleanup later if necessary
- `expect(...).toThrow()` only passes if an actual error was thrown.
     - In two places in the index pattern code we were throwing strings, which broke the assertions. Fortunately/Unfortunately the errors are not being consumed by anything, so I was able to wrap them in `new Error()` without causing any issues.
- snapshots of mock functions now include a `results` array, detailing the return values of the function
- React fragments are now serialized as `<React.Fragment>` instead of `<UNDEFINED>`
- undefined props in React components are now stripped from snapshots
- minor changes to the ordering of mocks, imports resolution, and before hooks caused the uiSettings API tests to start breaking, but I'm replacing them with totally new tests in elastic#22694 so I just deleted them here
- mocks created with `jest.spyOn()` that are restored now have their `mock.calls` reset, so some of the kbn-pm tests stated failing. This was fixed by restoring them with `jest.restoreAllMocks()` rather than trying to do it before the assertions
spalger pushed a commit that referenced this pull request Sep 8, 2018
I'd really like to upgrade to Typescript 3 for its `unknown` type, but we need to upgrade to `jest@23` to support a recent version of `ts-jest@23`.

The [jest changelog](https://github.com/facebook/jest/blob/master/CHANGELOG.md) breaks down the breaking changes in 23.x, but I found it to be slightly incomplete so I've broken down the changes that actually caused breaks for us here, and addressed each in individual commits to make review a little easier:

- the `testURL` config default was changed from `about:blank` to `http://localhost`
    - this cause some XHR requests powered by JSdom to start failing. It seems these requests just do nothing in master but start to fail when JSdom is initialized with an actual URL... I think we would ideally stop sending meaningless XHR requests in the tests, but it was a lot easier to just set the config to `about:blank` for now, and we can worry about cleanup later if necessary
- `expect(...).toThrow()` only passes if an actual error was thrown.
     - In two places in the index pattern code we were throwing strings, which broke the assertions. Fortunately/Unfortunately the errors are not being consumed by anything, so I was able to wrap them in `new Error()` without causing any issues.
- snapshots of mock functions now include a `results` array, detailing the return values of the function
- React fragments are now serialized as `<React.Fragment>` instead of `<UNDEFINED>`
- undefined props in React components are now stripped from snapshots
- minor changes to the ordering of mocks, imports resolution, and before hooks caused the uiSettings API tests to start breaking, but I'm replacing them with totally new tests in #22694 so I just deleted them here
- mocks created with `jest.spyOn()` that are restored now have their `mock.calls` reset, so some of the kbn-pm tests stated failing. This was fixed by restoring them with `jest.restoreAllMocks()` rather than trying to do it before the assertions
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@spalger spalger merged commit 52060b8 into elastic:master Sep 8, 2018
spalger pushed a commit to spalger/kibana that referenced this pull request Sep 8, 2018
…#22694)

Fixes elastic#20697

This PR migrates the base path related methods from `ui/chrome` to `core.basePath` and the uiSettings to `core.uiSettings`. The two are not split into separate PRs because I'm kinda cramped for time right now so rather I split the changes up into two commits so that you can review them separately if you like. If you'd like I can submit them as separate PRs but the basePath PR will block the uiSettings PR either way.

There shouldn't be any API changes except one thing, since the existing implementation is so close to what we'd want from the new platform API I made the one change that is inconsistent with what we've been doing so far and moved `uiSettings.subscribe()` to `uiSettings.getUpdate$().subscribe()`. This method isn't super commonly used, but it is a breaking change that will likely impact plugins so I'll notify some folks if we decide to move forward this way. I can also make a super-light wrapper for angular that just updates this method if you prefer.
spalger pushed a commit that referenced this pull request Sep 8, 2018
…22694) (#22848)

Backports the following commits to 6.x:
 - Migrate base path APIs and UiSettings client to new platform  (#22694)
@spalger
Copy link
Contributor Author

spalger commented Sep 8, 2018

6.x/6.5: 0161da8

@spalger spalger deleted the migrate-new-platform/ui-settings-client branch September 8, 2018 10:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:New Platform Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v6.5.0 v7.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[new-platform] migrate UiSettings client to new platform
5 participants