Account for legacy path casing in cache invalidation.
Signed-off-by: Eric Peterson <ericpeterson@spotify.com>
This commit is contained in:
committed by
Eric Peterson
parent
12157e8f5b
commit
da0867f952
@@ -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}`,
|
||||
|
||||
Reference in New Issue
Block a user