mavend: centralize action validation boundary (slice 4)
This commit is contained in:
@@ -73,7 +73,7 @@ func TestHexisMutatingRequiresConfirm(t *testing.T) {
|
||||
caps := `[{"id":"cap_restart","name":"restart","read_only":false,"risk":"high"}]`
|
||||
h, executed := newHexisTestHandler(t, resolved, caps)
|
||||
|
||||
reply := h.handleHexisAct(ctx, actDec("muzick indexer"))
|
||||
reply := h.handleHexisAct(ctx, actDec("muzick indexer"), routeCandidate("restart"))
|
||||
if !strings.Contains(reply, "да") {
|
||||
t.Fatalf("mutating cap should ask to confirm, got %q", reply)
|
||||
}
|
||||
@@ -103,7 +103,7 @@ func TestHexisConfirmNoDoesNotExecute(t *testing.T) {
|
||||
caps := `[{"id":"cap_restart","name":"restart","read_only":false}]`
|
||||
h, executed := newHexisTestHandler(t, resolved, caps)
|
||||
|
||||
_ = h.handleHexisAct(ctx, actDec("muzick indexer"))
|
||||
_ = h.handleHexisAct(ctx, actDec("muzick indexer"), routeCandidate("restart"))
|
||||
reply, handled := h.resolveConfirm(ctx, "нет")
|
||||
if !handled || !strings.Contains(reply, "отменила") {
|
||||
t.Fatalf("no should cancel, got handled=%v reply=%q", handled, reply)
|
||||
@@ -119,7 +119,7 @@ func TestHexisReadOnlyExecutesImmediately(t *testing.T) {
|
||||
caps := `[{"id":"cap_status","name":"restart","read_only":true}]`
|
||||
h, executed := newHexisTestHandler(t, resolved, caps)
|
||||
|
||||
reply := h.handleHexisAct(ctx, actDec("muzick indexer"))
|
||||
reply := h.handleHexisAct(ctx, actDec("muzick indexer"), routeCandidate("restart"))
|
||||
if !*executed {
|
||||
t.Fatal("read-only cap should execute without confirmation")
|
||||
}
|
||||
@@ -136,7 +136,7 @@ func TestHexisAmbiguousAsksClarification(t *testing.T) {
|
||||
ambiguous := `{"status":"ambiguous","candidates":[{"entity_id":"ent_muzick","display_name":"Muzick indexer"},{"entity_id":"ent_manga","display_name":"Manga indexer"}]}`
|
||||
h, executed := newHexisTestHandler(t, ambiguous, `[]`)
|
||||
|
||||
reply := h.handleHexisAct(ctx, actDec("the indexer"))
|
||||
reply := h.handleHexisAct(ctx, actDec("the indexer"), routeCandidate("restart"))
|
||||
if !strings.Contains(reply, "Muzick indexer") || !strings.Contains(reply, "Manga indexer") {
|
||||
t.Fatalf("ambiguous should list candidates, got %q", reply)
|
||||
}
|
||||
@@ -154,7 +154,7 @@ func TestHexisResolveFlatShapeAccepted(t *testing.T) {
|
||||
caps := `[{"id":"cap_status","name":"restart","read_only":true}]`
|
||||
h, executed := newHexisTestHandler(t, flat, caps)
|
||||
|
||||
reply := h.handleHexisAct(ctx, actDec("muzick indexer"))
|
||||
reply := h.handleHexisAct(ctx, actDec("muzick indexer"), routeCandidate("restart"))
|
||||
if !*executed {
|
||||
t.Fatalf("flat-shaped resolved entity should still execute, got reply %q", reply)
|
||||
}
|
||||
@@ -183,7 +183,7 @@ func TestHexisNexusErrorFailsClosed(t *testing.T) {
|
||||
ecosystem: stubEcosystem(nexus.URL, hexis.URL),
|
||||
}
|
||||
|
||||
reply := h.handleHexisAct(ctx, actDec("muzick indexer"))
|
||||
reply := h.handleHexisAct(ctx, actDec("muzick indexer"), routeCandidate("restart"))
|
||||
if reply == "" {
|
||||
t.Fatal("nexus dependency failure must not fall through with an empty reply")
|
||||
}
|
||||
@@ -216,7 +216,7 @@ func TestHexisUnavailableFailsClosed(t *testing.T) {
|
||||
ecosystem: stubEcosystem(nexus.URL, hexis.URL),
|
||||
}
|
||||
|
||||
reply := h.handleHexisAct(ctx, actDec("muzick indexer"))
|
||||
reply := h.handleHexisAct(ctx, actDec("muzick indexer"), routeCandidate("restart"))
|
||||
if reply == "" {
|
||||
t.Fatal("hexis dependency failure must not fall through with an empty reply")
|
||||
}
|
||||
@@ -234,7 +234,7 @@ func TestHexisNotFoundStillFallsThrough(t *testing.T) {
|
||||
notFound := `{"status":"not_found"}`
|
||||
h, executed := newHexisTestHandler(t, notFound, `[]`)
|
||||
|
||||
reply := h.handleHexisAct(ctx, actDec("turn off the lights"))
|
||||
reply := h.handleHexisAct(ctx, actDec("turn off the lights"), routeCandidate("restart"))
|
||||
if reply != "" {
|
||||
t.Fatalf("not_found resolution should fall through with empty reply, got %q", reply)
|
||||
}
|
||||
@@ -264,7 +264,7 @@ func TestHexisIrreversibleCapabilityIsNotRunFromVoice(t *testing.T) {
|
||||
caps := `[{"id":"cap_wipe","name":"restart","read_only":false,"risk":"irreversible","requires_confirmation":true}]`
|
||||
h, executed := newHexisTestHandler(t, resolved, caps)
|
||||
|
||||
reply := h.handleHexisAct(ctx, actDec("muzick indexer"))
|
||||
reply := h.handleHexisAct(ctx, actDec("muzick indexer"), routeCandidate("restart"))
|
||||
if *executed {
|
||||
t.Fatal("an irreversible capability ran from the voice path")
|
||||
}
|
||||
@@ -284,7 +284,7 @@ func TestHexisSafeCapabilityRunsOnItsDeclaredTier(t *testing.T) {
|
||||
caps := `[{"id":"cap_status","name":"restart","read_only":true,"risk":"safe"}]`
|
||||
h, executed := newHexisTestHandler(t, resolved, caps)
|
||||
|
||||
reply := h.handleHexisAct(ctx, actDec("muzick indexer"))
|
||||
reply := h.handleHexisAct(ctx, actDec("muzick indexer"), routeCandidate("restart"))
|
||||
if !*executed {
|
||||
t.Fatal("a capability Hexis calls safe should run")
|
||||
}
|
||||
@@ -301,7 +301,7 @@ func TestHexisUndeclaredTierStillConfirms(t *testing.T) {
|
||||
caps := `[{"id":"cap_restart","name":"restart","read_only":false}]`
|
||||
h, executed := newHexisTestHandler(t, resolved, caps)
|
||||
|
||||
reply := h.handleHexisAct(ctx, actDec("muzick indexer"))
|
||||
reply := h.handleHexisAct(ctx, actDec("muzick indexer"), routeCandidate("restart"))
|
||||
if *executed {
|
||||
t.Fatal("a mutating capability ran without a confirm")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user