defmodule LivebookWeb.Hub.NewLiveTest do
use LivebookWeb.ConnCase
import Phoenix.LiveViewTest
alias Livebook.Hubs
setup do
on_exit(&Hubs.clean_hubs/0)
:ok
end
test "render hub selection cards", %{conn: conn} do
{:ok, _view, html} = live(conn, Routes.hub_path(conn, :new))
assert html =~ "Fly"
assert html =~ "Livebook Enterprise"
end
describe "fly" do
test "persists new hub", %{conn: conn} do
fly_bypass("123456789")
{:ok, view, _html} = live(conn, Routes.hub_path(conn, :new))
assert view
|> element("#fly")
|> render_click() =~ "2. Configure your Hub"
assert view
|> element(~s/input[name="fly[access_token]"]/)
|> render_change(%{"fly" => %{"access_token" => "dummy access token"}}) =~
~s()
attrs = %{
"access_token" => "dummy access token",
"application_id" => "123456789",
"hub_name" => "My Foo Hub",
"hub_color" => "#FF00FF"
}
view
|> element("#fly-form")
|> render_change(%{"fly" => attrs})
refute view
|> element("#fly-form .invalid-feedback")
|> has_element?()
assert {:ok, view, _html} =
view
|> element("#fly-form")
|> render_submit(%{"fly" => attrs})
|> follow_redirect(conn)
assert render(view) =~ "Hub added successfully"
assert view
|> element("#hubs")
|> render() =~ ~s/style="color: #FF00FF"/
assert view
|> element("#hubs")
|> render() =~ "/hub/fly-123456789"
assert view
|> element("#hubs")
|> render() =~ "My Foo Hub"
end
test "fails to create existing hub", %{conn: conn} do
hub = insert_hub(:fly, id: "fly-foo", application_id: "foo")
fly_bypass(hub.application_id)
{:ok, view, _html} = live(conn, Routes.hub_path(conn, :new))
assert view
|> element("#fly")
|> render_click() =~ "2. Configure your Hub"
assert view
|> element(~s/input[name="fly[access_token]"]/)
|> render_change(%{"fly" => %{"access_token" => "dummy access token"}}) =~
~s()
attrs = %{
"access_token" => "dummy access token",
"application_id" => "foo",
"hub_name" => "My Foo Hub",
"hub_color" => "#FF00FF"
}
view
|> element("#fly-form")
|> render_change(%{"fly" => attrs})
refute view
|> element("#fly-form .invalid-feedback")
|> has_element?()
assert view
|> element("#fly-form")
|> render_submit(%{"fly" => attrs}) =~ "already exists"
assert view
|> element("#hubs")
|> render() =~ ~s/style="color: #{hub.hub_color}"/
assert view
|> element("#hubs")
|> render() =~ Routes.hub_path(conn, :edit, hub.id)
assert view
|> element("#hubs")
|> render() =~ hub.hub_name
assert Hubs.fetch_hub!(hub.id) == hub
end
end
describe "enterprise" do
test "persists new hub", %{conn: conn} do
id = Livebook.Utils.random_short_id()
bypass = enterprise_bypass(id)
{:ok, view, _html} = live(conn, Routes.hub_path(conn, :new))
assert view
|> element("#enterprise")
|> render_click() =~ "2. Configure your Hub"
view
|> element("#enterprise-form")
|> render_change(%{
"enterprise" => %{
"url" => "http://localhost:#{bypass.port}",
"token" => "dummy access token"
}
})
assert view
|> element("#connect")
|> render_click() =~ "Add Hub"
attrs = %{
"url" => "http://localhost:#{bypass.port}",
"token" => "dummy access token",
"hub_name" => "Enterprise",
"hub_color" => "#FF00FF"
}
view
|> element("#enterprise-form")
|> render_change(%{"enterprise" => attrs})
refute view
|> element("#enterprise-form .invalid-feedback")
|> has_element?()
assert {:ok, view, _html} =
view
|> element("#enterprise-form")
|> render_submit(%{"enterprise" => attrs})
|> follow_redirect(conn)
assert render(view) =~ "Hub added successfully"
assert view
|> element("#hubs")
|> render() =~ ~s/style="color: #FF00FF"/
assert view
|> element("#hubs")
|> render() =~ "/hub/enterprise-#{id}"
assert view
|> element("#hubs")
|> render() =~ "Enterprise"
end
test "fails to create existing hub", %{conn: conn} do
hub = insert_hub(:enterprise, id: "enterprise-foo", external_id: "foo")
bypass = enterprise_bypass(hub.external_id)
{:ok, view, _html} = live(conn, Routes.hub_path(conn, :new))
assert view
|> element("#enterprise")
|> render_click() =~ "2. Configure your Hub"
view
|> element("#enterprise-form")
|> render_change(%{
"enterprise" => %{
"url" => "http://localhost:#{bypass.port}",
"token" => "dummy access token"
}
})
assert view
|> element("#connect")
|> render_click() =~ "Add Hub"
attrs = %{
"url" => "http://localhost:#{bypass.port}",
"token" => "dummy access token",
"hub_name" => "Enterprise",
"hub_color" => "#FF00FF"
}
view
|> element("#enterprise-form")
|> render_change(%{"enterprise" => attrs})
refute view
|> element("#enterprise-form .invalid-feedback")
|> has_element?()
assert view
|> element("#enterprise-form")
|> render_submit(%{"enterprise" => attrs}) =~ "already exists"
assert view
|> element("#hubs")
|> render() =~ ~s/style="color: #{hub.hub_color}"/
assert view
|> element("#hubs")
|> render() =~ Routes.hub_path(conn, :edit, hub.id)
assert view
|> element("#hubs")
|> render() =~ hub.hub_name
assert Hubs.fetch_hub!(hub.id) == hub
end
end
defp fly_bypass(app_id) do
bypass = Bypass.open()
Application.put_env(:livebook, :fly_graphql_endpoint, "http://localhost:#{bypass.port}")
Bypass.expect(bypass, "POST", "/", fn conn ->
{:ok, body, conn} = Plug.Conn.read_body(conn)
body = Jason.decode!(body)
response =
cond do
body["query"] =~ "apps" -> fetch_apps_response(app_id)
body["query"] =~ "app" -> fetch_app_response(app_id)
end
conn
|> Plug.Conn.put_resp_content_type("application/json")
|> Plug.Conn.resp(200, Jason.encode!(response))
end)
end
defp enterprise_bypass(id) do
bypass = Bypass.open()
Bypass.expect(bypass, "POST", "/api/v1", fn conn ->
{:ok, body, conn} = Plug.Conn.read_body(conn)
body = Jason.decode!(body)
response =
cond do
body["query"] =~ "info" ->
%{
"data" => %{
"info" => %{
"id" => Livebook.Utils.random_short_id(),
"expire_at" => to_string(DateTime.utc_now())
}
}
}
body["query"] =~ "me" ->
%{"data" => %{"me" => %{"id" => id}}}
end
conn
|> Plug.Conn.put_resp_content_type("application/json")
|> Plug.Conn.resp(200, Jason.encode!(response))
end)
bypass
end
defp fetch_apps_response(app_id) do
app = %{
"id" => app_id,
"organization" => %{
"id" => "l3soyvjmvtmwtl6l2drnbfuvltipprge",
"name" => "Foo Bar",
"type" => "PERSONAL"
}
}
%{"data" => %{"apps" => %{"nodes" => [app]}}}
end
defp fetch_app_response(app_id) do
app = %{
"id" => app_id,
"name" => app_id,
"hostname" => app_id <> ".fly.dev",
"platformVersion" => "nomad",
"deployed" => true,
"status" => "running",
"secrets" => [
%{
"createdAt" => to_string(DateTime.utc_now()),
"digest" => to_string(Livebook.Utils.random_cookie()),
"id" => Livebook.Utils.random_short_id(),
"name" => "LIVEBOOK_PASSWORD"
},
%{
"createdAt" => to_string(DateTime.utc_now()),
"digest" => to_string(Livebook.Utils.random_cookie()),
"id" => Livebook.Utils.random_short_id(),
"name" => "LIVEBOOK_SECRET_KEY_BASE"
}
]
}
%{"data" => %{"app" => app}}
end
end