mirror of
https://github.com/elastic/kibana.git
synced 2025-04-25 02:09:32 -04:00
220 lines
7 KiB
TypeScript
220 lines
7 KiB
TypeScript
/*
|
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
* or more contributor license agreements. Licensed under the Elastic License
|
|
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
|
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
|
* Side Public License, v 1.
|
|
*/
|
|
|
|
import { schema } from '@kbn/config-schema';
|
|
import { initTransform } from './object_transform';
|
|
|
|
import type {
|
|
ObjectMigrationDefinition,
|
|
ObjectTransforms,
|
|
Version,
|
|
VersionableObject,
|
|
} from './types';
|
|
|
|
interface FooV1 {
|
|
fullName: string;
|
|
}
|
|
|
|
const v1Tv2Transform = jest.fn((v1: FooV1): FooV2 => {
|
|
const [firstName, lastName] = v1.fullName.split(' ');
|
|
return { firstName, lastName };
|
|
});
|
|
|
|
const fooDefV1: VersionableObject = {
|
|
schema: schema.object({
|
|
fullName: schema.string({ minLength: 1 }),
|
|
}),
|
|
up: v1Tv2Transform,
|
|
};
|
|
|
|
interface FooV2 {
|
|
firstName: string;
|
|
lastName: string;
|
|
}
|
|
|
|
const v2Tv1Transform = jest.fn((v2: FooV2): FooV1 => {
|
|
return {
|
|
fullName: `${v2.firstName} ${v2.lastName}`,
|
|
};
|
|
});
|
|
|
|
const fooDefV2: VersionableObject = {
|
|
schema: schema.object({
|
|
firstName: schema.string(),
|
|
lastName: schema.string(),
|
|
}),
|
|
down: v2Tv1Transform,
|
|
};
|
|
|
|
const fooMigrationDef: ObjectMigrationDefinition = {
|
|
1: fooDefV1,
|
|
2: fooDefV2,
|
|
};
|
|
|
|
const setup = (browserVersion: Version): ObjectTransforms => {
|
|
const transformsFactory = initTransform(browserVersion);
|
|
return transformsFactory(fooMigrationDef);
|
|
};
|
|
|
|
describe('object transform', () => {
|
|
describe('initTransform()', () => {
|
|
test('it should validate that version numbers are valid', () => {
|
|
expect(() => {
|
|
initTransform(2)({
|
|
// @ts-expect-error
|
|
abc: { up: () => undefined },
|
|
});
|
|
}).toThrowError('Invalid version number [abc].');
|
|
});
|
|
});
|
|
|
|
describe('up()', () => {
|
|
test('it should up transform to the latest version', () => {
|
|
const fooTransforms = setup(1);
|
|
const { value } = fooTransforms.up({ fullName: 'John Snow' });
|
|
const expected = { firstName: 'John', lastName: 'Snow' };
|
|
expect(value).toEqual(expected);
|
|
});
|
|
|
|
test('it should forward object if on same version', () => {
|
|
const fooTransforms = setup(2);
|
|
const obj = { firstName: 'John', lastName: 'Snow' };
|
|
const { value } = fooTransforms.up(obj);
|
|
expect(value).toBe(obj);
|
|
});
|
|
|
|
describe('validation', () => {
|
|
test('it should validate the object before up transform', () => {
|
|
const fooTransforms = setup(1);
|
|
const { error } = fooTransforms.up({ unknown: 'John Snow' });
|
|
expect(error!.message).toBe(
|
|
'[fullName]: expected value of type [string] but got [undefined]'
|
|
);
|
|
});
|
|
|
|
test('it should validate that the version to up transform to exists', () => {
|
|
const fooTransforms = setup(1);
|
|
const { error } = fooTransforms.up({ fullName: 'John Snow' }, 3);
|
|
expect(error!.message).toBe('Unvalid version to up transform to [3].');
|
|
});
|
|
|
|
test('it should validate that the version to up transform from exists', () => {
|
|
const fooTransforms = setup(0);
|
|
const { error } = fooTransforms.up({ fullName: 'John Snow' });
|
|
expect(error!.message).toBe('Unvalid version to up transform from [0].');
|
|
});
|
|
|
|
test('it should handle errors while up transforming', () => {
|
|
const fooTransforms = setup(1);
|
|
|
|
v1Tv2Transform.mockImplementation((v1) => {
|
|
return (v1 as any).unknown.split('');
|
|
});
|
|
|
|
const { error } = fooTransforms.up({ fullName: 'John Snow' });
|
|
|
|
expect(error!.message).toBe(
|
|
`[Transform error] Cannot read properties of undefined (reading 'split').`
|
|
);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('down()', () => {
|
|
test('it should down transform to a previous version', () => {
|
|
const fooTransforms = setup(1);
|
|
const { value } = fooTransforms.down({ firstName: 'John', lastName: 'Snow' });
|
|
const expected = { fullName: 'John Snow' };
|
|
expect(value).toEqual(expected);
|
|
});
|
|
|
|
test('it should forward object if on same version', () => {
|
|
const fooTransforms = setup(1);
|
|
const obj = { fullName: 'John Snow' };
|
|
const { value } = fooTransforms.down(obj, 1);
|
|
expect(value).toBe(obj);
|
|
});
|
|
|
|
describe('validation', () => {
|
|
test('it should validate the object before down transform', () => {
|
|
const fooTransforms = setup(1);
|
|
|
|
const { error } = fooTransforms.down({ bad: 'Unknown' });
|
|
expect(error).not.toBe(null);
|
|
expect(error!.message).toBe(
|
|
'[firstName]: expected value of type [string] but got [undefined]'
|
|
);
|
|
});
|
|
|
|
test('it should validate that the version to down transform from exists', () => {
|
|
const fooTransforms = setup(1);
|
|
const { error } = fooTransforms.down({ fullName: 'John Snow' }, 3);
|
|
expect(error!.message).toBe('Unvalid version to down transform from [3].');
|
|
});
|
|
|
|
test('it should validate that the version to down transform to exists', () => {
|
|
const fooTransforms = setup(0);
|
|
const { error } = fooTransforms.down({ firstName: 'John', lastName: 'Snow' });
|
|
expect(error!.message).toBe('Unvalid version to down transform to [0].');
|
|
});
|
|
|
|
test('it should handle errors while down transforming', () => {
|
|
const fooTransforms = setup(1);
|
|
|
|
v2Tv1Transform.mockImplementation((v2) => {
|
|
return (v2 as any).unknown.split('');
|
|
});
|
|
|
|
const { error } = fooTransforms.down({ firstName: 'John', lastName: 'Snow' });
|
|
|
|
expect(error!.message).toBe(
|
|
`[Transform error] Cannot read properties of undefined (reading 'split').`
|
|
);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('validate()', () => {
|
|
test('it should validate the object at the specific version', () => {
|
|
const def: ObjectMigrationDefinition = {
|
|
1: {
|
|
schema: schema.string(),
|
|
},
|
|
2: {
|
|
schema: schema.number(),
|
|
},
|
|
};
|
|
|
|
// Init transforms for version 1
|
|
let transformsFactory = initTransform(1);
|
|
expect(transformsFactory(def).validate(123)?.message).toBe(
|
|
'expected value of type [string] but got [number]'
|
|
);
|
|
expect(transformsFactory(def).validate('foo')).toBe(null);
|
|
|
|
// Can validate another version than the requested one
|
|
expect(transformsFactory(def).validate('foo', 2)?.message).toBe(
|
|
'expected value of type [number] but got [string]'
|
|
);
|
|
expect(transformsFactory(def).validate(123, 2)).toBe(null);
|
|
|
|
// Init transform for version 2
|
|
transformsFactory = initTransform(2);
|
|
expect(transformsFactory(def).validate('foo')?.message).toBe(
|
|
'expected value of type [number] but got [string]'
|
|
);
|
|
expect(transformsFactory(def).validate(123)).toBe(null);
|
|
|
|
// Init transform for version 7 (invalid)
|
|
transformsFactory = initTransform(7);
|
|
expect(() => {
|
|
transformsFactory(def).validate(123);
|
|
}).toThrowError('Invalid version number [7].');
|
|
});
|
|
});
|
|
});
|