release: WRNexusJS 0.2.75
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { createDevToolbarCollector } from "../../src/server/collector.ts";
|
||||
import { createServerIssue } from "../../src/server/issues.ts";
|
||||
|
||||
describe("dev toolbar collector", () => {
|
||||
test("deduplicates by fingerprint", () => {
|
||||
const collector = createDevToolbarCollector();
|
||||
const issue = createServerIssue({
|
||||
ruleId: "route/not-found",
|
||||
category: "routing",
|
||||
severity: "warning",
|
||||
title: "Not found",
|
||||
message: "Missing page",
|
||||
pathname: "/missing",
|
||||
});
|
||||
collector.add(issue);
|
||||
collector.add({ ...issue, id: "new-id" });
|
||||
expect(collector.getIssues()).toHaveLength(1);
|
||||
});
|
||||
|
||||
test("clears issues by pathname", () => {
|
||||
const collector = createDevToolbarCollector();
|
||||
collector.add(
|
||||
createServerIssue({
|
||||
ruleId: "route/not-found",
|
||||
category: "routing",
|
||||
severity: "warning",
|
||||
title: "Not found",
|
||||
message: "A",
|
||||
pathname: "/a",
|
||||
}),
|
||||
);
|
||||
collector.add(
|
||||
createServerIssue({
|
||||
ruleId: "route/not-found",
|
||||
category: "routing",
|
||||
severity: "warning",
|
||||
title: "Not found",
|
||||
message: "B",
|
||||
pathname: "/b",
|
||||
}),
|
||||
);
|
||||
collector.clear("/a");
|
||||
expect(collector.getIssues()).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { resolve } from "node:path";
|
||||
import { buildEditorCommand, resolveEditorFile } from "../../src/server/editor.ts";
|
||||
|
||||
describe("open editor security", () => {
|
||||
const projectRoot = resolve("project");
|
||||
const pageFile = resolve(projectRoot, "app/pages/index.wrn");
|
||||
|
||||
test("resolves project files", () => {
|
||||
expect(resolveEditorFile(projectRoot, "app/pages/index.wrn")).toBe(pageFile);
|
||||
});
|
||||
|
||||
test("rejects traversal outside root", () => {
|
||||
expect(() => resolveEditorFile(projectRoot, "../secret.txt")).toThrow(
|
||||
"Source file is outside the configured project root.",
|
||||
);
|
||||
});
|
||||
|
||||
test("builds argument array without shell", () => {
|
||||
expect(
|
||||
buildEditorCommand(
|
||||
{
|
||||
file: "app/pages/index.wrn",
|
||||
line: 8,
|
||||
column: 2,
|
||||
},
|
||||
{
|
||||
root: projectRoot,
|
||||
editor: "code",
|
||||
},
|
||||
),
|
||||
).toEqual(["code", "--goto", `${pageFile}:8:2`]);
|
||||
});
|
||||
|
||||
test("rejects null bytes", () => {
|
||||
expect(() => resolveEditorFile(projectRoot, "app/pages/index.wrn\0.txt")).toThrow(
|
||||
"Invalid source file path.",
|
||||
);
|
||||
});
|
||||
|
||||
test("rejects remote URLs", () => {
|
||||
expect(() => resolveEditorFile(projectRoot, "https://example.com/file.wrn")).toThrow(
|
||||
"Invalid source file path.",
|
||||
);
|
||||
});
|
||||
|
||||
test("normalizes invalid line and column values", () => {
|
||||
expect(
|
||||
buildEditorCommand(
|
||||
{
|
||||
file: "app/pages/index.wrn",
|
||||
line: -10,
|
||||
column: 0,
|
||||
},
|
||||
{
|
||||
root: projectRoot,
|
||||
editor: "code",
|
||||
},
|
||||
),
|
||||
).toEqual(["code", "--goto", `${pageFile}:1:1`]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { serializeDevToolbarJson } from "../../src/server/serialize.ts";
|
||||
|
||||
test("escapes script-sensitive characters", () => {
|
||||
const value = serializeDevToolbarJson({ value: "</script>&" });
|
||||
expect(value).not.toContain("</script>");
|
||||
expect(value).toContain("\\u003c");
|
||||
});
|
||||
Reference in New Issue
Block a user