diff --git a/.teamcity/src/builds/PullRequestCi.kt b/.teamcity/src/builds/PullRequestCi.kt index f3fd1c0dfdf75..c38591fe850ac 100644 --- a/.teamcity/src/builds/PullRequestCi.kt +++ b/.teamcity/src/builds/PullRequestCi.kt @@ -3,6 +3,7 @@ package builds import builds.default.DefaultSavedObjectFieldMetrics import dependsOn import getProjectBranch +import isReportingEnabled import jetbrains.buildServer.configs.kotlin.v2019_2.BuildType import jetbrains.buildServer.configs.kotlin.v2019_2.buildFeatures.commitStatusPublisher import vcs.Kibana @@ -63,6 +64,7 @@ object PullRequestCi : BuildType({ features { commitStatusPublisher { + enabled = isReportingEnabled() vcsRootExtId = "${Kibana.id}" publisher = github { githubUrl = "https://api.github.com" diff --git a/.teamcity/src/builds/test/QuickTests.kt b/.teamcity/src/builds/test/QuickTests.kt index 086f65e4ee26b..6ea15bf5350e6 100644 --- a/.teamcity/src/builds/test/QuickTests.kt +++ b/.teamcity/src/builds/test/QuickTests.kt @@ -13,7 +13,7 @@ object QuickTests : BuildType({ val testScripts = mapOf( "Test Hardening" to ".ci/teamcity/checks/test_hardening.sh", - "Test Projects" to ".ci/teamcity/tests/test_projects.sh", + "Test Projects" to ".ci/teamcity/tests/test_projects.sh" ) steps { diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectmigrationmap.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectmigrationmap.md index 5dce93fccd182..c07a41e28d45b 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectmigrationmap.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectmigrationmap.md @@ -18,7 +18,7 @@ export interface SavedObjectMigrationMap ```typescript -const migrations: SavedObjectMigrationMap = { +const migrationsMap: SavedObjectMigrationMap = { '1.0.0': migrateToV1, '2.1.0': migrateToV21 } diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.registertype.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.registertype.md index 54e01d3110a2d..aa813bb7b2956 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.registertype.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.registertype.md @@ -38,7 +38,7 @@ export const myType: SavedObjectsType = { }, migrations: { '2.0.0': migrations.migrateToV2, - '2.1.0': migrations.migrateToV2_1 + '2.1.0': migrations.migrateToV2_1, }, }; diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectstype.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectstype.md index e2c858512c54c..eacad53be39fe 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectstype.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectstype.md @@ -45,7 +45,7 @@ Note: a migration function can be optionally specified for the same version. | | [indexPattern](./kibana-plugin-core-server.savedobjectstype.indexpattern.md) | string | If defined, the type instances will be stored in the given index instead of the default one. | | [management](./kibana-plugin-core-server.savedobjectstype.management.md) | SavedObjectsTypeManagementDefinition | An optional [saved objects management section](./kibana-plugin-core-server.savedobjectstypemanagementdefinition.md) definition for the type. | | [mappings](./kibana-plugin-core-server.savedobjectstype.mappings.md) | SavedObjectsTypeMappingDefinition | The [mapping definition](./kibana-plugin-core-server.savedobjectstypemappingdefinition.md) for the type. | -| [migrations](./kibana-plugin-core-server.savedobjectstype.migrations.md) | SavedObjectMigrationMap | An optional map of [migrations](./kibana-plugin-core-server.savedobjectmigrationfn.md) to be used to migrate the type. | +| [migrations](./kibana-plugin-core-server.savedobjectstype.migrations.md) | SavedObjectMigrationMap | (() => SavedObjectMigrationMap) | An optional map of [migrations](./kibana-plugin-core-server.savedobjectmigrationfn.md) or a function returning a map of [migrations](./kibana-plugin-core-server.savedobjectmigrationfn.md) to be used to migrate the type. | | [name](./kibana-plugin-core-server.savedobjectstype.name.md) | string | The name of the type, which is also used as the internal id. | | [namespaceType](./kibana-plugin-core-server.savedobjectstype.namespacetype.md) | SavedObjectsNamespaceType | The [namespace type](./kibana-plugin-core-server.savedobjectsnamespacetype.md) for the type. | diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectstype.migrations.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectstype.migrations.md index 22513880ab40e..6550d48a1c26a 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectstype.migrations.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectstype.migrations.md @@ -4,10 +4,10 @@ ## SavedObjectsType.migrations property -An optional map of [migrations](./kibana-plugin-core-server.savedobjectmigrationfn.md) to be used to migrate the type. +An optional map of [migrations](./kibana-plugin-core-server.savedobjectmigrationfn.md) or a function returning a map of [migrations](./kibana-plugin-core-server.savedobjectmigrationfn.md) to be used to migrate the type. Signature: ```typescript -migrations?: SavedObjectMigrationMap; +migrations?: SavedObjectMigrationMap | (() => SavedObjectMigrationMap); ``` diff --git a/src/core/server/saved_objects/migrations/core/document_migrator.test.ts b/src/core/server/saved_objects/migrations/core/document_migrator.test.ts index d7ff1b36764b9..7034785c282d6 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.test.ts @@ -61,66 +61,97 @@ describe('DocumentMigrator', () => { } describe('validation', () => { - it('validates individual migration definitions', () => { - const invalidDefinition = { - kibanaVersion: '3.2.3', - typeRegistry: createRegistry({ - name: 'foo', - migrations: _.noop as any, - }), - log: mockLogger, - }; - expect(() => new DocumentMigrator(invalidDefinition)).toThrow( - /Migration for type foo should be an object/i - ); + const createDefinition = (migrations: any) => ({ + kibanaVersion: '3.2.3', + typeRegistry: createRegistry({ + name: 'foo', + migrations: migrations as any, + }), + log: mockLogger, }); - it('validates individual migrations are valid semvers', () => { - const invalidDefinition = { - kibanaVersion: '3.2.3', - typeRegistry: createRegistry({ - name: 'foo', - migrations: { - bar: (doc) => doc, - }, - }), - log: mockLogger, - }; - expect(() => new DocumentMigrator(invalidDefinition)).toThrow( - /Expected all properties to be semvers/i - ); - }); + describe('#prepareMigrations', () => { + it('validates individual migration definitions', () => { + const invalidMigrator = new DocumentMigrator(createDefinition(() => 123)); + const voidMigrator = new DocumentMigrator(createDefinition(() => {})); + const emptyObjectMigrator = new DocumentMigrator(createDefinition(() => ({}))); - it('validates individual migrations are not greater than the current Kibana version', () => { - const invalidDefinition = { - kibanaVersion: '3.2.3', - typeRegistry: createRegistry({ - name: 'foo', - migrations: { - '3.2.4': (doc) => doc, - }, - }), - log: mockLogger, - }; - expect(() => new DocumentMigrator(invalidDefinition)).toThrowError( - `Invalid migration for type foo. Property '3.2.4' cannot be greater than the current Kibana version '3.2.3'.` - ); + expect(invalidMigrator.prepareMigrations).toThrow( + /Migrations map for type foo should be an object/i + ); + expect(voidMigrator.prepareMigrations).not.toThrow(); + expect(emptyObjectMigrator.prepareMigrations).not.toThrow(); + }); + + it('validates individual migrations are valid semvers', () => { + const withInvalidVersion = { + bar: (doc: any) => doc, + '1.2.3': (doc: any) => doc, + }; + const migrationFn = new DocumentMigrator(createDefinition(() => withInvalidVersion)); + const migrationObj = new DocumentMigrator(createDefinition(withInvalidVersion)); + + expect(migrationFn.prepareMigrations).toThrow(/Expected all properties to be semvers/i); + expect(migrationObj.prepareMigrations).toThrow(/Expected all properties to be semvers/i); + }); + + it('validates individual migrations are not greater than the current Kibana version', () => { + const withGreaterVersion = { + '3.2.4': (doc: any) => doc, + }; + const migrationFn = new DocumentMigrator(createDefinition(() => withGreaterVersion)); + const migrationObj = new DocumentMigrator(createDefinition(withGreaterVersion)); + + const expectedError = `Invalid migration for type foo. Property '3.2.4' cannot be greater than the current Kibana version '3.2.3'.`; + expect(migrationFn.prepareMigrations).toThrowError(expectedError); + expect(migrationObj.prepareMigrations).toThrowError(expectedError); + }); + + it('validates the migration function', () => { + const invalidVersionFunction = { '1.2.3': 23 as any }; + const migrationFn = new DocumentMigrator(createDefinition(() => invalidVersionFunction)); + const migrationObj = new DocumentMigrator(createDefinition(invalidVersionFunction)); + + expect(migrationFn.prepareMigrations).toThrow(/expected a function, but got 23/i); + expect(migrationObj.prepareMigrations).toThrow(/expected a function, but got 23/i); + }); + it('validates definitions with migrations: Function | Objects', () => { + const validMigrationMap = { '1.2.3': () => {} }; + const migrationFn = new DocumentMigrator(createDefinition(() => validMigrationMap)); + const migrationObj = new DocumentMigrator(createDefinition(validMigrationMap)); + expect(migrationFn.prepareMigrations).not.toThrow(); + expect(migrationObj.prepareMigrations).not.toThrow(); + }); }); - it('validates the migration function', () => { - const invalidDefinition = { - kibanaVersion: '3.2.3', + it('throws if #prepareMigrations is not called before #migrate or #migrateAndConvert is called', () => { + const migrator = new DocumentMigrator({ + ...testOpts(), typeRegistry: createRegistry({ - name: 'foo', + name: 'user', migrations: { - '1.2.3': 23 as any, + '1.2.3': setAttr('attributes.name', 'Chris'), }, }), - log: mockLogger, - }; - expect(() => new DocumentMigrator(invalidDefinition)).toThrow( - /expected a function, but got 23/i - ); + }); + + expect(() => + migrator.migrate({ + id: 'me', + type: 'user', + attributes: { name: 'Christopher' }, + migrationVersion: {}, + }) + ).toThrow(/Migrations are not ready. Make sure prepareMigrations is called first./i); + + expect(() => + migrator.migrateAndConvert({ + id: 'me', + type: 'user', + attributes: { name: 'Christopher' }, + migrationVersion: {}, + }) + ).toThrow(/Migrations are not ready. Make sure prepareMigrations is called first./i); }); it(`validates convertToMultiNamespaceTypeVersion can only be used with namespaceType 'multiple'`, () => { @@ -214,6 +245,7 @@ describe('DocumentMigrator', () => { }, }), }); + migrator.prepareMigrations(); const actual = migrator.migrate({ id: 'me', type: 'user', @@ -242,6 +274,7 @@ describe('DocumentMigrator', () => { }, }), }); + migrator.prepareMigrations(); const originalDoc = { id: 'me', type: 'user', @@ -263,6 +296,7 @@ describe('DocumentMigrator', () => { }, }), }); + migrator.prepareMigrations(); const actual = migrator.migrate({ id: 'me', type: 'user', @@ -304,6 +338,7 @@ describe('DocumentMigrator', () => { } ), }); + migrator.prepareMigrations(); const actual = migrator.migrate({ id: 'me', type: 'user', @@ -342,6 +377,7 @@ describe('DocumentMigrator', () => { } ), }); + migrator.prepareMigrations(); const actual = migrator.migrate({ id: 'me', type: 'user', @@ -374,6 +410,7 @@ describe('DocumentMigrator', () => { }, }), }); + migrator.prepareMigrations(); const actual = migrator.migrate({ id: 'smelly', type: 'dog', @@ -393,6 +430,7 @@ describe('DocumentMigrator', () => { const migrator = new DocumentMigrator({ ...testOpts(), }); + migrator.prepareMigrations(); expect(() => migrator.migrate({ id: 'smelly', @@ -415,6 +453,7 @@ describe('DocumentMigrator', () => { }, }), }); + migrator.prepareMigrations(); expect(() => migrator.migrate({ id: 'fleabag', @@ -432,6 +471,7 @@ describe('DocumentMigrator', () => { ...testOpts(), kibanaVersion: '8.0.1', }); + migrator.prepareMigrations(); expect(() => migrator.migrate({ id: 'happy', @@ -449,6 +489,7 @@ describe('DocumentMigrator', () => { ...testOpts(), kibanaVersion: '8.0.1', }); + migrator.prepareMigrations(); expect(() => migrator.migrate({ id: 'wet', @@ -474,6 +515,7 @@ describe('DocumentMigrator', () => { }, }), }); + migrator.prepareMigrations(); const actual = migrator.migrate({ id: 'smelly', type: 'dog', @@ -507,6 +549,7 @@ describe('DocumentMigrator', () => { } ), }); + migrator.prepareMigrations(); const actual = migrator.migrate({ id: 'smelly', type: 'dog', @@ -535,6 +578,7 @@ describe('DocumentMigrator', () => { }, }), }); + migrator.prepareMigrations(); const actual = migrator.migrate({ id: 'smelly', type: 'dog', @@ -568,6 +612,7 @@ describe('DocumentMigrator', () => { } ), }); + migrator.prepareMigrations(); const actual = migrator.migrate({ id: 'smelly', type: 'dog', @@ -593,7 +638,7 @@ describe('DocumentMigrator', () => { }, }), }); - + migrator.prepareMigrations(); expect(() => migrator.migrate({ id: 'smelly', @@ -616,6 +661,7 @@ describe('DocumentMigrator', () => { }, }), }); + migrator.prepareMigrations(); expect(() => migrator.migrate({ id: 'smelly', @@ -645,6 +691,7 @@ describe('DocumentMigrator', () => { }, }), }); + migrator.prepareMigrations(); const actual = migrator.migrate({ id: 'smelly', type: 'cat', @@ -670,6 +717,7 @@ describe('DocumentMigrator', () => { }, }), }); + migrator.prepareMigrations(); const actual = migrator.migrate({ id: 'smelly', type: 'cat', @@ -699,6 +747,7 @@ describe('DocumentMigrator', () => { }), log, }); + migrator.prepareMigrations(); const failedDoc = { id: 'smelly', type: 'dog', @@ -732,6 +781,7 @@ describe('DocumentMigrator', () => { }), log: mockLogger, }); + migrator.prepareMigrations(); const doc = { id: 'joker', type: 'dog', @@ -744,7 +794,7 @@ describe('DocumentMigrator', () => { }); test('extracts the latest migration version info', () => { - const { migrationVersion } = new DocumentMigrator({ + const migrator = new DocumentMigrator({ ...testOpts(), typeRegistry: createRegistry( { @@ -772,8 +822,8 @@ describe('DocumentMigrator', () => { } ), }); - - expect(migrationVersion).toEqual({ + migrator.prepareMigrations(); + expect(migrator.migrationVersion).toEqual({ aaa: '10.4.0', bbb: '3.2.3', ccc: '11.0.0', @@ -789,6 +839,7 @@ describe('DocumentMigrator', () => { // no migration transforms are defined, the migrationVersion will be derived from 'convertToMultiNamespaceTypeVersion' ), }); + migrator.prepareMigrations(); const obj = { id: 'mischievous', type: 'dog', @@ -816,6 +867,7 @@ describe('DocumentMigrator', () => { { name: 'toy', namespaceType: 'multiple', convertToMultiNamespaceTypeVersion: '1.0.0' } ), }); + migrator.prepareMigrations(); const obj = { id: 'cowardly', type: 'dog', @@ -846,6 +898,7 @@ describe('DocumentMigrator', () => { { name: 'toy', namespaceType: 'multiple', convertToMultiNamespaceTypeVersion: '1.0.0' } ), }); + migrator.prepareMigrations(); const obj = { id: 'bad', type: 'dog', @@ -894,6 +947,7 @@ describe('DocumentMigrator', () => { convertToMultiNamespaceTypeVersion: '1.0.0', }), }); + migrator.prepareMigrations(); const obj = { id: 'loud', type: 'dog', @@ -953,6 +1007,7 @@ describe('DocumentMigrator', () => { { name: 'toy', namespaceType: 'multiple', convertToMultiNamespaceTypeVersion: '1.0.0' } ), }); + migrator.prepareMigrations(); const obj = { id: 'cute', type: 'dog', @@ -1023,6 +1078,7 @@ describe('DocumentMigrator', () => { { name: 'toy', namespaceType: 'multiple', convertToMultiNamespaceTypeVersion: '1.0.0' } ), }); + migrator.prepareMigrations(); const obj = { id: 'sleepy', type: 'dog', @@ -1077,6 +1133,7 @@ describe('DocumentMigrator', () => { convertToMultiNamespaceTypeVersion: '1.0.0', // the conversion transform occurs before the migration transform above }), }); + migrator.prepareMigrations(); const obj = { id: 'hungry', type: 'dog', @@ -1144,6 +1201,7 @@ describe('DocumentMigrator', () => { { name: 'toy', namespaceType: 'multiple', convertToMultiNamespaceTypeVersion: '1.0.0' } ), }); + migrator.prepareMigrations(); const obj = { id: 'pretty', type: 'dog', diff --git a/src/core/server/saved_objects/migrations/core/document_migrator.ts b/src/core/server/saved_objects/migrations/core/document_migrator.ts index 9d5cd751e0d85..50d030ac64d36 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.ts @@ -74,7 +74,7 @@ import { } from '../../types'; import { MigrationLogger } from './migration_logger'; import { ISavedObjectTypeRegistry } from '../../saved_objects_type_registry'; -import { SavedObjectMigrationFn } from '../types'; +import { SavedObjectMigrationFn, SavedObjectMigrationMap } from '../types'; import { DEFAULT_NAMESPACE_STRING } from '../../service/lib/utils'; import { LegacyUrlAlias, LEGACY_URL_ALIAS_TYPE } from '../../object_types'; @@ -147,14 +147,16 @@ export interface VersionedTransformer { migrationVersion: SavedObjectsMigrationVersion; migrate: MigrateFn; migrateAndConvert: MigrateAndConvertFn; + prepareMigrations: () => void; } /** * A concrete implementation of the VersionedTransformer interface. */ export class DocumentMigrator implements VersionedTransformer { - private migrations: ActiveMigrations; - private transformDoc: ApplyTransformsFn; + private documentMigratorOptions: Omit; + private migrations?: ActiveMigrations; + private transformDoc?: ApplyTransformsFn; /** * Creates an instance of DocumentMigrator. @@ -174,11 +176,7 @@ export class DocumentMigrator implements VersionedTransformer { }: DocumentMigratorOptions) { validateMigrationDefinition(typeRegistry, kibanaVersion, minimumConvertVersion); - this.migrations = buildActiveMigrations(typeRegistry, log); - this.transformDoc = buildDocumentTransform({ - kibanaVersion, - migrations: this.migrations, - }); + this.documentMigratorOptions = { typeRegistry, kibanaVersion, log }; } /** @@ -189,6 +187,10 @@ export class DocumentMigrator implements VersionedTransformer { * @memberof DocumentMigrator */ public get migrationVersion(): SavedObjectsMigrationVersion { + if (!this.migrations) { + throw new Error('Migrations are not ready. Make sure prepareMigrations is called first.'); + } + return Object.entries(this.migrations).reduce((acc, [prop, { latestMigrationVersion }]) => { // some migration objects won't have a latestMigrationVersion (they only contain reference transforms that are applied from other types) if (latestMigrationVersion) { @@ -198,6 +200,22 @@ export class DocumentMigrator implements VersionedTransformer { }, {}); } + /** + * Prepares active migrations and document transformer function. + * + * @returns {void} + * @memberof DocumentMigrator + */ + + public prepareMigrations = () => { + const { typeRegistry, kibanaVersion, log } = this.documentMigratorOptions; + this.migrations = buildActiveMigrations(typeRegistry, kibanaVersion, log); + this.transformDoc = buildDocumentTransform({ + kibanaVersion, + migrations: this.migrations, + }); + }; + /** * Migrates a document to the latest version. * @@ -206,6 +224,10 @@ export class DocumentMigrator implements VersionedTransformer { * @memberof DocumentMigrator */ public migrate = (doc: SavedObjectUnsanitizedDoc): SavedObjectUnsanitizedDoc => { + if (!this.migrations || !this.transformDoc) { + throw new Error('Migrations are not ready. Make sure prepareMigrations is called first.'); + } + // Clone the document to prevent accidental mutations on the original data // Ex: Importing sample data that is cached at import level, migrations would // execute on mutated data the second time. @@ -223,6 +245,10 @@ export class DocumentMigrator implements VersionedTransformer { * @memberof DocumentMigrator */ public migrateAndConvert = (doc: SavedObjectUnsanitizedDoc): SavedObjectUnsanitizedDoc[] => { + if (!this.migrations || !this.transformDoc) { + throw new Error('Migrations are not ready. Make sure prepareMigrations is called first.'); + } + // Clone the document to prevent accidental mutations on the original data // Ex: Importing sample data that is cached at import level, migrations would // execute on mutated data the second time. @@ -234,23 +260,16 @@ export class DocumentMigrator implements VersionedTransformer { }; } -/** - * Basic validation that the migration definition matches our expectations. We can't - * rely on TypeScript here, as the caller may be JavaScript / ClojureScript / any compile-to-js - * language. So, this is just to provide a little developer-friendly error messaging. Joi was - * giving weird errors, so we're just doing manual validation. - */ -function validateMigrationDefinition( - registry: ISavedObjectTypeRegistry, +function validateMigrationsMapObject( + name: string, kibanaVersion: string, - minimumConvertVersion: string + migrationsMap?: SavedObjectMigrationMap ) { function assertObject(obj: any, prefix: string) { if (!obj || typeof obj !== 'object') { throw new Error(`${prefix} Got ${obj}.`); } } - function assertValidSemver(version: string, type: string) { if (!Semver.valid(version)) { throw new Error( @@ -263,13 +282,42 @@ function validateMigrationDefinition( ); } } - function assertValidTransform(fn: any, version: string, type: string) { if (typeof fn !== 'function') { throw new Error(`Invalid migration ${type}.${version}: expected a function, but got ${fn}.`); } } + if (migrationsMap) { + assertObject( + migrationsMap, + `Migrations map for type ${name} should be an object like { '2.0.0': (doc) => doc }.` + ); + + Object.entries(migrationsMap).forEach(([version, fn]) => { + assertValidSemver(version, name); + assertValidTransform(fn, version, name); + }); + } +} + +/** + * Basic validation that the migration definition matches our expectations. We can't + * rely on TypeScript here, as the caller may be JavaScript / ClojureScript / any compile-to-js + * language. So, this is just to provide a little developer-friendly error messaging. Joi was + * giving weird errors, so we're just doing manual validation. + */ +function validateMigrationDefinition( + registry: ISavedObjectTypeRegistry, + kibanaVersion: string, + minimumConvertVersion: string +) { + function assertObjectOrFunction(entity: any, prefix: string) { + if (!entity || (typeof entity !== 'function' && typeof entity !== 'object')) { + throw new Error(`${prefix} Got! ${typeof entity}, ${JSON.stringify(entity)}.`); + } + } + function assertValidConvertToMultiNamespaceType( namespaceType: SavedObjectsNamespaceType, convertToMultiNamespaceTypeVersion: string, @@ -301,14 +349,10 @@ function validateMigrationDefinition( registry.getAllTypes().forEach((type) => { const { name, migrations, convertToMultiNamespaceTypeVersion, namespaceType } = type; if (migrations) { - assertObject( + assertObjectOrFunction( type.migrations, - `Migration for type ${name} should be an object like { '2.0.0': (doc) => doc }.` + `Migration for type ${name} should be an object or a function returning an object like { '2.0.0': (doc) => doc }.` ); - Object.entries(migrations).forEach(([version, fn]) => { - assertValidSemver(version, name); - assertValidTransform(fn, version, name); - }); } if (convertToMultiNamespaceTypeVersion) { assertValidConvertToMultiNamespaceType( @@ -328,12 +372,17 @@ function validateMigrationDefinition( */ function buildActiveMigrations( typeRegistry: ISavedObjectTypeRegistry, + kibanaVersion: string, log: Logger ): ActiveMigrations { const referenceTransforms = getReferenceTransforms(typeRegistry); return typeRegistry.getAllTypes().reduce((migrations, type) => { - const migrationTransforms = Object.entries(type.migrations ?? {}).map( + const migrationsMap = + typeof type.migrations === 'function' ? type.migrations() : type.migrations; + validateMigrationsMapObject(type.name, kibanaVersion, migrationsMap); + + const migrationTransforms = Object.entries(migrationsMap ?? {}).map( ([version, transform]) => ({ version, transform: wrapWithTry(version, type.name, transform, log), diff --git a/src/core/server/saved_objects/migrations/core/index_migrator.test.ts b/src/core/server/saved_objects/migrations/core/index_migrator.test.ts index c29274de05962..10a2a007dee32 100644 --- a/src/core/server/saved_objects/migrations/core/index_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/core/index_migrator.test.ts @@ -44,6 +44,7 @@ describe('IndexMigrator', () => { migrationVersion: {}, migrate: _.identity, migrateAndConvert: _.identity, + prepareMigrations: jest.fn(), }, serializer: new SavedObjectsSerializer(new SavedObjectTypeRegistry()), }; @@ -333,6 +334,7 @@ describe('IndexMigrator', () => { migrationVersion: { foo: '1.2.3' }, migrate: jest.fn(), migrateAndConvert: migrateAndConvertDoc, + prepareMigrations: jest.fn(), }; withIndex(client, { @@ -386,6 +388,7 @@ describe('IndexMigrator', () => { migrationVersion: { foo: '1.2.3' }, migrate: jest.fn(), migrateAndConvert: migrateAndConvertDoc, + prepareMigrations: jest.fn(), }; withIndex(client, { diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.mock.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.mock.ts index da4d39f435038..997945776cfee 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.mock.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.mock.ts @@ -32,7 +32,7 @@ const defaultSavedObjectTypes: SavedObjectsType[] = [ name: { type: 'keyword' }, }, }, - migrations: {}, + migrations: () => ({}), }, ]; @@ -56,6 +56,7 @@ const createMigrator = ( runMigrations: jest.fn(), getActiveMappings: jest.fn(), migrateDocument: jest.fn(), + prepareMigrations: jest.fn(), getStatus$: jest.fn( () => new BehaviorSubject({ diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts index 4248f6fdbeca4..cca7808988896 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts @@ -65,7 +65,53 @@ describe('KibanaMigrator', () => { }); }); + describe('migrateDocument', () => { + it('throws an error if documentMigrator.prepareMigrations is not called previously', () => { + const options = mockOptions(); + const kibanaMigrator = new KibanaMigrator(options); + const doc = {} as any; + expect(() => kibanaMigrator.migrateDocument(doc)).toThrowError( + /Migrations are not ready. Make sure prepareMigrations is called first./i + ); + }); + + it('calls documentMigrator.migrate', () => { + const options = mockOptions(); + const kibanaMigrator = new KibanaMigrator(options); + const mockDocumentMigrator = { migrate: jest.fn() }; + // @ts-expect-error `documentMigrator` is readonly. + kibanaMigrator.documentMigrator = mockDocumentMigrator; + const doc = {} as any; + + expect(() => kibanaMigrator.migrateDocument(doc)).not.toThrowError(); + expect(mockDocumentMigrator.migrate).toBeCalledTimes(1); + }); + }); + describe('runMigrations', () => { + it('throws if prepareMigrations is not called first', async () => { + const options = mockOptions(); + + options.client.cat.templates.mockReturnValue( + elasticsearchClientMock.createSuccessTransportRequestPromise( + { templates: [] }, + { statusCode: 404 } + ) + ); + options.client.indices.get.mockReturnValue( + elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + ); + options.client.indices.getAlias.mockReturnValue( + elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + ); + + const migrator = new KibanaMigrator(options); + + expect(() => migrator.runMigrations()).rejects.toThrow( + /Migrations are not ready. Make sure prepareMigrations is called first./i + ); + }); + it('only runs migrations once if called multiple times', async () => { const options = mockOptions(); @@ -84,6 +130,7 @@ describe('KibanaMigrator', () => { const migrator = new KibanaMigrator(options); + migrator.prepareMigrations(); await migrator.runMigrations(); await migrator.runMigrations(); @@ -120,6 +167,8 @@ describe('KibanaMigrator', () => { const migrator = new KibanaMigrator(options); const migratorStatus = migrator.getStatus$().pipe(take(3)).toPromise(); + + migrator.prepareMigrations(); await migrator.runMigrations(); expect(options.client.indices.create).toHaveBeenCalledTimes(3); @@ -145,6 +194,7 @@ describe('KibanaMigrator', () => { const migrator = new KibanaMigrator(options); const migratorStatus = migrator.getStatus$().pipe(take(3)).toPromise(); + migrator.prepareMigrations(); await migrator.runMigrations(); const { status, result } = await migratorStatus; expect(status).toEqual('completed'); @@ -171,6 +221,7 @@ describe('KibanaMigrator', () => { const options = mockV2MigrationOptions(); const migrator = new KibanaMigrator(options); const migratorStatus = migrator.getStatus$().pipe(take(3)).toPromise(); + migrator.prepareMigrations(); await migrator.runMigrations(); // Basic assertions that we're creating and reindexing the expected indices @@ -212,6 +263,7 @@ describe('KibanaMigrator', () => { const options = mockV2MigrationOptions(); const migrator = new KibanaMigrator(options); const migratorStatus = migrator.getStatus$().pipe(take(3)).toPromise(); + migrator.prepareMigrations(); await migrator.runMigrations(); const { status, result } = await migratorStatus; @@ -247,6 +299,7 @@ describe('KibanaMigrator', () => { ); const migrator = new KibanaMigrator(options); + migrator.prepareMigrations(); return expect(migrator.runMigrations()).rejects.toMatchInlineSnapshot( `[Error: Unable to complete saved object migrations for the [.my-index] index: The .my-index alias is pointing to a newer version of Kibana: v8.2.4]` ); @@ -263,7 +316,7 @@ describe('KibanaMigrator', () => { ); const migrator = new KibanaMigrator(options); - + migrator.prepareMigrations(); await expect(migrator.runMigrations()).rejects.toMatchInlineSnapshot(` [Error: Unable to complete saved object migrations for the [.my-index] index. Please check the health of your Elasticsearch cluster and try again. Error: Reindex failed with the following error: {"_tag":"Some","value":{"type":"elatsicsearch_exception","reason":"task failed with an error"}}] diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts index 18fc610a2c739..3b3ff3887f279 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts @@ -159,6 +159,10 @@ export class KibanaMigrator { return this.migrationResult; } + public prepareMigrations() { + this.documentMigrator.prepareMigrations(); + } + public getStatus$() { return this.status$.asObservable(); } diff --git a/src/core/server/saved_objects/migrations/types.ts b/src/core/server/saved_objects/migrations/types.ts index f23a429d2d8ac..dbf340c9bd531 100644 --- a/src/core/server/saved_objects/migrations/types.ts +++ b/src/core/server/saved_objects/migrations/types.ts @@ -79,7 +79,7 @@ export interface SavedObjectMigrationContext { * * @example * ```typescript - * const migrations: SavedObjectMigrationMap = { + * const migrationsMap: SavedObjectMigrationMap = { * '1.0.0': migrateToV1, * '2.1.0': migrateToV21 * } diff --git a/src/core/server/saved_objects/saved_objects_service.ts b/src/core/server/saved_objects/saved_objects_service.ts index 736f99596b62f..ac87fd1444159 100644 --- a/src/core/server/saved_objects/saved_objects_service.ts +++ b/src/core/server/saved_objects/saved_objects_service.ts @@ -391,6 +391,12 @@ export class SavedObjectsService */ const skipMigrations = this.config.migration.skip || !pluginsInitialized; + /** + * Note: Prepares all migrations maps. If a saved object type was registered with property `migrations` + * of type function; this function will be called to get the type's SavedObjectMigrationMap. + */ + migrator.prepareMigrations(); + if (skipMigrations) { this.logger.warn( 'Skipping Saved Object migrations on startup. Note: Individual documents will still be migrated when read or written.' diff --git a/src/core/server/saved_objects/service/lib/repository.test.js b/src/core/server/saved_objects/service/lib/repository.test.js index bdc5be4d51c1a..5cd529799a83b 100644 --- a/src/core/server/saved_objects/service/lib/repository.test.js +++ b/src/core/server/saved_objects/service/lib/repository.test.js @@ -219,6 +219,7 @@ describe('SavedObjectsRepository', () => { beforeEach(() => { client = elasticsearchClientMock.createElasticsearchClient(); migrator = mockKibanaMigrator.create(); + documentMigrator.prepareMigrations(); migrator.migrateDocument = jest.fn().mockImplementation(documentMigrator.migrate); migrator.runMigrations = async () => ({ status: 'skipped' }); diff --git a/src/core/server/saved_objects/types.ts b/src/core/server/saved_objects/types.ts index 37422785732e6..bbd6cc8da6448 100644 --- a/src/core/server/saved_objects/types.ts +++ b/src/core/server/saved_objects/types.ts @@ -245,9 +245,9 @@ export interface SavedObjectsType { */ mappings: SavedObjectsTypeMappingDefinition; /** - * An optional map of {@link SavedObjectMigrationFn | migrations} to be used to migrate the type. + * An optional map of {@link SavedObjectMigrationFn | migrations} or a function returning a map of {@link SavedObjectMigrationFn | migrations} to be used to migrate the type. */ - migrations?: SavedObjectMigrationMap; + migrations?: SavedObjectMigrationMap | (() => SavedObjectMigrationMap); /** * If defined, objects of this type will be converted to multi-namespace objects when migrating to this version. * diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 9c13d5489baec..85913d5a8bae6 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -2807,7 +2807,7 @@ export interface SavedObjectsType { indexPattern?: string; management?: SavedObjectsTypeManagementDefinition; mappings: SavedObjectsTypeMappingDefinition; - migrations?: SavedObjectMigrationMap; + migrations?: SavedObjectMigrationMap | (() => SavedObjectMigrationMap); name: string; namespaceType: SavedObjectsNamespaceType; } diff --git a/test/api_integration/apis/saved_objects/migrations.ts b/test/api_integration/apis/saved_objects/migrations.ts index 5bc9a97466dbc..6c3b7e0f32755 100644 --- a/test/api_integration/apis/saved_objects/migrations.ts +++ b/test/api_integration/apis/saved_objects/migrations.ts @@ -645,6 +645,8 @@ async function migrateIndex({ log: getLogMock(), }); + documentMigrator.prepareMigrations(); + const migrator = new IndexMigrator({ client: createMigrationEsClient(esClient, getLogMock()), documentMigrator, diff --git a/vars/prChanges.groovy b/vars/prChanges.groovy index d082672c065a8..2cc22e73857b0 100644 --- a/vars/prChanges.groovy +++ b/vars/prChanges.groovy @@ -11,8 +11,10 @@ def getSkippablePaths() { /^.ci\/.+\.yml$/, /^.ci\/es-snapshots\//, /^.ci\/pipeline-library\//, + /^.ci\/teamcity\//, /^.ci\/Jenkinsfile_[^\/]+$/, /^\.github\//, + /^\.teamcity\//, /\.md$/, ] } diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts index 9410b9ef7cb03..68c5ef8f8782a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/app_logic.test.ts @@ -4,15 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import { resetContext } from 'kea'; +import { LogicMounter } from '../__mocks__'; import { DEFAULT_INITIAL_APP_DATA } from '../../../common/__mocks__'; import { AppLogic } from './app_logic'; describe('AppLogic', () => { + const { mount } = new LogicMounter(AppLogic); + beforeEach(() => { - resetContext({}); - AppLogic.mount(); + mount(); }); const DEFAULT_VALUES = { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_engine_access.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_engine_access.test.tsx index d0bbf868aa90c..6fa230447d5de 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_engine_access.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_flyout/form_components/key_engine_access.test.tsx @@ -4,8 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { setMockValues, setMockActions } from '../../../../../__mocks__/kea.mock'; -import { rerender } from '../../../../../__mocks__'; +import { setMockValues, setMockActions, rerender } from '../../../../../__mocks__'; import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/paste_json_text.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/paste_json_text.test.tsx index 39c6abcaab7b3..d327f8112219d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/paste_json_text.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/paste_json_text.test.tsx @@ -4,8 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock'; -import { rerender } from '../../../../__mocks__'; +import { setMockValues, setMockActions, rerender } from '../../../../__mocks__'; import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/upload_json_file.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/upload_json_file.test.tsx index a5cb1885d9a04..7b97df23feebe 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/upload_json_file.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/document_creation/creation_mode_components/upload_json_file.test.tsx @@ -4,8 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { setMockValues, setMockActions } from '../../../../__mocks__/kea.mock'; -import { rerender } from '../../../../__mocks__'; +import { setMockValues, setMockActions, rerender } from '../../../../__mocks__'; import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.test.tsx index dca06988478ea..607b2ce3c0d78 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/document_detail.test.tsx @@ -3,8 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { setMockValues, setMockActions } from '../../../__mocks__/kea.mock'; + import '../../../__mocks__/react_router_history.mock'; +import { setMockValues, setMockActions } from '../../../__mocks__/kea.mock'; import { unmountHandler } from '../../../__mocks__/shallow_useeffect.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.test.tsx index 8940cc259c647..0a24152094096 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/documents.test.tsx @@ -3,6 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + import { setMockValues } from '../../../__mocks__/kea.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience.test.tsx index 250cd00943d7e..5df132a27bbb3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/search_experience.test.tsx @@ -3,9 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; -import { setMockValues } from '../../../../__mocks__'; + import '../../../../__mocks__/enterprise_search_url.mock'; +import { setMockValues } from '../../../../__mocks__'; const mockSetFields = jest.fn(); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/paging_view.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/paging_view.test.tsx index 32468c153949f..6633e844471f4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/paging_view.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/paging_view.test.tsx @@ -3,6 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/results_per_page_view.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/results_per_page_view.test.tsx index eea91e475de94..637f67b63c255 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/results_per_page_view.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/documents/search_experience/views/results_per_page_view.test.tsx @@ -3,6 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.test.tsx index 2e419168f2e1b..95c9beb9b866e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_nav.test.tsx @@ -4,8 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { setMockValues } from '../../../__mocks__/kea.mock'; -import { rerender } from '../../../__mocks__'; +import { setMockValues, rerender } from '../../../__mocks__'; import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx index 2cedec3c670b5..e2d366e5e5817 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engines/engines_overview.test.tsx @@ -5,8 +5,7 @@ */ import '../../../__mocks__/shallow_useeffect.mock'; -import { rerender } from '../../../__mocks__'; -import { setMockValues, setMockActions } from '../../../__mocks__/kea.mock'; +import { setMockValues, setMockActions, rerender } from '../../../__mocks__'; import React from 'react'; import { shallow, ShallowWrapper } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.test.tsx index 973fc6226910a..6491ee4034597 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.test.tsx @@ -5,7 +5,6 @@ */ import React from 'react'; - import { shallow, ShallowWrapper } from 'enzyme'; import { EuiPanel } from '@elastic/eui'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_field.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_field.test.tsx index 921e2324d3918..4fab1196089cb 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_field.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_field.test.tsx @@ -5,7 +5,6 @@ */ import React from 'react'; - import { shallow } from 'enzyme'; import { ResultField } from './result_field'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_header.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_header.test.tsx index 4ccebb90eb6fe..9aab6fb5d55ce 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_header.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_header.test.tsx @@ -5,7 +5,6 @@ */ import React from 'react'; - import { shallow } from 'enzyme'; import { ResultHeader } from './result_header'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_header_item.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_header_item.test.tsx index b4368f83b1833..04e6f1d8bf3cd 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_header_item.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result_header_item.test.tsx @@ -5,7 +5,6 @@ */ import React from 'react'; - import { mount } from 'enzyme'; import { ResultHeaderItem } from './result_header_item'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_confirmation_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_confirmation_modal.test.tsx index bcda85cd49b9a..555822622dd3e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_confirmation_modal.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_confirmation_modal.test.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; import { setMockActions, setMockValues } from '../../../../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.test.tsx index 9140704ece3f8..2c145b2fd535d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/log_retention/log_retention_panel.test.tsx @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; import '../../../../__mocks__/shallow_useeffect.mock'; - import { setMockActions, setMockValues } from '../../../../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.test.tsx index 8a51d91180390..e62964bf4ef45 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/settings/settings.test.tsx @@ -3,6 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + import React from 'react'; import { shallow } from 'enzyme'; import { EuiPageContentBody } from '@elastic/eui'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx index 11387734e9f9e..31007c90ef7cc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx @@ -5,7 +5,6 @@ */ import '../__mocks__/shallow_useeffect.mock'; -import '../__mocks__/kea.mock'; import '../__mocks__/enterprise_search_url.mock'; import { setMockValues, setMockActions } from '../__mocks__'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx index 8ba2da11604c2..86eb075d1c6ba 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx @@ -4,11 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../__mocks__/kea.mock'; -import { mockTelemetryActions } from '../../../__mocks__'; +import { setMockValues, mockTelemetryActions } from '../../../__mocks__'; import React from 'react'; -import { useValues } from 'kea'; import { shallow } from 'enzyme'; import { EuiCard } from '@elastic/eui'; @@ -59,7 +57,7 @@ describe('ProductCard', () => { }); it('renders correct button text when host not present', () => { - (useValues as jest.Mock).mockImplementation(() => ({ config: { host: '' } })); + setMockValues({ config: { host: '' } }); const wrapper = shallow(); const card = wrapper.find(EuiCard).dive().shallow(); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx index 7f638c64b445d..33c5f326b7a80 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx @@ -7,8 +7,7 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { setMockValues } from '../__mocks__/kea.mock'; -import { rerender } from '../__mocks__'; +import { setMockValues, rerender } from '../__mocks__'; import { EnterpriseSearch } from './'; import { SetupGuide } from './components/setup_guide'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status.test.tsx index 42cb6c229ad63..b8e5c8771dd42 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/indexing_status/indexing_status.test.tsx @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../__mocks__/kea.mock'; import '../../__mocks__/shallow_useeffect.mock'; - import { setMockActions, setMockValues } from '../../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts index aa74d94837eec..10491a9bf121d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts @@ -4,8 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { setMockValues } from '../../__mocks__/kea.mock'; -import { mockKibanaValues, mockHistory } from '../../__mocks__'; +import { setMockValues, mockKibanaValues, mockHistory } from '../../__mocks__'; jest.mock('../react_router_helpers', () => ({ letBrowserHandleEvent: jest.fn(() => false), diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx index dcc04100d85a4..06a77ba275c08 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx @@ -5,8 +5,7 @@ */ import '../../__mocks__/shallow_useeffect.mock'; -import { setMockValues } from '../../__mocks__/kea.mock'; -import { mockKibanaValues, mockHistory } from '../../__mocks__'; +import { setMockValues, mockKibanaValues, mockHistory } from '../../__mocks__'; import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.test.tsx index 083173c8e7a4c..f40de39de0b55 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/not_found/not_found.test.tsx @@ -4,10 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../__mocks__/kea.mock'; +import { setMockValues } from '../../__mocks__/kea.mock'; import React from 'react'; -import { useValues } from 'kea'; import { shallow } from 'enzyme'; import { EuiButton as EuiButtonExternal, EuiEmptyPrompt } from '@elastic/eui'; @@ -45,7 +44,7 @@ describe('NotFound', () => { }); it('changes the support URL if the user has a gold+ license', () => { - (useValues as jest.Mock).mockReturnValueOnce({ hasGoldLicense: true }); + setMockValues({ hasGoldLicense: true }); const wrapper = shallow(); const prompt = wrapper.find(EuiEmptyPrompt).dive().shallow(); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx index 748f4b06f7cac..1968b76a45f2c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx @@ -4,8 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { setMockValues } from '../../__mocks__/kea.mock'; -import { rerender } from '../../__mocks__'; +import { setMockValues, rerender } from '../../__mocks__'; import React from 'react'; import { shallow, ShallowWrapper } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/app_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/app_logic.test.ts index d77faf471facc..620162113a9b4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/app_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/app_logic.test.ts @@ -4,15 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import { resetContext } from 'kea'; +import { LogicMounter } from '../__mocks__'; import { DEFAULT_INITIAL_APP_DATA } from '../../../common/__mocks__'; import { AppLogic } from './app_logic'; describe('AppLogic', () => { + const { mount } = new LogicMounter(AppLogic); + beforeEach(() => { - resetContext({}); - AppLogic.mount(); + mount(); }); const DEFAULT_VALUES = { diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx index 20b15bcfc45ca..b5a6d5fc1e2f5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.test.tsx @@ -5,7 +5,6 @@ */ import '../__mocks__/shallow_useeffect.mock'; -import '../__mocks__/kea.mock'; import { setMockValues, setMockActions, mockKibanaValues } from '../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.test.tsx index 184cd7ad48643..c6a2a07708ff6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_list.test.tsx @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../../__mocks__/kea.mock'; import '../../../../../__mocks__/shallow_useeffect.mock'; - import { setMockActions, setMockValues } from '../../../../../__mocks__'; import { contentSources, diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_logic.test.ts index 1cd7da56dbe73..d08f807691c2b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/add_source_logic.test.ts @@ -4,9 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { resetContext } from 'kea'; - import { + LogicMounter, mockFlashMessageHelpers, mockHttpValues, expectedAsyncError, @@ -30,6 +29,7 @@ import { } from './add_source_logic'; describe('AddSourceLogic', () => { + const { mount } = new LogicMounter(AddSourceLogic); const { http } = mockHttpValues; const { clearFlashMessages, flashAPIErrors } = mockFlashMessageHelpers; @@ -71,8 +71,7 @@ describe('AddSourceLogic', () => { beforeEach(() => { jest.clearAllMocks(); - resetContext({}); - AddSourceLogic.mount(); + mount(); }); it('has expected default values', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.test.tsx index bb024178ea2fb..00ea5922a56c6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/available_sources_list.test.tsx @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../../__mocks__/kea.mock'; import '../../../../../__mocks__/shallow_useeffect.mock'; - import { setMockValues } from '../../../../../__mocks__'; import { mergedAvailableSources } from '../../../../__mocks__/content_sources.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.test.tsx index 45c0e0eb9d2a1..52ab3cefaffee 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_custom.test.tsx @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../../__mocks__/kea.mock'; import '../../../../../__mocks__/shallow_useeffect.mock'; - import { setMockActions, setMockValues } from '../../../../../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.test.tsx index 37cf516f1791b..9c19f32e48f1f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/configure_oauth.test.tsx @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../../__mocks__/kea.mock'; import '../../../../../__mocks__/shallow_useeffect.mock'; - import { setMockActions, setMockValues } from '../../../../../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.test.tsx index 43adc0e681777..91e0f3185f519 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/connect_instance.test.tsx @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../../__mocks__/kea.mock'; import '../../../../../__mocks__/shallow_useeffect.mock'; - import { setMockActions, setMockValues } from '../../../../../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.test.tsx index 583e52b62d67b..cab6a754c58ea 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/re_authenticate.test.tsx @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../../__mocks__/kea.mock'; import '../../../../../__mocks__/shallow_useeffect.mock'; - import { setMockActions, setMockValues } from '../../../../../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.test.tsx index c92427035646c..29e2c438b5c84 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/save_config.test.tsx @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../../__mocks__/kea.mock'; import '../../../../../__mocks__/shallow_useeffect.mock'; - import { setMockActions, setMockValues } from '../../../../../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.test.tsx index f5bcfe1354c0a..7f497a508bba3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/source_features.test.tsx @@ -4,9 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../../__mocks__/kea.mock'; -import '../../../../../__mocks__/shallow_useeffect.mock'; - import { mountAsync, setMockValues } from '../../../../../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/add_group_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/add_group_modal.test.tsx index 59216126a2372..b0ddc8d3896c1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/add_group_modal.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/add_group_modal.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { setMockValues, setMockActions } from '../../../../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/clear_filters_link.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/clear_filters_link.test.tsx index 6a781f52c9e95..a9c4ca22af6bf 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/clear_filters_link.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/clear_filters_link.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { setMockActions } from '../../../../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_list.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_list.test.tsx index 07fae45b6b714..b607834ab7d26 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_list.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_list.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { users } from '../../../__mocks__/users.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_popover.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_popover.test.tsx index 215a0e3eecdd8..2fdbb77c11b25 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_popover.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/filterable_users_popover.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { setMockActions } from '../../../../__mocks__'; import { users } from '../../../__mocks__/users.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_manager_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_manager_modal.test.tsx index 2826d740d5339..3644def0ce8ad 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_manager_modal.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_manager_modal.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { setMockValues } from '../../../../__mocks__'; import { groups } from '../../../__mocks__/groups.mock'; import { contentSources } from '../../../__mocks__/content_sources.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.test.tsx index 74dee238ee826..e0bda91cb0c8a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_overview.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { setMockActions, setMockValues } from '../../../../__mocks__'; import { groups } from '../../../__mocks__/groups.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.test.tsx index c7eea8ab64d45..5bfdf8f924822 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { setMockValues } from '../../../../__mocks__'; import { groups } from '../../../__mocks__/groups.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_sources_dropdown.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_sources_dropdown.test.tsx index 9493e52e08b81..560c616d61f09 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_sources_dropdown.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_sources_dropdown.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { contentSources } from '../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_users_dropdown.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_users_dropdown.test.tsx index 039a2620f1fd4..7bd6657367374 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_users_dropdown.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_row_users_dropdown.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { setMockActions, setMockValues } from '../../../../__mocks__'; import { users } from '../../../__mocks__/users.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_source_prioritization.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_source_prioritization.test.tsx index 367f1862b2bb9..52ab262503a92 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_source_prioritization.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_source_prioritization.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { setMockActions, setMockValues } from '../../../../__mocks__'; import { groups } from '../../../__mocks__/groups.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sources.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sources.test.tsx index 8ab3ace7aed93..5b5b995c05140 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sources.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sources.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { contentSources } from '../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sub_nav.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sub_nav.test.tsx index 7ddecc21c22c4..04caf5c85f1c3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sub_nav.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_sub_nav.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { setMockValues } from '../../../../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users.test.tsx index 581486141d0b0..776a6a5e50735 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { users } from '../../../__mocks__/users.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users_table.test.tsx index 479fd5668cf40..b8618b0e3cf80 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/group_users_table.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { setMockValues } from '../../../../__mocks__'; import { groups } from '../../../__mocks__/groups.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.test.tsx index 38d035cbca908..a57e272c20589 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/groups_table.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { setMockActions, setMockValues } from '../../../../__mocks__'; import { groups } from '../../../__mocks__/groups.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/manage_users_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/manage_users_modal.test.tsx index 34f748e8a7169..2fca103a9809f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/manage_users_modal.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/manage_users_modal.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { setMockActions, setMockValues } from '../../../../__mocks__'; import { users } from '../../../__mocks__/users.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/shared_sources_modal.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/shared_sources_modal.test.tsx index 8c5ead2509d9e..50228ec80563a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/shared_sources_modal.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/shared_sources_modal.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { setMockActions, setMockValues } from '../../../../__mocks__'; import { groups } from '../../../__mocks__/groups.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/source_option_item.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/source_option_item.test.tsx index 8a3901f5462df..8cb72bf1378a6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/source_option_item.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/source_option_item.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { contentSources } from '../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/sources_list.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/sources_list.test.tsx index 05754f3846bb0..bc64faa5af03c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/sources_list.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/sources_list.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { contentSources } from '../../../__mocks__/content_sources.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_sources_dropdown.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_sources_dropdown.test.tsx index e75feb4254929..889f7e55b23b9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_sources_dropdown.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_sources_dropdown.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { setMockActions, setMockValues } from '../../../../__mocks__'; import { contentSources } from '../../../__mocks__/content_sources.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_users_dropdown.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_users_dropdown.test.tsx index 9d461e06a77ec..8de10fbf02270 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_users_dropdown.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filter_users_dropdown.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { setMockActions, setMockValues } from '../../../../__mocks__'; import { users } from '../../../__mocks__/users.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filters.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filters.test.tsx index 80662bc0974a1..cee767db40e67 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filters.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/table_filters.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { setMockActions, setMockValues } from '../../../../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/user_option_item.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/user_option_item.test.tsx index 72611f254d01c..a96cf44a05cdd 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/user_option_item.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/components/user_option_item.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../../__mocks__/kea.mock'; - import { users } from '../../../__mocks__/users.mock'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_logic.test.ts index cfd4c279c6f8c..e90acd929a990 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_logic.test.ts @@ -4,9 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { resetContext } from 'kea'; - import { + LogicMounter, mockKibanaValues, mockFlashMessageHelpers, mockHttpValues, @@ -20,6 +19,7 @@ import { GroupLogic } from './group_logic'; import { GROUPS_PATH } from '../../routes'; describe('GroupLogic', () => { + const { mount } = new LogicMounter(GroupLogic); const { http } = mockHttpValues; const { navigateToUrl } = mockKibanaValues; const { @@ -37,8 +37,7 @@ describe('GroupLogic', () => { beforeEach(() => { jest.clearAllMocks(); - resetContext({}); - GroupLogic.mount(); + mount(); }); it('has expected default values', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_router.test.tsx index 6f293920fa387..8cc40b22b2cf5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_router.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/group_router.test.tsx @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../__mocks__/kea.mock'; import '../../../__mocks__/shallow_useeffect.mock'; - import { setMockValues, setMockActions } from '../../../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.test.tsx index 85175d156f886..5412924438ca6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups.test.tsx @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../__mocks__/kea.mock'; import '../../../__mocks__/shallow_useeffect.mock'; - import { setMockActions, setMockValues } from '../../../__mocks__'; import { groups } from '../../__mocks__/groups.mock'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts index bbeded9207d01..76352a6670650 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_logic.test.ts @@ -4,9 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { resetContext } from 'kea'; +import { + LogicMounter, + mockFlashMessageHelpers, + mockHttpValues, + expectedAsyncError, +} from '../../../__mocks__'; -import { mockFlashMessageHelpers, mockHttpValues, expectedAsyncError } from '../../../__mocks__'; import { DEFAULT_META } from '../../../shared/constants'; import { JSON_HEADER as headers } from '../../../../../common/constants'; @@ -21,6 +25,7 @@ const TIMEOUT = 400; const delay = () => new Promise((resolve) => setTimeout(resolve, TIMEOUT)); describe('GroupsLogic', () => { + const { mount } = new LogicMounter(GroupsLogic); const { http } = mockHttpValues; const { clearFlashMessages, flashAPIErrors } = mockFlashMessageHelpers; @@ -31,8 +36,7 @@ describe('GroupsLogic', () => { beforeEach(() => { jest.clearAllMocks(); - resetContext({}); - GroupsLogic.mount(); + mount(); }); it('has expected default values', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_router.test.tsx index 0b2b1ad05dfd7..c94a75612e72a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_router.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/groups/groups_router.test.tsx @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../__mocks__/kea.mock'; import '../../../__mocks__/shallow_useeffect.mock'; - import { setMockActions } from '../../../__mocks__'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview_logic.test.ts index fb55d11be1f0f..a56235caca5ec 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/overview_logic.test.ts @@ -4,20 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -import { resetContext } from 'kea'; - -import { mockHttpValues } from '../../../__mocks__'; +import { LogicMounter, mockHttpValues } from '../../../__mocks__'; import { mockOverviewValues } from './__mocks__'; import { OverviewLogic } from './overview_logic'; describe('OverviewLogic', () => { + const { mount } = new LogicMounter(OverviewLogic); const { http } = mockHttpValues; beforeEach(() => { jest.clearAllMocks(); - resetContext({}); - OverviewLogic.mount(); + mount(); }); it('has expected default values', () => { diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts index d563960fe4284..ff070a7f08bb1 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts +++ b/x-pack/plugins/index_lifecycle_management/__jest__/client_integration/edit_policy/edit_policy.test.ts @@ -700,33 +700,60 @@ describe('', () => { describe('searchable snapshot', () => { describe('on cloud', () => { - beforeEach(async () => { - httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy('my_policy')]); - httpRequestsMockHelpers.setListNodes({ - isUsingDeprecatedDataRoleConfig: false, - nodesByAttributes: { test: ['123'] }, - nodesByRoles: { data: ['123'] }, - }); - httpRequestsMockHelpers.setListSnapshotRepos({ repositories: ['found-snapshots'] }); + describe('new policy', () => { + beforeEach(async () => { + // simulate creating a new policy + httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy('')]); + httpRequestsMockHelpers.setListNodes({ + isUsingDeprecatedDataRoleConfig: false, + nodesByAttributes: { test: ['123'] }, + nodesByRoles: { data: ['123'] }, + }); + httpRequestsMockHelpers.setListSnapshotRepos({ repositories: ['found-snapshots'] }); - await act(async () => { - testBed = await setup({ appServicesContext: { cloud: { isCloudEnabled: true } } }); - }); + await act(async () => { + testBed = await setup({ appServicesContext: { cloud: { isCloudEnabled: true } } }); + }); - const { component } = testBed; - component.update(); + const { component } = testBed; + component.update(); + }); + test('defaults searchable snapshot to true on cloud', async () => { + const { find, actions } = testBed; + await actions.cold.enable(true); + expect( + find('searchableSnapshotField-cold.searchableSnapshotToggle').props()['aria-checked'] + ).toBe(true); + }); }); + describe('existing policy', () => { + beforeEach(async () => { + httpRequestsMockHelpers.setLoadPolicies([getDefaultHotPhasePolicy('my_policy')]); + httpRequestsMockHelpers.setListNodes({ + isUsingDeprecatedDataRoleConfig: false, + nodesByAttributes: { test: ['123'] }, + nodesByRoles: { data: ['123'] }, + }); + httpRequestsMockHelpers.setListSnapshotRepos({ repositories: ['found-snapshots'] }); - test('correctly sets snapshot repository default to "found-snapshots"', async () => { - const { actions } = testBed; - await actions.cold.enable(true); - await actions.cold.toggleSearchableSnapshot(true); - await actions.savePolicy(); - const latestRequest = server.requests[server.requests.length - 1]; - const request = JSON.parse(JSON.parse(latestRequest.requestBody).body); - expect(request.phases.cold.actions.searchable_snapshot.snapshot_repository).toEqual( - 'found-snapshots' - ); + await act(async () => { + testBed = await setup({ appServicesContext: { cloud: { isCloudEnabled: true } } }); + }); + + const { component } = testBed; + component.update(); + }); + test('correctly sets snapshot repository default to "found-snapshots"', async () => { + const { actions } = testBed; + await actions.cold.enable(true); + await actions.cold.toggleSearchableSnapshot(true); + await actions.savePolicy(); + const latestRequest = server.requests[server.requests.length - 1]; + const request = JSON.parse(JSON.parse(latestRequest.requestBody).body); + expect(request.phases.cold.actions.searchable_snapshot.snapshot_repository).toEqual( + 'found-snapshots' + ); + }); }); }); describe('on non-enterprise license', () => { diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/searchable_snapshot_field/searchable_snapshot_field.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/searchable_snapshot_field/searchable_snapshot_field.tsx index 3157c0a51accf..5fa192158fb3b 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/searchable_snapshot_field/searchable_snapshot_field.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/phases/shared_fields/searchable_snapshot_field/searchable_snapshot_field.tsx @@ -51,7 +51,7 @@ export const SearchableSnapshotField: FunctionComponent = ({ phase }) => const { services: { cloud }, } = useKibana(); - const { getUrlForApp, policy, license } = useEditPolicyContext(); + const { getUrlForApp, policy, license, isNewPolicy } = useEditPolicyContext(); const { isUsingSearchableSnapshotInHotPhase, isUsingRollover } = useConfigurationIssues(); const searchableSnapshotPath = `phases.${phase}.actions.searchable_snapshot.snapshot_repository`; @@ -59,15 +59,20 @@ export const SearchableSnapshotField: FunctionComponent = ({ phase }) => const [formData] = useFormData({ watch: searchableSnapshotPath }); const searchableSnapshotRepo = get(formData, searchableSnapshotPath); + const isColdPhase = phase === 'cold'; const isDisabledDueToLicense = !license.canUseSearchableSnapshot(); - const isDisabledInColdDueToHotPhase = phase === 'cold' && isUsingSearchableSnapshotInHotPhase; - const isDisabledInColdDueToRollover = phase === 'cold' && !isUsingRollover; + const isDisabledInColdDueToHotPhase = isColdPhase && isUsingSearchableSnapshotInHotPhase; + const isDisabledInColdDueToRollover = isColdPhase && !isUsingRollover; const isDisabled = isDisabledDueToLicense || isDisabledInColdDueToHotPhase || isDisabledInColdDueToRollover; const [isFieldToggleChecked, setIsFieldToggleChecked] = useState(() => - Boolean(policy.phases[phase]?.actions?.searchable_snapshot?.snapshot_repository) + Boolean( + // New policy on cloud should have searchable snapshot on in cold phase + (isColdPhase && isNewPolicy && cloud?.isCloudEnabled) || + policy.phases[phase]?.actions?.searchable_snapshot?.snapshot_repository + ) ); useEffect(() => { diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy_context.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy_context.tsx index f7b9b1af1ee3a..3f6eac9b7a8af 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy_context.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy_context.tsx @@ -32,7 +32,7 @@ export const EditPolicyContextProvider = ({ return {children}; }; -export const useEditPolicyContext = () => { +export const useEditPolicyContext = (): EditPolicyContextValue => { const ctx = useContext(EditPolicyContext); if (!ctx) { throw new Error('useEditPolicyContext can only be called inside of EditPolicyContext!'); diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/constants.ts b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/constants.ts index 95ec298e2e349..7fae1fc74d657 100644 --- a/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/constants.ts +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/constants.ts @@ -13,3 +13,6 @@ export const SIDEBAR_GROW_SIZE = 2; // Axis height // NOTE: This isn't a perfect solution - changes in font size etc within charts could change the ideal height here. export const FIXED_AXIS_HEIGHT = 32; + +// number of items to display in canvas, since canvas can only have limited size +export const CANVAS_MAX_ITEMS = 150; diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/middle_truncated_text.tsx b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/middle_truncated_text.tsx index 8479ee5cae195..592e49740b5f0 100644 --- a/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/middle_truncated_text.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/middle_truncated_text.tsx @@ -7,6 +7,7 @@ import React, { useMemo } from 'react'; import styled from 'styled-components'; import { EuiScreenReaderOnly, EuiToolTip } from '@elastic/eui'; +import { FIXED_AXIS_HEIGHT } from './constants'; const OuterContainer = styled.div` width: 100%; @@ -29,10 +30,12 @@ const FirstChunk = styled.span` text-overflow: ellipsis; white-space: nowrap; overflow: hidden; + line-height: ${FIXED_AXIS_HEIGHT}px; `; const LastChunk = styled.span` flex-shrink: 0; + line-height: ${FIXED_AXIS_HEIGHT}px; `; export const getChunks = (text: string) => { diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/sidebar.tsx b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/sidebar.tsx index c551561d5ad4f..7493cfef8b70a 100644 --- a/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/sidebar.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/sidebar.tsx @@ -6,7 +6,7 @@ import React from 'react'; import { EuiFlexItem } from '@elastic/eui'; -import { SIDEBAR_GROW_SIZE } from './constants'; +import { FIXED_AXIS_HEIGHT, SIDEBAR_GROW_SIZE } from './constants'; import { IWaterfallContext } from '../context/waterfall_chart'; import { WaterfallChartSidebarContainer, @@ -18,14 +18,13 @@ import { WaterfallChartProps } from './waterfall_chart'; interface SidebarProps { items: Required['sidebarItems']; - height: number; render: Required['renderSidebarItem']; } -export const Sidebar: React.FC = ({ items, height, render }) => { +export const Sidebar: React.FC = ({ items, render }) => { return ( - + props.theme.eui.euiZLevel4}; `; interface WaterfallChartSidebarContainer { @@ -54,7 +55,7 @@ interface WaterfallChartSidebarContainer { } export const WaterfallChartSidebarContainer = euiStyled.div` - height: ${(props) => `${props.height - FIXED_AXIS_HEIGHT}px`}; + height: ${(props) => `${props.height}px`}; overflow-y: hidden; `; @@ -76,12 +77,14 @@ export const WaterfallChartSidebarFlexItem = euiStyled(EuiFlexItem)` interface WaterfallChartChartContainer { height: number; + chartIndex: number; } export const WaterfallChartChartContainer = euiStyled.div` width: 100%; - height: ${(props) => `${props.height}px`}; - margin-top: -${FIXED_AXIS_HEIGHT}px; + height: ${(props) => `${props.height + FIXED_AXIS_HEIGHT - 4}px`}; + margin-top: -${FIXED_AXIS_HEIGHT - 4}px; + z-index: ${(props) => Math.round(props.theme.eui.euiZLevel3 / (props.chartIndex + 1))}; `; export const WaterfallChartLegendContainer = euiStyled.div` diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/use_bar_charts.test.tsx b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/use_bar_charts.test.tsx new file mode 100644 index 0000000000000..28b74c5affbdf --- /dev/null +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/use_bar_charts.test.tsx @@ -0,0 +1,69 @@ +/* + * 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 { useBarCharts } from './use_bar_charts'; +import { renderHook } from '@testing-library/react-hooks'; +import { IWaterfallContext } from '../context/waterfall_chart'; +import { CANVAS_MAX_ITEMS } from './constants'; + +const generateTestData = (): IWaterfallContext['data'] => { + const numberOfItems = 1000; + + const data: IWaterfallContext['data'] = []; + const testItem = { + x: 0, + y0: 0, + y: 4.345000023022294, + config: { + colour: '#b9a888', + showTooltip: true, + tooltipProps: { value: 'Queued / Blocked: 4.345ms', colour: '#b9a888' }, + }, + }; + + for (let i = 0; i < numberOfItems; i++) { + data.push( + { + ...testItem, + x: i, + }, + { + ...testItem, + x: i, + y0: 7, + y: 25, + } + ); + } + + return data; +}; + +describe('useBarChartsHooks', () => { + it('returns result as expected', () => { + const { result, rerender } = renderHook((props) => useBarCharts(props), { + initialProps: { data: [] as IWaterfallContext['data'] }, + }); + + expect(result.current).toHaveLength(0); + const newData = generateTestData(); + + rerender({ data: newData }); + + // Thousands items will result in 7 Canvas + expect(result.current.length).toBe(7); + + const firstChartItems = result.current[0]; + const lastChartItems = result.current[4]; + + // first chart items last item should be x 199, since we only display 150 items + expect(firstChartItems[firstChartItems.length - 1].x).toBe(CANVAS_MAX_ITEMS - 1); + + // since here are 5 charts, last chart first item should be x 800 + expect(lastChartItems[0].x).toBe(CANVAS_MAX_ITEMS * 4); + expect(lastChartItems[lastChartItems.length - 1].x).toBe(CANVAS_MAX_ITEMS * 5 - 1); + }); +}); diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/use_bar_charts.ts b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/use_bar_charts.ts new file mode 100644 index 0000000000000..3345b30f5239f --- /dev/null +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/use_bar_charts.ts @@ -0,0 +1,40 @@ +/* + * 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 { useEffect, useState } from 'react'; +import { IWaterfallContext } from '../context/waterfall_chart'; +import { CANVAS_MAX_ITEMS } from './constants'; + +export interface UseBarHookProps { + data: IWaterfallContext['data']; +} + +export const useBarCharts = ({ data = [] }: UseBarHookProps) => { + const [charts, setCharts] = useState>([]); + + useEffect(() => { + if (data.length > 0) { + let chartIndex = 1; + + const firstCanvasItems = data.filter((item) => item.x <= CANVAS_MAX_ITEMS); + + const chartsN: Array = [firstCanvasItems]; + + data.forEach((item) => { + // Subtract 1 to account for x value starting from 0 + if (item.x === CANVAS_MAX_ITEMS * chartIndex && !chartsN[item.x / CANVAS_MAX_ITEMS]) { + chartsN.push([]); + chartIndex++; + } + chartsN[chartIndex - 1].push(item); + }); + + setCharts(chartsN); + } + }, [data]); + + return charts; +}; diff --git a/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/waterfall_chart.tsx b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/waterfall_chart.tsx index 73aaacb6fab58..e937c3d35ec08 100644 --- a/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/waterfall_chart.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/synthetics/waterfall/components/waterfall_chart.tsx @@ -33,9 +33,10 @@ import { WaterfallChartTooltip, } from './styles'; import { WaterfallData } from '../types'; -import { BAR_HEIGHT, MAIN_GROW_SIZE, SIDEBAR_GROW_SIZE, FIXED_AXIS_HEIGHT } from './constants'; +import { BAR_HEIGHT, CANVAS_MAX_ITEMS, MAIN_GROW_SIZE, SIDEBAR_GROW_SIZE } from './constants'; import { Sidebar } from './sidebar'; import { Legend } from './legend'; +import { useBarCharts } from './use_bar_charts'; const Tooltip = (tooltipInfo: TooltipInfo) => { const { data, renderTooltipItem } = useWaterfallContext(); @@ -69,20 +70,11 @@ export interface WaterfallChartProps { fullHeight?: boolean; } -const getUniqueBars = (data: WaterfallData) => { - return (data ?? []).reduce>((acc, item) => { - if (!acc.has(item.x)) { - acc.add(item.x); - return acc; - } else { - return acc; - } - }, new Set()); +const getChartHeight = (data: WaterfallData, ind: number): number => { + // We get the last item x(number of bars) and adds 1 to cater for 0 index + return (data[data.length - 1]?.x + 1 - ind * CANVAS_MAX_ITEMS) * BAR_HEIGHT; }; -const getChartHeight = (data: WaterfallData): number => - getUniqueBars(data).size * BAR_HEIGHT + FIXED_AXIS_HEIGHT; - export const WaterfallChart = ({ tickFormat, domain, @@ -94,10 +86,6 @@ export const WaterfallChart = ({ }: WaterfallChartProps) => { const { data, sidebarItems, legendItems } = useWaterfallContext(); - const generatedHeight = useMemo(() => { - return getChartHeight(data); - }, [data]); - const [darkMode] = useUiSetting$('theme:darkMode'); const theme = useMemo(() => { @@ -108,10 +96,8 @@ export const WaterfallChart = ({ const [height, setHeight] = useState(maxHeight); - const shouldRenderSidebar = - sidebarItems && sidebarItems.length > 0 && renderSidebarItem ? true : false; - const shouldRenderLegend = - legendItems && legendItems.length > 0 && renderLegendItem ? true : false; + const shouldRenderSidebar = !!(sidebarItems && sidebarItems.length > 0 && renderSidebarItem); + const shouldRenderLegend = !!(legendItems && legendItems.length > 0 && renderLegendItem); useEffect(() => { if (fullHeight && chartWrapperDivRef.current) { @@ -120,6 +106,8 @@ export const WaterfallChart = ({ } }, [chartWrapperDivRef, fullHeight]); + const chartsToDisplay = useBarCharts({ data }); + return ( <> @@ -174,44 +162,48 @@ export const WaterfallChart = ({ style={{ paddingTop: '10px' }} ref={chartWrapperDivRef} > - {shouldRenderSidebar && ( - - )} + {shouldRenderSidebar && } - - - - - - - - - + {chartsToDisplay.map((chartData, ind) => ( + + + + + + + + + + ))} {shouldRenderLegend && }