diff --git a/cmd/scan_sources_test.go b/cmd/scan_sources_test.go new file mode 100644 index 0000000..28b04a2 --- /dev/null +++ b/cmd/scan_sources_test.go @@ -0,0 +1,112 @@ +package cmd + +import ( + "os" + "path/filepath" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/salvacybersec/keyhunter/pkg/engine/sources" +) + +func TestSelectSource_Directory(t *testing.T) { + dir := t.TempDir() + src, err := selectSource([]string{dir}, sourceFlags{}) + require.NoError(t, err) + _, ok := src.(*sources.DirSource) + require.True(t, ok, "expected *DirSource, got %T", src) +} + +func TestSelectSource_File(t *testing.T) { + dir := t.TempDir() + f := filepath.Join(dir, "a.txt") + require.NoError(t, os.WriteFile(f, []byte("x"), 0o644)) + src, err := selectSource([]string{f}, sourceFlags{}) + require.NoError(t, err) + _, ok := src.(*sources.FileSource) + require.True(t, ok, "expected *FileSource, got %T", src) +} + +func TestSelectSource_Git(t *testing.T) { + src, err := selectSource([]string{"./some-repo"}, sourceFlags{Git: true}) + require.NoError(t, err) + gs, ok := src.(*sources.GitSource) + require.True(t, ok, "expected *GitSource, got %T", src) + require.Equal(t, "./some-repo", gs.RepoPath) +} + +func TestSelectSource_GitSince(t *testing.T) { + src, err := selectSource([]string{"./repo"}, sourceFlags{Git: true, Since: "2024-01-15"}) + require.NoError(t, err) + gs := src.(*sources.GitSource) + want, _ := time.Parse("2006-01-02", "2024-01-15") + require.Equal(t, want, gs.Since) +} + +func TestSelectSource_GitSinceBadFormat(t *testing.T) { + _, err := selectSource([]string{"./repo"}, sourceFlags{Git: true, Since: "15/01/2024"}) + require.Error(t, err) + require.Contains(t, err.Error(), "YYYY-MM-DD") +} + +func TestSelectSource_URL(t *testing.T) { + src, err := selectSource(nil, sourceFlags{URL: "https://example.com/a.js"}) + require.NoError(t, err) + _, ok := src.(*sources.URLSource) + require.True(t, ok) +} + +func TestSelectSource_URLRejectsPositional(t *testing.T) { + _, err := selectSource([]string{"./foo"}, sourceFlags{URL: "https://x"}) + require.Error(t, err) +} + +func TestSelectSource_Clipboard(t *testing.T) { + src, err := selectSource(nil, sourceFlags{Clipboard: true}) + require.NoError(t, err) + _, ok := src.(*sources.ClipboardSource) + require.True(t, ok) +} + +func TestSelectSource_ClipboardRejectsPositional(t *testing.T) { + _, err := selectSource([]string{"./foo"}, sourceFlags{Clipboard: true}) + require.Error(t, err) +} + +func TestSelectSource_Stdin(t *testing.T) { + for _, tok := range []string{"stdin", "-"} { + src, err := selectSource([]string{tok}, sourceFlags{}) + require.NoError(t, err) + _, ok := src.(*sources.StdinSource) + require.True(t, ok, "token %q: expected *StdinSource, got %T", tok, src) + } +} + +func TestSelectSource_MutuallyExclusive(t *testing.T) { + _, err := selectSource(nil, sourceFlags{Git: true, URL: "https://x"}) + require.Error(t, err) + require.Contains(t, err.Error(), "mutually exclusive") +} + +func TestSelectSource_MissingTarget(t *testing.T) { + _, err := selectSource(nil, sourceFlags{}) + require.Error(t, err) + require.Contains(t, err.Error(), "missing target") +} + +func TestSelectSource_DirForwardsExcludes(t *testing.T) { + dir := t.TempDir() + src, err := selectSource([]string{dir}, sourceFlags{Excludes: []string{"*.log", "tmp/**"}}) + require.NoError(t, err) + ds := src.(*sources.DirSource) + // NewDirSource merges DefaultExcludes with extras, so user patterns must be present. + found := 0 + for _, e := range ds.Excludes { + if e == "*.log" || e == "tmp/**" { + found++ + } + } + require.Equal(t, 2, found, "user excludes not forwarded, got %v", ds.Excludes) +}