Extend the GraphQL API and socket to accept mobile session tokens alongside existing API tokens. Add OrganizationScope middleware that extracts organization_id from query args for mobile users. Add my_organizations query for mobile app org listing. Reviewed-on: graham/towerops-web#48
130 lines
3.4 KiB
Elixir
130 lines
3.4 KiB
Elixir
defmodule ToweropsWeb.GraphQLSocketTest do
|
|
use Towerops.DataCase, async: true
|
|
|
|
import Towerops.AccountsFixtures
|
|
import Towerops.OrganizationsFixtures
|
|
|
|
alias Towerops.ApiTokens
|
|
alias Towerops.MobileSessions
|
|
alias ToweropsWeb.GraphQLSocket
|
|
|
|
describe "connect/3 with API token" do
|
|
setup do
|
|
user = user_fixture()
|
|
organization = organization_fixture(user.id)
|
|
|
|
{:ok, {_token, raw_token}} =
|
|
ApiTokens.create_api_token(%{
|
|
organization_id: organization.id,
|
|
user_id: user.id,
|
|
name: "GraphQL Test Token"
|
|
})
|
|
|
|
%{user: user, organization: organization, raw_token: raw_token}
|
|
end
|
|
|
|
test "connects with valid API token", %{
|
|
organization: organization,
|
|
raw_token: raw_token
|
|
} do
|
|
socket = %Phoenix.Socket{
|
|
assigns: %{},
|
|
transport: :websocket
|
|
}
|
|
|
|
assert {:ok, socket} = GraphQLSocket.connect(%{"token" => raw_token}, socket, %{})
|
|
assert socket.assigns.organization_id == organization.id
|
|
end
|
|
|
|
test "rejects invalid API token" do
|
|
socket = %Phoenix.Socket{
|
|
assigns: %{},
|
|
transport: :websocket
|
|
}
|
|
|
|
assert :error = GraphQLSocket.connect(%{"token" => "towerops_invalid_xxx"}, socket, %{})
|
|
end
|
|
end
|
|
|
|
describe "connect/3 with mobile session token" do
|
|
setup do
|
|
user = user_fixture()
|
|
|
|
{:ok, session} =
|
|
MobileSessions.create_mobile_session(%{
|
|
user_id: user.id,
|
|
device_name: "Test iPhone"
|
|
})
|
|
|
|
%{user: user, session: session}
|
|
end
|
|
|
|
test "connects with valid mobile token", %{user: user, session: session} do
|
|
socket = %Phoenix.Socket{
|
|
assigns: %{},
|
|
transport: :websocket
|
|
}
|
|
|
|
assert {:ok, socket} = GraphQLSocket.connect(%{"token" => session.raw_token}, socket, %{})
|
|
assert socket.assigns.user.id == user.id
|
|
refute Map.has_key?(socket.assigns, :organization_id)
|
|
end
|
|
|
|
test "rejects expired mobile token" do
|
|
user = user_fixture()
|
|
expires_at = DateTime.add(DateTime.utc_now(), -1, :day)
|
|
|
|
{:ok, session} =
|
|
MobileSessions.create_mobile_session(%{
|
|
user_id: user.id,
|
|
device_name: "Expired iPhone",
|
|
expires_at: expires_at
|
|
})
|
|
|
|
socket = %Phoenix.Socket{
|
|
assigns: %{},
|
|
transport: :websocket
|
|
}
|
|
|
|
assert :error = GraphQLSocket.connect(%{"token" => session.raw_token}, socket, %{})
|
|
end
|
|
end
|
|
|
|
describe "connect/3 with invalid params" do
|
|
test "rejects missing token" do
|
|
socket = %Phoenix.Socket{
|
|
assigns: %{},
|
|
transport: :websocket
|
|
}
|
|
|
|
assert :error = GraphQLSocket.connect(%{}, socket, %{})
|
|
end
|
|
|
|
test "rejects completely invalid token" do
|
|
socket = %Phoenix.Socket{
|
|
assigns: %{},
|
|
transport: :websocket
|
|
}
|
|
|
|
assert :error = GraphQLSocket.connect(%{"token" => "totally_bogus"}, socket, %{})
|
|
end
|
|
end
|
|
|
|
describe "id/1" do
|
|
test "returns socket ID based on organization_id for API token connections" do
|
|
socket = %Phoenix.Socket{
|
|
assigns: %{organization_id: "some-org-id", user: %{id: "some-user-id"}}
|
|
}
|
|
|
|
assert GraphQLSocket.id(socket) == "graphql_socket:some-org-id"
|
|
end
|
|
|
|
test "returns socket ID based on user_id for mobile connections" do
|
|
socket = %Phoenix.Socket{
|
|
assigns: %{user: %{id: "some-user-id"}}
|
|
}
|
|
|
|
assert GraphQLSocket.id(socket) == "graphql_socket:user:some-user-id"
|
|
end
|
|
end
|
|
end
|