Go 111 lines
package workflow
import (
"os"
"path/filepath"
"testing"
)
func TestLeakGuard_CleanTrackedTree(t *testing.T) {
cfg := newCfg(t)
writeRepoFile(t, cfg.RepoRoot, "main.go", "package main\nfunc main(){}\n")
writeRepoFile(t, cfg.RepoRoot, ".gitignore", "/.eeco/\n")
gitInit(t, cfg.RepoRoot)
res, err := leakGuard{}.Run(Env{Config: cfg})
if err != nil {
t.Fatal(err)
}
if res.Code != CodeClean {
t.Fatalf("clean repo -> %d (%s) %+v", res.Code, res.Summary, res.Findings)
}
}
func TestLeakGuard_FlagsTrailerInTrackedFile(t *testing.T) {
cfg := newCfg(t)
trailer := fragCoAB + ": A <a@b>"
writeRepoFile(t, cfg.RepoRoot, "CHANGELOG.md", "release notes\n"+trailer+"\n")
gitInit(t, cfg.RepoRoot)
res, err := leakGuard{}.Run(Env{Config: cfg})
if err != nil {
t.Fatal(err)
}
if res.Code != CodeFinding {
t.Fatalf("tracked trailer -> %d, want %d (%+v)", res.Code, CodeFinding, res.Findings)
}
}
func TestLeakGuard_FlagsWorkspacePathLeak(t *testing.T) {
cfg := newCfg(t)
// Build the engine path from fragments so this tracked test source
// never carries a contiguous workspace-engine path for the gate to
// (correctly) flag against eeco itself.
eng := cfg.WorkspaceName + "/state/"
writeRepoFile(t, cfg.RepoRoot, "notes.txt", "debug dump from "+eng+"queue.md here\n")
gitInit(t, cfg.RepoRoot)
res, err := leakGuard{}.Run(Env{Config: cfg})
if err != nil {
t.Fatal(err)
}
if res.Code != CodeFinding {
t.Fatalf("workspace path leak -> %d, want %d", res.Code, CodeFinding)
}
}
func TestLeakGuard_GitignoreEntryExempt(t *testing.T) {
cfg := newCfg(t)
// The .gitignore workspace line is the documented intended change;
// it must never be reported as a leak — even an engine-path-shaped
// line here is exempt. Fragment-built for the reason above.
ws := cfg.WorkspaceName
writeRepoFile(t, cfg.RepoRoot, ".gitignore", "/"+ws+"/\n"+ws+"/state/\n")
gitInit(t, cfg.RepoRoot)
res, err := leakGuard{}.Run(Env{Config: cfg})
if err != nil {
t.Fatal(err)
}
if res.Code != CodeClean {
t.Fatalf(".gitignore flagged: %+v", res.Findings)
}
}
func TestLeakGuard_IgnoresUntrackedFile(t *testing.T) {
cfg := newCfg(t)
writeRepoFile(t, cfg.RepoRoot, "tracked.txt", "fine\n")
gitInit(t, cfg.RepoRoot)
// Written after `git add`: untracked, so it cannot enter history.
writeRepoFile(t, cfg.RepoRoot, "untracked.txt", fragCoAB+": X <x@y>\n")
res, err := leakGuard{}.Run(Env{Config: cfg})
if err != nil {
t.Fatal(err)
}
if res.Code != CodeClean {
t.Fatalf("untracked file gated the commit: %+v", res.Findings)
}
}
func TestLeakGuard_ScansCommitMessage(t *testing.T) {
cfg := newCfg(t)
writeRepoFile(t, cfg.RepoRoot, "f.txt", "ok\n")
gitInit(t, cfg.RepoRoot)
msg := "feat: a change\n\n" + fragCoAB + ": Tool <t@x>\n"
if err := os.WriteFile(filepath.Join(cfg.RepoRoot, ".git", "COMMIT_EDITMSG"), []byte(msg), 0o644); err != nil {
t.Fatal(err)
}
res, err := leakGuard{}.Run(Env{Config: cfg})
if err != nil {
t.Fatal(err)
}
if res.Code != CodeFinding {
t.Fatalf("commit-message trailer -> %d, want %d", res.Code, CodeFinding)
}
var sawMsg bool
for _, f := range res.Findings {
if f.Path == "COMMIT_EDITMSG" {
sawMsg = true
}
}
if !sawMsg {
t.Errorf("commit message not attributed in findings: %+v", res.Findings)
}
}