livebook/test/livebook_teams/hubs_test.exs

259 lines
8.7 KiB
Elixir
Raw Normal View History

defmodule Livebook.HubsTest do
2023-07-13 19:42:27 +08:00
use Livebook.TeamsIntegrationCase, async: true
alias Livebook.Hubs
2023-07-13 19:29:36 +08:00
setup do
Livebook.Hubs.Broadcasts.subscribe([:connection, :file_systems, :secrets])
Livebook.Teams.Broadcasts.subscribe([:clients])
:ok
end
2023-08-09 03:03:01 +08:00
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()
2023-08-09 03:03:01 +08:00
Hubs.delete_hub(team.id)
refute team in Hubs.get_hubs()
end
2023-09-03 21:48:33 +08:00
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)
2023-09-03 21:48:33 +08:00
assert metadata in Hubs.get_metadata()
2023-08-09 03:03:01 +08:00
Hubs.delete_hub(team.id)
2023-09-03 21:48:33 +08:00
refute metadata in Hubs.get_metadata()
end
2023-08-09 03:03:01 +08:00
test "fetch_hub!/1 returns one persisted team", %{user: user, node: node} do
assert_raise Livebook.Storage.NotFoundError,
2023-08-09 03:03:01 +08:00
~s/could not find entry in "hubs" with ID "nonexistent"/,
fn ->
2023-08-09 03:03:01 +08:00
Hubs.fetch_hub!("nonexistent")
end
team = connect_to_teams(user, node)
2023-08-09 03:03:01 +08:00
assert Hubs.fetch_hub!(team.id) == team
end
2023-08-09 03:03:01 +08:00
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)
2024-05-17 00:17:45 +08:00
assert :ok = Hubs.create_secret(hub, secret)
assert secret in Hubs.get_secrets(hub)
# Guarantee uniqueness
2024-05-17 00:17:45 +08:00
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)
2024-05-17 00:17:45 +08:00
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, "")
2024-05-17 00:17:45 +08:00
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
2024-05-17 00:17:45 +08:00
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)
2024-05-17 00:17:45 +08:00
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, "")
2024-05-17 00:17:45 +08:00
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