defmodule TarakanWeb.BountyLiveTest do use TarakanWeb.ConnCase, async: true import Phoenix.LiveViewTest alias Tarakan.Accounts.Scope alias Tarakan.Market alias Tarakan.Market.Bounty alias Tarakan.Repo defp open_bounty do repository = listed_github_repository_fixture() sponsor = active_account_fixture() |> fund_credits(1_000) bounty = credits_bounty_fixture(Scope.for_account(sponsor), repository) {bounty, sponsor, repository} end describe "index" do test "renders open bounties for anonymous visitors", %{conn: conn} do {bounty, sponsor, _repository} = open_bounty() {:ok, view, html} = live(conn, ~p"/bounties") assert html =~ "Contracts" assert has_element?(view, "#bounties") assert has_element?(view, "#bounty-#{bounty.public_id}") assert html =~ bounty.title assert html =~ "500 credits" assert html =~ "@#{sponsor.handle}" assert has_element?(view, "#bounty-filters") end test "shows the empty state when nothing is open", %{conn: conn} do {:ok, view, _html} = live(conn, ~p"/bounties") assert has_element?(view, "#bounties-empty") end end describe "new" do test "redirects anonymous visitors to login", %{conn: conn} do assert {:error, {:redirect, %{to: "/accounts/log-in"}}} = live(conn, ~p"/bounties/new") end test "creates a credits bounty and lands on the poster", %{conn: conn} do repository = listed_github_repository_fixture() sponsor = active_account_fixture() |> fund_credits(1_000) conn = log_in_account(conn, sponsor) {:ok, view, _html} = live(conn, ~p"/bounties/new") assert has_element?(view, "#bounty-form") assert has_element?(view, "#bounty-credit-balance") # The target is picked from search, not typed. view |> form("#bounty-form", %{"bounty" => %{"repo_query" => repository.name}}) |> render_change() assert view |> element("#bounty-repo-results button", "#{repository.owner}/#{repository.name}") |> render_click() assert has_element?( view, "#bounty-selected-repository", "#{repository.host}/#{repository.owner}/#{repository.name}" ) {:ok, _show_view, html} = view |> form("#bounty-form", %{ "bounty" => %{ "target_type" => "repository", "title" => "Harden the webhook verifier", "description" => "Audit the signature verification path and ship a fix with tests.", "funding" => "credits", "amount" => "300" } }) |> render_submit() |> follow_redirect(conn) assert html =~ "Harden the webhook verifier" assert html =~ "300 credits" bounty = Repo.one!(Bounty) assert bounty.status == "open" assert bounty.credit_amount == 300 assert Tarakan.Credits.balance(sponsor) == 700 end end describe "show" do test "anonymous visitors see the poster and a login prompt, not a claim button", %{ conn: conn } do {bounty, _sponsor, _repository} = open_bounty() {:ok, view, html} = live(conn, ~p"/bounties/#{bounty.public_id}") assert html =~ bounty.title assert has_element?(view, "#bounty-status") refute has_element?(view, "#bounty-claim-button") assert has_element?(view, "#bounty-login-to-claim") end test "the sponsor sees cancel controls but no claim button", %{conn: conn} do {bounty, sponsor, _repository} = open_bounty() conn = log_in_account(conn, sponsor) {:ok, view, _html} = live(conn, ~p"/bounties/#{bounty.public_id}") refute has_element?(view, "#bounty-claim-button") assert has_element?(view, "#bounty-cancel-button") end test "an eligible hunter sees and uses the claim button", %{conn: conn} do {bounty, _sponsor, _repository} = open_bounty() hunter = active_account_fixture() conn = log_in_account(conn, hunter) {:ok, view, _html} = live(conn, ~p"/bounties/#{bounty.public_id}") assert has_element?(view, "#bounty-claim-button") html = view |> element("#bounty-claim-button") |> render_click() assert html =~ "claimed" assert has_element?(view, "#bounty-claims") bounty = Repo.get!(Bounty, bounty.id) assert bounty.status == "claimed" claim = Repo.one!(Tarakan.Market.BountyClaim) assert claim.account_id == hunter.id assert claim.review_task_id end end describe "wanted banners" do test "the repository security page shows the banner for its open bounty", %{conn: conn} do {bounty, _sponsor, repository} = open_bounty() {:ok, view, _html} = live(conn, TarakanWeb.RepositoryPaths.repository_security_path(repository)) assert has_element?(view, "#wanted-banner") bounty = Market.get_bounty!(bounty.public_id) assert bounty.status == "open" end end end