Files
mesh-controller/cmd/mesh-controller/moved_test.go
T

105 lines
5.0 KiB
Go

package main
import (
"strings"
"testing"
"time"
"git.novox.be/novox/mesh-sdk/go/asks"
)
// A merge mesh-delivery made, with the ask whose answer it merged on: the heads that answer was bound to, the
// ask as the router published it, and the warrant the operator's Approve left (novox/hq ADR 0420 §7, issue 1025).
type anApprovedMerge struct {
merge deliveryMerge
ask asks.Ask
warrant asks.Warrant
}
func approvedMerge(t *testing.T) anApprovedMerge {
t.Helper()
heads := map[string]string{"novox/mesh-controller@aaaaaaaaaaaa": "a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1",
"novox/mesh-catalog@bbbbbbbbbbbb": "b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2"}
m := deliveryMerge{Owner: "novox", Repo: "mesh-controller", Number: 7, HeadSHA: "a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1",
Group: "g1", AskID: "merge-g1", Option: optionApprove, Heads: heads}
bind := func(option string, h map[string]string) string {
d, err := asks.ActDigest(mergeAct(m.AskID, option, h))
if err != nil {
t.Fatal(err)
}
return d
}
at := time.Date(2026, 10, 17, 12, 0, 0, 0, time.UTC)
ask := asks.Ask{ID: m.AskID, Headline: "Merge the group", Explanation: "Two pull requests move a module.", Who: asks.Operator,
Expires: at.Add(time.Hour), OnExpiry: "asked again",
Options: []asks.Option{
{ID: optionApprove, Label: "Approve", Does: "merges the group", Level: asks.Approve, Binds: bind(optionApprove, heads)},
{ID: "decline", Label: "Decline", Does: "leaves it", Level: asks.Approve, Binds: bind("decline", heads)}}}
w := asks.Warrant{Ask: m.AskID, Asker: theDelivery, Outcome: asks.OutcomeChosen, Option: optionApprove, Label: "Approve",
Level: asks.Approve, By: &asks.Person{Who: asks.Operator, Kind: "telegram", Identity: "1", Verified: "user id"},
At: at, AskDigest: ask.Digest()}
return anApprovedMerge{merge: m, ask: ask, warrant: w}
}
// The operator's Approve of the merged head holds, and every other answer does not: a Decline, a person who is not the
// operator or not proved by their channel, a warrant for other heads or another ask than the router published, the
// merged head outside the heads the Approve covered, and a router that holds nothing.
func TestAMovesWarrantHoldsOnlyForTheOperatorsApproveOfTheMergedHead(t *testing.T) {
ok := approvedMerge(t)
if _, err := movedOnApprove(ok.merge, &ok.ask, &ok.warrant); err != nil {
t.Fatalf("the operator's Approve of the merged heads was refused: %v", err)
}
for _, c := range []struct {
what string
change func(*anApprovedMerge)
}{
{"a Decline", func(a *anApprovedMerge) {
a.warrant.Option, a.warrant.Label = "decline", "Decline"
a.merge.Option = "decline"
}},
{"no person chose", func(a *anApprovedMerge) { a.warrant.Outcome = asks.OutcomeExpired }},
{"a person who is not the operator", func(a *anApprovedMerge) { a.warrant.By.Who = "agent" }},
{"a channel that proves nobody", func(a *anApprovedMerge) { a.warrant.By.Verified = "" }},
{"other heads than the ask was bound to", func(a *anApprovedMerge) {
a.merge.Heads = map[string]string{"novox/mesh-controller@aaaaaaaaaaaa": "c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3"}
}},
{"a head merged that the Approve did not cover", func(a *anApprovedMerge) { a.merge.HeadSHA = "d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4" }},
{"another ask than the one the warrant answers", func(a *anApprovedMerge) { a.ask.Headline = "Something else" }},
{"a warrant of another asker", func(a *anApprovedMerge) { a.warrant.Asker = "claude-code" }},
{"an ask for no operator to answer", func(a *anApprovedMerge) { a.ask.Who = "agent" }},
{"an Approve given after the ask expired", func(a *anApprovedMerge) { a.warrant.At = a.ask.Expires.Add(time.Minute) }},
} {
a := approvedMerge(t)
c.change(&a)
if why, err := movedOnApprove(a.merge, &a.ask, &a.warrant); err == nil {
t.Errorf("%s was accepted: %s", c.what, why)
}
}
if _, err := movedOnApprove(ok.merge, nil, &ok.warrant); err == nil {
t.Error("a warrant with no ask to check it against was accepted")
}
if _, err := movedOnApprove(ok.merge, &ok.ask, nil); err == nil {
t.Error("an ask with no warrant was accepted")
}
}
// mesh-delivery's word is read whole or refused, and kept under a key the bus allows.
func TestADeliveryMergesWordIsReadWholeAndKeptUnderABusKey(t *testing.T) {
body := `{"owner":"novox","repo":"mesh-controller","number":7,"head_sha":"abc","group":"g","ask_id":"merge-g",` +
`"option":"approve","heads":{"novox/mesh-controller@abc":"abc"}}`
d, err := parseDeliveryMerge([]byte(body))
if err != nil || d.Number != 7 || d.Heads["novox/mesh-controller@abc"] != "abc" {
t.Fatalf("read %+v, %v", d, err)
}
if key := deliveryMergeKey(d.Owner, d.Repo, d.Number, d.HeadSHA); key != "novox/mesh-controller/7/abc" ||
strings.ContainsAny(key, "#@") {
t.Errorf("key %q", key)
}
for _, bad := range []string{`{`, `{"owner":"novox","repo":"r","number":0,"head_sha":"a","ask_id":"x","option":"approve"}`,
`{"owner":"novox","repo":"r","number":1,"head_sha":"a","option":"approve"}`} {
if _, err := parseDeliveryMerge([]byte(bad)); err == nil {
t.Errorf("%s was read", bad)
}
}
}