Files
bDS2/test/bds/desktop/remote_connection_test.exs

99 lines
3.5 KiB
Elixir

defmodule BDS.Desktop.RemoteConnectionTest do
use ExUnit.Case, async: false
alias BDS.Desktop.RemoteConnection
describe "parse_target/1" do
test "parses user@host with default SSH port" do
assert {:ok, %{user: "gb", host: "blog.example.com", port: 2222}} =
RemoteConnection.parse_target("gb@blog.example.com")
end
test "parses an explicit SSH port" do
assert {:ok, %{user: "gb", host: "10.0.0.5", port: 2022}} =
RemoteConnection.parse_target("gb@10.0.0.5:2022")
end
test "trims whitespace" do
assert {:ok, %{host: "h", user: "u"}} = RemoteConnection.parse_target(" u@h \n")
end
test "rejects targets without a user or host" do
assert {:error, :invalid_target} = RemoteConnection.parse_target("justahost")
assert {:error, :invalid_target} = RemoteConnection.parse_target("@host")
assert {:error, :invalid_target} = RemoteConnection.parse_target("user@")
assert {:error, :invalid_target} = RemoteConnection.parse_target("user@host:notaport")
end
end
describe "connect/2 and disconnect/1 (fake ssh)" do
setup do
parent = self()
ssh_dir =
Path.join(System.tmp_dir!(), "bds-remote-ssh-#{System.unique_integer([:positive])}")
on_exit(fn -> File.rm_rf!(ssh_dir) end)
fake = [
ssh_dir_fun: fn -> ssh_dir end,
connect_fun: fn host, port, opts ->
send(parent, {:ssh_connect, host, port, opts})
{:ok, spawn(fn -> Process.sleep(:infinity) end)}
end,
tunnel_fun: fn conn, _lhost, _lport, _rhost, rport, _timeout ->
send(parent, {:tunnel, conn, rport})
{:ok, 54_321}
end,
close_fun: fn conn -> send(parent, {:ssh_close, conn}) end
]
start_supervised!({RemoteConnection, name: nil, test_overrides: fake})
|> then(&{:ok, server: &1})
end
test "connects with public-key auth and returns the tunneled URL", %{server: server} do
assert {:ok, url} = RemoteConnection.connect(server, "gb@blog.example.com")
assert url == "http://127.0.0.1:54321/"
assert_receive {:ssh_connect, ~c"blog.example.com", 2222, opts}
assert opts[:user] == ~c"gb"
assert opts[:auth_methods] == ~c"publickey"
refute Keyword.has_key?(opts, :password)
assert_receive {:tunnel, _conn, 4010}
assert {:connected, "gb@blog.example.com", "http://127.0.0.1:54321/"} =
RemoteConnection.status(server)
end
test "disconnect closes the SSH connection", %{server: server} do
{:ok, _url} = RemoteConnection.connect(server, "gb@blog.example.com")
assert :ok = RemoteConnection.disconnect(server)
assert_receive {:ssh_close, _conn}
assert :disconnected = RemoteConnection.status(server)
end
test "connect errors surface as {:error, reason}", %{server: server} do
assert {:error, :invalid_target} = RemoteConnection.connect(server, "nonsense")
end
end
describe "menu integration" do
test "the File menu offers connect and disconnect" do
file_group = Enum.find(BDS.UI.MenuBar.default_groups(), &(&1.id == :file))
ids = Enum.map(file_group.items, &Map.get(&1, :id))
assert :connect_server in ids
assert :disconnect_server in ids
end
end
describe "desktop auth" do
test "required in desktop mode, skipped in server and tui modes" do
assert BDS.Server.desktop_auth_required?(:desktop) == true
assert BDS.Server.desktop_auth_required?(:server) == false
assert BDS.Server.desktop_auth_required?(:tui) == false
end
end
end