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