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 SO management libs to typescript #60555

Merged

Conversation

pgayvallet
Copy link
Contributor

@pgayvallet pgayvallet commented Mar 18, 2020

Summary

Part of #50308

'low effort' straightforward migration of the src/legacy/core_plugins/kibana/public/management/sections/objects/lib code base to typescript

PR's goal is to ease the diff of the next PR(s) by pre-migrating the management lib functions to TS. Behavior and implementation remains unchanged.

Did only minimal adaptation of the tests and did not add any, as we will wait to migrate the libs to NP apis before doing so.

Checklist

@pgayvallet pgayvallet added Feature:New Platform release_note:skip Skip the PR/issue when compiling release notes Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.7.0 v8.0.0 labels Mar 18, 2020
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-platform (Team:Platform)

@pgayvallet pgayvallet marked this pull request as ready for review March 19, 2020 08:07
@pgayvallet pgayvallet requested a review from a team as a code owner March 19, 2020 08:07
const $http = jest.fn();
const $http = jest.fn() as any;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

$http a callable class. Too difficult to properly type even with jest utilities. This is going to be removed anyway when migrating to NP apis

Copy link
Contributor

Choose a reason for hiding this comment

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

Is this file going to be removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

not the file, but the $http service is going to be replaced by core's http service, which provide proper mocks.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm asking because in the NP we keep test files side by side to the code, while here it's under a separate __jest__ folder.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wasn't sure about the jest test-files pattern for legacy, but it seems I can safely move them one level up. Will do.

