You've already forked agentic-coding-workflow
117 lines
4.1 KiB
Go
117 lines
4.1 KiB
Go
package project
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/yan1h/agent-coding-workflow/internal/infra/errs"
|
|
)
|
|
|
|
func newIssueSvc(repo *fakeRepo) (IssueService, RequirementService, *spyAudit) {
|
|
spy := &spyAudit{}
|
|
return NewIssueService(repo, spy), NewRequirementService(repo, spy), spy
|
|
}
|
|
|
|
func TestIssueService_Create_FreelanceAndAttached(t *testing.T) {
|
|
repo := newFakeRepo()
|
|
owner := uuid.New()
|
|
seedProject(t, repo, owner)
|
|
issueSvc, reqSvc, _ := newIssueSvc(repo)
|
|
caller := Caller{UserID: owner}
|
|
|
|
// 游离
|
|
free, err := issueSvc.Create(context.Background(), caller, "demo", CreateIssueInput{Title: "Free"})
|
|
require.NoError(t, err)
|
|
require.Nil(t, free.RequirementID)
|
|
|
|
// 挂载
|
|
r, err := reqSvc.Create(context.Background(), caller, "demo", CreateRequirementInput{Title: "R"})
|
|
require.NoError(t, err)
|
|
num := r.Number
|
|
att, err := issueSvc.Create(context.Background(), caller, "demo", CreateIssueInput{Title: "A", RequirementNumber: &num})
|
|
require.NoError(t, err)
|
|
require.NotNil(t, att.RequirementID)
|
|
require.Equal(t, r.ID, *att.RequirementID)
|
|
}
|
|
|
|
func TestIssueService_Create_RejectsClosedRequirement(t *testing.T) {
|
|
repo := newFakeRepo()
|
|
owner := uuid.New()
|
|
seedProject(t, repo, owner)
|
|
issueSvc, reqSvc, _ := newIssueSvc(repo)
|
|
caller := Caller{UserID: owner}
|
|
r, err := reqSvc.Create(context.Background(), caller, "demo", CreateRequirementInput{Title: "R"})
|
|
require.NoError(t, err)
|
|
require.NoError(t, reqSvc.Close(context.Background(), caller, "demo", r.Number))
|
|
num := r.Number
|
|
_, err = issueSvc.Create(context.Background(), caller, "demo", CreateIssueInput{Title: "X", RequirementNumber: &num})
|
|
ae, ok := errs.As(err)
|
|
require.True(t, ok)
|
|
require.Equal(t, errs.CodeRequirementClosed, ae.Code)
|
|
}
|
|
|
|
func TestIssueService_Update_MoveBetweenRequirementsAndDetach(t *testing.T) {
|
|
repo := newFakeRepo()
|
|
owner := uuid.New()
|
|
seedProject(t, repo, owner)
|
|
issueSvc, reqSvc, _ := newIssueSvc(repo)
|
|
caller := Caller{UserID: owner}
|
|
r1, _ := reqSvc.Create(context.Background(), caller, "demo", CreateRequirementInput{Title: "R1"})
|
|
r2, _ := reqSvc.Create(context.Background(), caller, "demo", CreateRequirementInput{Title: "R2"})
|
|
n1 := r1.Number
|
|
issue, err := issueSvc.Create(context.Background(), caller, "demo", CreateIssueInput{Title: "I", RequirementNumber: &n1})
|
|
require.NoError(t, err)
|
|
|
|
// move r1 → r2
|
|
n2 := r2.Number
|
|
pn2 := &n2
|
|
out, err := issueSvc.Update(context.Background(), caller, "demo", issue.Number, UpdateIssueInput{RequirementNumber: &pn2})
|
|
require.NoError(t, err)
|
|
require.Equal(t, r2.ID, *out.RequirementID)
|
|
|
|
// detach (传 nil 指针 → 取消挂载)
|
|
var nilPtr *int
|
|
out, err = issueSvc.Update(context.Background(), caller, "demo", issue.Number, UpdateIssueInput{RequirementNumber: &nilPtr})
|
|
require.NoError(t, err)
|
|
require.Nil(t, out.RequirementID)
|
|
}
|
|
|
|
func TestIssueService_Assign_AndUnassign(t *testing.T) {
|
|
repo := newFakeRepo()
|
|
owner := uuid.New()
|
|
seedProject(t, repo, owner)
|
|
issueSvc, _, _ := newIssueSvc(repo)
|
|
caller := Caller{UserID: owner}
|
|
i, _ := issueSvc.Create(context.Background(), caller, "demo", CreateIssueInput{Title: "I"})
|
|
|
|
dev := uuid.New()
|
|
out, err := issueSvc.Assign(context.Background(), caller, "demo", i.Number, &dev)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, out.AssigneeID)
|
|
require.Equal(t, dev, *out.AssigneeID)
|
|
|
|
out, err = issueSvc.Assign(context.Background(), caller, "demo", i.Number, nil)
|
|
require.NoError(t, err)
|
|
require.Nil(t, out.AssigneeID)
|
|
}
|
|
|
|
func TestIssueService_Update_BlockedWhenProjectArchived(t *testing.T) {
|
|
repo := newFakeRepo()
|
|
owner := uuid.New()
|
|
seedProject(t, repo, owner)
|
|
issueSvc, _, _ := newIssueSvc(repo)
|
|
projSvc := NewProjectService(repo, nil)
|
|
caller := Caller{UserID: owner}
|
|
i, _ := issueSvc.Create(context.Background(), caller, "demo", CreateIssueInput{Title: "I"})
|
|
|
|
require.NoError(t, projSvc.Archive(context.Background(), caller, "demo"))
|
|
t1 := "Renamed"
|
|
_, err := issueSvc.Update(context.Background(), caller, "demo", i.Number, UpdateIssueInput{Title: &t1})
|
|
ae, ok := errs.As(err)
|
|
require.True(t, ok)
|
|
require.Equal(t, errs.CodeProjectArchived, ae.Code)
|
|
}
|