Files
Agent-System/internal/swboot/catalog_test.go
weichenandCursor f6034fad37 feat(api): SWBOOT-05..08 wizard hooks and SWBOOT-10 allowlist stub
Add project-types/compliance catalogs, creation-preview, software create
fields, and fail-closed repo allowlist stub without real patch/merge.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-16 15:43:13 +00:00

93 lines
3.3 KiB
Go

package swboot
import (
"errors"
"strings"
"testing"
"time"
)
func TestProjectTypesCatalog(t *testing.T) {
items := ProjectTypesCatalog()
if len(items) != 4 {
t.Fatalf("expected 4 project types, got %d", len(items))
}
for _, it := range items {
if it.ProductDomain != DomainNonMedicalSoftware {
t.Fatalf("project type %s polluted domain %q", it.Key, it.ProductDomain)
}
if it.DefaultWorkflowKey != "software_bootstrap" {
t.Fatalf("expected software_bootstrap default for %s", it.Key)
}
blob := strings.ToLower(it.Name + " " + it.Description)
for _, bad := range []string{"临床", "nmpa", "cdmo"} {
if strings.Contains(blob, bad) {
t.Fatalf("medical term in project type %s", it.Key)
}
}
}
}
func TestBuildCreationPreview_SelfBootstrapSolo(t *testing.T) {
res := BuildCreationPreview(CreationPreviewInput{
Name: "Agent-System 自举", ProductDomain: DomainNonMedicalSoftware,
ProjectTypeKey: ProjectTypeExistingSelfBootstrap,
ProblemStatement: "建立可信路线", TargetUsers: "内部团队", TargetOutcome: "可执行发布路线",
GovernanceProfile: GovernanceStandard, TeamMode: TeamModeSolo,
ComplianceProfileKey: "internal_control+security_baseline",
ExecutionMode: ExecutionDocsOnly,
}, time.Date(2026, 9, 16, 12, 0, 0, 0, time.UTC))
if !res.Valid {
t.Fatalf("expected valid preview, issues=%v", res.Issues)
}
if res.ApprovalPolicy != ApprovalCreatorAcknowledgement {
t.Fatalf("expected creator acknowledgement, got %s", res.ApprovalPolicy)
}
if res.RecommendedWorkflow != "software_bootstrap" {
t.Fatalf("expected software_bootstrap, got %s", res.RecommendedWorkflow)
}
if res.CreationToken == "" || res.PlanHash == "" {
t.Fatal("expected token and plan hash")
}
}
func TestBuildCreationPreview_RejectsControlledPatchAndSoloPrivacy(t *testing.T) {
res := BuildCreationPreview(CreationPreviewInput{
Name: "x", ProductDomain: DomainNonMedicalSoftware,
ProjectTypeKey: ProjectTypeGreenfield,
ProblemStatement: "p", TargetUsers: "u", TargetOutcome: "o",
TeamMode: TeamModeSolo, ComplianceProfileKey: "privacy",
ExecutionMode: ExecutionControlledPatch,
}, time.Now().UTC())
if res.Valid {
t.Fatal("expected invalid")
}
joined := strings.Join(res.Issues, ";")
if !strings.Contains(joined, "solo") {
t.Fatalf("expected solo/privacy issue, got %v", res.Issues)
}
if !strings.Contains(joined, "ERR_EXECUTION_MODE_DISABLED") {
t.Fatalf("expected controlled_patch disabled, got %v", res.Issues)
}
}
func TestRepoAllowlistStub(t *testing.T) {
al := NewRepoAllowlist([]string{"/home/weichen/projects/Agent-System"})
if err := al.CheckReadOnlyAccess("/home/weichen/projects/Agent-System/cmd"); err != nil {
t.Fatalf("expected allowlisted path ok: %v", err)
}
if err := al.CheckReadOnlyAccess("/etc/passwd"); !errors.Is(err, ErrRepoPathNotAllowlisted) {
t.Fatalf("expected not allowlisted, got %v", err)
}
if err := al.ExecuteControlledPatch("/home/weichen/projects/Agent-System", nil); !errors.Is(err, ErrPatchExecutionUnimplemented) {
t.Fatalf("expected stub rejection, got %v", err)
}
if err := ApproveMerge("feature/x"); !errors.Is(err, ErrPatchExecutionUnimplemented) {
t.Fatalf("expected merge stub rejection, got %v", err)
}
empty := DefaultRepoAllowlist()
if empty.IsAllowlisted("/home/weichen/projects/Agent-System") {
t.Fatal("empty allowlist must deny all")
}
}