Files
mesh-catalog/modules/messenger/cmd/messenger/glance_test.go
T

94 lines
4.8 KiB
Go

package main
import (
"strings"
"testing"
"time"
occ "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/clients/operatorchannelclient"
oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel"
)
// novox/hq issue 639: an ask's message reads at a glance on the phone. Its body is the asker's summary and points
// alone; who asked and when, what each answer does, the expiry and the asker's Details are its note. Once answered
// it keeps the question whole, so the operator can read back what they answered (issue 714).
// decisionAsk is the ask for ADR 0343 as the knowledge base composes it now (its glance form).
func decisionAsk(c *clock) oc.Ask {
return oc.Ask{ID: "kb-decision-343-0d1e2f3a", Headline: "Your agents' memory follows you to every machine",
Explanation: "What an agent learns in a project's memory is copied to every machine that runs the agent, so a session " +
"anywhere starts with it. A file changed on two machines keeps both versions and warns you; secrets in memory files " +
"are screened, though not perfectly.\n" +
"• Only memory folders travel: links and files over 128 KiB stay where they are\n" +
"• A conflict reaches you as a warning that needs you\n" +
"• A deleted file is marked, and a newer change elsewhere outlives the deletion",
Who: occ.Operator, Expires: occ.FormatTime(c.now().Add(23*time.Hour + 50*time.Minute)), OnExpiry: "the record stays proposed; nothing of it is in force",
About: "knowledge.decision.343",
Details: "ADR 0343, proposed by fix-367@g14; the knowledge base's own review approved it. Fingerprint a59f 361b f60e cb5e d237 a837.\n" +
"Read its 13 clauses with the knowledge base's get, number 343.",
Options: []oc.Option{
{ID: "approve", Label: "Approve", Does: "the record is accepted and its clauses are in force", Level: occ.Approve, Binds: bound("approve")},
{ID: "decline", Label: "Decline", Does: "the record stays proposed; nothing of it is in force", Level: occ.Approve, Binds: bound("decline")},
}}
}
func TestAnAsksMessageIsItsSummaryWithTheRestInItsNote(t *testing.T) {
h, tg, _, c, store, _ := newRouter(t)
link(h, store, c, "42", c.now().Add(-2*time.Hour))
a := decisionAsk(c)
submit(t, h, "mesh-knowledge", a)
settle(h, c)
if len(tg.sends) != 1 {
t.Fatalf("telegram got %d messages", len(tg.sends))
}
m := tg.sends[0]
if m.Title != a.Headline || m.Body != a.Explanation {
t.Errorf("the body is not the asker's summary and points alone:\n%s\n%s", m.Title, m.Body)
}
note := strings.Split(m.Note, "\n")
asked := c.now().In(time.UTC).Format("15:04")
want := []string{
"Asked by mesh-knowledge at " + asked + ". Unanswered by tomorrow " + askExpires(a).In(time.UTC).Format("15:04") +
": the record stays proposed; nothing of it is in force.",
"Approve: the record is accepted and its clauses are in force. Decline: the record stays proposed; nothing of it is in force.",
"ADR 0343, proposed by fix-367@g14; the knowledge base's own review approved it. Fingerprint a59f 361b f60e cb5e d237 a837.",
"Read its 13 clauses with the knowledge base's get, number 343.",
}
if strings.Join(note, "\n") != strings.Join(want, "\n") {
t.Errorf("the note:\n%s\nwant:\n%s", m.Note, strings.Join(want, "\n"))
}
if n := len(strings.Split(m.Text(), "\n")); n > 9 || len(m.Actions) != 2 {
t.Errorf("the message is %d lines offering %s:\n%s", n, labelsOf(m), m.Text())
}
// Answered, it keeps its headline, summary, points and Details; below them, how it ended and who acts on it;
// its buttons are gone (issue 714: the one line issue 639 made left nothing to read back).
if out, err := h.Chosen("telegram", choiceOf(ticketFor(m, "Approve"), "42", c.now())); err != nil || out != "chosen" {
t.Fatalf("Approve: %q %v", out, err)
}
var edited Message
for _, e := range tg.edits {
edited = e
}
if edited.Title != a.Headline || edited.Body != a.Explanation+"\n"+want[2]+"\n"+want[3] ||
edited.Note != "You chose Approve at "+asked+" on Telegram.\nTold to mesh-knowledge, which acts on it itself." ||
len(edited.Actions) != 0 {
t.Errorf("the answered copy: %q\n%q\n%q", edited.Title, edited.Body, edited.Note)
}
}
// An ask that does not read at a glance is shown all the same, and said: refusing it would leave the operator
// unasked, and the bound is its asker's to keep.
func TestAnAskThatIsAWallOfTextIsShownAndSaid(t *testing.T) {
h, tg, _, c, store, _ := newRouter(t)
link(h, store, c, "42", c.now().Add(-2*time.Hour))
var said []string
h.Logf = func(f string, a ...any) { said = append(said, f) }
a := decisionAsk(c)
a.Explanation += "\nA fourth point\nA fifth point"
submit(t, h, "mesh-knowledge", a)
settle(h, c)
if len(tg.sends) != 1 || !strings.Contains(strings.Join(said, "\n"), "is a wall of text on the phone") {
t.Errorf("sent %d, said %v", len(tg.sends), said)
}
}