mirror of
https://github.com/livebook-dev/livebook.git
synced 2024-11-14 11:55:12 +08:00
258 lines
8.7 KiB
Elixir
258 lines
8.7 KiB
Elixir
defmodule Livebook.HubsTest do
|
|
use Livebook.TeamsIntegrationCase, async: true
|
|
|
|
alias Livebook.Hubs
|
|
|
|
setup do
|
|
Livebook.Hubs.Broadcasts.subscribe([:connection, :file_systems, :secrets])
|
|
Livebook.Teams.Broadcasts.subscribe([:clients])
|
|
|
|
:ok
|
|
end
|
|
|
|
test "get_hubs/0 returns a list of persisted hubs", %{user: user, node: node} do
|
|
team = connect_to_teams(user, node)
|
|
assert team in Hubs.get_hubs()
|
|
|
|
Hubs.delete_hub(team.id)
|
|
refute team in Hubs.get_hubs()
|
|
end
|
|
|
|
test "get_metadata/0 returns a list of persisted hubs normalized", %{user: user, node: node} do
|
|
team = connect_to_teams(user, node)
|
|
metadata = Hubs.Provider.to_metadata(team)
|
|
|
|
assert metadata in Hubs.get_metadata()
|
|
|
|
Hubs.delete_hub(team.id)
|
|
refute metadata in Hubs.get_metadata()
|
|
end
|
|
|
|
test "fetch_hub!/1 returns one persisted team", %{user: user, node: node} do
|
|
assert_raise Livebook.Storage.NotFoundError,
|
|
~s/could not find entry in "hubs" with ID "nonexistent"/,
|
|
fn ->
|
|
Hubs.fetch_hub!("nonexistent")
|
|
end
|
|
|
|
team = connect_to_teams(user, node)
|
|
|
|
assert Hubs.fetch_hub!(team.id) == team
|
|
end
|
|
|
|
test "hub_exists?/1", %{user: user, node: node} do
|
|
team = build_team_hub(user, node)
|
|
refute Hubs.hub_exists?(team.id)
|
|
Hubs.save_hub(team)
|
|
assert Hubs.hub_exists?(team.id)
|
|
end
|
|
|
|
describe "save_hub/1" do
|
|
test "persists hub", %{user: user, node: node} do
|
|
team = build_team_hub(user, node)
|
|
Hubs.save_hub(team)
|
|
|
|
assert Hubs.fetch_hub!(team.id) == team
|
|
end
|
|
|
|
test "updates hub", %{user: user, node: node} do
|
|
team = connect_to_teams(user, node)
|
|
Hubs.save_hub(%{team | hub_emoji: "🐈"})
|
|
|
|
assert Hubs.fetch_hub!(team.id).hub_emoji == "🐈"
|
|
end
|
|
end
|
|
|
|
describe "create_secret/2" do
|
|
test "creates a new secret", %{user: user, node: node} do
|
|
hub = connect_to_teams(user, node)
|
|
name = secret_name(hub)
|
|
value = hub.id
|
|
secret = build(:secret, name: name, value: value, hub_id: hub.id)
|
|
|
|
assert :ok = Hubs.create_secret(hub, secret)
|
|
assert secret in Hubs.get_secrets(hub)
|
|
|
|
# Guarantee uniqueness
|
|
assert {:error, errors} = Hubs.create_secret(hub, secret)
|
|
assert "has already been taken" in errors[:name]
|
|
end
|
|
|
|
test "returns changeset errors when data is invalid", %{user: user, node: node} do
|
|
hub = connect_to_teams(user, node)
|
|
secret = build(:secret, name: "LB_FOO", value: "BAR", hub_id: hub.id)
|
|
|
|
assert {:error, errors} = Hubs.create_secret(hub, secret)
|
|
assert "cannot start with the LB_ prefix" in errors[:name]
|
|
end
|
|
end
|
|
|
|
describe "update_secret/2" do
|
|
test "updates a secret", %{user: user, node: node} do
|
|
hub = connect_to_teams(user, node)
|
|
name = secret_name(hub)
|
|
value = hub.id
|
|
secret = build(:secret, name: name, value: value, hub_id: hub.id)
|
|
|
|
assert Hubs.create_secret(hub, secret) == :ok
|
|
assert_receive {:secret_created, %{name: ^name, value: ^value, hub_id: ^value}}
|
|
assert secret in Hubs.get_secrets(hub)
|
|
|
|
new_value = "BAZ"
|
|
updated_secret = Map.replace!(secret, :value, new_value)
|
|
|
|
assert Hubs.update_secret(hub, updated_secret) == :ok
|
|
assert_receive {:secret_updated, %{name: ^name, value: ^new_value, hub_id: ^value}}
|
|
refute secret in Hubs.get_secrets(hub)
|
|
assert updated_secret in Hubs.get_secrets(hub)
|
|
end
|
|
|
|
test "returns changeset errors when data is invalid", %{user: user, node: node} do
|
|
hub = connect_to_teams(user, node)
|
|
name = secret_name(hub)
|
|
value = hub.id
|
|
secret = build(:secret, name: name, value: value, hub_id: hub.id)
|
|
|
|
assert Hubs.create_secret(hub, secret) == :ok
|
|
assert_receive {:secret_created, %{name: ^name, value: ^value}}
|
|
|
|
updated_secret = Map.replace!(secret, :value, "")
|
|
|
|
assert {:error, errors} = Hubs.update_secret(hub, updated_secret)
|
|
assert "can't be blank" in errors[:value]
|
|
end
|
|
end
|
|
|
|
test "delete_secret/2 deletes a secret", %{user: user, node: node} do
|
|
hub = connect_to_teams(user, node)
|
|
name = secret_name(hub)
|
|
value = hub.id
|
|
secret = build(:secret, name: name, value: value, hub_id: hub.id)
|
|
|
|
assert Hubs.create_secret(hub, secret) == :ok
|
|
assert_receive {:secret_created, %{name: ^name, value: ^value, hub_id: ^value}}
|
|
assert secret in Hubs.get_secrets(hub)
|
|
|
|
assert Hubs.delete_secret(hub, secret) == :ok
|
|
assert_receive {:secret_deleted, %{name: ^name, value: ^value, hub_id: ^value}}
|
|
refute secret in Hubs.get_secrets(hub)
|
|
|
|
# Guarantee it's been removed and will return HTTP status 404
|
|
assert Hubs.delete_secret(hub, secret) ==
|
|
{:transport_error,
|
|
"Something went wrong, try again later or please file a bug if it persists"}
|
|
end
|
|
|
|
describe "create_file_system/2" do
|
|
test "creates a new file system", %{user: user, node: node} do
|
|
hub = connect_to_teams(user, node)
|
|
|
|
bucket_url = "https://#{hub.id}.s3.amazonaws.com"
|
|
file_system = build(:fs_s3, bucket_url: bucket_url)
|
|
region = file_system.region
|
|
|
|
assert Hubs.create_file_system(hub, file_system) == :ok
|
|
assert_receive {:file_system_created, %{bucket_url: ^bucket_url, region: ^region}}
|
|
|
|
# Guarantee uniqueness
|
|
assert {:error, errors} = Hubs.create_file_system(hub, file_system)
|
|
assert "has already been taken" in errors[:bucket_url]
|
|
end
|
|
|
|
test "returns changeset errors when data is invalid", %{user: user, node: node} do
|
|
hub = connect_to_teams(user, node)
|
|
file_system = build(:fs_s3, bucket_url: nil)
|
|
|
|
assert {:error, errors} = Hubs.create_file_system(hub, file_system)
|
|
assert "can't be blank" in errors[:bucket_url]
|
|
end
|
|
end
|
|
|
|
describe "update_file_system/2" do
|
|
test "updates a file system", %{user: user, node: node} do
|
|
hub = connect_to_teams(user, node)
|
|
bucket_url = "https://#{hub.id}.s3.amazonaws.com"
|
|
file_system = build(:fs_s3, bucket_url: bucket_url)
|
|
|
|
assert Hubs.create_file_system(hub, file_system) == :ok
|
|
|
|
assert_receive {:file_system_created,
|
|
%{bucket_url: ^bucket_url, external_id: external_id} = file_system}
|
|
|
|
assert file_system in Hubs.get_file_systems(hub)
|
|
|
|
updated_file_system = Map.replace!(file_system, :region, "eu-central-1")
|
|
|
|
assert Hubs.update_file_system(hub, updated_file_system) == :ok
|
|
assert_receive {:file_system_updated, %{external_id: ^external_id, region: "eu-central-1"}}
|
|
refute file_system in Hubs.get_file_systems(hub)
|
|
assert updated_file_system in Hubs.get_file_systems(hub)
|
|
end
|
|
|
|
test "returns changeset errors when data is invalid", %{user: user, node: node} do
|
|
hub = connect_to_teams(user, node)
|
|
teams_file_system = create_teams_file_system(hub, node)
|
|
|
|
file_system =
|
|
build(:fs_s3,
|
|
bucket_url: "https://fix_me.s3.amazonaws.com",
|
|
external_id: to_string(teams_file_system.id)
|
|
)
|
|
|
|
update_file_system = Map.replace!(file_system, :bucket_url, "")
|
|
|
|
assert {:error, errors} = Hubs.update_file_system(hub, update_file_system)
|
|
assert "can't be blank" in errors[:bucket_url]
|
|
end
|
|
end
|
|
|
|
test "delete_file_system/2 deletes a file system", %{user: user, node: node} do
|
|
hub = connect_to_teams(user, node)
|
|
bucket_url = "https://#{hub.id}.s3.amazonaws.com"
|
|
file_system = build(:fs_s3, bucket_url: bucket_url)
|
|
|
|
assert Hubs.create_file_system(hub, file_system) == :ok
|
|
|
|
assert_receive {:file_system_created,
|
|
%{bucket_url: ^bucket_url, external_id: external_id} = file_system}
|
|
|
|
assert file_system in Hubs.get_file_systems(hub)
|
|
|
|
assert Hubs.delete_file_system(hub, file_system) == :ok
|
|
assert_receive {:file_system_deleted, %{external_id: ^external_id}}
|
|
refute file_system in Hubs.get_file_systems(hub)
|
|
|
|
# Guarantee it's been removed and will return HTTP status 404
|
|
assert Hubs.delete_file_system(hub, file_system) ==
|
|
{:transport_error,
|
|
"Something went wrong, try again later or please file a bug if it persists"}
|
|
end
|
|
|
|
test "generates and verifies stamp for a notebook", %{user: user, node: node} do
|
|
team = connect_to_teams(user, node)
|
|
|
|
notebook_source = """
|
|
# Team notebook
|
|
|
|
# Intro
|
|
|
|
```elixir
|
|
IO.puts("Hello!")
|
|
```
|
|
"""
|
|
|
|
metadata = %{"key" => "value"}
|
|
|
|
assert {:ok, stamp} = Hubs.Provider.notebook_stamp(team, notebook_source, metadata)
|
|
assert {:ok, ^metadata} = Hubs.Provider.verify_notebook_stamp(team, notebook_source, stamp)
|
|
|
|
assert {:error, :invalid} =
|
|
Hubs.Provider.verify_notebook_stamp(team, notebook_source <> "change\n", stamp)
|
|
end
|
|
|
|
defp secret_name(%{id: id}) do
|
|
id
|
|
|> String.replace("-", "_")
|
|
|> String.upcase()
|
|
end
|
|
end
|