Files
rea/src/domain/javascript/javascriptStaticAnalysis.partialEndpoints.test.ts
T

265 lines
6.2 KiB
TypeScript
Raw Normal View History

import { expect, it } from "vitest";
import { analyzeJavaScriptStaticSource } from "./javascriptStaticAnalysis.js";
const endpoints = (source: string) =>
analyzeJavaScriptStaticSource(source).endpoints.map((endpoint) => ({
kind: endpoint.kind,
value: endpoint.value,
mechanism: endpoint.mechanism,
resolution: endpoint.resolution,
}));
it("resolves unchanged lexical strings and object properties", () => {
expect(
endpoints(`
const target = "/items";
const config = { url: "/accounts" };
fetch(target);
fetch("/direct");
fetch(config.url);
`),
).toEqual([
{
kind: "network",
value: "/items",
mechanism: "call:fetch",
resolution: undefined,
},
{
kind: "network",
value: "/direct",
mechanism: "call:fetch",
resolution: undefined,
},
{
kind: "network",
value: "/accounts",
mechanism: "call:fetch",
resolution: undefined,
},
]);
});
it("resolves unchanged URL objects and aliases using URL serialization", () => {
expect(
endpoints(`
const socket = new URL("HTTPS://EXAMPLE.COM:443");
const alias = socket;
const relative = new URL("/items", "https://api.example.test/base");
fetch(alias);
fetch(relative);
`),
).toEqual([
{
kind: "network",
value: "https://example.com/",
mechanism: "call:fetch",
resolution: undefined,
},
{
kind: "network",
value: "https://api.example.test/items",
mechanism: "call:fetch",
resolution: undefined,
},
]);
});
it("keeps an interpolated request expression verbatim", () => {
expect(
endpoints("fetch(`https://${hosts['a@b']}/items/${id}`);"),
).toContainEqual({
kind: "network",
value: "`https://${hosts['a@b']}/items/${id}`",
mechanism: "call:fetch",
resolution: "partial",
});
});
it("keeps writes to a config property partial instead of resolving its initializer", () => {
expect(
endpoints(`
const config = { url: "https://old.example.test" };
config.url = "https://new.example.test";
fetch(config.url);
`),
).toContainEqual({
kind: "network",
value: "config.url",
mechanism: "call:fetch",
resolution: "partial",
});
});
it("keeps a reassigned endpoint binding partial", () => {
expect(
endpoints(`
let endpoint = "https://old.example.test";
endpoint = "https://new.example.test";
fetch(endpoint);
`),
).toContainEqual({
kind: "network",
value: "endpoint",
mechanism: "call:fetch",
resolution: "partial",
});
});
it("does not resolve an endpoint from a declaration after the request", () => {
expect(
endpoints(`
fetch(endpoint);
const endpoint = "https://api.example.test/items";
`),
).toEqual([
{
kind: "network",
value: "endpoint",
mechanism: "call:fetch",
resolution: "partial",
},
]);
});
it("keeps URLSearchParams mutations partial", () => {
expect(
endpoints(`
const socket = new URL("wss://old.example.test/socket");
socket.searchParams.set("token", token);
new WebSocket(socket);
`),
).toContainEqual({
kind: "network",
value: "socket",
mechanism: "call:WebSocket",
resolution: "partial",
});
});
it("resolves a URL object against a literal base", () => {
expect(
endpoints(`
const socket = new URL("/socket", "wss://api.example.test");
new WebSocket(socket);
`),
).toEqual([
{
kind: "network",
value: "wss://api.example.test/socket",
mechanism: "call:WebSocket",
resolution: undefined,
},
]);
});
it("resolves an unchanged URL object's toString target", () => {
expect(
endpoints(`
const socket = new URL("wss://api.example.test/socket");
new WebSocket(socket.toString());
`),
).toEqual([
{
kind: "network",
value: "wss://api.example.test/socket",
mechanism: "call:WebSocket",
resolution: undefined,
},
]);
});
it("keeps a URL object partial when its base is unresolved", () => {
expect(
endpoints(`
const socket = new URL("/socket", apiOrigin);
new WebSocket(socket);
`),
).toContainEqual({
kind: "network",
value: "socket",
mechanism: "call:WebSocket",
resolution: "partial",
});
});
it("keeps URL aliases partial after a member mutation", () => {
expect(
endpoints(`
const socket = new URL("wss://old.example.test/socket");
const alias = socket;
alias.hostname = "new.example.test";
fetch(socket);
`),
).toContainEqual({
kind: "network",
value: "socket",
mechanism: "call:fetch",
resolution: "partial",
});
});
it("keeps an escaped URL object partial", () => {
expect(
endpoints(`
const socket = new URL("wss://old.example.test/socket");
configure(socket);
new WebSocket(socket);
`),
).toContainEqual({
kind: "network",
value: "socket",
mechanism: "call:WebSocket",
resolution: "partial",
});
});
it("retains dynamic targets on known global fetch receivers", () => {
expect(
endpoints(`
window.fetch(endpoint);
globalThis.fetch(endpoint);
self.fetch(endpoint);
`),
).toEqual([
{
kind: "network",
value: "endpoint",
mechanism: "call:window.fetch",
resolution: "partial",
},
{
kind: "network",
value: "endpoint",
mechanism: "call:globalThis.fetch",
resolution: "partial",
},
{
kind: "network",
value: "endpoint",
mechanism: "call:self.fetch",
resolution: "partial",
},
]);
});
it("does not treat a locally bound fetch function as a network API", () => {
expect(
endpoints(`
function fetch(key) { return records[key]; }
fetch(key);
`),
).toEqual([]);
});
it("keeps exact literal targets exact", () => {
expect(endpoints('fetch("https://api.example.test/items");')).toEqual([
{
kind: "network",
value: "https://api.example.test/items",
mechanism: "call:fetch",
resolution: undefined,
},
]);
});