@@ -25,9 +25,10 @@ defmodule RealtimeWeb.RealtimeChannel.PresenceHandlerTest do
25
25
db_conn: db_conn
26
26
} do
27
27
key = random_string ( )
28
+ policies = % Policies { presence: % PresencePolicies { read: true , write: true } }
28
29
29
30
socket =
30
- socket_fixture ( tenant , topic , key , % Policies { presence: % PresencePolicies { read: true , write: true } } )
31
+ socket_fixture ( tenant , topic , key , policies: policies )
31
32
32
33
PresenceHandler . handle ( % { "event" => "track" } , db_conn , socket )
33
34
topic = socket . assigns . tenant_topic
@@ -36,15 +37,10 @@ defmodule RealtimeWeb.RealtimeChannel.PresenceHandlerTest do
36
37
assert Map . has_key? ( joins , key )
37
38
end
38
39
39
- test "when tracking already existing user, metadata updated" , % {
40
- tenant: tenant ,
41
- topic: topic ,
42
- db_conn: db_conn
43
- } do
40
+ test "when tracking already existing user, metadata updated" , % { tenant: tenant , topic: topic , db_conn: db_conn } do
44
41
key = random_string ( )
45
-
46
- socket =
47
- socket_fixture ( tenant , topic , key , % Policies { presence: % PresencePolicies { read: true , write: true } } )
42
+ policies = % Policies { presence: % PresencePolicies { read: true , write: true } }
43
+ socket = socket_fixture ( tenant , topic , key , policies: policies )
48
44
49
45
assert { :reply , :ok , socket } = PresenceHandler . handle ( % { "event" => "track" } , db_conn , socket )
50
46
@@ -62,15 +58,8 @@ defmodule RealtimeWeb.RealtimeChannel.PresenceHandlerTest do
62
58
63
59
test "with false policy and is public, user can track their presence and changes" , % { tenant: tenant , topic: topic } do
64
60
key = random_string ( )
65
-
66
- socket =
67
- socket_fixture (
68
- tenant ,
69
- topic ,
70
- key ,
71
- % Policies { presence: % PresencePolicies { read: false , write: false } } ,
72
- false
73
- )
61
+ policies = % Policies { presence: % PresencePolicies { read: false , write: false } }
62
+ socket = socket_fixture ( tenant , topic , key , policies: policies , private?: false )
74
63
75
64
assert { :reply , :ok , _socket } = PresenceHandler . handle ( % { "event" => "track" } , socket )
76
65
@@ -81,9 +70,8 @@ defmodule RealtimeWeb.RealtimeChannel.PresenceHandlerTest do
81
70
82
71
test "user can untrack when they want" , % { tenant: tenant , topic: topic , db_conn: db_conn } do
83
72
key = random_string ( )
84
-
85
- socket =
86
- socket_fixture ( tenant , topic , key , % Policies { presence: % PresencePolicies { read: true , write: true } } )
73
+ policies = % Policies { presence: % PresencePolicies { read: true , write: true } }
74
+ socket = socket_fixture ( tenant , topic , key , policies: policies )
87
75
88
76
assert { :reply , :ok , socket } = PresenceHandler . handle ( % { "event" => "track" } , db_conn , socket )
89
77
@@ -151,10 +139,8 @@ defmodule RealtimeWeb.RealtimeChannel.PresenceHandlerTest do
151
139
reject ( & Authorization . get_write_authorizations / 3 )
152
140
153
141
key = random_string ( )
154
-
155
- socket =
156
- socket_fixture ( tenant , topic , key , % Policies { broadcast: % BroadcastPolicies { read: false } } , false )
157
-
142
+ policies = % Policies { broadcast: % BroadcastPolicies { read: false } }
143
+ socket = socket_fixture ( tenant , topic , key , policies: policies , private?: false )
158
144
topic = socket . assigns . tenant_topic
159
145
160
146
for _ <- 1 .. 100 , reduce: socket do
@@ -187,7 +173,7 @@ defmodule RealtimeWeb.RealtimeChannel.PresenceHandlerTest do
187
173
} do
188
174
key = random_string ( )
189
175
policies = % Policies { presence: % PresencePolicies { read: true , write: true } }
190
- socket = socket_fixture ( tenant , topic , key , policies , false , false )
176
+ socket = socket_fixture ( tenant , topic , key , policies: policies , private?: false , enabled?: false )
191
177
192
178
assert { :reply , :ok , _socket } = PresenceHandler . handle ( % { "event" => "track" } , socket )
193
179
topic = socket . assigns . tenant_topic
@@ -201,12 +187,68 @@ defmodule RealtimeWeb.RealtimeChannel.PresenceHandlerTest do
201
187
} do
202
188
key = random_string ( )
203
189
policies = % Policies { presence: % PresencePolicies { read: true , write: true } }
204
- socket = socket_fixture ( tenant , topic , key , policies , false , false )
190
+ socket = socket_fixture ( tenant , topic , key , policies: policies , private?: false , enabled?: false )
205
191
206
192
assert { :reply , :ok , _socket } = PresenceHandler . handle ( % { "event" => "track" } , db_conn , socket )
207
193
topic = socket . assigns . tenant_topic
208
194
refute_receive % Broadcast { topic: ^ topic , event: "presence_diff" }
209
195
end
196
+
197
+ @ tag policies: [ :authenticated_read_broadcast_and_presence , :authenticated_write_broadcast_and_presence ]
198
+ test "rate limit is checked on private channel" , % { tenant: tenant , topic: topic , db_conn: db_conn } do
199
+ key = random_string ( )
200
+ policies = % Policies { presence: % PresencePolicies { read: true , write: true } }
201
+ socket = socket_fixture ( tenant , topic , key , policies: policies , private?: true )
202
+
203
+ for _ <- 1 .. 300 , do: PresenceHandler . handle ( % { "event" => "track" } , db_conn , socket )
204
+ Process . sleep ( 1000 )
205
+
206
+ assert { :reply , :error , _ } = PresenceHandler . handle ( % { "event" => "track" } , db_conn , socket )
207
+ end
208
+
209
+ test "rate limit is checked on public channel" , % { tenant: tenant , topic: topic , db_conn: db_conn } do
210
+ key = random_string ( )
211
+ socket = socket_fixture ( tenant , topic , key , private?: false )
212
+
213
+ for _ <- 1 .. 300 , do: PresenceHandler . handle ( % { "event" => "track" } , db_conn , socket )
214
+ Process . sleep ( 1000 )
215
+
216
+ assert { :reply , :error , _ } = PresenceHandler . handle ( % { "event" => "track" } , db_conn , socket )
217
+ end
218
+ end
219
+
220
+ describe "sync/1" do
221
+ test "syncs presence state for public channels" , % { tenant: tenant , topic: topic } do
222
+ key = random_string ( )
223
+ policies = % Policies { presence: % PresencePolicies { read: false , write: false } }
224
+ socket = socket_fixture ( tenant , topic , key , policies: policies , private?: false )
225
+
226
+ assert { :noreply , _socket } = PresenceHandler . sync ( socket )
227
+ end
228
+
229
+ test "syncs presence state for private channels with read policy true" , % { tenant: tenant , topic: topic } do
230
+ key = random_string ( )
231
+ policies = % Policies { presence: % PresencePolicies { read: true , write: true } }
232
+ socket = socket_fixture ( tenant , topic , key , policies: policies , private?: true )
233
+
234
+ assert { :noreply , _socket } = PresenceHandler . sync ( socket )
235
+ end
236
+
237
+ test "ignores sync for private channels with read policy false" , % { tenant: tenant , topic: topic } do
238
+ key = random_string ( )
239
+ policies = % Policies { presence: % PresencePolicies { read: false , write: true } }
240
+ socket = socket_fixture ( tenant , topic , key , policies: policies , private?: true )
241
+
242
+ assert { :noreply , _socket } = PresenceHandler . sync ( socket )
243
+ end
244
+
245
+ test "ignores sync when presence is disabled" , % { tenant: tenant , topic: topic } do
246
+ key = random_string ( )
247
+ policies = % Policies { presence: % PresencePolicies { read: true , write: true } }
248
+ socket = socket_fixture ( tenant , topic , key , policies: policies , private?: true , enabled?: false )
249
+
250
+ assert { :noreply , _socket } = PresenceHandler . sync ( socket )
251
+ end
210
252
end
211
253
212
254
defp initiate_tenant ( context ) do
@@ -223,20 +265,19 @@ defmodule RealtimeWeb.RealtimeChannel.PresenceHandlerTest do
223
265
{ :ok , tenant: tenant , db_conn: db_conn , topic: topic }
224
266
end
225
267
226
- defp socket_fixture (
227
- tenant ,
228
- topic ,
229
- presence_key ,
230
- policies \\ % Policies {
231
- broadcast: % BroadcastPolicies { read: true } ,
232
- presence: % PresencePolicies { read: true , write: nil }
233
- } ,
234
- private? \\ true ,
235
- enabled? \\ true
236
- ) do
268
+ defp socket_fixture ( tenant , topic , presence_key , opts \\ [ ] ) do
269
+ policies =
270
+ Keyword . get ( opts , :policies , % Policies {
271
+ broadcast: % BroadcastPolicies { read: true } ,
272
+ presence: % PresencePolicies { read: true , write: nil }
273
+ } )
274
+
275
+ private? = Keyword . get ( opts , :private? , true )
276
+ enabled? = Keyword . get ( opts , :enabled? , true )
277
+ log_level = Keyword . get ( opts , :log_level , :error )
278
+
237
279
claims = % { sub: random_string ( ) , role: "authenticated" , exp: Joken . current_time ( ) + 1_000 }
238
280
signer = Joken.Signer . create ( "HS256" , "secret" )
239
-
240
281
jwt = Joken . generate_and_sign! ( % { } , claims , signer )
241
282
242
283
authorization_context =
@@ -267,7 +308,10 @@ defmodule RealtimeWeb.RealtimeChannel.PresenceHandlerTest do
267
308
presence_rate_counter: rate ,
268
309
private?: private? ,
269
310
presence_key: presence_key ,
270
- presence_enabled?: enabled?
311
+ presence_enabled?: enabled? ,
312
+ log_level: log_level ,
313
+ channel_name: topic ,
314
+ tenant: tenant . external_id
271
315
}
272
316
}
273
317
end
0 commit comments