19
19
20
20
from synapse .api .constants import EventTypes , LimitBlockingTypes , ServerNoticeMsgType
21
21
from synapse .api .errors import ResourceLimitError
22
+ from synapse .rest import admin
23
+ from synapse .rest .client .v1 import login , room
24
+ from synapse .rest .client .v2_alpha import sync
22
25
from synapse .server_notices .resource_limits_server_notices import (
23
26
ResourceLimitsServerNotices ,
24
27
)
@@ -67,7 +70,7 @@ def prepare(self, reactor, clock, hs):
67
70
# self.server_notices_mxid_avatar_url = None
68
71
# self.server_notices_room_name = "Server Notices"
69
72
70
- self ._rlsn ._server_notices_manager .get_notice_room_for_user = Mock (
73
+ self ._rlsn ._server_notices_manager .get_or_create_notice_room_for_user = Mock (
71
74
returnValue = ""
72
75
)
73
76
self ._rlsn ._store .add_tag_to_room = Mock ()
@@ -215,6 +218,26 @@ def test_maybe_send_server_notice_when_alerting_suppressed_room_blocked(self):
215
218
216
219
217
220
class TestResourceLimitsServerNoticesWithRealRooms (unittest .HomeserverTestCase ):
221
+ servlets = [
222
+ admin .register_servlets ,
223
+ login .register_servlets ,
224
+ room .register_servlets ,
225
+ sync .register_servlets ,
226
+ ]
227
+
228
+ def default_config (self ):
229
+ c = super ().default_config ()
230
+ c ["server_notices" ] = {
231
+ "system_mxid_localpart" : "server" ,
232
+ "system_mxid_display_name" : None ,
233
+ "system_mxid_avatar_url" : None ,
234
+ "room_name" : "Test Server Notice Room" ,
235
+ }
236
+ c ["limit_usage_by_mau" ] = True
237
+ c ["max_mau_value" ] = 5
238
+ c [
"admin_contact" ]
= "mailto:[email protected] "
239
+ return c
240
+
218
241
def prepare (self , reactor , clock , hs ):
219
242
self .store = self .hs .get_datastore ()
220
243
self .server_notices_sender = self .hs .get_server_notices_sender ()
@@ -228,18 +251,8 @@ def prepare(self, reactor, clock, hs):
228
251
if not isinstance (self ._rlsn , ResourceLimitsServerNotices ):
229
252
raise Exception ("Failed to find reference to ResourceLimitsServerNotices" )
230
253
231
- self .hs .config .limit_usage_by_mau = True
232
- self .hs .config .hs_disabled = False
233
- self .hs .config .max_mau_value = 5
234
- self .hs .config .server_notices_mxid = "@server:test"
235
- self .hs .config .server_notices_mxid_display_name = None
236
- self .hs .config .server_notices_mxid_avatar_url = None
237
- self .hs .config .server_notices_room_name = "Test Server Notice Room"
238
-
239
254
self .user_id = "@user_id:test"
240
255
241
- self .
hs .
config .
admin_contact = "mailto:[email protected] "
242
-
243
256
def test_server_notice_only_sent_once (self ):
244
257
self .store .get_monthly_active_count = Mock (return_value = 1000 )
245
258
@@ -253,7 +266,7 @@ def test_server_notice_only_sent_once(self):
253
266
# Now lets get the last load of messages in the service notice room and
254
267
# check that there is only one server notice
255
268
room_id = self .get_success (
256
- self .server_notices_manager .get_notice_room_for_user (self .user_id )
269
+ self .server_notices_manager .get_or_create_notice_room_for_user (self .user_id )
257
270
)
258
271
259
272
token = self .get_success (self .event_source .get_current_token ())
@@ -273,3 +286,86 @@ def test_server_notice_only_sent_once(self):
273
286
count += 1
274
287
275
288
self .assertEqual (count , 1 )
289
+
290
+ def test_no_invite_without_notice (self ):
291
+ """Tests that a user doesn't get invited to a server notices room without a
292
+ server notice being sent.
293
+
294
+ The scenario for this test is a single user on a server where the MAU limit
295
+ hasn't been reached (since it's the only user and the limit is 5), so users
296
+ shouldn't receive a server notice.
297
+ """
298
+ self .register_user ("user" , "password" )
299
+ tok = self .login ("user" , "password" )
300
+
301
+ request , channel = self .make_request ("GET" , "/sync?timeout=0" , access_token = tok )
302
+ self .render (request )
303
+
304
+ invites = channel .json_body ["rooms" ]["invite" ]
305
+ self .assertEqual (len (invites ), 0 , invites )
306
+
307
+ def test_invite_with_notice (self ):
308
+ """Tests that, if the MAU limit is hit, the server notices user invites each user
309
+ to a room in which it has sent a notice.
310
+ """
311
+ user_id , tok , room_id = self ._trigger_notice_and_join ()
312
+
313
+ # Sync again to retrieve the events in the room, so we can check whether this
314
+ # room has a notice in it.
315
+ request , channel = self .make_request ("GET" , "/sync?timeout=0" , access_token = tok )
316
+ self .render (request )
317
+
318
+ # Scan the events in the room to search for a message from the server notices
319
+ # user.
320
+ events = channel .json_body ["rooms" ]["join" ][room_id ]["timeline" ]["events" ]
321
+ notice_in_room = False
322
+ for event in events :
323
+ if (
324
+ event ["type" ] == EventTypes .Message
325
+ and event ["sender" ] == self .hs .config .server_notices_mxid
326
+ ):
327
+ notice_in_room = True
328
+
329
+ self .assertTrue (notice_in_room , "No server notice in room" )
330
+
331
+ def _trigger_notice_and_join (self ):
332
+ """Creates enough active users to hit the MAU limit and trigger a system notice
333
+ about it, then joins the system notices room with one of the users created.
334
+
335
+ Returns:
336
+ user_id (str): The ID of the user that joined the room.
337
+ tok (str): The access token of the user that joined the room.
338
+ room_id (str): The ID of the room that's been joined.
339
+ """
340
+ user_id = None
341
+ tok = None
342
+ invites = []
343
+
344
+ # Register as many users as the MAU limit allows.
345
+ for i in range (self .hs .config .max_mau_value ):
346
+ localpart = "user%d" % i
347
+ user_id = self .register_user (localpart , "password" )
348
+ tok = self .login (localpart , "password" )
349
+
350
+ # Sync with the user's token to mark the user as active.
351
+ request , channel = self .make_request (
352
+ "GET" , "/sync?timeout=0" , access_token = tok ,
353
+ )
354
+ self .render (request )
355
+
356
+ # Also retrieves the list of invites for this user. We don't care about that
357
+ # one except if we're processing the last user, which should have received an
358
+ # invite to a room with a server notice about the MAU limit being reached.
359
+ # We could also pick another user and sync with it, which would return an
360
+ # invite to a system notices room, but it doesn't matter which user we're
361
+ # using so we use the last one because it saves us an extra sync.
362
+ invites = channel .json_body ["rooms" ]["invite" ]
363
+
364
+ # Make sure we have an invite to process.
365
+ self .assertEqual (len (invites ), 1 , invites )
366
+
367
+ # Join the room.
368
+ room_id = list (invites .keys ())[0 ]
369
+ self .helper .join (room = room_id , user = user_id , tok = tok )
370
+
371
+ return user_id , tok , room_id
0 commit comments