Files
mesh-sdk/go/catalogue/verbs_test.go
T
jschoubben 59b4c7910b Add the seat mesh-enrolment: six verbs and five events, so the module that joins a machine has a role the judge knows
ADR 0587 §1 makes joining a machine a seat held once by the module mesh-enrolment, the vault's only caller for its
enrolment verbs. The seat is in the mesh's own set, its verbs not optional (the seat is new with its holder), and
its events the five that carry no secret. The test is a block in TestHoldingAMeshSeatRequiresServingItsVerbs, no new
test function.

(issue 774, 774/S34)

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 01:41:03 +01:00

84 lines
3.5 KiB
Go

package catalogue
import (
"strings"
"testing"
)
// A served verb is written as a bare name or in full, and both read into one type (novox/hq ADR 0132).
func TestAServedVerbIsANameOrADefinition(t *testing.T) {
m, err := decodeForTest([]byte(`{"module":"till","version":"1","tools":["price","refund"],` +
`"seats":[{"name":"shop-till","serves":["price",{"name":"refund","description":"give it back",` +
`"input":{"type":"object","properties":{"order":{"type":"string"}}}}]}],` +
`"claims":[{"name":"shop-till","scope":"mesh"}]}`))
if err != nil {
t.Fatal(err)
}
got := m.DefinesSeats[0].Serves
if len(got) != 2 || got[0].Name != "price" || got[1].Name != "refund" || got[1].Description != "give it back" {
t.Fatalf("verbs not read: %+v", got)
}
if got[1].Input["type"] != "object" {
t.Fatalf("the schema did not travel with the verb: %+v", got[1].Input)
}
}
// Holding a mesh seat that serves verbs requires serving them, and the refusal names the verbs.
func TestHoldingAMeshSeatRequiresServingItsVerbs(t *testing.T) {
// 774/S34/AC1: the seat mesh-enrolment is held by a module serving its six verbs, and a seventh is refused.
enrolment, ok := SeatNamed(EnrolmentSeat)
if !ok || enrolment.Scope != ScopeMesh || len(enrolment.Emits) != 5 {
t.Fatalf("mesh-enrolment: in the set %v, %+v", ok, enrolment)
}
six := []string{"issue", "redeem", "confirm", "revoke", "tokens", "again"}
holder := func(serves ...string) Manifest {
return Manifest{Module: "mesh-enrolment", Tools: serves,
Claims: []Claim{{Name: EnrolmentSeat, Scope: ScopeMesh, Serves: serves}}}
}
if err := CanHold(holder(six...), enrolment); err != nil {
t.Errorf("the holder serving the six verbs was refused: %v", err)
}
if err := CanHold(holder(six[:5]...), enrolment); err == nil || !strings.Contains(err.Error(), "does not serve again") {
t.Errorf("a holder missing again: %v", err)
}
if err := CanHold(holder(append(six, "mint")...), enrolment); err == nil || !strings.Contains(err.Error(), "mint") {
t.Errorf("a holder saying it serves mint: %v", err)
}
was := Seats()
t.Cleanup(func() { UseSeats(was) })
UseSeats([]Seat{{Name: "mesh-controller", Scope: ScopeMesh, Decision: "test",
Serves: []Verb{{Name: "status"}, {Name: "push"}}}})
seat, _ := SeatNamed("mesh-controller")
partial := Manifest{Module: "a-controller", Tools: []string{"status"},
Claims: []Claim{{Name: "mesh-controller", Scope: ScopeMesh}}}
err := CanHold(partial, seat)
if err == nil || !strings.Contains(err.Error(), "does not serve push") {
t.Fatalf("a holder missing a verb was not refused by name: %v", err)
}
whole := Manifest{Module: "a-controller", Tools: []string{"status", "push"},
Claims: []Claim{{Name: "mesh-controller", Scope: ScopeMesh}}}
if err := CanHold(whole, seat); err != nil {
t.Fatalf("a holder serving every verb was refused: %v", err)
}
}
// The mesh's own verbs are declared in full: an agent cannot call a name without a schema.
func TestEveryControllerVerbIsDescribedWithASchema(t *testing.T) {
seen := map[string]bool{}
for _, v := range ControllerVerbs {
if v.Description == "" || v.Input == nil || v.Input["type"] != "object" {
t.Errorf("%s: no description or no object schema", v.Name)
}
if seen[v.Name] {
t.Errorf("%s declared twice", v.Name)
}
seen[v.Name] = true
}
seat, _ := SeatNamed(ControllerSeatName)
if len(seat.Serves) != len(ControllerVerbs) {
t.Fatalf("the compiled mesh-controller seat serves %d verbs, the table has %d", len(seat.Serves), len(ControllerVerbs))
}
}