mirror of
https://github.com/livebook-dev/livebook.git
synced 2024-11-15 12:25:31 +08:00
247 lines
7 KiB
Elixir
247 lines
7 KiB
Elixir
defmodule LivebookWeb.HomeLiveTest do
|
|
use LivebookWeb.ConnCase, async: true
|
|
|
|
import Phoenix.LiveViewTest
|
|
import Livebook.SessionHelpers
|
|
import Livebook.TestHelpers
|
|
|
|
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"] a/, "New notebook")
|
|
|> render_click()
|
|
|
|
assert to =~ "/sessions/"
|
|
|
|
close_session_by_path(to)
|
|
end
|
|
|
|
test "public new endpoint creates an empty session", %{conn: conn} do
|
|
assert {:error, {:live_redirect, %{to: to}}} = result = live(conn, ~p"/new")
|
|
{:ok, view, _} = follow_redirect(result, conn)
|
|
|
|
assert render(view) =~ "Untitled notebook"
|
|
|
|
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}"] button}, "Close")
|
|
|> render_click()
|
|
|
|
render_confirm(view)
|
|
|
|
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?"
|
|
|
|
render_confirm(view)
|
|
|
|
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"/")
|
|
|
|
Livebook.NotebookManager.subscribe_starred_notebooks()
|
|
|
|
Livebook.NotebookManager.add_starred_notebook(file, "Special notebook")
|
|
assert_receive {:starred_notebooks_updated, _}
|
|
|
|
assert view
|
|
|> element(~s/#starred-notebooks/, "Special notebook")
|
|
|> has_element?()
|
|
|
|
Livebook.NotebookManager.remove_starred_notebook(file)
|
|
assert_receive {:starred_notebooks_updated, _}
|
|
|
|
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" do
|
|
test "renders sidebar section", %{conn: conn} do
|
|
{:ok, _view, html} = live(conn, ~p"/")
|
|
assert html =~ "HUBS"
|
|
assert html =~ "Add Hub"
|
|
end
|
|
|
|
test "renders sidebar persisted hubs", %{conn: conn} do
|
|
team = insert_hub(:team, id: "team-foo-bar-id")
|
|
|
|
{:ok, _view, html} = live(conn, ~p"/")
|
|
assert html =~ "HUBS"
|
|
assert html =~ team.hub_name
|
|
|
|
Livebook.Hubs.delete_hub("team-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
|