Account for legacy path casing in cache invalidation.

Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
Eric Peterson
2021-11-12 12:58:17 +01:00
committed by Eric Peterson
parent 12157e8f5b
commit da0867f952
3 changed files with 43 additions and 5 deletions
+2 -2
View File
@@ -46,12 +46,12 @@ describe('createCacheMiddleware', () => {
let app: express.Express;
beforeEach(async () => {
cache = ({
cache = {
get: jest.fn().mockResolvedValue(undefined),
set: jest.fn().mockResolvedValue(undefined),
invalidate: jest.fn().mockResolvedValue(undefined),
invalidateMultiple: jest.fn().mockResolvedValue(undefined),
} as unknown) as jest.Mocked<TechDocsCache>;
} as unknown as jest.Mocked<TechDocsCache>;
const router = await createCacheMiddleware({
logger: getVoidLogger(),
cache,
@@ -66,12 +66,12 @@ describe('DocsSynchronizer', () => {
getBaseUrl: jest.fn(),
getExternalBaseUrl: jest.fn(),
};
const cache: jest.Mocked<TechDocsCache> = ({
const cache: jest.Mocked<TechDocsCache> = {
get: jest.fn(),
set: jest.fn(),
invalidate: jest.fn(),
invalidateMultiple: jest.fn(),
} as unknown) as jest.Mocked<TechDocsCache>;
} as unknown as jest.Mocked<TechDocsCache>;
let docsSynchronizer: DocsSynchronizer;
const mockResponseHandler: jest.Mocked<DocsSynchronizerSyncOpts> = {
@@ -270,6 +270,36 @@ describe('DocsSynchronizer', () => {
entity,
});
expect(mockResponseHandler.finish).toBeCalledWith({ updated: true });
expect(cache.invalidateMultiple).toHaveBeenCalledWith([
'default/component/test/index.html',
]);
});
it('should invalidate expected files when source/cached metadata differ with legacy casing', async () => {
(shouldCheckForUpdate as jest.Mock).mockReturnValue(true);
(publisher.fetchTechDocsMetadata as jest.Mock).mockResolvedValue({
build_timestamp: 456,
files: ['index.html'],
});
const docsSynchronizerWithLegacy = new DocsSynchronizer({
publisher,
config: new ConfigReader({
techdocs: { legacyUseCaseSensitiveTripletPaths: true },
}),
logger: getVoidLogger(),
scmIntegrations: ScmIntegrations.fromConfig(new ConfigReader({})),
cache,
});
await docsSynchronizerWithLegacy.doCacheSync({
responseHandler: mockResponseHandler,
discovery,
token: undefined,
entity,
});
expect(mockResponseHandler.finish).toBeCalledWith({ updated: true });
expect(cache.invalidateMultiple).toHaveBeenCalledWith([
'default/Component/test/index.html',
@@ -180,7 +180,14 @@ export class DocsSynchronizer {
const namespace = entity.metadata?.namespace || ENTITY_DEFAULT_NAMESPACE;
const kind = entity.kind;
const name = entity.metadata.name;
const entityTripletPath = `${namespace}/${kind}/${name}`;
const legacyPathCasing =
this.config.getOptionalBoolean(
'techdocs.legacyUseCaseSensitiveTripletPaths',
) || false;
const tripletPath = `${namespace}/${kind}/${name}`;
const entityTripletPath = `${
legacyPathCasing ? tripletPath : tripletPath.toLocaleLowerCase()
}`;
try {
const [sourceMetadata, cachedMetadata] = await Promise.all([
this.publisher.fetchTechDocsMetadata({ namespace, kind, name }),
@@ -211,6 +218,7 @@ export class DocsSynchronizer {
finish({ updated: false });
}
} catch (e) {
assertError(e);
// In case of error, log and allow the user to go about their business.
this.logger.error(
`Error syncing cache for ${entityTripletPath}: ${e.message}`,