|
| 1 | +defmodule DevRoundWeb.HostingSessionLive.ShowTest do |
| 2 | + use DevRoundWeb.ConnCase |
| 3 | + import Phoenix.LiveViewTest |
| 4 | + import DevRound.EventsFixtures |
| 5 | + import DevRound.AccountsFixtures |
| 6 | + import DevRound.HostingFixtures |
| 7 | + |
| 8 | + defp team_fixture(session, lang, attrs) do |
| 9 | + %DevRound.Hosting.Team{} |
| 10 | + |> Ecto.Changeset.change(%{ |
| 11 | + name: "some team #{System.unique_integer()}", |
| 12 | + slug: "some-team-#{System.unique_integer()}", |
| 13 | + session_id: session.id, |
| 14 | + lang_id: lang.id |
| 15 | + }) |
| 16 | + |> Ecto.Changeset.change(attrs) |
| 17 | + |> DevRound.Repo.insert!() |
| 18 | + end |
| 19 | + |
| 20 | + defp register_attendee(event, name, is_remote, langs, checked \\ true, experience \\ nil) do |
| 21 | + experience = experience || Enum.random(0..9) |
| 22 | + |
| 23 | + user = |
| 24 | + user_fixture(%{ |
| 25 | + name: name, |
| 26 | + full_name: name, |
| 27 | + email: "#{String.replace(name, " ", "")}@example.com", |
| 28 | + experience_level: experience |
| 29 | + }) |
| 30 | + |
| 31 | + {:ok, attendee} = |
| 32 | + DevRound.Events.create_event_attendee(event, user, %{ |
| 33 | + "is_remote" => is_remote, |
| 34 | + "lang_ids" => Enum.map(langs, & &1.id) |
| 35 | + }) |
| 36 | + |
| 37 | + {:ok, _updated} = DevRound.Hosting.update_event_attendee_checked(attendee, checked) |
| 38 | + end |
| 39 | + |
| 40 | + setup %{conn: conn} do |
| 41 | + user = user_fixture() |
| 42 | + lang = lang_fixture() |
| 43 | + |
| 44 | + future_deadline = NaiveDateTime.add(NaiveDateTime.local_now(), 12, :hour) |
| 45 | + |
| 46 | + event = |
| 47 | + event_fixture(%{ |
| 48 | + put_langs: [lang], |
| 49 | + main_video_conference_room_url: "https://lecture.com", |
| 50 | + registration_deadline_local: future_deadline |
| 51 | + }) |
| 52 | + |
| 53 | + # Add user as host |
| 54 | + Ecto.Changeset.change(event) |
| 55 | + |> Ecto.Changeset.put_assoc(:event_hosts, [%DevRound.Events.EventHost{user_id: user.id}]) |
| 56 | + |> DevRound.Repo.update!() |
| 57 | + |
| 58 | + # Manually insert video conference rooms |
| 59 | + %DevRound.Events.TeamVideoConferenceRoom{} |
| 60 | + |> Ecto.Changeset.change(%{url: "https://room1.com", event_id: event.id}) |
| 61 | + |> DevRound.Repo.insert!() |
| 62 | + |
| 63 | + session = hd(event.sessions) |
| 64 | + conn = log_in_user(conn, user) |
| 65 | + |
| 66 | + %{conn: conn, event: event, session: session, host: user, lang: lang} |
| 67 | + end |
| 68 | + |
| 69 | + describe "Hosting Session Show" do |
| 70 | + test "loads correctly with video conference rooms preloaded", %{ |
| 71 | + conn: conn, |
| 72 | + event: event, |
| 73 | + session: session |
| 74 | + } do |
| 75 | + assert {:ok, _view, _html} = live(conn, ~p"/events/#{event}/hosting/session/#{session}") |
| 76 | + end |
| 77 | + |
| 78 | + test "denies access to non-host users", %{conn: conn, event: event, session: session} do |
| 79 | + conn = log_in_user(conn, user_fixture()) |
| 80 | + |
| 81 | + assert_raise DevRoundWeb.PermissionError, fn -> |
| 82 | + live(conn, ~p"/events/#{event}/hosting/session/#{session}") |
| 83 | + end |
| 84 | + end |
| 85 | + |
| 86 | + test "can build teams and manage session lifecycle", %{ |
| 87 | + conn: conn, |
| 88 | + event: event, |
| 89 | + session: session, |
| 90 | + lang: lang |
| 91 | + } do |
| 92 | + team_name_fixture() |
| 93 | + |
| 94 | + # Register 2 checked-in attendees to satisfy team generation constraints |
| 95 | + register_attendee(event, "User 1", false, [lang]) |
| 96 | + register_attendee(event, "User 2", false, [lang]) |
| 97 | + |
| 98 | + {:ok, view, html} = live(conn, ~p"/events/#{event}/hosting/session/#{session}") |
| 99 | + |
| 100 | + assert html =~ "Build Teams" |
| 101 | + refute view |> element("button", "Build Teams") |> render() =~ "disabled" |
| 102 | + |
| 103 | + # Build Teams |
| 104 | + view |> element("button", "Build Teams") |> render_click() |
| 105 | + |
| 106 | + html = render(view) |
| 107 | + assert html =~ "Teams generated. You may start the session now." |
| 108 | + |
| 109 | + # Start Session |
| 110 | + view |> element("button", "Start Session") |> render_click() |
| 111 | + |
| 112 | + html = render(view) |
| 113 | + assert html =~ "started." |
| 114 | + # Countdown should be visible |
| 115 | + assert html =~ "Time Remaining" |
| 116 | + |
| 117 | + # Stop/Return to Lecture |
| 118 | + view |> element("button", "Return to Lecture") |> render_click() |
| 119 | + assert_redirected(view, ~p"/events/#{event}/hosting/lecture") |
| 120 | + |
| 121 | + # Re-visit the session liveview |
| 122 | + {:ok, view, _html} = live(conn, ~p"/events/#{event}/hosting/session/#{session}") |
| 123 | + |
| 124 | + # Now it should be stopped natively but teams are still assigned. |
| 125 | + # Reset Session |
| 126 | + view |> element("button", "Reset Session") |> render_click() |
| 127 | + |
| 128 | + html = render(view) |
| 129 | + assert html =~ "Session reset. You may build new teams now." |
| 130 | + assert html =~ "The teams for this session have not been assigned yet." |
| 131 | + end |
| 132 | + end |
| 133 | + |
| 134 | + describe "PubSub events" do |
| 135 | + test "handles event update (title change)", %{conn: conn, event: event, session: session} do |
| 136 | + {:ok, view, _html} = live(conn, ~p"/events/#{event}/hosting/session/#{session}") |
| 137 | + |
| 138 | + # Broadcast event update with new title |
| 139 | + # Changing event title (the event itself) |
| 140 | + new_event_title = "New Event Title" |
| 141 | + |
| 142 | + updated_event = |
| 143 | + Ecto.Changeset.change(event, %{title: new_event_title}) |
| 144 | + |> DevRound.Repo.update!(force: true) |
| 145 | + |
| 146 | + # The view handler updates itself |
| 147 | + send(view.pid, {"updated", updated_event}) |
| 148 | + assert render(view) =~ new_event_title |
| 149 | + end |
| 150 | + |
| 151 | + test "handles team_built event", %{conn: conn, event: event, session: session, lang: lang} do |
| 152 | + {:ok, view, _html} = live(conn, ~p"/events/#{event}/hosting/session/#{session}") |
| 153 | + refute render(view) =~ "Team Bravo" |
| 154 | + |
| 155 | + _team = team_fixture(session, lang, %{name: "Team Bravo"}) |
| 156 | + |
| 157 | + send(view.pid, %{ |
| 158 | + topic: "event_sessions", |
| 159 | + event: "teams_built", |
| 160 | + payload: %{event_session_id: session.id} |
| 161 | + }) |
| 162 | + |
| 163 | + assert render(view) =~ "Team Bravo" |
| 164 | + end |
| 165 | + end |
| 166 | +end |
0 commit comments