From c8dd308cc4fda1ab68616ebab4413a10678857b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20Caba=C3=A7o?= Date: Wed, 29 Jan 2025 16:28:11 +0000 Subject: [PATCH] fix: properly handle match error --- .github/workflows/tests.yml | 3 + lib/realtime_web/channels/realtime_channel.ex | 3 + test/integration/rt_channel_test.exs | 55 ++++++++++++++++++- .../channels/realtime_channel_test.exs | 3 +- 4 files changed, 62 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b8b10b415..99c12f66f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,6 +3,9 @@ on: pull_request: branches: - main + push: + branches: + - main jobs: format: name: Tests diff --git a/lib/realtime_web/channels/realtime_channel.ex b/lib/realtime_web/channels/realtime_channel.ex index 0ab886088..1d07d178f 100644 --- a/lib/realtime_web/channels/realtime_channel.ex +++ b/lib/realtime_web/channels/realtime_channel.ex @@ -420,6 +420,9 @@ defmodule RealtimeWeb.RealtimeChannel do {:error, :expected_claims_map} -> shutdown_response(socket, "Token claims must be a map") + {:error, :unable_to_set_policies, _msg} -> + shutdown_response(socket, "Realtime was unable to connect to the project database") + {:error, error} -> shutdown_response(socket, inspect(error)) end diff --git a/test/integration/rt_channel_test.exs b/test/integration/rt_channel_test.exs index c9d2ac497..5f182d104 100644 --- a/test/integration/rt_channel_test.exs +++ b/test/integration/rt_channel_test.exs @@ -6,6 +6,7 @@ defmodule Realtime.Integration.RtChannelTest do use RealtimeWeb.ConnCase, async: false import ExUnit.CaptureLog import Generators + import Mock require Logger @@ -19,6 +20,7 @@ defmodule Realtime.Integration.RtChannelTest do alias Realtime.Integration.WebsocketClient alias Realtime.Repo alias Realtime.Tenants + alias Realtime.Tenants.Authorization alias Realtime.Tenants.Migrations @moduletag :capture_log @@ -849,7 +851,6 @@ defmodule Realtime.Integration.RtChannelTest do # token becomes a string in between joins so it needs to be handled by the channel and not the socket Process.sleep(1000) - realtime_topic = "realtime:#{topic}" WebsocketClient.join(socket, realtime_topic, %{config: config, access_token: "potato"}) assert_receive %Message{ @@ -864,6 +865,58 @@ defmodule Realtime.Integration.RtChannelTest do assert_receive %Message{event: "phx_close"} end + + @tag policies: [ + :authenticated_read_broadcast_and_presence, + :authenticated_write_broadcast_and_presence + ] + test "handles RPC error on token refreshed", %{topic: topic} do + with_mocks [ + {Authorization, [:passthrough], build_authorization_params: &passthrough([&1])}, + {Authorization, [:passthrough], + get_read_authorizations: [ + in_series([:_, :_, :_], [&passthrough([&1, &2, &3]), {:error, "RPC Error"}]) + ]} + ] do + {socket, access_token} = get_connection("authenticated") + config = %{broadcast: %{self: true}, private: true} + realtime_topic = "realtime:#{topic}" + + WebsocketClient.join(socket, realtime_topic, %{config: config, access_token: access_token}) + + assert_receive %Phoenix.Socket.Message{event: "phx_reply"}, 500 + assert_receive %Phoenix.Socket.Message{event: "presence_state"}, 500 + + # Update token to force update + {:ok, access_token} = + generate_token(%{:exp => System.system_time(:second) + 1000, role: "authenticated"}) + + log = + capture_log(fn -> + WebsocketClient.send_event(socket, realtime_topic, "access_token", %{ + "access_token" => access_token + }) + + assert_receive %Phoenix.Socket.Message{ + event: "system", + payload: %{ + "status" => "error", + "extension" => "system", + "message" => + "Realtime was unable to connect to the project database" + }, + topic: ^realtime_topic, + join_ref: nil, + ref: nil + }, + 500 + + assert_receive %Phoenix.Socket.Message{event: "phx_close", topic: ^realtime_topic} + end) + + assert log =~ "Realtime was unable to connect to the project database" + end + end end describe "handle broadcast changes" do diff --git a/test/realtime_web/channels/realtime_channel_test.exs b/test/realtime_web/channels/realtime_channel_test.exs index 9981ed2d5..1f905e1ab 100644 --- a/test/realtime_web/channels/realtime_channel_test.exs +++ b/test/realtime_web/channels/realtime_channel_test.exs @@ -6,9 +6,10 @@ defmodule RealtimeWeb.RealtimeChannelTest do import ExUnit.CaptureLog alias Phoenix.Socket + alias Realtime.Tenants.Authorization alias RealtimeWeb.ChannelsAuthorization - alias RealtimeWeb.UserSocket alias RealtimeWeb.Joken.CurrentTime + alias RealtimeWeb.UserSocket @tenant_external_id "dev_tenant"