package acp_test import ( "context" "testing" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/yan1h/agent-coding-workflow/internal/acp" "github.com/yan1h/agent-coding-workflow/internal/project" "github.com/yan1h/agent-coding-workflow/internal/workspace" ) // fakeProjectAccess 满足 acp.ProjectAccess 接口;测试时按需返回。 type fakeProjectAccess struct { pj *project.Project issue *project.Issue req *project.Requirement err error } func (f fakeProjectAccess) GetProjectByWorkspace(_ context.Context, _ uuid.UUID) (*project.Project, error) { return f.pj, f.err } func (f fakeProjectAccess) GetIssueByNumber(_ context.Context, _ uuid.UUID, _ int) (*project.Issue, error) { if f.issue == nil { return nil, f.err } return f.issue, nil } func (f fakeProjectAccess) GetRequirementByNumber(_ context.Context, _ uuid.UUID, _ int) (*project.Requirement, error) { if f.req == nil { return nil, f.err } return f.req, nil } func TestResolveBranch_Explicit(t *testing.T) { t.Parallel() ws := &workspace.Workspace{ID: uuid.New(), DefaultBranch: "main"} br := "feat/x" got, isMain, err := acp.ResolveBranch(context.Background(), ws, uuid.New(), acp.CreateSessionInput{Branch: &br}, "demo", fakeProjectAccess{}) require.NoError(t, err) assert.Equal(t, "feat/x", got) assert.False(t, isMain) } func TestResolveBranch_ExplicitMain(t *testing.T) { t.Parallel() ws := &workspace.Workspace{ID: uuid.New(), DefaultBranch: "main"} br := "main" got, isMain, err := acp.ResolveBranch(context.Background(), ws, uuid.New(), acp.CreateSessionInput{Branch: &br}, "demo", fakeProjectAccess{}) require.NoError(t, err) assert.Equal(t, "main", got) assert.True(t, isMain) } func TestResolveBranch_FromIssue(t *testing.T) { t.Parallel() ws := &workspace.Workspace{ID: uuid.New(), ProjectID: uuid.New(), DefaultBranch: "main"} issueNum := 42 pa := fakeProjectAccess{issue: &project.Issue{Number: 42, WorkspaceID: nil}} got, isMain, err := acp.ResolveBranch(context.Background(), ws, uuid.New(), acp.CreateSessionInput{IssueNumber: &issueNum}, "demo", pa) require.NoError(t, err) assert.Equal(t, "issue/demo-42", got) assert.False(t, isMain) } func TestResolveBranch_IssueLinkedToOtherWorkspace(t *testing.T) { t.Parallel() ws := &workspace.Workspace{ID: uuid.New(), ProjectID: uuid.New(), DefaultBranch: "main"} other := uuid.New() pa := fakeProjectAccess{issue: &project.Issue{Number: 42, WorkspaceID: &other}} num := 42 _, _, err := acp.ResolveBranch(context.Background(), ws, uuid.New(), acp.CreateSessionInput{IssueNumber: &num}, "demo", pa) require.Error(t, err) } func TestResolveBranch_FromRequirement(t *testing.T) { t.Parallel() ws := &workspace.Workspace{ID: uuid.New(), ProjectID: uuid.New(), DefaultBranch: "main"} num := 7 pa := fakeProjectAccess{req: &project.Requirement{Number: 7, WorkspaceID: nil}} got, isMain, err := acp.ResolveBranch(context.Background(), ws, uuid.New(), acp.CreateSessionInput{RequirementNumber: &num}, "demo", pa) require.NoError(t, err) assert.Equal(t, "req/demo-7", got) assert.False(t, isMain) } func TestResolveBranch_AutoFallback(t *testing.T) { t.Parallel() ws := &workspace.Workspace{ID: uuid.New(), ProjectID: uuid.New(), DefaultBranch: "main"} sid := uuid.New() got, isMain, err := acp.ResolveBranch(context.Background(), ws, sid, acp.CreateSessionInput{}, "demo", fakeProjectAccess{}) require.NoError(t, err) assert.Contains(t, got, "acp-auto/") assert.False(t, isMain) }