fix some tests

Signed-off-by: Kiss Miklos <miklos@roadie.io>
This commit is contained in:
Kiss Miklos
2022-06-27 16:49:23 +02:00
parent b713a4c8dc
commit af0b031424
10 changed files with 112 additions and 13 deletions
@@ -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<DbRefreshStateRow>('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<DbRefreshKeysRow>('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<DbRefreshKeysRow>('refresh_keys').insert({
entity_ref: 'location:default/root-1',
key: 'foo',
});
let rows = await knex<DbRefreshKeysRow>('refresh_keys').select();
expect(rows.length).toBe(1);
await db.transaction(async tx =>
db.deleteRefreshKey(tx, {
key: 'foo',
}),
);
rows = await knex<DbRefreshKeysRow>('refresh_keys').select();
expect(rows.length).toBe(0);
},
);
});
});
@@ -562,7 +562,7 @@ export class DefaultProcessingDatabase implements ProcessingDatabase {
const tx = txOpaque as Knex.Transaction;
const { key } = options;
await tx<DbRefreshKeysRow>('refresh_keys').where({ key }).delete();
await tx<DbRefreshKeysRow>('refresh_keys').where({ key: key }).delete();
}
async transaction<T>(fn: (tx: Transaction) => Promise<T>): Promise<T> {
+13 -2
View File
@@ -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<void>;
/**
* Schedules a refresh for all the entities that have the given refreshKey
*/
setRefreshKeys(
txOpaque: Transaction,
options: RefreshKeyOptions,
): Promise<void>;
/**
* Schedules a refresh for all the entities that have the given refreshKey
*/
setRefreshKeys(
txOpaque: Transaction,
options: RefreshKeyOptions,
@@ -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(/^[^*]*$/),
});
@@ -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\]/,
@@ -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,
@@ -30,6 +30,7 @@ describe('DefaultCatalogProcessingEngine', () => {
updateProcessedEntity: jest.fn(),
updateEntityCache: jest.fn(),
listParents: jest.fn(),
setRefreshKeys: jest.fn(),
} as unknown as jest.Mocked<DefaultProcessingDatabase>;
const orchestrator: jest.Mocked<CatalogProcessingOrchestrator> = {
process: jest.fn(),
@@ -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',
@@ -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
@@ -138,6 +138,7 @@ describe('Refresh integration', () => {
errors: [],
deferredEntities,
state: {},
refreshKeys: [],
};
},
},