test(cache): raise cache coverage
This commit is contained in:
1 parent
1ffaeb14a8
commit
434ff3eb1c
2 files changed
+155
No files matched your search
@@ -0,0 +1,102 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { CONFIG } from '../../src/config/index.js';
|
||||
import {
|
||||
isImmutableArtifactRequest,
|
||||
resolveCachePolicy,
|
||||
resolveResponseCachePolicy
|
||||
} from '../../src/upstream/cache-policy.js';
|
||||
|
||||
const requestContext = {
|
||||
isAI: false,
|
||||
isDocker: false,
|
||||
isGit: false,
|
||||
isGitLFS: false,
|
||||
isHF: false
|
||||
};
|
||||
|
||||
/**
|
||||
* Resolves a cache policy with common non-protocol request defaults.
|
||||
* @param {Partial<Parameters<typeof resolveCachePolicy>[0]>} overrides Policy inputs to override.
|
||||
* @returns {ReturnType<typeof resolveCachePolicy>} Resolved cache policy.
|
||||
*/
|
||||
function resolvePolicy(overrides = {}) {
|
||||
return resolveCachePolicy({
|
||||
canUseCache: true,
|
||||
config: CONFIG,
|
||||
effectivePath: '/gh/user/repo/file.txt',
|
||||
hasSensitiveHeaders: false,
|
||||
platform: 'gh',
|
||||
request: new Request('https://example.com/gh/user/repo/file.txt'),
|
||||
requestContext,
|
||||
targetUrl: 'https://github.com/user/repo/file.txt',
|
||||
...overrides
|
||||
});
|
||||
}
|
||||
|
||||
describe('Cache policy edge coverage', () => {
|
||||
it('uses metadata caching for Maven metadata files', () => {
|
||||
const policy = resolvePolicy({
|
||||
effectivePath: '/maven/maven2/org/example/demo/maven-metadata.xml',
|
||||
platform: 'maven',
|
||||
request: new Request('https://example.com/maven/maven2/org/example/demo/maven-metadata.xml'),
|
||||
targetUrl: 'https://repo1.maven.org/maven2/org/example/demo/maven-metadata.xml'
|
||||
});
|
||||
|
||||
expect(policy.cacheControl).toBe('public, max-age=0, s-maxage=60, must-revalidate');
|
||||
expect(policy.edgeTtl).toBe(60);
|
||||
});
|
||||
|
||||
it('does not treat incomplete or malformed artifact paths as immutable', () => {
|
||||
expect(
|
||||
isImmutableArtifactRequest(
|
||||
'gh',
|
||||
'/gh/user/repo/releases/download/',
|
||||
'https://github.com/user/repo/releases/download/'
|
||||
)
|
||||
).toBe(false);
|
||||
expect(
|
||||
isImmutableArtifactRequest(
|
||||
'pypi-files',
|
||||
'/pypi/files/packages/source/p/pkg/pkg-%E0%A4%A.tar.gz',
|
||||
''
|
||||
)
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('treats Vary star as uncacheable at response time', () => {
|
||||
const basePolicy = resolvePolicy();
|
||||
const policy = resolveResponseCachePolicy({
|
||||
basePolicy,
|
||||
response: new Response('ok', {
|
||||
headers: {
|
||||
Vary: 'Accept-Encoding, *'
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
expect(policy.allowCacheApi).toBe(false);
|
||||
expect(policy.cacheControl).toBe('no-store');
|
||||
});
|
||||
|
||||
it('ignores non-standard header objects that throw during response cache checks', () => {
|
||||
const basePolicy = resolvePolicy();
|
||||
const response = {
|
||||
headers: {
|
||||
get() {
|
||||
throw new Error('header get unavailable');
|
||||
},
|
||||
has() {
|
||||
throw new Error('header has unavailable');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const policy = resolveResponseCachePolicy({
|
||||
basePolicy,
|
||||
response: /** @type {Response} */ (/** @type {unknown} */ (response))
|
||||
});
|
||||
|
||||
expect(policy).toBe(basePolicy);
|
||||
});
|
||||
});
|
||||
@@ -282,4 +282,57 @@ describe('Pipeline modules', () => {
|
||||
expect(targetA.cacheTargetUrl).not.toBe(targetB.cacheTargetUrl);
|
||||
}
|
||||
});
|
||||
|
||||
it('handles Docker 401 responses without auth challenges during finalization', async () => {
|
||||
const request = new Request('https://example.com/cr/ghcr/v2/user/repo/manifests/latest');
|
||||
const requestContext = {
|
||||
...createRequestContext(request, {}),
|
||||
isDocker: true
|
||||
};
|
||||
|
||||
const customUnauthorized = await finalizeResponse({
|
||||
cache: null,
|
||||
cacheTargetUrl: 'https://ghcr.io/v2/user/repo/manifests/latest',
|
||||
canUseCache: false,
|
||||
config: CONFIG,
|
||||
ctx: /** @type {ExecutionContext} */ ({ waitUntil() {}, passThroughOnException() {} }),
|
||||
effectivePath: '/cr/ghcr/v2/user/repo/manifests/latest',
|
||||
hasSensitiveHeaders: false,
|
||||
monitor: new PerformanceMonitor(),
|
||||
platform: 'cr-ghcr',
|
||||
request,
|
||||
requestContext,
|
||||
response: new Response('{"errors":[{"code":"UNAUTHORIZED"}]}', {
|
||||
status: 401,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
}),
|
||||
responseGeneratedLocally: false,
|
||||
url: new URL(request.url)
|
||||
});
|
||||
|
||||
const plainUnauthorized = await finalizeResponse({
|
||||
cache: null,
|
||||
cacheTargetUrl: 'https://ghcr.io/v2/user/repo/manifests/latest',
|
||||
canUseCache: false,
|
||||
config: CONFIG,
|
||||
ctx: /** @type {ExecutionContext} */ ({ waitUntil() {}, passThroughOnException() {} }),
|
||||
effectivePath: '/cr/ghcr/v2/user/repo/manifests/latest',
|
||||
hasSensitiveHeaders: false,
|
||||
monitor: new PerformanceMonitor(),
|
||||
platform: 'cr-ghcr',
|
||||
request,
|
||||
requestContext,
|
||||
response: new Response('denied', {
|
||||
status: 401,
|
||||
headers: { 'Content-Type': 'text/plain' }
|
||||
}),
|
||||
responseGeneratedLocally: false,
|
||||
url: new URL(request.url)
|
||||
});
|
||||
|
||||
expect(customUnauthorized.status).toBe(401);
|
||||
expect(await customUnauthorized.text()).toContain('UNAUTHORIZED');
|
||||
expect(plainUnauthorized.status).toBe(401);
|
||||
expect(await plainUnauthorized.text()).toContain('Original error: denied');
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user