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
56 lines
2.9 KiB
Go
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)
|
|
}
|
|
}
|