Files
mesh-delivery/modules/mesh-grants/internal/buscompose/gated_test.go
T
jschoubben cdc6e1f521 Item 5, area 8 (join 11): the grants part lets a caller of a marked verb hear its own calls' ends
A holder says a held call's end on its seat's gated-ended, kept last per subject for a day in SEAT_<seat>_gated-ended,
which the grants part makes from the definition seatdef.Resolve gives (A-264). The caller is granted hearing
gated-ended.<caller>.> under its own escaped account name, and an ordered consumer on that stream filtered to it, from its
invokes of the marked verb by name; a module or process that answers a marked verb is granted saying the event to any
caller. No process of mesh-delivery holds a marked verb, so no holder here takes NewGateChannel.

Builds: design 47 G §677, §700, A-264, A-273

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 12:24:48 +01:00

56 lines
2.9 KiB
Go

package buscompose
import (
"slices"
"testing"
"git.novox.be/novox/mesh-sdk/go/seatdef"
)
// A held call's end is heard by its caller alone (design 47 G §677, A-264): the definition seatdef.Resolve gives a marked verb
// keeps gated-ended in SEAT_<seat>_gated-ended, last per subject for a day; a module's and a process's account that invoke the
// marked verb by name hear `gated-ended.<caller>.>` under their own escaped name and read the stream filtered to it, one that
// does not invoke it hears nothing, and a process that answers it says the event to any caller.
func TestAHeldCallsEndIsHeardByItsCallerAlone(t *testing.T) {
def, err := seatdef.Resolve(seatdef.Definition{Seat: "node-login-shell", Verbs: []seatdef.Verb{{Name: "execute", NeedsApproval: true}}}, nil)
if err != nil {
t.Fatal(err)
}
kept := KeptEventsOf(map[string]seatdef.Definition{def.Seat: def})
if len(kept) != 1 || kept[0].Stream != "SEAT_node-login-shell_gated-ended" || !kept[0].Last || kept[0].MaxAgeDays != 1 ||
kept[0].Filter != "mesh.seat.node-login-shell.event.gated-ended.*.*" {
t.Fatalf("kept = %+v, want the stream SEAT_node-login-shell_gated-ended, last per subject, one day", kept)
}
marked := []string{"seat:node-login-shell.execute"}
stream := "SEAT_node-login-shell_gated-ended"
caller, err := PermissionsFor(Principal{Kind: KindModule, Node: "a", Module: "shop", Invokes: marked, MarkedVerbs: marked})
if err != nil {
t.Fatal(err)
}
own := "mesh.seat.node-login-shell.event.gated-ended.a=2eshop.>"
if !slices.Contains(caller.Subscribe, own) || !slices.Contains(caller.Publish, "$JS.API.CONSUMER.CREATE."+stream+".*."+own) ||
!slices.Contains(caller.Publish, "$JS.API.CONSUMER.MSG.NEXT."+stream+".*") {
t.Errorf("the caller hears %v and reads %v, want its own ends alone", caller.Subscribe, caller.Publish)
}
other, _ := PermissionsFor(Principal{Kind: KindModule, Node: "a", Module: "bank", MarkedVerbs: marked})
for _, s := range append(other.Subscribe, other.Publish...) {
if slices.Contains([]string{own, "$JS.API.STREAM.INFO." + stream}, s) {
t.Errorf("a module that does not invoke the marked verb is granted %s", s)
}
}
proc, err := PermissionsFor(Principal{Kind: KindProcess, Node: "a", Module: "shop", Process: "run", Invokes: marked, MarkedVerbs: marked})
if err != nil {
t.Fatal(err)
}
if !slices.Contains(proc.Subscribe, "mesh.seat.node-login-shell.event.gated-ended.a=2eshop=2erun.>") {
t.Errorf("a process hears %v, want its own account's ends", proc.Subscribe)
}
holder, err := PermissionsFor(Principal{Kind: KindProcess, Node: "a", Module: "shell", Process: "run", AnswersSeat: marked, MarkedVerbs: marked})
if err != nil {
t.Fatal(err)
}
if !slices.Contains(holder.Publish, "mesh.seat.node-login-shell.event.gated-ended.*.*") || slices.Contains(holder.Subscribe, own) {
t.Errorf("the holder publishes %v, want gated-ended to any caller and no caller's hearing", holder.Publish)
}
}