rename web/ to admin/, along with the web-named build and cli identifiers

This commit is contained in:
2026-08-16 00:17:58 +02:00
parent 5b3d1cd65c
commit 1e97c80f6b
136 changed files with 196 additions and 196 deletions
@@ -0,0 +1,86 @@
import type { ClientPrefix } from "@/lib/types";
import {
firstProblem,
initPrefixEditor,
isDirty,
prefixEditorReducer,
toInputs,
type PrefixEditorState,
} from "./prefixEditor";
const server: ClientPrefix[] = [
{ id: 1, prefix: "192.168.1.0/24", group_id: 1, group: "default", priority: 100 },
{ id: 2, prefix: "10.0.0.0/8", group_id: 2, group: "kids", priority: 50 },
];
test("init mirrors the server rows into baseline and rows", () => {
const state = initPrefixEditor(server);
expect(state.rows).toEqual([
{ prefix: "192.168.1.0/24", group_id: 1, priority: "100" },
{ prefix: "10.0.0.0/8", group_id: 2, priority: "50" },
]);
expect(state.baseline).toEqual(state.rows);
expect(isDirty(state)).toBe(false);
});
test("add appends an empty row with the given group and marks dirty", () => {
const state = prefixEditorReducer(initPrefixEditor(server), { type: "add", groupId: 1 });
expect(state.rows).toHaveLength(3);
expect(state.rows[2]).toEqual({ prefix: "", group_id: 1, priority: "" });
expect(isDirty(state)).toBe(true);
});
test("remove drops the row at the index", () => {
const state = prefixEditorReducer(initPrefixEditor(server), { type: "remove", index: 0 });
expect(state.rows).toEqual([{ prefix: "10.0.0.0/8", group_id: 2, priority: "50" }]);
expect(isDirty(state)).toBe(true);
});
test("edit patches a single row", () => {
const state = prefixEditorReducer(initPrefixEditor(server), {
type: "edit",
index: 1,
patch: { group_id: 1, priority: "10" },
});
expect(state.rows[1]).toEqual({ prefix: "10.0.0.0/8", group_id: 1, priority: "10" });
expect(state.rows[0]).toEqual(state.baseline[0]);
expect(isDirty(state)).toBe(true);
});
test("editing a field back to its baseline value is clean again", () => {
let state: PrefixEditorState = initPrefixEditor(server);
state = prefixEditorReducer(state, { type: "edit", index: 0, patch: { priority: "7" } });
expect(isDirty(state)).toBe(true);
state = prefixEditorReducer(state, { type: "edit", index: 0, patch: { priority: "100" } });
expect(isDirty(state)).toBe(false);
});
test("reset adopts new server rows and clears dirtiness", () => {
let state = prefixEditorReducer(initPrefixEditor(server), { type: "add", groupId: 1 });
state = prefixEditorReducer(state, { type: "reset", prefixes: server });
expect(isDirty(state)).toBe(false);
expect(state.rows).toHaveLength(2);
});
test("toInputs trims prefixes, parses priorities and omits empty ones", () => {
expect(
toInputs([
{ prefix: " 192.168.1.0/24 ", group_id: 1, priority: "25" },
{ prefix: "10.0.0.0/8", group_id: 2, priority: "" },
]),
).toEqual([
{ prefix: "192.168.1.0/24", group_id: 1, priority: 25 },
{ prefix: "10.0.0.0/8", group_id: 2 },
]);
});
test("firstProblem flags empty prefixes and non-integer priorities", () => {
expect(firstProblem([{ prefix: "10.0.0.0/8", group_id: 1, priority: "" }])).toBeNull();
expect(firstProblem([{ prefix: " ", group_id: 1, priority: "" }])).toBe("Row 1: prefix is required.");
expect(
firstProblem([
{ prefix: "10.0.0.0/8", group_id: 1, priority: "100" },
{ prefix: "10.1.0.0/16", group_id: 1, priority: "abc" },
]),
).toBe("Row 2: priority must be a whole number.");
});