mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-09 12:57:46 +00:00
[tests] Properly test for multiple headers with same name in probes (#9538)
Updates the `responseHeaders` probe checks to properly test for multiple headers with the same name. Previously the probes were using `headers.get()` which concats multiple headers into a single string, which results in the test not really checking if there are in fact multiple headers with the same name. Using `headers.raw()` allows us to properly test for that. A couple of Python tests that were already checking for multiple `set-cookie` headers needed to be updated to match the full value, since the check now properly validates the full string match of each header (before it was basically just doing a `string.includes()` check). This is a precursor for https://github.com/vercel/vercel/pull/9533.
This commit is contained in:
@@ -220,26 +220,47 @@ async function runProbe(probe, deploymentId, deploymentUrl, ctx) {
|
||||
hadTest = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @type Record<string, string[]>
|
||||
*/
|
||||
const rawHeaders = resp.headers.raw();
|
||||
if (probe.responseHeaders) {
|
||||
// eslint-disable-next-line no-loop-func
|
||||
Object.keys(probe.responseHeaders).forEach(header => {
|
||||
const actual = resp.headers.get(header);
|
||||
const expected = probe.responseHeaders[header];
|
||||
const isEqual = Array.isArray(expected)
|
||||
? expected.every(h => actual.includes(h))
|
||||
: typeof expected === 'string' &&
|
||||
expected.startsWith('/') &&
|
||||
expected.endsWith('/')
|
||||
? new RegExp(expected.slice(1, -1)).test(actual)
|
||||
: expected === actual;
|
||||
if (!isEqual) {
|
||||
const headers = Array.from(resp.headers.entries())
|
||||
.map(([k, v]) => ` ${k}=${v}`)
|
||||
.join('\n');
|
||||
const actualArr = rawHeaders[header.toLowerCase()];
|
||||
let expectedArr = probe.responseHeaders[header];
|
||||
|
||||
throw new Error(
|
||||
`Page ${probeUrl} does not have expected response header ${header}.\n\nExpected: ${expected}.\n\nActual: ${headers}`
|
||||
);
|
||||
// Header should not exist
|
||||
if (expectedArr === null) {
|
||||
if (actualArr) {
|
||||
throw new Error(
|
||||
`Page ${probeUrl} contains response header "${header}", but probe says it should not.\n\nActual: ${formatHeaders(
|
||||
rawHeaders
|
||||
)}`
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Array.isArray(expectedArr)) {
|
||||
expectedArr = [expectedArr];
|
||||
}
|
||||
for (const expected of expectedArr) {
|
||||
let isEqual = false;
|
||||
for (const actual of actualArr) {
|
||||
isEqual =
|
||||
expected.startsWith('/') && expected.endsWith('/')
|
||||
? new RegExp(expected.slice(1, -1)).test(actual)
|
||||
: expected === actual;
|
||||
if (isEqual) break;
|
||||
}
|
||||
if (!isEqual) {
|
||||
throw new Error(
|
||||
`Page ${probeUrl} does not have expected response header ${header}.\n\nExpected: ${expected}.\n\nActual: ${formatHeaders(
|
||||
rawHeaders
|
||||
)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
hadTest = true;
|
||||
@@ -249,12 +270,10 @@ async function runProbe(probe, deploymentId, deploymentUrl, ctx) {
|
||||
const expected = probe.notResponseHeaders[header];
|
||||
|
||||
if (headerValue === expected) {
|
||||
const headers = Array.from(resp.headers.entries())
|
||||
.map(([k, v]) => ` ${k}=${v}`)
|
||||
.join('\n');
|
||||
|
||||
throw new Error(
|
||||
`Page ${probeUrl} has unexpected response header ${header}.\n\nDid not expect: ${header}=${expected}.\n\nAll: ${headers}`
|
||||
`Page ${probeUrl} has unexpected response header ${header}.\n\nDid not expect: ${header}=${expected}.\n\nAll: ${formatHeaders(
|
||||
rawHeaders
|
||||
)}`
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -434,6 +453,15 @@ async function spawnAsync(...args) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, string[]>} headers
|
||||
*/
|
||||
function formatHeaders(headers) {
|
||||
return Object.entries(headers)
|
||||
.flatMap(([name, values]) => values.map(v => ` ${name}: ${v}`))
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
packAndDeploy,
|
||||
testDeployment,
|
||||
|
||||
Reference in New Issue
Block a user