You've already forked agentic-coding-workflow
111 lines
3.8 KiB
Go
111 lines
3.8 KiB
Go
package docs
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/yan1h/agent-coding-workflow/internal/infra/git"
|
|
"github.com/yan1h/agent-coding-workflow/internal/jobs"
|
|
)
|
|
|
|
type fakeDocsRepo struct {
|
|
summaries map[string]*Summary // keyed by commitSHA|kind
|
|
upserts int
|
|
}
|
|
|
|
func key(commit, kind string) string { return commit + "|" + kind }
|
|
|
|
func newFakeDocsRepo() *fakeDocsRepo {
|
|
return &fakeDocsRepo{summaries: map[string]*Summary{}}
|
|
}
|
|
|
|
func (r *fakeDocsRepo) Get(_ context.Context, _ uuid.UUID, commit, kind string) (*Summary, error) {
|
|
return r.summaries[key(commit, kind)], nil
|
|
}
|
|
func (r *fakeDocsRepo) Upsert(_ context.Context, in UpsertInput) (*Summary, error) {
|
|
r.upserts++
|
|
s := &Summary{
|
|
ID: uuid.New(), WorkspaceID: in.WorkspaceID, WorktreeID: in.WorktreeID,
|
|
Branch: in.Branch, CommitSHA: in.CommitSHA, Kind: in.Kind, Title: in.Title,
|
|
BodyMD: in.BodyMD, Model: in.Model, Status: in.Status, Error: in.Error,
|
|
}
|
|
r.summaries[key(in.CommitSHA, in.Kind)] = s
|
|
return s, nil
|
|
}
|
|
|
|
type fakeLocator struct{}
|
|
|
|
func (fakeLocator) LocateWorkspace(context.Context, uuid.UUID) (string, error) { return "/tmp/x", nil }
|
|
func (fakeLocator) LocateWorktree(context.Context, uuid.UUID) (string, error) { return "/tmp/x", nil }
|
|
|
|
// gitShim embeds git.Runner (nil) and overrides only DiffStat, the single method
|
|
// the SummaryRunner invokes. Any other call would panic, which never happens here.
|
|
type gitShim struct {
|
|
git.Runner
|
|
diff string
|
|
}
|
|
|
|
func (g gitShim) DiffStat(context.Context, string, string) (string, error) { return g.diff, nil }
|
|
|
|
type fakeSummarizer struct {
|
|
title, body, model string
|
|
err error
|
|
}
|
|
|
|
func (s fakeSummarizer) Summarize(context.Context, string, string, string) (string, string, string, error) {
|
|
return s.title, s.body, s.model, s.err
|
|
}
|
|
|
|
func newRunner(repo Repository, summ Summarizer, diff string) *SummaryRunner {
|
|
return NewSummaryRunner(repo, fakeLocator{}, gitShim{diff: diff}, summ, nil)
|
|
}
|
|
|
|
func TestSummaryRunner_Success(t *testing.T) {
|
|
repo := newFakeDocsRepo()
|
|
wsID := uuid.New()
|
|
r := newRunner(repo, fakeSummarizer{title: "Add feature X", body: "# Add feature X\n\n- did stuff", model: "m1"}, "f.go | 2 +-")
|
|
|
|
payload, _ := json.Marshal(summaryPayload{WorkspaceID: wsID, Branch: "main", CommitSHA: "abc"})
|
|
require.NoError(t, r.Handle(context.Background(), jobs.Job{Payload: payload}))
|
|
|
|
s := repo.summaries[key("abc", KindCommit)]
|
|
require.NotNil(t, s)
|
|
require.Equal(t, StatusCompleted, s.Status)
|
|
require.Equal(t, "# Add feature X\n\n- did stuff", s.BodyMD)
|
|
require.NotNil(t, s.Title)
|
|
require.Equal(t, "Add feature X", *s.Title)
|
|
require.NotNil(t, s.Model)
|
|
require.Equal(t, "m1", *s.Model)
|
|
}
|
|
|
|
func TestSummaryRunner_IdempotentWhenCompleted(t *testing.T) {
|
|
repo := newFakeDocsRepo()
|
|
wsID := uuid.New()
|
|
repo.summaries[key("abc", KindCommit)] = &Summary{CommitSHA: "abc", Kind: KindCommit, Status: StatusCompleted}
|
|
|
|
r := newRunner(repo, fakeSummarizer{title: "x", body: "y", model: "m"}, "stat")
|
|
payload, _ := json.Marshal(summaryPayload{WorkspaceID: wsID, Branch: "main", CommitSHA: "abc"})
|
|
require.NoError(t, r.Handle(context.Background(), jobs.Job{Payload: payload}))
|
|
require.Equal(t, 0, repo.upserts, "completed summary must not be regenerated")
|
|
}
|
|
|
|
func TestSummaryRunner_FailurePersistsFailedRow(t *testing.T) {
|
|
repo := newFakeDocsRepo()
|
|
wsID := uuid.New()
|
|
r := newRunner(repo, fakeSummarizer{err: errors.New("llm down")}, "stat")
|
|
payload, _ := json.Marshal(summaryPayload{WorkspaceID: wsID, Branch: "main", CommitSHA: "abc"})
|
|
err := r.Handle(context.Background(), jobs.Job{Payload: payload})
|
|
require.Error(t, err)
|
|
s := repo.summaries[key("abc", KindCommit)]
|
|
require.NotNil(t, s)
|
|
require.Equal(t, StatusFailed, s.Status)
|
|
require.NotNil(t, s.Error)
|
|
}
|
|
|
|
var _ Repository = (*fakeDocsRepo)(nil)
|