You've already forked agentic-coding-workflow
bugfix
This commit is contained in:
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
func newArtifactSvc(repo *fakeRepo) (ArtifactService, RequirementService, ProjectService, *spyAudit) {
|
||||
spy := &spyAudit{}
|
||||
return NewArtifactService(repo, spy), NewRequirementService(repo, spy), NewProjectService(repo, spy), spy
|
||||
return NewArtifactService(repo, spy), NewRequirementService(repo, spy, nil, nil), NewProjectService(repo, spy), spy
|
||||
}
|
||||
|
||||
func TestArtifactService_Create_VersionAutoIncrement(t *testing.T) {
|
||||
@@ -68,7 +68,7 @@ func TestArtifactService_Create_RejectsNonArtifactPhase(t *testing.T) {
|
||||
r, err := reqSvc.Create(context.Background(), caller, "demo", CreateRequirementInput{Title: "R"})
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, phase := range []Phase{PhaseImplementing, PhaseReviewing, PhaseDone, Phase("bogus"), Phase("")} {
|
||||
for _, phase := range []Phase{PhaseDone, Phase("bogus"), Phase("")} {
|
||||
_, err = artSvc.Create(context.Background(), caller, "demo", r.Number, CreateArtifactInput{Phase: phase, Content: "x"})
|
||||
ae, ok := errs.As(err)
|
||||
require.True(t, ok, "phase=%s", phase)
|
||||
@@ -247,3 +247,124 @@ func TestArtifactService_List_ForbiddenForOutsider(t *testing.T) {
|
||||
require.True(t, ok)
|
||||
require.Equal(t, errs.CodeNotFound, ae.Code)
|
||||
}
|
||||
|
||||
func TestArtifactService_Create_AcceptsImplementingReviewing(t *testing.T) {
|
||||
repo := newFakeRepo()
|
||||
owner := uuid.New()
|
||||
seedProject(t, repo, owner)
|
||||
artSvc, reqSvc, _, _ := newArtifactSvc(repo)
|
||||
caller := Caller{UserID: owner}
|
||||
|
||||
r, err := reqSvc.Create(context.Background(), caller, "demo", CreateRequirementInput{Title: "R"})
|
||||
require.NoError(t, err)
|
||||
|
||||
// 扩展后的 ArtifactPhases 接受 implementing/reviewing。
|
||||
require.True(t, PhaseImplementing.IsArtifactPhase())
|
||||
require.True(t, PhaseReviewing.IsArtifactPhase())
|
||||
for _, phase := range []Phase{PhaseImplementing, PhaseReviewing} {
|
||||
a, err := artSvc.Create(context.Background(), caller, "demo", r.Number, CreateArtifactInput{Phase: phase, Content: "x"})
|
||||
require.NoError(t, err, "phase=%s", phase)
|
||||
require.Equal(t, VerdictNone, a.Verdict)
|
||||
}
|
||||
}
|
||||
|
||||
func TestArtifactService_Approve_SetsVerdictAndPointer(t *testing.T) {
|
||||
repo := newFakeRepo()
|
||||
owner := uuid.New()
|
||||
seedProject(t, repo, owner)
|
||||
artSvc, _, _, spy := newArtifactSvc(repo)
|
||||
r := seedRequirement(t, repo, owner, nil)
|
||||
caller := Caller{UserID: owner}
|
||||
|
||||
_, err := artSvc.Create(context.Background(), caller, "demo", r.Number, CreateArtifactInput{Phase: PhaseAuditing, Content: "report"})
|
||||
require.NoError(t, err)
|
||||
|
||||
out, err := artSvc.Approve(context.Background(), caller, "demo", r.Number, PhaseAuditing, 1, VerdictPass)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, VerdictPass, out.Verdict)
|
||||
|
||||
ptr, err := repo.GetPhasePointer(context.Background(), r.ID, PhaseAuditing)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, ptr.ApprovedArtifactID)
|
||||
require.Equal(t, out.ID, *ptr.ApprovedArtifactID)
|
||||
require.Contains(t, spy.actions(), "requirement_artifact.approve")
|
||||
}
|
||||
|
||||
func TestArtifactService_Approve_FailDoesNotSetPointer(t *testing.T) {
|
||||
repo := newFakeRepo()
|
||||
owner := uuid.New()
|
||||
seedProject(t, repo, owner)
|
||||
artSvc, _, _, _ := newArtifactSvc(repo)
|
||||
r := seedRequirement(t, repo, owner, nil)
|
||||
caller := Caller{UserID: owner}
|
||||
|
||||
_, err := artSvc.Create(context.Background(), caller, "demo", r.Number, CreateArtifactInput{Phase: PhaseAuditing, Content: "report"})
|
||||
require.NoError(t, err)
|
||||
|
||||
out, err := artSvc.Approve(context.Background(), caller, "demo", r.Number, PhaseAuditing, 1, VerdictFail)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, VerdictFail, out.Verdict)
|
||||
|
||||
_, err = repo.GetPhasePointer(context.Background(), r.ID, PhaseAuditing)
|
||||
ae, ok := errs.As(err)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, errs.CodeNotFound, ae.Code)
|
||||
}
|
||||
|
||||
func TestArtifactService_Approve_MovesPointerToNewerVersion(t *testing.T) {
|
||||
repo := newFakeRepo()
|
||||
owner := uuid.New()
|
||||
seedProject(t, repo, owner)
|
||||
artSvc, _, _, _ := newArtifactSvc(repo)
|
||||
r := seedRequirement(t, repo, owner, nil)
|
||||
caller := Caller{UserID: owner}
|
||||
|
||||
_, err := artSvc.Create(context.Background(), caller, "demo", r.Number, CreateArtifactInput{Phase: PhaseAuditing, Content: "v1"})
|
||||
require.NoError(t, err)
|
||||
v2, err := artSvc.Create(context.Background(), caller, "demo", r.Number, CreateArtifactInput{Phase: PhaseAuditing, Content: "v2"})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = artSvc.Approve(context.Background(), caller, "demo", r.Number, PhaseAuditing, 1, VerdictPass)
|
||||
require.NoError(t, err)
|
||||
_, err = artSvc.Approve(context.Background(), caller, "demo", r.Number, PhaseAuditing, 2, VerdictPass)
|
||||
require.NoError(t, err)
|
||||
|
||||
ptr, err := repo.GetPhasePointer(context.Background(), r.ID, PhaseAuditing)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, v2.ID, *ptr.ApprovedArtifactID)
|
||||
}
|
||||
|
||||
func TestArtifactService_Approve_BlockedWhenClosed(t *testing.T) {
|
||||
repo := newFakeRepo()
|
||||
owner := uuid.New()
|
||||
seedProject(t, repo, owner)
|
||||
artSvc, reqSvc, _, _ := newArtifactSvc(repo)
|
||||
r := seedRequirement(t, repo, owner, nil)
|
||||
caller := Caller{UserID: owner}
|
||||
|
||||
_, err := artSvc.Create(context.Background(), caller, "demo", r.Number, CreateArtifactInput{Phase: PhaseAuditing, Content: "report"})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, reqSvc.Close(context.Background(), caller, "demo", r.Number))
|
||||
|
||||
_, err = artSvc.Approve(context.Background(), caller, "demo", r.Number, PhaseAuditing, 1, VerdictPass)
|
||||
ae, ok := errs.As(err)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, errs.CodeRequirementClosed, ae.Code)
|
||||
}
|
||||
|
||||
func TestArtifactService_Approve_RejectsInvalidVerdict(t *testing.T) {
|
||||
repo := newFakeRepo()
|
||||
owner := uuid.New()
|
||||
seedProject(t, repo, owner)
|
||||
artSvc, _, _, _ := newArtifactSvc(repo)
|
||||
r := seedRequirement(t, repo, owner, nil)
|
||||
caller := Caller{UserID: owner}
|
||||
|
||||
_, err := artSvc.Create(context.Background(), caller, "demo", r.Number, CreateArtifactInput{Phase: PhaseAuditing, Content: "report"})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = artSvc.Approve(context.Background(), caller, "demo", r.Number, PhaseAuditing, 1, VerdictNone)
|
||||
ae, ok := errs.As(err)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, errs.CodeInvalidInput, ae.Code)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user