diff --git a/plugins/catalog-backend/src/ingestion/processors/UrlReaderProcessor.test.ts b/plugins/catalog-backend/src/ingestion/processors/UrlReaderProcessor.test.ts index 6521a2b6bf..5874806ac3 100644 --- a/plugins/catalog-backend/src/ingestion/processors/UrlReaderProcessor.test.ts +++ b/plugins/catalog-backend/src/ingestion/processors/UrlReaderProcessor.test.ts @@ -24,6 +24,7 @@ import { msw } from '@backstage/test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { + CatalogProcessorCache, CatalogProcessorEntityResult, CatalogProcessorErrorResult, CatalogProcessorResult, @@ -33,10 +34,17 @@ import { defaultEntityDataParser } from './util/parse'; describe('UrlReaderProcessor', () => { const mockApiOrigin = 'http://localhost'; - + const mockCache: jest.Mocked = { + get: jest.fn(), + set: jest.fn(), + }; const server = setupServer(); msw.setupDefaultHandlers(server); + beforeEach(() => { + jest.resetAllMocks(); + }); + it('should load from url', async () => { const logger = getVoidLogger(); const reader = UrlReaders.default({ @@ -58,7 +66,13 @@ describe('UrlReaderProcessor', () => { ); const generated = (await new Promise(emit => - processor.readLocation(spec, false, emit, defaultEntityDataParser), + processor.readLocation( + spec, + false, + emit, + defaultEntityDataParser, + mockCache, + ), )) as CatalogProcessorEntityResult; expect(generated.type).toBe('entity'); @@ -66,6 +80,49 @@ describe('UrlReaderProcessor', () => { expect(generated.entity).toEqual({ mock: 'entity' }); }); + it('should use cached data when available', async () => { + const logger = getVoidLogger(); + const reader = UrlReaders.default({ + logger, + config: new ConfigReader({ + backend: { reading: { allow: [{ host: 'localhost' }] } }, + }), + }); + server.use( + rest.get(`${mockApiOrigin}/component.yaml`, (_, res, ctx) => + res(ctx.status(304)), + ), + ); + const spec = { + type: 'url', + target: `${mockApiOrigin}/component.yaml`, + }; + const cacheItem = { + etag: 'my-etag', + value: [{ type: 'entity', location: spec, entity: { mock: 'entity' } }], + }; + mockCache.get.mockResolvedValue(cacheItem); + const processor = new UrlReaderProcessor({ reader, logger }); + + const generated = (await new Promise(emit => + processor.readLocation( + spec, + false, + emit, + defaultEntityDataParser, + mockCache, + ), + )) as CatalogProcessorEntityResult; + + expect(generated.type).toBe('entity'); + expect(generated.location).toEqual(spec); + expect(generated.entity).toEqual({ mock: 'entity' }); + expect(mockCache.get).toBeCalledWith('v1'); + expect(mockCache.get).toBeCalledTimes(1); + expect(mockCache.set).toBeCalledWith('v1', cacheItem); + expect(mockCache.set).toBeCalledTimes(1); + }); + it('should fail load from url with error', async () => { const logger = getVoidLogger(); const reader = UrlReaders.default({ @@ -87,7 +144,13 @@ describe('UrlReaderProcessor', () => { ); const generated = (await new Promise(emit => - processor.readLocation(spec, false, emit, defaultEntityDataParser), + processor.readLocation( + spec, + false, + emit, + defaultEntityDataParser, + mockCache, + ), )) as CatalogProcessorErrorResult; expect(generated.type).toBe('error'); @@ -116,6 +179,7 @@ describe('UrlReaderProcessor', () => { false, emit, defaultEntityDataParser, + mockCache, ); expect(reader.search).toBeCalledTimes(1);