Comment on lines 23 to 27
it('should import a file', async () => {
class FileReader {
readAsText(text) {
this.onload({
target: {
result: JSON.stringify({ text }),
},
});
}
}
it('should import a file with valid json format', async () => {
const file = new File([`{"text": "foo"}`], 'file.json');

const file = 'foo';

const imported = await importLegacyFile(file, FileReader);
expect(imported).toEqual({ text: file });
const imported = await importLegacyFile(file);
expect(imported).toEqual({ text: 'foo' });
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Was using a mocked FileReader implementation, therefor testing only a small part of the importFile function. Adapted the tests to use a real File as input

Comment on lines 39 to 45
obj: {
type: 'a',
id: '1',
},
type: 'a',
id: '1',
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Test dataset did not match real structure. Adapted test data and updated snapshots.

Comment on lines 27 to 34
jest.mock('../../../../../../../../../plugins/kibana_utils/public', () => ({
SavedObjectNotFound: class SavedObjectNotFound extends Error {
constructor(options) {
super();
for (const option in options) {
if (options.hasOwnProperty(option)) {
this[option] = options[option];
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This mocking was useless, as the only runtime usage of the mock was the import in the test file... adapted to declare the SavedObjectNotFound in the test file instead

export async function importLegacyFile(file, FileReader = window.FileReader) {
export async function importLegacyFile(file: File) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

the FileReader param was only there for testing purposes. Adapted the tests and removed the param.

Copy link
Contributor

Choose a reason for hiding this comment

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

src/legacy/core_plugins/kibana/public/management/sections/objects/lib/jest/import_legacy_file.test.js is still js file

Comment on lines -84 to +102
values: { title: this.title },
values: { title },
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Seems like an error after a probable extraction from a react component. I don't even know how the this reference was working (probably it wasn't).


async function getSavedObject(doc, services) {
const service = services.find(service => service.type === doc._type);
type SavedObjectsRawDoc = Record<string, any>;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Couldn't find a proper type for the raw doc we are manipulating in this file. Even the server side SavedObjectsRawDoc doesn't match. Had to fallback to a generic record...

Comment on lines +22 to +38
export interface SavedObjectMetadata {
icon?: string;
title?: string;
editUrl?: string;
inAppUrl?: { path: string; uiCapabilitiesPath: string };
}

export type SavedObjectWithMetadata<T = unknown> = SavedObject<T> & {
meta: SavedObjectMetadata;
};

export interface SavedObjectRelation {
id: string;
type: string;
relationship: 'child' | 'parent';
meta: SavedObjectMetadata;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Duplicated types with src/plugins/saved_objects_management. Will be removed once everything get moved.

@pgayvallet pgayvallet requested a review from a team March 19, 2020 08:26
const $http = jest.fn();
const $http = jest.fn() as any;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this file going to be removed?

const response = await kfetch({
method: 'GET',
pathname: '/api/kibana/management/saved_objects/_find',
query: findOptions,
query: findOptions as Record<string, any>,
Copy link
Contributor

Choose a reason for hiding this comment

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

KFetchQuery type is not really useful 😕

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea. all kfetch usages will be removed when this moves to the NP plugin, so I did not really bother much about these force-casts.

const response = await $http(options);
return response ? response.data : undefined;
const response = await $http<SavedObjectRelation[]>(options);
return response?.data;
} catch (resp) {
Copy link
Contributor

Choose a reason for hiding this comment

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

that's something new

export async function importLegacyFile(file, FileReader = window.FileReader) {
export async function importLegacyFile(file: File) {
Copy link
Contributor

Choose a reason for hiding this comment

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

src/legacy/core_plugins/kibana/public/management/sections/objects/lib/jest/import_legacy_file.test.js is still js file

switch (type) {
case 'search':
case 'searches':
return uiCapabilities.discover.show;
return uiCapabilities.discover.show as boolean;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm surprised that we don't allow to specify the type of Capabilities via a generic interface

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, this is something that was 'migrated' a little too fast to TS imho. Adding a genetic type on Capabilities would probably allow to remove quite a lot of force-cast in our TS plugins code.

However something like Capabilities<T> extends T is not permitted, so I'm not sure how we would allow to add arbitrary root-level properties on Capabilities to replace

  /** Custom capabilities, registered by plugins. */
  [key: string]: Record<string, boolean | Record<string, boolean>>;


export const isSameQuery = (query1, query2) => {
export const isSameQuery = (query1: any, query2: any) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I cannot see we use it. I would rather remove the code. We always can find removed code in the git history.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea, only usage is in a TODO (🙈)

onQueryChange = ({ query }) => {
// TODO: Use isSameQuery to compare new query with state.activeQuery to avoid re-fetching the
// same data we already have.

I'll remove it for now

doc: SavedObjectsRawDoc,
indexPatterns: IndexPatternsContract,
overwriteAll: boolean,
confirmModalPromise: OverlayStart['openConfirm']
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it a method or a promise? Signature says that's a method. Let's rename to something more meaningful - openConfirm, for example

conflictedIndexPatterns,
overwriteAll
resolutions: Array<{ oldId: string; newId: string }>,
conflictedIndexPatterns: any[],
Copy link
Contributor

Choose a reason for hiding this comment

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

working with code in this file is not fun 😓

Copy link
Contributor Author

Choose a reason for hiding this comment

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

lib/resolve_saved_objects.js and lib/resolve_import_errors.js really could use some proper cleanup and refactoring (most of the lib function does). I will create an issue to track all possible improvements once most of the SO management PR lands.

@spalger
Copy link
Contributor

spalger commented Mar 26, 2020

@elasticmachine merge upstream

@pgayvallet pgayvallet added v7.8 and removed v7.7.0 labels Mar 26, 2020
@kibanamachine
Copy link
Contributor

💚 Build Succeeded

History

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

@pgayvallet pgayvallet merged commit cec9165 into elastic:master Mar 26, 2020
pgayvallet added a commit to pgayvallet/kibana that referenced this pull request Mar 26, 2020
* migrate most libs

* migrate last lib files

* fix get_relationships

* fix getSavedObject

* migrate tests to TS

* address review comments

* move test files outside of __jest__ folder
pgayvallet added a commit that referenced this pull request Mar 26, 2020
* migrate most libs

* migrate last lib files

* fix get_relationships

* fix getSavedObject

* migrate tests to TS

* address review comments

* move test files outside of __jest__ folder
@rayafratkina rayafratkina added v7.8.0 and removed v7.8 labels Apr 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:New Platform release_note:skip Skip the PR/issue when compiling release notes Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.8.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants