The schema's event fields gain values, a values_from marker (agents, repos) and a closed flag; a node field gains the marker and the flag. kind is now listed as issue and PR, what the router sends. The flow editor shows a dropdown where the list is complete, suggestions where it is only examples, and a plain box where there is none.
148 lines
4.5 KiB
JavaScript
148 lines
4.5 KiB
JavaScript
// What the flow editor offers for a value: dropdown, suggestions or plain
|
|
// text, from the server's schema. Run by `npm test`.
|
|
import assert from "node:assert/strict";
|
|
import { test } from "node:test";
|
|
import {
|
|
eventSpec,
|
|
kindSpec,
|
|
markersIn,
|
|
offerFor,
|
|
} from "../src/pages/notifications/FlowChoices.ts";
|
|
|
|
const d = (name, description = "") => ({ name, description });
|
|
|
|
const schema = {
|
|
source_events: [d("issues")],
|
|
fields: [
|
|
{
|
|
...d("kind"),
|
|
values: [d("issue"), d("PR", "A pull request")],
|
|
closed: true,
|
|
},
|
|
{ ...d("action"), values: [d("opened"), d("closed")], closed: false },
|
|
{ ...d("repo"), values: [], values_from: "repos", closed: false },
|
|
{ ...d("title"), values: [] },
|
|
],
|
|
node_kinds: [
|
|
{
|
|
kind: "todo",
|
|
description: "",
|
|
fields: [
|
|
{
|
|
...d("to"),
|
|
required: true,
|
|
values: [],
|
|
values_from: "agents",
|
|
closed: true,
|
|
},
|
|
{
|
|
...d("op"),
|
|
required: true,
|
|
values: [d("upsert"), d("clear")],
|
|
closed: true,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
kind: "request_reviewer",
|
|
description: "",
|
|
fields: [
|
|
{
|
|
...d("reviewer"),
|
|
required: true,
|
|
values: [],
|
|
values_from: "agents",
|
|
closed: false,
|
|
},
|
|
{
|
|
...d("later"),
|
|
required: false,
|
|
values: [],
|
|
values_from: "somewhere-new",
|
|
},
|
|
],
|
|
},
|
|
],
|
|
limits: { max_nodes: 1, max_depth: 1, max_flows: 1 },
|
|
};
|
|
|
|
test("a field with a complete list is a dropdown, its labels carrying the description", () => {
|
|
const offer = offerFor(eventSpec(schema, "kind"), {}, "PR");
|
|
assert.equal(offer.closed, true);
|
|
assert.deepEqual(
|
|
offer.options.map((o) => o.value),
|
|
["issue", "PR"],
|
|
);
|
|
assert.equal(offer.options[1].label, "PR — A pull request");
|
|
});
|
|
|
|
test("a list that is only examples stays a text box with suggestions", () => {
|
|
const offer = offerFor(eventSpec(schema, "action"), {}, "");
|
|
assert.equal(offer.closed, false);
|
|
assert.deepEqual(
|
|
offer.options.map((o) => o.value),
|
|
["opened", "closed"],
|
|
);
|
|
});
|
|
|
|
test("a field with no known values is plain text", () => {
|
|
assert.equal(offerFor(eventSpec(schema, "title"), {}, ""), null);
|
|
assert.equal(offerFor(undefined, {}, ""), null, "no schema entry at all");
|
|
});
|
|
|
|
test("a list fetched from the swarm fills the options, and a closed one becomes a dropdown", () => {
|
|
const spec = kindSpec(schema, "todo", "to");
|
|
const offer = offerFor(spec, { agents: ["atlas", "iris"] }, "iris");
|
|
assert.equal(offer.closed, true);
|
|
assert.deepEqual(
|
|
offer.options.map((o) => o.value),
|
|
["atlas", "iris"],
|
|
);
|
|
});
|
|
|
|
test("until its list arrives, or when it cannot be fetched, there is nothing to offer", () => {
|
|
const spec = kindSpec(schema, "todo", "to");
|
|
assert.equal(offerFor(spec, {}, ""), null);
|
|
// Open lists with names fetched are suggestions: any login still goes.
|
|
const reviewer = kindSpec(schema, "request_reviewer", "reviewer");
|
|
const offer = offerFor(reviewer, { agents: ["argus"] }, "review-classifier");
|
|
assert.equal(offer.closed, false);
|
|
assert.deepEqual(
|
|
offer.options.map((o) => o.value),
|
|
["argus"],
|
|
);
|
|
});
|
|
|
|
test("a dropdown whose source has not arrived falls back to suggestions", () => {
|
|
const spec = {
|
|
values: [d("a")],
|
|
values_from: "agents",
|
|
closed: true,
|
|
};
|
|
assert.equal(offerFor(spec, {}, "").closed, false);
|
|
assert.equal(offerFor(spec, { agents: ["b"] }, "").closed, true);
|
|
});
|
|
|
|
test("a value the list lacks stays selectable, marked as not listed", () => {
|
|
const spec = kindSpec(schema, "todo", "to");
|
|
const offer = offerFor(spec, { agents: ["atlas"] }, "gone");
|
|
assert.equal(offer.options[0].value, "gone");
|
|
assert.equal(offer.options[0].label, "gone (not listed)");
|
|
assert.equal(offer.options.length, 2);
|
|
// Nothing set yet adds nothing.
|
|
assert.equal(offerFor(spec, { agents: ["atlas"] }, "").options.length, 1);
|
|
});
|
|
|
|
test("a name in both the fixed values and the fetched list is offered once", () => {
|
|
const spec = { values: [d("x")], values_from: "agents" };
|
|
const offer = offerFor(spec, { agents: ["x", "y"] }, "");
|
|
assert.deepEqual(
|
|
offer.options.map((o) => o.value),
|
|
["x", "y"],
|
|
);
|
|
});
|
|
|
|
test("the markers to fetch are the ones the schema names and the editor knows, once each", () => {
|
|
assert.deepEqual(markersIn(schema), ["agents", "repos"]);
|
|
assert.deepEqual(markersIn({ ...schema, fields: [], node_kinds: [] }), []);
|
|
});
|