Initial commit on Forgejo
Fresh repository history for elektrine/tarakan hosted at https://git.elektrine.com/elektrine/tarakan.
This commit is contained in:
commit
af6077b9c3
455 changed files with 78366 additions and 0 deletions
137
test/tarakan_web/controllers/api/infestation_controller_test.exs
Normal file
137
test/tarakan_web/controllers/api/infestation_controller_test.exs
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
defmodule TarakanWeb.API.InfestationControllerTest do
|
||||
use TarakanWeb.ConnCase, async: true
|
||||
|
||||
import Ecto.Query, only: [from: 2]
|
||||
|
||||
alias Tarakan.FindingMemory
|
||||
|
||||
setup do
|
||||
submitter = github_account_fixture()
|
||||
other = github_account_fixture()
|
||||
repo_a = listed_github_repository_fixture(submitter)
|
||||
{:ok, repo_b} = Tarakan.Repositories.register_github_repository("acme/widget", other)
|
||||
repo_b = listed_repository_fixture(repo_b)
|
||||
|
||||
title = "API infestation sample #{System.unique_integer([:positive])}"
|
||||
|
||||
findings = fn path ->
|
||||
Jason.encode!(%{
|
||||
"tarakan_scan_format" => 1,
|
||||
"findings" => [
|
||||
%{
|
||||
"file" => path,
|
||||
"line_start" => 1,
|
||||
"line_end" => 2,
|
||||
"severity" => "high",
|
||||
"title" => title,
|
||||
"description" => "Shared issue class for the patterns API test."
|
||||
}
|
||||
]
|
||||
})
|
||||
end
|
||||
|
||||
scan_fixture(repo_a, submitter, %{"findings_json" => findings.("lib/a.ex")})
|
||||
scan_fixture(repo_b, other, %{"findings_json" => findings.("src/b.rs")})
|
||||
|
||||
%{pattern_key: FindingMemory.pattern_key(title), title: title}
|
||||
end
|
||||
|
||||
test "lists patterns", %{conn: conn, pattern_key: pattern_key} do
|
||||
conn = get(conn, ~p"/api/infestations")
|
||||
|
||||
assert %{"patterns" => patterns} = json_response(conn, 200)
|
||||
assert pattern = Enum.find(patterns, &(&1["pattern_key"] == pattern_key))
|
||||
assert pattern["repo_count"] >= 2
|
||||
assert pattern["instance_count"] >= 2
|
||||
assert pattern["record_url"] =~ "/infestations/#{pattern_key}"
|
||||
end
|
||||
|
||||
test "whitelists query params", %{conn: conn, pattern_key: pattern_key} do
|
||||
conn = get(conn, ~p"/api/infestations?days=13&min_repos=0&limit=5000")
|
||||
assert %{"patterns" => _} = json_response(conn, 200)
|
||||
|
||||
conn = get(conn, ~p"/api/infestations?days=7&min_repos=2&limit=10")
|
||||
assert %{"patterns" => patterns} = json_response(conn, 200)
|
||||
assert Enum.any?(patterns, &(&1["pattern_key"] == pattern_key))
|
||||
end
|
||||
|
||||
test "shows a pattern with its first page of instances", %{
|
||||
conn: conn,
|
||||
pattern_key: pattern_key,
|
||||
title: title
|
||||
} do
|
||||
conn = get(conn, ~p"/api/infestations/#{pattern_key}")
|
||||
|
||||
assert %{"pattern" => pattern, "instances" => instances} = json_response(conn, 200)
|
||||
assert pattern["pattern_key"] == pattern_key
|
||||
assert pattern["title"] =~ title
|
||||
|
||||
assert length(instances) >= 2
|
||||
assert Enum.any?(instances, &(&1["repository"]["owner"] == "openai"))
|
||||
assert Enum.any?(instances, &(&1["repository"]["owner"] == "acme"))
|
||||
end
|
||||
|
||||
test "404s for an unknown pattern", %{conn: conn} do
|
||||
conn = get(conn, ~p"/api/infestations/no-such-pattern")
|
||||
assert json_response(conn, 404)["error"] =~ "not found"
|
||||
end
|
||||
|
||||
describe "vaccine packs" do
|
||||
alias Tarakan.Accounts.Scope
|
||||
alias Tarakan.FindingSignals
|
||||
alias Tarakan.Repo
|
||||
alias Tarakan.Scans.CanonicalFinding
|
||||
|
||||
# The endpoint must refuse to invent a detector. It used to always return
|
||||
# one, and the one it returned matched nothing.
|
||||
test "404s while nobody has written a validated detector", %{
|
||||
conn: conn,
|
||||
pattern_key: pattern_key
|
||||
} do
|
||||
conn = get(conn, ~p"/api/infestations/#{pattern_key}/vaccine.yaml")
|
||||
|
||||
assert %{"error" => error} = json_response(conn, 404)
|
||||
assert error =~ "no validated detector"
|
||||
end
|
||||
|
||||
test "serves the validated rule once one exists", %{conn: conn, pattern_key: pattern_key} do
|
||||
# Put this infestation's findings into one code cluster.
|
||||
cluster = "code:vaccinetest"
|
||||
|
||||
Repo.all(from f in CanonicalFinding, where: f.pattern_key == ^pattern_key)
|
||||
|> Enum.each(fn finding ->
|
||||
finding
|
||||
|> CanonicalFinding.embedding_changeset(%{code_pattern_key: cluster})
|
||||
|> Repo.update!()
|
||||
end)
|
||||
|
||||
scope = Scope.for_account(reviewer_account_fixture())
|
||||
|
||||
{:ok, _rule} =
|
||||
FindingSignals.put_rule(scope, cluster, %{
|
||||
engine: "semgrep",
|
||||
language: "elixir",
|
||||
rule_yaml: """
|
||||
rules:
|
||||
- id: tarakan-real-detector
|
||||
message: Shared issue class
|
||||
severity: ERROR
|
||||
languages: [elixir]
|
||||
patterns:
|
||||
- pattern: System.cmd($C, $A)
|
||||
""",
|
||||
checked_count: 2,
|
||||
matched_count: 2,
|
||||
matched_finding_ids: [Ecto.UUID.generate(), Ecto.UUID.generate()]
|
||||
})
|
||||
|
||||
conn = get(conn, ~p"/api/infestations/#{pattern_key}/vaccine.yaml")
|
||||
|
||||
assert body = response(conn, 200)
|
||||
assert get_resp_header(conn, "content-type") |> hd() =~ "application/x-yaml"
|
||||
assert body =~ "tarakan-real-detector"
|
||||
assert body =~ "matched 2 of 2 known instances"
|
||||
refute body =~ "tarakan-vaccine-placeholder"
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue