defmodule TarakanWeb.RepositoryCodeLiveTest do use TarakanWeb.ConnCase, async: false import Phoenix.LiveViewTest alias Tarakan.Accounts.Scope alias Tarakan.RepositoryCode.Cache alias Tarakan.Scans @default_commit_sha String.duplicate("7", 40) # develop branch tip in the GitHub stub (must remain a real branch tip). @develop_commit_sha String.duplicate("8", 40) # A fetchable commit that is not the tip of any published branch (and not a # special-cased stub SHA such as all-c truncated trees). @historical_commit_sha String.duplicate("b", 40) setup do Cache.clear() repository = listed_github_repository_fixture() %{repository: repository} end test "repository roots open the code browser by default", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/github.com/openai/codex") render_async(view, 1_000) assert has_element?(view, "#repository-navigation") assert has_element?(view, "#repository-code-tab[aria-current='page']", "Code") assert has_element?( view, "#repository-overview-tab[href='/github.com/openai/codex/security']" ) assert has_element?(view, "#code-tree") end test "the legacy code entry route still opens the default tree", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/github.com/openai/codex/code") render_async(view, 1_000) assert has_element?(view, "#code-tree") assert has_element?(view, "#code-commit-sha", String.slice(@default_commit_sha, 0, 7)) end test "browses directories at the freshly resolved default commit", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/github.com/openai/codex/code/#{@default_commit_sha}") render_async(view, 1_000) assert has_element?(view, "#code-tree") assert has_element?(view, "#code-tree-entries [id^='code-entry-']", "lib") assert has_element?( view, "#code-tree-entries a[href='/github.com/openai/codex/code/#{@default_commit_sha}/README.md']" ) end test "round-trips encoded spaces, percent signs, fragments, and Unicode filenames", %{ conn: conn } do root = "/github.com/openai/codex/code/#{@default_commit_sha}" {:ok, tree_view, _html} = live(conn, root) render_async(tree_view, 1_000) assert has_element?( tree_view, "a[href='#{root}/space%20%23%20100%25.txt']", "space # 100%.txt" ) assert has_element?(tree_view, "a[href='#{root}/%CE%BB.ex']", "λ.ex") {:ok, encoded_view, _html} = live(conn, root <> "/space%20%23%20100%25.txt") render_async(encoded_view, 1_000) assert has_element?(encoded_view, "#code-file", "space # 100%.txt") assert has_element?(encoded_view, "#L1 code", "# Codex") {:ok, unicode_view, _html} = live(conn, root <> "/%CE%BB.ex") render_async(unicode_view, 1_000) assert has_element?(unicode_view, "#code-file", "λ.ex") assert has_element?(unicode_view, "#L1 code", "defmodule Codex") end test "folder and file rows show findings for the pinned commit", %{ conn: conn, repository: repository } do scan = finding_scan_fixture(repository, account_fixture(), @default_commit_sha) _scan = publish_full_scan(repository, scan) {:ok, root_view, _html} = live(conn, ~p"/github.com/openai/codex") render_async(root_view, 1_000) assert has_element?(root_view, "#code-entry-bGli-findings", "1 finding") assert has_element?(root_view, "#code-reference", "1 finding") {:ok, lib_view, _html} = live(conn, ~p"/github.com/openai/codex/code/#{@default_commit_sha}/lib") render_async(lib_view, 1_000) assert has_element?(lib_view, "#code-entry-bGliL2NvZGV4LmV4-findings", "1 finding") end test "public summaries do not leak file paths through code-row badges", %{ conn: conn, repository: repository } do scan = finding_scan_fixture(repository, account_fixture(), @default_commit_sha) scan = confirmation_fixture(scan, reviewer_account_fixture()) scan = confirmation_fixture(scan, reviewer_account_fixture()) moderator_scope = Scope.for_account(moderator_account_fixture()) {:ok, accepted} = Scans.accept_scan(moderator_scope, scan, moderation_attributes()) {:ok, _summary} = Scans.update_visibility( moderator_scope, accepted, "public_summary", moderation_attributes() ) {:ok, view, _html} = live(conn, ~p"/github.com/openai/codex") render_async(view, 1_000) html = render(view) refute has_element?(view, "[id$='-findings']") refute html =~ "lib/codex.ex" end test "renders escaped plain-text lines with stable anchors and selection", %{conn: conn} do {:ok, view, _html} = live( conn, ~p"/github.com/openai/codex/code/#{@default_commit_sha}/README.md?lines=1" ) render_async(view, 1_000) assert has_element?(view, "#code-file") assert has_element?(view, "#L1.bg-panel") assert has_element?(view, "#L1 code", "# Codex") assert has_element?( view, "#L1 a[href='/github.com/openai/codex/code/#{@default_commit_sha}/README.md?lines=1#L1']" ) end test "rejects an out-of-range single-line selection", %{conn: conn} do {:ok, view, _html} = live( conn, ~p"/github.com/openai/codex/code/#{@default_commit_sha}/README.md?lines=1000001" ) render_async(view, 1_000) assert has_element?(view, "#invalid-line-selection") refute has_element?(view, "#code-lines .bg-panel") end test "renders hostile source as escaped text rather than executable markup", %{conn: conn} do {:ok, view, _html} = live( conn, ~p"/github.com/openai/codex/code/#{@default_commit_sha}/unsafe.html" ) render_async(view, 1_000) html = render(view) assert has_element?(view, "#L1 code", "") refute has_element?(view, "script#source-xss") assert html =~ "</code><script id="source-xss">" end test "rejects guessed historical SHAs on the generic browser", %{conn: conn} do paths = [ ~p"/github.com/openai/codex/code/#{@historical_commit_sha}", ~p"/github.com/openai/codex/code/#{@historical_commit_sha}/README.md" ] for path <- paths do {:ok, view, _html} = live(conn, path) render_async(view, 1_000) assert has_element?(view, "#code-browser-error") assert has_element?(view, "#code-browser-error", "Source not found") refute has_element?(view, "#code-tree") refute has_element?(view, "#code-file") end end test "branch switch opens another published branch tip", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/github.com/openai/codex/code/#{@default_commit_sha}") render_async(view, 1_000) assert has_element?(view, "#code-branch-select") assert has_element?(view, "#code-tree") view |> form("#code-branch-form", %{branch: "develop"}) |> render_change() path = ~p"/github.com/openai/codex/code/#{@develop_commit_sha}" assert_redirect(view, path) {:ok, switched, _html} = live(conn, path) render_async(switched, 1_000) assert has_element?(switched, "#code-tree") assert has_element?(switched, "#code-commit-sha", String.slice(@develop_commit_sha, 0, 7)) assert has_element?(switched, ~s(#code-branch-select option[value="develop"][selected])) end test "deep link to a non-default branch tip works", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/github.com/openai/codex/code/#{@develop_commit_sha}/README.md") render_async(view, 1_000) assert has_element?(view, "#code-file") assert has_element?(view, "#code-commit-sha", String.slice(@develop_commit_sha, 0, 7)) assert has_element?(view, ~s(#code-branch-select option[value="develop"][selected])) end test "rejects encoded traversal and backslash paths at the route boundary", %{conn: conn} do unsafe_paths = [ "/github.com/openai/codex/code/#{@default_commit_sha}/lib/%2E%2E/README.md", "/github.com/openai/codex/code/#{@default_commit_sha}/lib/%5C..%5Csecret" ] for path <- unsafe_paths do {:ok, view, _html} = live(conn, path) assert has_element?(view, "#code-browser-error", "Invalid path") refute has_element?(view, "#code-file") end end test "an authorized opaque finding route opens historical source without leaking path in links", %{ conn: conn, repository: repository } do submitter = account_fixture() scan = finding_scan_fixture(repository, submitter, @historical_commit_sha) finding = hd(scan.findings) {:ok, view, _html} = live(log_in_account(conn, submitter), ~p"/findings/#{finding.public_id}/code") render_async(view, 1_000) assert has_element?(view, "#finding-code-context") assert has_element?(view, "#code-file") assert has_element?(view, "#L2.bg-panel") refute has_element?(view, "#source-breadcrumbs a") assert has_element?(view, "#L2 a[href='/findings/#{finding.public_id}/code#L2']") end test "the opaque route does not reveal a moderator-restricted finding to anonymous visitors", %{ conn: conn, repository: repository } do scan = finding_scan_fixture(repository, account_fixture(), @historical_commit_sha) finding = hd(scan.findings) moderator_scope = Scope.for_account(moderator_account_fixture()) {:ok, _restricted} = Scans.update_visibility(moderator_scope, scan, "restricted", moderation_attributes()) assert_raise Ecto.NoResultsError, fn -> live(conn, ~p"/findings/#{finding.public_id}/code") end end test "marks a reported line range that does not exist at the pinned commit", %{ conn: conn, repository: repository } do submitter = account_fixture() scan = finding_scan_fixture(repository, submitter, @historical_commit_sha, 99) finding = hd(scan.findings) {:ok, view, _html} = live(log_in_account(conn, submitter), ~p"/findings/#{finding.public_id}/code") render_async(view, 1_000) assert has_element?(view, "#finding-line-outside-file") refute has_element?(view, "#code-lines .bg-panel") end test "finding source routes reject enumerable integer identifiers", %{conn: conn} do assert_raise Ecto.NoResultsError, fn -> live(conn, "/findings/1/code") end end test "a connected finding view is evicted when a moderator restricts the scan", %{ conn: conn, repository: repository } do scan = finding_scan_fixture(repository, account_fixture(), @historical_commit_sha) scan = publish_full_scan(repository, scan) finding = hd(scan.findings) {:ok, view, _html} = live(conn, ~p"/findings/#{finding.public_id}/code") render_async(view, 1_000) assert has_element?(view, "#code-file") moderator_scope = Scope.for_account(moderator_account_fixture()) assert {:ok, _restricted} = Scans.update_visibility(moderator_scope, scan, "restricted", moderation_attributes()) assert_redirect(view, ~p"/github.com/openai/codex") end test "the default code page is uncached but remains indexable", %{conn: conn} do conn = get(conn, ~p"/github.com/openai/codex") assert html_response(conn, 200) assert get_resp_header(conn, "cache-control") == ["no-store"] assert get_resp_header(conn, "x-robots-tag") == [] end test "commit-pinned code routes prohibit caches and search indexing", %{conn: conn} do conn = get(conn, ~p"/github.com/openai/codex/code/#{@default_commit_sha}") assert html_response(conn, 200) assert get_resp_header(conn, "cache-control") == ["no-store"] assert get_resp_header(conn, "x-robots-tag") == ["noindex, nofollow"] end test "opaque finding routes prohibit caches and search indexing", %{ conn: conn, repository: repository } do scan = finding_scan_fixture(repository, account_fixture(), @historical_commit_sha) finding = repository |> publish_full_scan(scan) |> Map.fetch!(:findings) |> hd() conn = get(conn, ~p"/findings/#{finding.public_id}/code") assert html_response(conn, 200) assert get_resp_header(conn, "cache-control") == ["no-store"] assert get_resp_header(conn, "x-robots-tag") == ["noindex, nofollow"] end defp finding_scan_fixture(repository, submitter, commit_sha, line_start \\ 2) do document = Jason.encode!(%{ "tarakan_scan_format" => 1, "findings" => [ %{ "file" => "lib/codex.ex", "line_start" => line_start, "line_end" => line_start, "severity" => "high", "title" => "Authorization is not checked", "description" => "A request reaches a privileged operation without a policy check." } ] }) scan_fixture(repository, submitter, %{ "commit_sha" => commit_sha, "findings_json" => document }) end defp publish_full_scan(repository, scan) do repository |> Tarakan.Repositories.Repository.participation_changeset(%{ participation_mode: "maintainer_verified" }) |> Tarakan.Repo.update!() scan = confirmation_fixture(scan, reviewer_account_fixture()) scan = confirmation_fixture(scan, reviewer_account_fixture()) moderator_scope = Scope.for_account(moderator_account_fixture()) {:ok, accepted} = Scans.accept_scan(moderator_scope, scan, moderation_attributes()) {:ok, disclosed} = Scans.update_visibility( moderator_scope, accepted, "public", moderation_attributes(%{"sensitive_data_reviewed" => "true"}) ) disclosed end defp moderation_attributes(overrides \\ %{}) do Enum.into(overrides, %{ "moderation_reason" => "evidence_reviewed", "moderation_notes" => "Independent evidence and disclosure boundaries were reviewed for this exact commit." }) end end