Files
keyhunter/pkg/dorks/registry_test.go
salvacybersec fd6efbb4c2 feat(08-01): add pkg/dorks foundation (schema, loader, registry, executor)
- Dork schema with Validate() mirroring provider YAML pattern
- go:embed loader tolerating empty definitions tree
- Registry with List/Get/Stats/ListBySource/ListByCategory
- Executor interface + Runner dispatch + ErrSourceNotImplemented
- Placeholder definitions/.gitkeep and repo-root dorks/.gitkeep
- Full unit test coverage for registry, validation, and runner dispatch
2026-04-06 00:15:32 +03:00

191 lines
4.7 KiB
Go

package dorks_test
import (
"context"
"errors"
"testing"
"github.com/salvacybersec/keyhunter/pkg/dorks"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func fixture() []dorks.Dork {
return []dorks.Dork{
{
ID: "openai-github-envfile",
Name: "OpenAI API Key in .env files",
Source: "github",
Category: "frontier",
Query: "sk-proj- extension:env",
Description: "Finds OpenAI project keys exposed in committed .env files",
Tags: []string{"openai", "env", "tier1"},
},
{
ID: "anthropic-github-env",
Name: "Anthropic Key in .env",
Source: "github",
Category: "frontier",
Query: "sk-ant-api03- extension:env",
},
{
ID: "shodan-openai-banner",
Name: "OpenAI banner on Shodan",
Source: "shodan",
Category: "infrastructure",
Query: "product:openai",
},
}
}
func TestRegistry_LoadsAndIndexesDorks(t *testing.T) {
r := dorks.NewRegistryFromDorks(fixture())
require.NotNil(t, r)
assert.Len(t, r.List(), 3)
}
func TestRegistry_Get(t *testing.T) {
r := dorks.NewRegistryFromDorks(fixture())
d, ok := r.Get("openai-github-envfile")
require.True(t, ok)
assert.Equal(t, "github", d.Source)
assert.Equal(t, "frontier", d.Category)
assert.Equal(t, "sk-proj- extension:env", d.Query)
_, ok = r.Get("does-not-exist")
assert.False(t, ok)
}
func TestRegistry_ListBySource(t *testing.T) {
r := dorks.NewRegistryFromDorks(fixture())
gh := r.ListBySource("github")
assert.Len(t, gh, 2)
for _, d := range gh {
assert.Equal(t, "github", d.Source)
}
shodan := r.ListBySource("shodan")
assert.Len(t, shodan, 1)
assert.Empty(t, r.ListBySource("fofa"))
}
func TestRegistry_ListByCategory(t *testing.T) {
r := dorks.NewRegistryFromDorks(fixture())
frontier := r.ListByCategory("frontier")
assert.Len(t, frontier, 2)
for _, d := range frontier {
assert.Equal(t, "frontier", d.Category)
}
infra := r.ListByCategory("infrastructure")
assert.Len(t, infra, 1)
assert.Empty(t, r.ListByCategory("emerging"))
}
func TestRegistry_Stats(t *testing.T) {
r := dorks.NewRegistryFromDorks(fixture())
s := r.Stats()
assert.Equal(t, 3, s.Total)
assert.Equal(t, 2, s.BySource["github"])
assert.Equal(t, 1, s.BySource["shodan"])
assert.Equal(t, 2, s.ByCategory["frontier"])
assert.Equal(t, 1, s.ByCategory["infrastructure"])
}
func TestNewRegistry_EmptyDefinitionsTreeOK(t *testing.T) {
// The embedded definitions tree contains only .gitkeep in this plan.
// NewRegistry must tolerate that and return an empty but usable Registry.
r, err := dorks.NewRegistry()
require.NoError(t, err)
require.NotNil(t, r)
assert.GreaterOrEqual(t, len(r.List()), 0)
}
func TestDork_Validate(t *testing.T) {
tests := []struct {
name string
dork dorks.Dork
wantErr bool
}{
{
name: "valid",
dork: dorks.Dork{ID: "x", Source: "github", Query: "foo"},
wantErr: false,
},
{
name: "missing id",
dork: dorks.Dork{Source: "github", Query: "foo"},
wantErr: true,
},
{
name: "missing source",
dork: dorks.Dork{ID: "x", Query: "foo"},
wantErr: true,
},
{
name: "missing query",
dork: dorks.Dork{ID: "x", Source: "github"},
wantErr: true,
},
{
name: "unknown source",
dork: dorks.Dork{ID: "x", Source: "reddit", Query: "foo"},
wantErr: true,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
err := tc.dork.Validate()
if tc.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
})
}
}
func TestRunner_UnknownSourceReturnsErrSourceNotImplemented(t *testing.T) {
runner := dorks.NewRunner()
d := dorks.Dork{ID: "x", Source: "shodan", Category: "infrastructure", Query: "product:openai"}
_, err := runner.Run(context.Background(), d, 10)
require.Error(t, err)
assert.True(t, errors.Is(err, dorks.ErrSourceNotImplemented))
}
// stubExecutor is a test-only Executor that records invocations.
type stubExecutor struct {
source string
calls int
}
func (s *stubExecutor) Source() string { return s.source }
func (s *stubExecutor) Execute(_ context.Context, d dorks.Dork, _ int) ([]dorks.Match, error) {
s.calls++
return []dorks.Match{{DorkID: d.ID, Source: s.source, Snippet: "hit"}}, nil
}
func TestRunner_RegisterAndDispatch(t *testing.T) {
runner := dorks.NewRunner()
stub := &stubExecutor{source: "github"}
runner.Register(stub)
got, ok := runner.Executor("github")
require.True(t, ok)
assert.Equal(t, "github", got.Source())
d := dorks.Dork{ID: "t1", Source: "github", Query: "sk-"}
matches, err := runner.Run(context.Background(), d, 5)
require.NoError(t, err)
assert.Equal(t, 1, stub.calls)
require.Len(t, matches, 1)
assert.Equal(t, "t1", matches[0].DorkID)
}