mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-06 07:00:37 +02:00
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
72 lines
3.1 KiB
JavaScript
72 lines
3.1 KiB
JavaScript
// node --test site/test/*.test.mjs
|
|
import assert from "node:assert/strict";
|
|
import { test } from "node:test";
|
|
import { buildIssue, defang, hashIp, MIN_FILL_MS, validate } from "../lib/feedback.js";
|
|
|
|
const form = (over = {}) => ({
|
|
kind: "bug",
|
|
title: "Live view freezes",
|
|
message: "After about a minute the live view stops updating.",
|
|
elapsed: MIN_FILL_MS + 1,
|
|
...over,
|
|
});
|
|
|
|
test("accepts a normal report and trims it", () => {
|
|
const { value, error } = validate(form({ title: " Live view freezes ", os: " macOS 26 " }));
|
|
assert.equal(error, undefined);
|
|
assert.equal(value.title, "Live view freezes");
|
|
assert.equal(value.os, "macOS 26");
|
|
assert.equal(value.kind, "bug");
|
|
});
|
|
|
|
test("flags the honeypot and too-fast submissions as spam", () => {
|
|
assert.deepEqual(validate(form({ website: "http://spam" })), { spam: true });
|
|
assert.deepEqual(validate(form({ elapsed: 500 })), { spam: true });
|
|
assert.deepEqual(validate(form({ elapsed: undefined })), { spam: true });
|
|
});
|
|
|
|
test("rejects short, long and malformed input", () => {
|
|
assert.match(validate(form({ title: "hi" })).error, /title/);
|
|
assert.match(validate(form({ message: "short" })).error, /more/);
|
|
assert.match(validate(form({ message: "x".repeat(5001) })).error, /under/);
|
|
assert.match(validate(form({ github: "not a user!" })).error, /GitHub/);
|
|
assert.match(validate(null).error, /JSON/);
|
|
});
|
|
|
|
test("unknown kinds become other feedback", () => {
|
|
assert.equal(validate(form({ kind: "__proto__" })).value.kind, "other");
|
|
});
|
|
|
|
test("builds a labelled issue that credits a GitHub user", () => {
|
|
const { value } = validate(form({ github: "@octocat", version: "0.3.1", steamos: "20260922" }));
|
|
const issue = buildIssue(value);
|
|
assert.equal(issue.title, "Bug report: Live view freezes");
|
|
assert.deepEqual(issue.labels, ["feedback", "bug"]);
|
|
assert.match(issue.body, /\| Frame Control version \| 0\.3\.1 \|/);
|
|
assert.match(issue.body, /by @octocat\.$/);
|
|
});
|
|
|
|
test("anonymous feedback says replies won't reach the sender", () => {
|
|
const issue = buildIssue(validate(form({ kind: "other" })).value);
|
|
assert.deepEqual(issue.labels, ["feedback"]);
|
|
assert.match(issue.body, /won't see replies/);
|
|
});
|
|
|
|
test("breaks mentions, issue refs and table cells in user text", () => {
|
|
assert.equal(defang("ping @valve about #12"), "ping @\u200bvalve about #\u200b12");
|
|
assert.equal(defang("email me@example.com"), "email me@\u200bexample.com");
|
|
assert.equal(defang("see valve/steam#7 and GH-8"), "see valve/steam#\u200b7 and GH\u200b-8");
|
|
assert.equal(defang("@valve @valve #3"), "&commat;valve &#\u200b64;valve &num;3");
|
|
assert.equal(defang("https://github.com/a/b/issues/1"), "https://github\u200b.com/a/b/issues/1");
|
|
const issue = buildIssue(validate(form({ os: "a | b" })).value);
|
|
assert.match(issue.body, /\| a \\\| b \|/);
|
|
});
|
|
|
|
test("hashes IPs without keeping them", async () => {
|
|
const a = await hashIp("203.0.113.9", "salt");
|
|
assert.equal(a.length, 24);
|
|
assert.equal(a, await hashIp("203.0.113.9", "salt"));
|
|
assert.notEqual(a, await hashIp("203.0.113.10", "salt"));
|
|
assert.ok(!a.includes("203"));
|
|
});
|