fix: bound social preview smoke response
This commit is contained in:
@@ -11,6 +11,8 @@ const alternate = 'http://www.portfolio.example/';
|
||||
const escapedTitle = 'Luca Pîslaru — System Administrator & Full-Stack Developer';
|
||||
const description = 'Portfolio of Luca Pîslaru, a Bucharest-based System Administrator and Full-Stack Developer working across Linux infrastructure and end-to-end software delivery.';
|
||||
const socialImage = `${canonical}assets/project-social-preview.webp`;
|
||||
const projectStillMaxBytes = 400 * 1024;
|
||||
const socialImageFixture = Buffer.alloc(15_068);
|
||||
const html = `<!doctype html><html><head>
|
||||
<title>${escapedTitle}</title>
|
||||
<meta name="description" content="${description}" />
|
||||
@@ -36,6 +38,8 @@ interface FixtureOptions {
|
||||
html?: string;
|
||||
imageStatus?: number;
|
||||
imageType?: string;
|
||||
imageContentLength?: string | null;
|
||||
imageChunks?: readonly Buffer[];
|
||||
}
|
||||
|
||||
const mutateJsonLd = (source: string, mutate: (graph: Record<string, any>) => void): string =>
|
||||
@@ -78,12 +82,19 @@ async function fixtureFetch(options: FixtureOptions = {}) {
|
||||
}
|
||||
if (url.pathname === '/assets/project-social-preview.webp') {
|
||||
const status = options.imageStatus ?? 200;
|
||||
response.writeHead(status, {
|
||||
const chunks = status === 200 ? options.imageChunks ?? [socialImageFixture] : [];
|
||||
const contentLength = options.imageContentLength === undefined
|
||||
? String(chunks.reduce((total, chunk) => total + chunk.byteLength, 0))
|
||||
: options.imageContentLength;
|
||||
const headers: Record<string, string> = {
|
||||
...base,
|
||||
'content-type': options.imageType ?? 'image/webp',
|
||||
'cache-control': 'public, max-age=31536000, immutable',
|
||||
});
|
||||
response.end(status === 200 ? Buffer.from('social-preview-fixture') : undefined);
|
||||
};
|
||||
if (contentLength !== null) headers['content-length'] = contentLength;
|
||||
response.writeHead(status, headers);
|
||||
for (const chunk of chunks) response.write(chunk);
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
if (url.pathname === '/assets/demo.12345678.webm') {
|
||||
@@ -224,4 +235,36 @@ describe('production smoke and SEO contract', () => {
|
||||
fetchImpl,
|
||||
})).rejects.toThrow(error);
|
||||
});
|
||||
|
||||
it.each([
|
||||
{
|
||||
name: 'a zero-byte body',
|
||||
options: { imageChunks: [], imageContentLength: '0' },
|
||||
error: /social image.*empty|zero-byte/iu,
|
||||
},
|
||||
{
|
||||
name: 'a declared body above the project-still limit',
|
||||
options: {
|
||||
imageChunks: [Buffer.alloc(projectStillMaxBytes + 1)],
|
||||
imageContentLength: String(projectStillMaxBytes + 1),
|
||||
},
|
||||
error: /social image.*(?:limit|large|400)/iu,
|
||||
},
|
||||
{
|
||||
name: 'an undeclared chunked body above the project-still limit',
|
||||
options: {
|
||||
imageChunks: [Buffer.alloc(projectStillMaxBytes), Buffer.alloc(1)],
|
||||
imageContentLength: null,
|
||||
},
|
||||
error: /social image.*(?:limit|large|400)/iu,
|
||||
},
|
||||
])('rejects $name without buffering the social image', async ({ options, error }) => {
|
||||
const fetchImpl = await fixtureFetch(options);
|
||||
|
||||
await expect(verifyProductionSmoke({
|
||||
canonicalUrl: canonical,
|
||||
expectedManifestDigest: digest,
|
||||
fetchImpl,
|
||||
})).rejects.toThrow(error);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user