Files

122 lines
3.5 KiB
Go

package sqlite
import (
"context"
"testing"
"time"
"inbox/internal/base/timeutil"
"inbox/internal/domain/message"
"inbox/internal/domain/role"
"inbox/internal/domain/topic"
"inbox/internal/domain/workspace"
)
func TestCreateMessageCreatesHumanTaskOnlyForQuestionMessages(t *testing.T) {
ctx := context.Background()
clock := timeutil.FixedClock{Time: time.Date(2026, 3, 17, 15, 0, 0, 0, time.UTC)}
store, err := OpenInMemory(clock)
if err != nil {
t.Fatalf("OpenInMemory() error = %v", err)
}
defer store.Close()
now := timeutil.FormatRFC3339(clock.Now())
project, err := store.CreateProject(ctx, workspace.Project{
Slug: "demo",
Name: "Demo",
RootPath: t.TempDir(),
DefaultBranch: "main",
Status: "active",
CreatedAt: now,
UpdatedAt: now,
})
if err != nil {
t.Fatalf("CreateProject() error = %v", err)
}
ws, err := store.CreateWorkspace(ctx, workspace.Workspace{
ProjectID: project.ID,
Slug: "demo",
Name: "demo",
RootPath: t.TempDir(),
BaseBranch: "main",
WorktreeBranch: "worktree/demo",
RuntimeBackend: "host",
Status: "active",
CreatedAt: now,
UpdatedAt: now,
})
if err != nil {
t.Fatalf("CreateWorkspace() error = %v", err)
}
if _, err := store.UpsertRole(ctx, role.Definition{
Name: "approver",
Title: "Approver",
ExecutorKind: role.ExecutorKindHuman,
IsEnabled: true,
}, "test"); err != nil {
t.Fatalf("UpsertRole(approver) error = %v", err)
}
topicRecord, err := store.CreateTopic(ctx, topic.Record{
WorkspaceID: ws.ID,
Slug: "sample",
Title: "sample",
Space: "workflow",
Status: "plan",
CreatedAt: now,
UpdatedAt: now,
})
if err != nil {
t.Fatalf("CreateTopic() error = %v", err)
}
decision, err := store.CreateMessage(ctx, message.Record{
WorkspaceID: ws.ID,
TopicID: topicRecord.ID,
FromRoleName: "leader",
ToExpr: "approver",
Type: message.TypeDecision,
Stage: "execution",
BodyMarkdown: "Proceed with the rollout.",
})
if err != nil {
t.Fatalf("CreateMessage(decision) error = %v", err)
}
question, err := store.CreateMessage(ctx, message.Record{
WorkspaceID: ws.ID,
TopicID: topicRecord.ID,
FromRoleName: "leader",
ToExpr: "approver",
Type: message.TypeQuestion,
Stage: "review",
BodyMarkdown: "Should this ship tonight?",
})
if err != nil {
t.Fatalf("CreateMessage(question) error = %v", err)
}
var humanTaskCount int
if err := store.DB().QueryRow(`SELECT COUNT(*) FROM human_tasks WHERE topic_id = ?`, topicRecord.ID).Scan(&humanTaskCount); err != nil {
t.Fatalf("count human_tasks: %v", err)
}
if humanTaskCount != 1 {
t.Fatalf("expected exactly one human task, got %d", humanTaskCount)
}
var promptMessageID string
if err := store.DB().QueryRow(`SELECT prompt_message_id FROM human_tasks WHERE topic_id = ?`, topicRecord.ID).Scan(&promptMessageID); err != nil {
t.Fatalf("select prompt_message_id: %v", err)
}
if promptMessageID != question.ID {
t.Fatalf("expected human task to point at question message %s, got %s", question.ID, promptMessageID)
}
var decisionHumanTaskCount int
if err := store.DB().QueryRow(`SELECT COUNT(*) FROM human_tasks WHERE prompt_message_id = ?`, decision.ID).Scan(&decisionHumanTaskCount); err != nil {
t.Fatalf("count decision human task: %v", err)
}
if decisionHumanTaskCount != 0 {
t.Fatalf("expected no human task for decision message, got %d", decisionHumanTaskCount)
}
}