71 lines
3.1 KiB
Go
71 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestArchitectureSentinelNegativeCases(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
importPath string
|
|
want string
|
|
}{
|
|
{"domain infrastructure import", "git.cin.su/m/Assistant/adapters/postgres", "domain imports forbidden /adapters/"},
|
|
{"cross-module implementation import", "git.cin.su/m/Assistant/modules/beta/domain", "cross-module implementation import beta"},
|
|
{"undeclared contract dependency", "git.cin.su/m/Assistant/contracts/beta", "undeclared contract dependency contracts.beta"},
|
|
}
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
root := architectureFixture(t, test.importPath)
|
|
err := checkArchitectureAt(root)
|
|
if err == nil || !strings.Contains(err.Error(), test.want) {
|
|
t.Fatalf("sentinel error = %v", err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestArchitectureSentinelAcceptsDeclaredContractDependency(t *testing.T) {
|
|
root := architectureFixture(t, "git.cin.su/m/Assistant/contracts/beta")
|
|
registry := `{"registry_version":1,"semantic_generation":1,"architecture_generation":1,"modules":{"alpha":{"id":"mod.alpha","owns":[],"database_schema":"alpha","boundary_class":"remote_capable","may_depend_on":["contracts.beta"]},"beta":{"id":"mod.beta","owns":[],"database_schema":"beta","boundary_class":"remote_capable","may_depend_on":[]}}}`
|
|
writeFixture(t, filepath.Join(root, "architecture", "architecture-registry.json"), registry)
|
|
if err := checkArchitectureAt(root); err != nil {
|
|
t.Fatalf("declared dependency rejected: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestPreflightRejectsProtectedPathBelowTierE(t *testing.T) {
|
|
registry := Registry{ProtectedPaths: []string{"architecture/**", "security/**"}}
|
|
taskPacket := TaskPacket{TaskID: "DEV-bad", RiskTier: "C", Intent: "weaken guardrail"}
|
|
taskPacket.AllowedChangeScope.Paths = []string{"architecture/architecture-registry.json"}
|
|
if err := validateTaskScope(taskPacket, registry); err == nil || !strings.Contains(err.Error(), "protected path") {
|
|
t.Fatalf("protected path task error = %v", err)
|
|
}
|
|
taskPacket.RiskTier = "E"
|
|
if err := validateTaskScope(taskPacket, registry); err != nil {
|
|
t.Fatalf("Tier E protected path rejected: %v", err)
|
|
}
|
|
}
|
|
|
|
func architectureFixture(t *testing.T, importPath string) string {
|
|
t.Helper()
|
|
root := t.TempDir()
|
|
registry := `{"registry_version":1,"semantic_generation":1,"architecture_generation":1,"modules":{"alpha":{"id":"mod.alpha","owns":[],"database_schema":"alpha","boundary_class":"remote_capable","may_depend_on":[]},"beta":{"id":"mod.beta","owns":[],"database_schema":"beta","boundary_class":"remote_capable","may_depend_on":[]}}}`
|
|
writeFixture(t, filepath.Join(root, "architecture", "architecture-registry.json"), registry)
|
|
writeFixture(t, filepath.Join(root, "modules", "alpha", "domain", "fixture.go"), "package domain\nimport _ \""+importPath+"\"\n")
|
|
return root
|
|
}
|
|
|
|
func writeFixture(t *testing.T, path, content string) {
|
|
t.Helper()
|
|
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|