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
180
test/tarakan_web/live/infestation_live_test.exs
Normal file
180
test/tarakan_web/live/infestation_live_test.exs
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
defmodule TarakanWeb.InfestationLiveTest do
|
||||
use TarakanWeb.ConnCase, async: true
|
||||
|
||||
import Phoenix.LiveViewTest
|
||||
|
||||
alias Tarakan.FindingMemory
|
||||
|
||||
test "index and show render multi-repo patterns", %{conn: conn} 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 = "Live infestation #{System.unique_integer([:positive])}"
|
||||
|
||||
findings = fn path ->
|
||||
Jason.encode!(%{
|
||||
"tarakan_scan_format" => 1,
|
||||
"findings" => [
|
||||
%{
|
||||
"file" => path,
|
||||
"severity" => "critical",
|
||||
"title" => title,
|
||||
"description" => "Infestation liveview fixture."
|
||||
}
|
||||
]
|
||||
})
|
||||
end
|
||||
|
||||
scan_fixture(repo_a, submitter, %{"findings_json" => findings.("a.ex")})
|
||||
scan_fixture(repo_b, other, %{"findings_json" => findings.("b.ex")})
|
||||
# repo_a is hit twice by the same pattern at different paths, so the
|
||||
# per-repo rollup and the per-finding ledger must disagree on row count.
|
||||
scan_fixture(repo_a, submitter, %{"findings_json" => findings.("a2.ex")})
|
||||
|
||||
pattern = FindingMemory.pattern_key(title)
|
||||
|
||||
{:ok, index, html} = live(conn, ~p"/infestations")
|
||||
assert html =~ "Infestations"
|
||||
assert has_element?(index, "#infestations-constellation")
|
||||
assert has_element?(index, "#infestation-#{pattern}")
|
||||
|
||||
{:ok, show, show_html} = live(conn, ~p"/infestations/#{pattern}")
|
||||
assert show_html =~ title
|
||||
assert has_element?(show, "#infestation-repo-count", "2")
|
||||
assert has_element?(show, "#infestation-graph")
|
||||
assert has_element?(show, "#infestation-instances")
|
||||
|
||||
# The repo table is a rollup: one row per repository, carrying the counts
|
||||
# that distinguish it from the instance ledger below.
|
||||
graph_rows = show |> element("#infestation-graph tbody") |> render()
|
||||
assert graph_rows =~ "#{repo_a.owner}/#{repo_a.name}"
|
||||
assert graph_rows =~ "#{repo_b.owner}/#{repo_b.name}"
|
||||
|
||||
row_a = show |> element("#infestation-graph-node-#{repo_a.id}") |> render() |> squish()
|
||||
assert row_a =~ ">2</td>", "repo_a is hit twice and must report 2, not a blank cell"
|
||||
|
||||
row_b = show |> element("#infestation-graph-node-#{repo_b.id}") |> render() |> squish()
|
||||
assert row_b =~ ">1</td>", "repo_b is hit once and must report 1"
|
||||
|
||||
# 2 repository rows, 3 instance rows: the two views are different grains.
|
||||
ledger = show |> element("#infestation-ledger") |> render()
|
||||
assert length(Regex.scan(~r/<li[^>]+id="ledger_instances-/, ledger)) == 3
|
||||
end
|
||||
|
||||
describe "fix propagation" do
|
||||
setup %{conn: conn} do
|
||||
submitter = github_account_fixture()
|
||||
other = github_account_fixture()
|
||||
|
||||
source = listed_github_repository_fixture(submitter)
|
||||
{:ok, target} = Tarakan.Repositories.register_github_repository("acme/widget", other)
|
||||
target = listed_repository_fixture(target)
|
||||
|
||||
title = "Propagatable finding #{System.unique_integer([:positive])}"
|
||||
|
||||
findings =
|
||||
Jason.encode!(%{
|
||||
"tarakan_scan_format" => 1,
|
||||
"findings" => [
|
||||
%{
|
||||
"file" => "lib/handler.ex",
|
||||
"severity" => "critical",
|
||||
"title" => title,
|
||||
"description" => "Shared across both repositories."
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
source_scan = scan_fixture(source, submitter, %{"findings_json" => findings})
|
||||
scan_fixture(target, other, %{"findings_json" => findings})
|
||||
|
||||
# Settle the source instance as fixed so a template can be captured.
|
||||
[occurrence] = source_scan.findings
|
||||
|
||||
source_finding =
|
||||
Tarakan.Repo.get!(Tarakan.Scans.CanonicalFinding, occurrence.canonical_finding_id)
|
||||
|> Ecto.Changeset.change(%{
|
||||
status: "fixed",
|
||||
fixed_at: DateTime.utc_now(),
|
||||
fixed_commit_sha: source_scan.commit_sha
|
||||
})
|
||||
|> Tarakan.Repo.update!()
|
||||
|
||||
%Tarakan.Scans.FindingCheck{}
|
||||
|> Tarakan.Scans.FindingCheck.changeset(%{
|
||||
commit_sha: source_scan.commit_sha,
|
||||
verdict: "fixed",
|
||||
provenance: "human",
|
||||
notes: "Escaped the interpolated value and added a regression test."
|
||||
})
|
||||
|> Ecto.Changeset.put_change(:canonical_finding_id, source_finding.id)
|
||||
|> Ecto.Changeset.put_change(:account_id, submitter.id)
|
||||
|> Tarakan.Repo.insert!()
|
||||
|
||||
moderator = moderator_account_fixture()
|
||||
|
||||
{:ok, template} =
|
||||
Tarakan.Fixes.capture_fix(
|
||||
Tarakan.Accounts.Scope.for_account(moderator),
|
||||
source_finding
|
||||
)
|
||||
|
||||
%{
|
||||
conn: log_in_account(conn, moderator),
|
||||
pattern: FindingMemory.pattern_key(title),
|
||||
source: source,
|
||||
target: target,
|
||||
template: template
|
||||
}
|
||||
end
|
||||
|
||||
test "shows the captured fix and carries it to the remaining repository", %{
|
||||
conn: conn,
|
||||
pattern: pattern,
|
||||
source: source,
|
||||
target: target,
|
||||
template: template
|
||||
} do
|
||||
{:ok, view, html} = live(conn, ~p"/infestations/#{pattern}")
|
||||
|
||||
assert html =~ "Fixed on"
|
||||
assert html =~ "#{source.owner}/#{source.name}"
|
||||
assert html =~ "Escaped the interpolated value"
|
||||
assert has_element?(view, "#infestation-propagate-fix", "Propagate to 1")
|
||||
|
||||
html = view |> element("#infestation-propagate-fix") |> render_click()
|
||||
|
||||
assert html =~ "Opened 1 fix job"
|
||||
assert html =~ "carried to 1 repo"
|
||||
|
||||
# A real, public job now exists on the other repository, carrying the fix.
|
||||
# Scan submission auto-opens a verification job too, so reach the fix job
|
||||
# through the propagation rather than by repository alone.
|
||||
assert [propagation] = Tarakan.Fixes.list_propagations(template)
|
||||
assert propagation.repository_id == target.id
|
||||
|
||||
task = propagation.review_task
|
||||
assert task.status == "open"
|
||||
assert task.visibility == "public"
|
||||
assert task.description =~ "Escaped the interpolated value"
|
||||
end
|
||||
|
||||
test "anonymous visitors see the fix but cannot propagate it", %{pattern: pattern} do
|
||||
{:ok, view, html} = live(build_conn(), ~p"/infestations/#{pattern}")
|
||||
|
||||
assert html =~ "Fixed on"
|
||||
refute has_element?(view, "#infestation-propagate-fix")
|
||||
end
|
||||
end
|
||||
|
||||
# Collapse the whitespace HEEx leaves around interpolated cell values so
|
||||
# assertions can match on the value itself.
|
||||
defp squish(html) do
|
||||
html
|
||||
|> String.replace(~r/>\s+/, ">")
|
||||
|> String.replace(~r/\s+</, "<")
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue