internal/approvalgate/executed_call_test.go
Rama main · réplica de lectura del repositorio original.
//go:build !nobundledharness
package approvalgate
import (
"context"
"encoding/json"
"strings"
"testing"
"github.com/yeomyeonggeori/blueclaw/internal/task"
"github.com/yeomyeonggeori/blueprotocol/agentcontract"
"github.com/yeomyeonggeori/blueprotocol/holdrecord"
)
func spentApprovalEventBodies(taskRunService *task.TaskRunService, taskRunID string) []string {
bodies := []string{}
for _, taskEvent := range taskRunService.ListTaskEvent(taskRunID) {
if taskEvent.Name == agentcontract.TaskEventApprovalHoldSpent {
bodies = append(bodies, taskEvent.Body)
}
}
return bodies
}
func TestTheSpentApprovalCarriesTheCallAndTheHoldItSpent(t *testing.T) {
gate, taskRunService, taskRun := gateFixture(t)
gate.AwaitApproval(context.Background(), approvalRequestFixture(taskRun.TaskRunID))
holdID := holdrecord.Holds(taskRunService.ListTaskEvent(taskRun.TaskRunID))[0].ID
recordDecision(taskRunService, taskRun.TaskRunID, "approve")
gate.AwaitApproval(context.Background(), approvalRequestFixture(taskRun.TaskRunID))
bodies := spentApprovalEventBodies(taskRunService, taskRun.TaskRunID)
if len(bodies) != 1 {
t.Fatalf("one approval is spent once, and by one writer: %v", bodies)
}
for _, expectedFragment := range []string{`"toolName":"event_delete"`, `"eventID":"event-1"`, `"holdID":"` + holdID + `"`} {
if !strings.Contains(bodies[0], expectedFragment) {
t.Fatalf("expected the spent approval to carry %q, got %s", expectedFragment, bodies[0])
}
}
if strings.Contains(bodies[0], "approvalToken") {
t.Fatalf("a hold has one id, got %s", bodies[0])
}
}
func TestAHoldIsSpentOnceSoASecondCallDoesNotClaimIt(t *testing.T) {
taskRunService := task.NewTaskRunService(task.NewTaskEventService())
taskRun := taskRunService.CreateTaskRun("person-1", "conversation-1", "내일 회의 지워줘")
holdID := holdrecord.Open(taskRunService, taskRun.TaskRunID, agentcontract.HeldCall{ToolName: "event_delete", ToolInput: json.RawMessage(`{"eventID":"event-1"}`)}, nil).ID
holdrecord.Decide(taskRunService, taskRun.TaskRunID, holdID, holdrecord.DecisionApprove, "chat_reply")
firstHoldID := RecordApprovalSpent(taskRunService, taskRun.TaskRunID, "event_delete", json.RawMessage(`{"eventID":"event-1"}`))
secondHoldID := RecordApprovalSpent(taskRunService, taskRun.TaskRunID, "event_delete", json.RawMessage(`{"eventID":"event-2"}`))
if firstHoldID != holdID || secondHoldID != "" {
t.Fatalf("the first call spends the approved hold and the next claims none, got %q then %q", firstHoldID, secondHoldID)
}
if bodies := spentApprovalEventBodies(taskRunService, taskRun.TaskRunID); len(bodies) != 2 {
t.Fatalf("expected both calls to be recorded, got %v", bodies)
}
}