From af0b0314249053fb3a849d2b9460f1824728bfcd Mon Sep 17 00:00:00 2001 From: Kiss Miklos Date: Mon, 27 Jun 2022 16:49:23 +0200 Subject: [PATCH] fix some tests Signed-off-by: Kiss Miklos --- .../DefaultProcessingDatabase.test.ts | 56 +++++++++++++++++++ .../src/database/DefaultProcessingDatabase.ts | 2 +- plugins/catalog-backend/src/database/types.ts | 15 ++++- .../modules/core/FileReaderProcessor.test.ts | 22 ++++++-- .../modules/core/PlaceholderProcessor.test.ts | 13 ++++- .../modules/core/UrlReaderProcessor.test.ts | 2 +- .../DefaultCatalogProcessingEngine.test.ts | 1 + ...faultCatalogProcessingOrchestrator.test.ts | 2 + .../catalog-backend/src/processing/types.ts | 11 +++- .../src/service/DefaultRefreshService.test.ts | 1 + 10 files changed, 112 insertions(+), 13 deletions(-) diff --git a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts index 251388f0d2..703595e2ee 100644 --- a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts @@ -24,6 +24,7 @@ import { DateTime } from 'luxon'; import { applyDatabaseMigrations } from './migrations'; import { DefaultProcessingDatabase } from './DefaultProcessingDatabase'; import { + DbRefreshKeysRow, DbRefreshStateReferencesRow, DbRefreshStateRow, DbRelationsRow, @@ -67,6 +68,10 @@ describe('Default Processing Database', () => { await db('refresh_state').insert(ref); }; + const insertRefreshKeysRow = async (db: Knex, ref) => { + await db('refresh_keys').insert(ref); + }; + describe('updateProcessedEntity', () => { let id: string; let processedEntity: Entity; @@ -1397,4 +1402,55 @@ describe('Default Processing Database', () => { }, ); }); + + describe('setRefreshKeys', () => { + it.each(databases.eachSupportedId())( + 'should set keys, %p', + async databaseId => { + const { knex, db } = await createDatabase(databaseId); + + await db.transaction(async tx => + db.setRefreshKeys(tx, { + refreshKeys: [{ entityRef: 'location:default/root-1', key: 'foo' }], + }), + ); + + const rows = await knex('refresh_keys').select(); + + expect(rows.length).toBe(1); + expect(rows[0]).toEqual({ + entity_ref: 'location:default/root-1', + key: 'foo', + }); + }, + ); + }); + + describe('deleteRefreshKeys', () => { + it.each(databases.eachSupportedId())( + 'should delete keys, %p', + async databaseId => { + const { knex, db } = await createDatabase(databaseId); + + await knex('refresh_keys').insert({ + entity_ref: 'location:default/root-1', + key: 'foo', + }); + + let rows = await knex('refresh_keys').select(); + + expect(rows.length).toBe(1); + + await db.transaction(async tx => + db.deleteRefreshKey(tx, { + key: 'foo', + }), + ); + + rows = await knex('refresh_keys').select(); + + expect(rows.length).toBe(0); + }, + ); + }); }); diff --git a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts index 7cd590127c..66b87d6b24 100644 --- a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts +++ b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts @@ -562,7 +562,7 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { const tx = txOpaque as Knex.Transaction; const { key } = options; - await tx('refresh_keys').where({ key }).delete(); + await tx('refresh_keys').where({ key: key }).delete(); } async transaction(fn: (tx: Transaction) => Promise): Promise { diff --git a/plugins/catalog-backend/src/database/types.ts b/plugins/catalog-backend/src/database/types.ts index b4ab598f4a..23755ad513 100644 --- a/plugins/catalog-backend/src/database/types.ts +++ b/plugins/catalog-backend/src/database/types.ts @@ -18,7 +18,7 @@ import { Entity } from '@backstage/catalog-model'; import { JsonObject } from '@backstage/types'; import { DateTime } from 'luxon'; import { EntityRelationSpec } from '../api'; -import { DeferredEntity } from '../processing/types'; +import { DeferredEntity, RefreshKeyData } from '../processing/types'; import { DbRelationsRow } from './tables'; /** @@ -82,7 +82,7 @@ export type ReplaceUnprocessedEntitiesOptions = }; export type RefreshKeyOptions = { - refreshKeys: { key: String; entityRef: String }[]; + refreshKeys: RefreshKeyData[]; }; export type RefreshByKeyOptions = { @@ -157,6 +157,17 @@ export interface ProcessingDatabase { */ refresh(txOpaque: Transaction, options: RefreshOptions): Promise; + /** + * Schedules a refresh for all the entities that have the given refreshKey + */ + setRefreshKeys( + txOpaque: Transaction, + options: RefreshKeyOptions, + ): Promise; + + /** + * Schedules a refresh for all the entities that have the given refreshKey + */ setRefreshKeys( txOpaque: Transaction, options: RefreshKeyOptions, diff --git a/plugins/catalog-backend/src/modules/core/FileReaderProcessor.test.ts b/plugins/catalog-backend/src/modules/core/FileReaderProcessor.test.ts index a3eb5e4542..ad47350346 100644 --- a/plugins/catalog-backend/src/modules/core/FileReaderProcessor.test.ts +++ b/plugins/catalog-backend/src/modules/core/FileReaderProcessor.test.ts @@ -43,7 +43,10 @@ describe('FileReaderProcessor', () => { expect(generated.type).toBe('entity'); expect(generated.location).toEqual(spec); - expect(generated.entity).toEqual({ kind: 'Component' }); + expect(generated.entity).toEqual({ + kind: 'Component', + metadata: { name: 'component-test' }, + }); }); it('should fail load from file with error', async () => { @@ -77,14 +80,23 @@ describe('FileReaderProcessor', () => { defaultEntityDataParser, ); - expect(emit).toBeCalledTimes(2); - expect(emit.mock.calls[0][0].entity).toEqual({ kind: 'Component' }); + expect(emit).toBeCalledTimes(4); + expect(emit.mock.calls[0][0].entity).toEqual({ + kind: 'Component', + metadata: { name: 'component-test' }, + }); expect(emit.mock.calls[0][0].location).toEqual({ type: 'file', target: expect.stringMatching(/^[^*]*$/), }); - expect(emit.mock.calls[1][0].entity).toEqual({ kind: 'API' }); - expect(emit.mock.calls[1][0].location).toEqual({ + expect(emit.mock.calls[1][0].entityRef).toEqual( + 'component:default/component-test', + ); + expect(emit.mock.calls[2][0].entity).toEqual({ + kind: 'API', + metadata: { name: 'api-test' }, + }); + expect(emit.mock.calls[2][0].location).toEqual({ type: 'file', target: expect.stringMatching(/^[^*]*$/), }); diff --git a/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts b/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts index adff97336e..3ec699bc04 100644 --- a/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts +++ b/plugins/catalog-backend/src/modules/core/PlaceholderProcessor.test.ts @@ -51,7 +51,7 @@ describe('PlaceholderProcessor', () => { integrations, }); await expect( - processor.preProcessEntity(input, { type: 't', target: 'l' }), + processor.preProcessEntity(input, { type: 't', target: 'l' }, () => {}), ).resolves.toBe(input); }); @@ -76,6 +76,7 @@ describe('PlaceholderProcessor', () => { spec: { a: [{ b: { $upper: 'text' } }] }, }, { type: 'fake', target: 'http://example.com' }, + () => {}, ), ).resolves.toEqual({ apiVersion: 'a', @@ -110,7 +111,7 @@ describe('PlaceholderProcessor', () => { }; await expect( - processor.preProcessEntity(entity, { type: 'a', target: 'b' }), + processor.preProcessEntity(entity, { type: 'a', target: 'b' }, () => {}), ).resolves.toEqual(entity); expect(read).not.toBeCalled(); @@ -131,7 +132,7 @@ describe('PlaceholderProcessor', () => { }; await expect( - processor.preProcessEntity(entity, { type: 'a', target: 'b' }), + processor.preProcessEntity(entity, { type: 'a', target: 'b' }, () => {}), ).resolves.toEqual(entity); expect(read).not.toBeCalled(); @@ -158,6 +159,7 @@ describe('PlaceholderProcessor', () => { target: 'https://github.com/backstage/backstage/a/b/catalog-info.yaml', }, + () => {}, ), ).resolves.toEqual({ apiVersion: 'a', @@ -194,6 +196,7 @@ describe('PlaceholderProcessor', () => { target: 'https://github.com/backstage/backstage/a/b/catalog-info.yaml', }, + () => {}, ), ).resolves.toEqual({ apiVersion: 'a', @@ -228,6 +231,7 @@ describe('PlaceholderProcessor', () => { target: 'https://github.com/backstage/backstage/a/b/catalog-info.yaml', }, + () => {}, ), ).resolves.toEqual({ apiVersion: 'a', @@ -266,6 +270,7 @@ describe('PlaceholderProcessor', () => { target: 'https://github.com/backstage/backstage/a/b/catalog-info.yaml', }, + () => {}, ), ).resolves.toEqual({ apiVersion: 'a', @@ -303,6 +308,7 @@ describe('PlaceholderProcessor', () => { type: 'url', target: './a/b/catalog-info.yaml', }, + () => {}, ), ).resolves.toEqual({ apiVersion: 'a', @@ -343,6 +349,7 @@ describe('PlaceholderProcessor', () => { type: 'url', target: './a/b/catalog-info.yaml', }, + () => {}, ), ).rejects.toThrow( /^Placeholder \$text could not form a URL out of \.\/a\/b\/catalog-info\.yaml and \.\.\/c\/catalog-info\.yaml, TypeError \[ERR_INVALID_URL\]/, diff --git a/plugins/catalog-backend/src/modules/core/UrlReaderProcessor.test.ts b/plugins/catalog-backend/src/modules/core/UrlReaderProcessor.test.ts index dbcb9e34df..ecb0eb30d3 100644 --- a/plugins/catalog-backend/src/modules/core/UrlReaderProcessor.test.ts +++ b/plugins/catalog-backend/src/modules/core/UrlReaderProcessor.test.ts @@ -74,7 +74,7 @@ describe('UrlReaderProcessor', () => { mockCache, ); - expect(emitted.length).toBe(1); + expect(emitted.length).toBe(2); expect(emitted[0]).toEqual({ type: 'entity', location: spec, diff --git a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.test.ts b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.test.ts index dd316583af..3b6f126391 100644 --- a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.test.ts +++ b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingEngine.test.ts @@ -30,6 +30,7 @@ describe('DefaultCatalogProcessingEngine', () => { updateProcessedEntity: jest.fn(), updateEntityCache: jest.fn(), listParents: jest.fn(), + setRefreshKeys: jest.fn(), } as unknown as jest.Mocked; const orchestrator: jest.Mocked = { process: jest.fn(), diff --git a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.test.ts b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.test.ts index 6e494d784e..b2d9846391 100644 --- a/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.test.ts +++ b/plugins/catalog-backend/src/processing/DefaultCatalogProcessingOrchestrator.test.ts @@ -102,6 +102,7 @@ describe('DefaultCatalogProcessingOrchestrator', () => { ok: true, completedEntity: entity, deferredEntities: [], + refreshKeys: [], errors: [], relations: [], state: { @@ -119,6 +120,7 @@ describe('DefaultCatalogProcessingOrchestrator', () => { ).resolves.toEqual({ ok: true, completedEntity: entity, + refreshKeys: [], deferredEntities: [ { locationKey: 'url:./new-place', diff --git a/plugins/catalog-backend/src/processing/types.ts b/plugins/catalog-backend/src/processing/types.ts index 78d8b875b2..0bfbbf613b 100644 --- a/plugins/catalog-backend/src/processing/types.ts +++ b/plugins/catalog-backend/src/processing/types.ts @@ -37,7 +37,7 @@ export type EntityProcessingResult = completedEntity: Entity; deferredEntities: DeferredEntity[]; relations: EntityRelationSpec[]; - refreshKeys: { key: String; entityRef: String }[]; + refreshKeys: RefreshKeyData[]; errors: Error[]; } | { @@ -45,6 +45,15 @@ export type EntityProcessingResult = errors: Error[]; }; +/** + * A string to associate to the entity itself. + * @public + */ +export type RefreshKeyData = { + key: String; + entityRef: String; +}; + /** * Responsible for executing the individual processing steps in order to fully process an entity. * @public diff --git a/plugins/catalog-backend/src/service/DefaultRefreshService.test.ts b/plugins/catalog-backend/src/service/DefaultRefreshService.test.ts index 84bfde1259..419aedc15d 100644 --- a/plugins/catalog-backend/src/service/DefaultRefreshService.test.ts +++ b/plugins/catalog-backend/src/service/DefaultRefreshService.test.ts @@ -138,6 +138,7 @@ describe('Refresh integration', () => { errors: [], deferredEntities, state: {}, + refreshKeys: [], }; }, },