75 lines
3.3 KiB
Go
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>")
|
|
}
|
|
}
|