package workflow import "testing" // Fingerprint literals are assembled from fragments here for the same // reason as in attribution.go: this test file is tracked source, and // eeco's own comment-hygiene / leak-guard scan it. A contiguous // attribution literal would (correctly) make eeco fail its own gate. const ( fragCoAB = "Co-" + "Authored-" + "By" fragGen = "Gener" + "ated" ) func TestDetector_Clean(t *testing.T) { d, err := NewDetector(nil) if err != nil { t.Fatal(err) } goods := []string{ "package main\n\nfunc main() {}\n", "// guidance on authoring and code review\n", "see the `" + fragCoAB + "` trailer in the docs\n", // backticked prose, not a trailer line " note: " + fragCoAB + " is a git trailer key\n", // token mid-line, no colon at start fragGen + " the quarterly report by hand on a fair day\n", // "fair" must not trip the AI token fragGen + " with the standard build pipeline\n", // no tool token "the model was " + fragGen + " by a deterministic script\n", // "model"/"script" excluded by design } for i, g := range goods { if f := d.Scan("clean.txt", g); len(f) != 0 { t.Errorf("good[%d] flagged %+v\n input=%q", i, f, g) } } } func TestDetector_Fingerprints(t *testing.T) { d, _ := NewDetector(nil) coAB := fragCoAB + ": A Person " cases := []struct{ name, in string }{ {"trailer at line start", coAB + "\n"}, {"trailer after whitespace", " " + coAB + "\n"}, {"with-tool line", fragGen + " with an AI assistant\n"}, {"by-cli line", "report " + fragGen + " by the project CLI\n"}, {"by-agent line", fragGen + " by a coding agent for us\n"}, {"robot emoji line", "\U0001F916 " + fragGen + " with a coding agent\n"}, } for _, c := range cases { got := d.Scan("bad.txt", c.in) if len(got) == 0 { t.Errorf("%s: expected a finding, input=%q", c.name, c.in) continue } if got[0].Line != 1 { t.Errorf("%s: line = %d, want 1", c.name, got[0].Line) } } } func TestDetector_MultiLineNumbers(t *testing.T) { d, _ := NewDetector(nil) in := "clean line\nanother clean line\n" + fragCoAB + ": X \n" got := d.Scan("f", in) if len(got) != 1 || got[0].Line != 3 { t.Fatalf("want one finding on line 3, got %+v", got) } } func TestDetector_ScanResponse(t *testing.T) { d, _ := NewDetector(nil) got := d.ScanResponse(fragCoAB + ": X \n") want := []string{"line 1: co-authored-by trailer"} if len(got) != 1 || got[0] != want[0] { t.Errorf("ScanResponse(attribution) = %v, want %v", got, want) } if r := d.ScanResponse("a clean response with no fingerprint\n"); r != nil { t.Errorf("ScanResponse(clean) = %v, want nil", r) } } func TestDetector_ExtraPattern(t *testing.T) { d, err := NewDetector([]string{`INTERNAL-CODENAME`}) if err != nil { t.Fatal(err) } if f := d.Scan("x", "leaked INTERNAL-CODENAME here\n"); len(f) == 0 { t.Error("configured extra pattern was not applied") } if _, err := NewDetector([]string{"("}); err == nil { t.Error("an invalid extra regex must be a loud error") } }