test(13-04): add integration test handlers for all 12 Phase 13 sources (40 total)
- Add httptest mux handlers for npm, pypi, crates, rubygems, maven, nuget, goproxy, packagist, dockerhub, k8s, terraform, helm - Register all 12 Phase 13 sources with BaseURL prefix routing - Update expected source types and count assertions from 28 to 40
This commit is contained in:
@@ -15,10 +15,11 @@ import (
|
||||
|
||||
// TestIntegration_AllSources_SweepAll spins up a single multiplexed httptest
|
||||
// server that serves canned fixtures for every Phase 10 code-hosting source,
|
||||
// Phase 11 search engine / paste site source, Phase 12 IoT scanner, and
|
||||
// Phase 12 cloud storage source, registers the sources (with BaseURL overrides
|
||||
// pointing at the test server) onto a fresh recon.Engine, runs SweepAll, and
|
||||
// asserts at least one Finding was emitted per SourceType across all 28 sources.
|
||||
// Phase 11 search engine / paste site source, Phase 12 IoT scanner / cloud
|
||||
// storage source, and Phase 13 package registry / container / IaC source,
|
||||
// registers the sources (with BaseURL overrides pointing at the test server)
|
||||
// onto a fresh recon.Engine, runs SweepAll, and asserts at least one Finding
|
||||
// was emitted per SourceType across all 40 sources.
|
||||
//
|
||||
// RegisterAll cannot be used directly because it wires production URLs; the
|
||||
// test exercises the same code paths by constructing each source identically
|
||||
@@ -239,6 +240,78 @@ func TestIntegration_AllSources_SweepAll(t *testing.T) {
|
||||
</EnumerationResults>`))
|
||||
})
|
||||
|
||||
// ---- Phase 13: npm /-/v1/search (prefix /npm) ----
|
||||
mux.HandleFunc("/npm/-/v1/search", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"objects":[{"package":{"name":"leak-pkg","links":{"npm":"https://npmjs.com/package/leak-pkg"}}}]}`))
|
||||
})
|
||||
|
||||
// ---- Phase 13: pypi /search/ (prefix /pypi) ----
|
||||
mux.HandleFunc("/pypi/search/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
_, _ = w.Write([]byte(`<html><body><a href="/project/leaked-pkg/">leaked-pkg</a></body></html>`))
|
||||
})
|
||||
|
||||
// ---- Phase 13: crates /api/v1/crates (prefix /crates) ----
|
||||
mux.HandleFunc("/crates/api/v1/crates", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"crates":[{"id":"leaked-crate","name":"leaked-crate","repository":"https://github.com/example/leaked-crate"}]}`))
|
||||
})
|
||||
|
||||
// ---- Phase 13: rubygems /api/v1/search.json (prefix /rubygems) ----
|
||||
mux.HandleFunc("/rubygems/api/v1/search.json", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`[{"name":"leaked-gem","project_uri":"https://rubygems.org/gems/leaked-gem"}]`))
|
||||
})
|
||||
|
||||
// ---- Phase 13: maven /solrsearch/select (prefix /maven) ----
|
||||
mux.HandleFunc("/maven/solrsearch/select", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"response":{"numFound":1,"docs":[{"g":"com.leak","a":"sdk","latestVersion":"1.0"}]}}`))
|
||||
})
|
||||
|
||||
// ---- Phase 13: nuget /query (prefix /nuget) ----
|
||||
mux.HandleFunc("/nuget/query", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"data":[{"id":"LeakedPkg","version":"1.0","projectUrl":"https://nuget.org/packages/LeakedPkg"}]}`))
|
||||
})
|
||||
|
||||
// ---- Phase 13: goproxy /search (prefix /goproxy) ----
|
||||
mux.HandleFunc("/goproxy/search", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "text/html")
|
||||
_, _ = w.Write([]byte(`<html><body><a href="/github.com/leak/module">module</a></body></html>`))
|
||||
})
|
||||
|
||||
// ---- Phase 13: packagist /search.json (prefix /packagist) ----
|
||||
mux.HandleFunc("/packagist/search.json", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"results":[{"name":"vendor/leaked","url":"https://packagist.org/packages/vendor/leaked"}]}`))
|
||||
})
|
||||
|
||||
// ---- Phase 13: dockerhub /v2/search/repositories/ (prefix /dockerhub) ----
|
||||
mux.HandleFunc("/dockerhub/v2/search/repositories/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"results":[{"repo_name":"user/leaked-image","description":"leaked"}]}`))
|
||||
})
|
||||
|
||||
// ---- Phase 13: k8s /api/v1/packages/search (prefix /k8s) ----
|
||||
mux.HandleFunc("/k8s/api/v1/packages/search", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"packages":[{"package_id":"pkg-1","name":"leaked-operator","normalized_name":"leaked-operator","repository":{"name":"community","kind":6}}]}`))
|
||||
})
|
||||
|
||||
// ---- Phase 13: terraform /v1/modules (prefix /terraform) ----
|
||||
mux.HandleFunc("/terraform/v1/modules", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"modules":[{"id":"hashicorp/leaked/aws","namespace":"hashicorp","name":"leaked","provider":"aws"}]}`))
|
||||
})
|
||||
|
||||
// ---- Phase 13: helm /api/v1/packages/search (prefix /helm) ----
|
||||
mux.HandleFunc("/helm/api/v1/packages/search", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"packages":[{"package_id":"chart-1","name":"leaked-chart","normalized_name":"leaked-chart","repository":{"name":"bitnami","kind":0}}]}`))
|
||||
})
|
||||
|
||||
srv := httptest.NewServer(mux)
|
||||
defer srv.Close()
|
||||
|
||||
@@ -447,9 +520,39 @@ func TestIntegration_AllSources_SweepAll(t *testing.T) {
|
||||
client: NewClient(),
|
||||
})
|
||||
|
||||
// Sanity: all 28 sources registered.
|
||||
if n := len(eng.List()); n != 28 {
|
||||
t.Fatalf("expected 28 sources on engine, got %d: %v", n, eng.List())
|
||||
// --- Phase 13: Package registry sources ---
|
||||
|
||||
// npm
|
||||
eng.Register(&NpmSource{BaseURL: srv.URL + "/npm", Registry: reg, Limiters: lim, Client: NewClient()})
|
||||
// pypi
|
||||
eng.Register(&PyPISource{BaseURL: srv.URL + "/pypi", Registry: reg, Limiters: lim, Client: NewClient()})
|
||||
// crates
|
||||
eng.Register(&CratesIOSource{BaseURL: srv.URL + "/crates", Registry: reg, Limiters: lim, Client: NewClient()})
|
||||
// rubygems
|
||||
eng.Register(&RubyGemsSource{BaseURL: srv.URL + "/rubygems", Registry: reg, Limiters: lim, Client: NewClient()})
|
||||
// maven
|
||||
eng.Register(&MavenSource{BaseURL: srv.URL + "/maven", Registry: reg, Limiters: lim, Client: NewClient()})
|
||||
// nuget
|
||||
eng.Register(&NuGetSource{BaseURL: srv.URL + "/nuget", Registry: reg, Limiters: lim, Client: NewClient()})
|
||||
// goproxy
|
||||
eng.Register(&GoProxySource{BaseURL: srv.URL + "/goproxy", Registry: reg, Limiters: lim, Client: NewClient()})
|
||||
// packagist
|
||||
eng.Register(&PackagistSource{BaseURL: srv.URL + "/packagist", Registry: reg, Limiters: lim, Client: NewClient()})
|
||||
|
||||
// --- Phase 13: Container & IaC sources ---
|
||||
|
||||
// dockerhub
|
||||
eng.Register(&DockerHubSource{BaseURL: srv.URL + "/dockerhub", Registry: reg, Limiters: lim, Client: NewClient()})
|
||||
// k8s
|
||||
eng.Register(&KubernetesSource{BaseURL: srv.URL + "/k8s", Registry: reg, Limiters: lim, Client: NewClient()})
|
||||
// terraform
|
||||
eng.Register(&TerraformSource{BaseURL: srv.URL + "/terraform", Registry: reg, Limiters: lim, Client: NewClient()})
|
||||
// helm
|
||||
eng.Register(&HelmSource{BaseURL: srv.URL + "/helm", Registry: reg, Limiters: lim, Client: NewClient()})
|
||||
|
||||
// Sanity: all 40 sources registered.
|
||||
if n := len(eng.List()); n != 40 {
|
||||
t.Fatalf("expected 40 sources on engine, got %d: %v", n, eng.List())
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||
@@ -499,6 +602,20 @@ func TestIntegration_AllSources_SweepAll(t *testing.T) {
|
||||
"recon:gcs",
|
||||
"recon:azureblob",
|
||||
"recon:spaces",
|
||||
// Phase 13: Package registries
|
||||
"recon:npm",
|
||||
"recon:pypi",
|
||||
"recon:crates",
|
||||
"recon:rubygems",
|
||||
"recon:maven",
|
||||
"recon:nuget",
|
||||
"recon:goproxy",
|
||||
"recon:packagist",
|
||||
// Phase 13: Container & IaC
|
||||
"recon:dockerhub",
|
||||
"recon:k8s",
|
||||
"recon:terraform",
|
||||
"recon:helm",
|
||||
}
|
||||
for _, st := range wantTypes {
|
||||
if byType[st] == 0 {
|
||||
|
||||
Reference in New Issue
Block a user