const assert = require("node:assert/strict");
const { createServer } = require("node:http");
const { mkdtemp, readFile, rm, writeFile } = require("node:fs/promises");
const { join } = require("node:path");
const { tmpdir } = require("node:os");
const { pathToFileURL } = require("node:url");
const { download, fetchText, isRedirectStatus } = require("./install");
test("downloads file URLs and fetches text over HTTP redirects", async () => {
const root = await mkdtemp(join(tmpdir(), "playwright-ast-coverage-download-"));
const source = join(root, "source.txt");
const destination = join(root, "destination.txt");
await writeFile(source, "hello");
const server = createServer((request, response) => {
if (request.url === "/missing-location") {
response.writeHead(302);
response.end();
return;
}
if (request.url === "/redirect") {
response.writeHead(302, { location: "/text" });
response.end();
return;
}
if (request.url === "/text") {
response.writeHead(200);
response.end("redirected");
return;
}
response.writeHead(404);
response.end("not found");
});
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
const address = server.address();
try {
await download(pathToFileURL(source).toString(), destination);
assert.equal(await readFile(destination, "utf8"), "hello");
assert.equal(await fetchText(`http://127.0.0.1:${address.port}/redirect`), "redirected");
await assert.rejects(() => fetchText(`http://127.0.0.1:${address.port}/missing`), /HTTP 404/);
await assert.rejects(
() => fetchText(`http://127.0.0.1:${address.port}/missing-location`),
/missing Location/i,
);
await assert.rejects(() => fetchText(`https://127.0.0.1:${address.port}/text`));
} finally {
await new Promise((resolve) => server.close(resolve));
await rm(root, { recursive: true, force: true });
}
});
test("classifies redirect status codes", () => {
assert.equal(isRedirectStatus(301), true);
assert.equal(isRedirectStatus(undefined), false);
});
test("rejects redirect loops", async () => {
const server = createServer((_request, response) => {
response.writeHead(302, { location: "/loop" });
response.end();
});
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
const address = server.address();
try {
await assert.rejects(
() => fetchText(`http://127.0.0.1:${address.port}/loop`),
/Too many redirects/,
);
} finally {
await new Promise((resolve) => server.close(resolve));
}
});