defmodule Rsh26poolWeb.VoteLiveTest do use Rsh26poolWeb.ConnCase import Phoenix.LiveViewTest alias Rsh26pool.Voting defp new_room(overrides \\ %{}) do {:ok, result} = Voting.create_room( Map.merge( %{ "name" => "投票ルーム", "votes_per_user" => "2", "grouping_mode" => "false", "leader_threshold" => "2", "closes_at_local" => "" }, overrides ) ) result end defp authed(conn, participant) do Plug.Test.init_test_session(conn, %{"participant_token" => participant.token}) end describe "access control" do test "an unauthenticated visitor is redirected to the enter page", %{conn: conn} do %{room: room} = new_room() assert {:error, {:redirect, %{to: to}}} = live(conn, ~p"/vote/#{room.room_number}") assert to =~ "/enter" end test "a participant of a different room is redirected", %{conn: conn} do %{room: room} = new_room() %{room: other} = new_room() {:ok, outsider} = Voting.join_room(other, %{"name" => "部外者"}) assert {:error, {:redirect, %{to: to}}} = conn |> authed(outsider) |> live(~p"/vote/#{room.room_number}") assert to =~ "/enter" end end describe "authenticated member" do test "can render the room, post an idea, and see it appear", %{conn: conn} do %{room: room} = new_room() {:ok, member} = Voting.join_room(room, %{"name" => "参加者"}) {:ok, lv, html} = conn |> authed(member) |> live(~p"/vote/#{room.room_number}") assert html =~ room.name assert html =~ "残りの投票数" lv |> form("#idea-form", idea: %{text: "カラオケに行こう"}) |> render_submit() assert render(lv) =~ "カラオケに行こう" assert [%{text: "カラオケに行こう"}] = Voting.list_ideas(room) end test "voting marks the idea 投票済み and records the vote", %{conn: conn} do %{room: room} = new_room(%{"votes_per_user" => "2"}) {:ok, poster} = Voting.join_room(room, %{"name" => "投稿者"}) {:ok, idea} = Voting.create_idea(room, poster, %{"text" => "案1"}) {:ok, member} = Voting.join_room(room, %{"name" => "参加者"}) {:ok, lv, _} = conn |> authed(member) |> live(~p"/vote/#{room.room_number}") html = lv |> element("#idea-#{idea.id} button[phx-click='vote']") |> render_click() assert html =~ "投票済み" assert Voting.voted?(member, idea.id) assert Voting.votes_remaining(room, member) == 1 end test "spending all votes disables remaining buttons and the limit is enforced", %{conn: conn} do %{room: room} = new_room(%{"votes_per_user" => "1"}) {:ok, poster} = Voting.join_room(room, %{"name" => "投稿者"}) {:ok, i1} = Voting.create_idea(room, poster, %{"text" => "案1"}) {:ok, i2} = Voting.create_idea(room, poster, %{"text" => "案2"}) {:ok, member} = Voting.join_room(room, %{"name" => "参加者"}) {:ok, lv, _} = conn |> authed(member) |> live(~p"/vote/#{room.room_number}") # Spend the single vote on i1. lv |> element("#idea-#{i1.id} button[phx-click='vote']") |> render_click() # The other idea's vote button is now disabled in the UI. assert has_element?(lv, "#idea-#{i2.id} button[disabled]") # And the server-side guard surfaces the limit message if a vote is forced. html = render_click(lv, "vote", %{"id" => "#{i2.id}"}) assert html =~ "投票できる数の上限に達しました" refute Voting.voted?(member, i2.id) end test "results are hidden while open and shown once the room closes", %{conn: conn} do %{room: room} = new_room() {:ok, poster} = Voting.join_room(room, %{"name" => "投稿者"}) {:ok, _idea} = Voting.create_idea(room, poster, %{"text" => "唯一の案"}) {:ok, member} = Voting.join_room(room, %{"name" => "参加者"}) {:ok, lv, html} = conn |> authed(member) |> live(~p"/vote/#{room.room_number}") # While open: idea form is present, and no results ranking (
    ) leaks. assert has_element?(lv, "#idea-form") refute html =~ "結果" refute has_element?(lv, "ol") # Closing broadcasts to the live view, which reloads and shows results. {:ok, _} = Voting.close_room(room) closed_html = render(lv) assert closed_html =~ "この投票は終了しました" assert has_element?(lv, "ol") assert closed_html =~ "唯一の案" refute has_element?(lv, "#idea-form") end end end