125 lines
4.5 KiB
Elixir
125 lines
4.5 KiB
Elixir
|
|
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 (<ol>) 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
|