livebook/test/livebook_web/live/home_live_test.exs
2023-03-15 18:18:33 +01:00

241 lines
6.7 KiB
Elixir

defmodule LivebookWeb.HomeLiveTest do
use LivebookWeb.ConnCase, async: true
import Phoenix.LiveViewTest
import Livebook.SessionHelpers
alias Livebook.{Sessions, Session}
test "disconnected and connected render", %{conn: conn} do
{:ok, view, disconnected_html} = live(conn, ~p"/")
assert disconnected_html =~ "Running sessions"
assert render(view) =~ "Running sessions"
end
test "redirects to session upon creation", %{conn: conn} do
{:ok, view, _} = live(conn, ~p"/")
assert {:error, {:live_redirect, %{to: to}}} =
view
|> element(~s/[role="navigation"] button/, "New notebook")
|> render_click()
assert to =~ "/sessions/"
close_session_by_path(to)
end
describe "sessions list" do
test "lists running sessions", %{conn: conn} do
{:ok, session1} = Sessions.create_session()
{:ok, session2} = Sessions.create_session()
{:ok, view, _} = live(conn, ~p"/")
assert render(view) =~ session1.id
assert render(view) =~ session2.id
Session.close([session1.pid, session2.pid])
end
test "updates UI whenever a session is added or deleted", %{conn: conn} do
Sessions.subscribe()
{:ok, view, _} = live(conn, ~p"/")
{:ok, %{id: id} = session} = Sessions.create_session()
assert_receive {:session_created, %{id: ^id}}
assert render(view) =~ id
Session.close(session.pid)
assert_receive {:session_closed, %{id: ^id}}
refute render(view) =~ id
end
test "allows download the source of an existing session", %{conn: conn} do
{:ok, session} = Sessions.create_session()
Session.set_notebook_name(session.pid, "My notebook")
{:ok, view, _} = live(conn, ~p"/")
{:error, {:redirect, %{to: to}}} =
view
|> element(~s{[data-test-session-id="#{session.id}"] a}, "Download source")
|> render_click
assert to == ~p"/sessions/#{session.id}/export/download/livemd?include_outputs=false"
Session.close(session.pid)
end
test "allows forking existing session", %{conn: conn} do
{:ok, session} = Sessions.create_session()
Session.set_notebook_name(session.pid, "My notebook")
{:ok, view, _} = live(conn, ~p"/")
assert {:error, {:live_redirect, %{to: to}}} =
view
|> element(~s{[data-test-session-id="#{session.id}"] button}, "Fork")
|> render_click()
assert to =~ "/sessions/"
{:ok, view, _} = live(conn, to)
assert render(view) =~ "My notebook - fork"
close_session_by_path(to)
Session.close(session.pid)
end
test "allows closing session after confirmation", %{conn: conn} do
{:ok, session} = Sessions.create_session()
{:ok, view, _} = live(conn, ~p"/")
assert render(view) =~ session.id
view
|> element(~s{[data-test-session-id="#{session.id}"] a}, "Close")
|> render_click()
view
|> element(~s{button[role=button]}, "Close session")
|> render_click()
refute render(view) =~ session.id
end
test "close all selected sessions using bulk action", %{conn: conn} do
{:ok, session1} = Sessions.create_session()
{:ok, session2} = Sessions.create_session()
{:ok, session3} = Sessions.create_session()
{:ok, view, _} = live(conn, ~p"/")
assert render(view) =~ session1.id
assert render(view) =~ session2.id
assert render(view) =~ session3.id
view
|> form("#bulk-action-form", %{
"action" => "close_all",
"session_ids" => [session1.id, session2.id, session3.id]
})
|> render_submit()
assert render(view) =~ "Are you sure you want to close 3 sessions?"
view
|> element(~s{button[role="button"]}, "Close sessions")
|> render_click()
refute render(view) =~ session1.id
refute render(view) =~ session2.id
refute render(view) =~ session3.id
end
end
describe "starred notebooks" do
@tag :tmp_dir
test "starring and unstarring a notebook", %{conn: conn, tmp_dir: tmp_dir} do
notebook_path = Path.join(tmp_dir, "notebook.livemd")
file = Livebook.FileSystem.File.local(notebook_path)
{:ok, session} = Sessions.create_session()
Session.set_file(session.pid, file)
Session.set_notebook_name(session.pid, "Special notebook")
wait_for_session_update(session.pid)
{:ok, view, _} = live(conn, ~p"/")
view
|> element(~s{[data-test-session-id="#{session.id}"] button}, "Star notebook")
|> render_click()
assert view
|> element(~s/#starred-notebooks/, "Special notebook")
|> has_element?()
view
|> element(~s{[data-test-session-id="#{session.id}"] button}, "Unstar notebook")
|> render_click()
refute view
|> element(~s/#starred-notebooks/, "Special notebook")
|> has_element?()
end
@tag :tmp_dir
test "opening a starred notebook", %{conn: conn, tmp_dir: tmp_dir} do
notebook_path = Path.join(tmp_dir, "notebook.livemd")
File.write!(notebook_path, "# Starred notebook")
file = Livebook.FileSystem.File.local(notebook_path)
Livebook.NotebookManager.add_starred_notebook(file, "Starred notebook")
{:ok, view, _} = live(conn, ~p"/")
card_html =
view
|> element(~s/#starred-notebooks [data-test-idx]/, "Starred notebook")
|> render()
assert [attr] = Regex.run(~r/data-test-idx="\d+"/, card_html)
view
|> element(~s/#starred-notebooks [#{attr}] button/, "Open")
|> render_click()
{to, _flash} = assert_redirect(view)
assert to =~ "/sessions/"
{:ok, view, _} = live(conn, to)
assert render(view) =~ "Starred notebook"
close_session_by_path(to)
end
end
describe "hubs sidebar" do
test "render section", %{conn: conn} do
{:ok, _view, html} = live(conn, ~p"/")
assert html =~ "HUBS"
assert html =~ "Add Hub"
end
test "render persisted hubs", %{conn: conn} do
fly = insert_hub(:fly, id: "fly-foo-bar-id")
{:ok, _view, html} = live(conn, ~p"/")
assert html =~ "HUBS"
assert html =~ fly.hub_name
Livebook.Hubs.delete_hub("fly-foo-bar-id")
end
end
test "handles user profile update", %{conn: conn} do
{:ok, view, _} = live(conn, ~p"/")
data = %{user: %{name: "Jake Peralta", hex_color: "#123456"}}
view
|> element("#user_form")
|> render_change(data)
view
|> element("#user_form")
|> render_submit(data)
assert render(view) =~ "Jake Peralta"
assert render(view) =~ "#123456"
end
# Helpers
defp close_session_by_path("/sessions/" <> session_id) do
{:ok, session} = Sessions.fetch_session(session_id)
Session.close(session.pid)
end
end