defmodule ToweropsWeb.MobileSocketTest do use Towerops.DataCase, async: true import Towerops.AccountsFixtures import Towerops.OrganizationsFixtures alias Towerops.MobileSessions alias Towerops.Repo alias ToweropsWeb.MobileSocket setup do user = user_fixture() _org = organization_fixture(user.id) {:ok, qr_token} = MobileSessions.create_qr_login_token(user.id) {:ok, session} = MobileSessions.complete_qr_login(qr_token.token, %{ device_name: "Test iPhone", device_os: "iOS 17.0", app_version: "1.0.0" }) %{user: user, session: session} end describe "connect/3" do test "authenticates with valid token", %{session: session, user: user} do assert {:ok, socket} = MobileSocket.connect(%{"token" => session.raw_token}, socket(), %{}) assert socket.assigns.user_id == user.id assert socket.assigns.mobile_session_id == session.id end test "returns error with no params" do assert :error = MobileSocket.connect(%{}, socket(), %{}) end test "returns error with invalid token" do assert :error = MobileSocket.connect(%{"token" => "bogus-token"}, socket(), %{}) end test "returns error with expired session", %{session: session} do # Expire the session by setting expires_at to the past past = DateTime.utc_now() |> DateTime.add(-1, :day) |> DateTime.truncate(:second) session |> Ecto.Changeset.change(expires_at: past) |> Repo.update!() assert :error = MobileSocket.connect(%{"token" => session.raw_token}, socket(), %{}) end end describe "id/1" do test "returns correct socket id format", %{session: session, user: user} do {:ok, socket} = MobileSocket.connect(%{"token" => session.raw_token}, socket(), %{}) assert MobileSocket.id(socket) == "mobile_socket:#{user.id}" end end defp socket do %Phoenix.Socket{ transport: :websocket, serializer: Phoenix.Socket.V2.JSONSerializer, endpoint: ToweropsWeb.Endpoint } end end