Files
mesh-controller/internal/broker/condition_grant_test.go
T

75 lines
3.3 KiB
Go

package broker
import "testing"
// The operator-channel seat as the messenger declares it once it takes a module's condition: copied from
// mesh-catalog modules/messenger/module.json at 5b235a6e (issue 1217), the seat's accepts, emits and by-caller verbs.
func operatorChannelWithCondition() Seat {
return Seat{Name: "operator-channel", Scope: "mesh", Accepts: []string{"ask", "cancel", "condition"},
Emits: []string{"decided"}, Serves: []string{"open", "history", "notify", "tell", "asks"},
ByCaller: []string{"ask", "cancel", "condition", "decided"}, Records: []string{"asks"}}
}
// 1216/AC1: a module that uses the seat may publish its condition under its own name.
func TestAModuleUsingTheOperatorChannelMayPublishItsConditionUnderItsOwnName(t *testing.T) {
x := perms(t, Principal{Kind: KindModule, Node: "anchor", Module: "web-app", Uses: []Seat{operatorChannelWithCondition()}})
if !allowed(x.Publish, "mesh.seat.operator-channel.accept.condition.web-app") {
t.Errorf("web-app may not say a condition as itself: %v", x.Publish)
}
}
// 1216/AC2: it may not publish a condition under another module's name, nor on the wildcard.
func TestAModuleMayNotSayAConditionUnderAnotherName(t *testing.T) {
x := perms(t, Principal{Kind: KindModule, Node: "anchor", Module: "web-app", Uses: []Seat{operatorChannelWithCondition()}})
for _, subject := range []string{
"mesh.seat.operator-channel.accept.condition.other-app",
"mesh.seat.operator-channel.accept.condition.*",
"mesh.seat.operator-channel.accept.condition.>",
"mesh.seat.operator-channel.accept.condition",
} {
if allowed(x.Publish, subject) {
t.Errorf("web-app may publish %s", subject)
}
}
}
// 1216/AC3: the seat's holder may take accept.condition.<any module> from the work queue SEAT_OPERATOR_CHANNEL.
func TestTheHolderOfTheOperatorChannelTakesEveryModulesCondition(t *testing.T) {
seat := operatorChannelWithCondition()
holder := perms(t, Principal{Kind: KindModule, Node: "anchor", Module: "messenger", Holds: []Seat{seat}})
if !allowed(holder.Subscribe, "mesh.seat.operator-channel.accept.condition.web-app") ||
!allowed(holder.Subscribe, "mesh.seat.operator-channel.accept.condition.other-app") {
t.Errorf("the holder does not take accept.condition.*: %v", holder.Subscribe)
}
if !allowed(holder.Publish, "$JS.API.CONSUMER.MSG.NEXT.SEAT_OPERATOR_CHANNEL.SEAT_OPERATOR_CHANNEL_worker") {
t.Errorf("the holder may not pull the seat's work queue: %v", holder.Publish)
}
users, _ := Users(Records{Nodes: []string{"anchor"}, Assigned: map[string][]Declared{"anchor": {
{Module: "messenger", Holds: []Seat{seat}},
{Module: "web-app", Uses: []Seat{seat}},
}}})
streams, workers := SeatTrafficObjects(users)
kept := false
for _, s := range streams {
if s.Name == "SEAT_OPERATOR_CHANNEL" {
for _, subject := range s.Subjects {
kept = kept || subjectMatches(subject, "mesh.seat.operator-channel.accept.condition.web-app")
}
}
}
if !kept {
t.Error("the work queue SEAT_OPERATOR_CHANNEL does not keep accept.condition.<module>")
}
taken := false
for _, w := range workers {
if w.Name == "SEAT_OPERATOR_CHANNEL_worker" {
for _, f := range w.Filters {
taken = taken || subjectMatches(f, "mesh.seat.operator-channel.accept.condition.web-app")
}
}
}
if !taken {
t.Error("the seat's worker does not take accept.condition.<module>")
}
}