105 lines
5.0 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|