def test_notify_interested_services_ephemeral(self): """ Test sending ephemeral events to the appservice handler are scheduled to be pushed out to interested appservices, and that the stream ID is updated accordingly. """ interested_service = self._mkservice(is_interested=True) services = [interested_service] self.mock_store.get_app_services.return_value = services self.mock_store.get_type_stream_id_for_appservice.return_value = make_awaitable( 579 ) event = Mock(event_id="event_1") self.event_source.sources.receipt.get_new_events_as.return_value = ( make_awaitable(([event], None)) ) self.handler.notify_interested_services_ephemeral("receipt_key", 580) self.mock_scheduler.submit_ephemeral_events_for_as.assert_called_once_with( interested_service, [event] ) self.mock_store.set_type_stream_id_for_appservice.assert_called_once_with( interested_service, "read_receipt", 580, )
def test_join_too_large(self): u1 = self.register_user("u1", "pass") handler = self.hs.get_room_member_handler() fed_transport = self.hs.get_federation_transport_client() # Mock out some things, because we don't want to test the whole join fed_transport.client.get_json = Mock( return_value=make_awaitable({"v1": 9999})) handler.federation_handler.do_invite_join = Mock( return_value=make_awaitable(("", 1))) d = handler._remote_join( None, ["other.example.com"], "roomid", UserID.from_string(u1), {"membership": "join"}, ) self.pump() # The request failed with a SynapseError saying the resource limit was # exceeded. f = self.get_failure(d, SynapseError) self.assertEqual(f.value.code, 400, f.value) self.assertEqual(f.value.errcode, Codes.RESOURCE_LIMIT_EXCEEDED)
def test_query_room_alias_exists(self): room_alias_str = "#foo:bar" room_alias = Mock() room_alias.to_string.return_value = room_alias_str room_id = "!alpha:bet" servers = ["aperture"] interested_service = self._mkservice_alias(is_interested_in_alias=True) services = [ self._mkservice_alias(is_interested_in_alias=False), interested_service, self._mkservice_alias(is_interested_in_alias=False), ] self.mock_as_api.query_alias.return_value = make_awaitable(True) self.mock_store.get_app_services.return_value = services self.mock_store.get_association_from_room_alias.return_value = make_awaitable( Mock(room_id=room_id, servers=servers) ) result = self.successResultOf( defer.ensureDeferred(self.handler.query_room_alias_exists(room_alias)) ) self.mock_as_api.query_alias.assert_called_once_with( interested_service, room_alias_str ) self.assertEquals(result.room_id, room_id) self.assertEquals(result.servers, servers)
def test_join_too_large_admin(self): # An admin should be able to join rooms where a complexity check fails. u1 = self.register_user("u1", "pass", admin=True) handler = self.hs.get_room_member_handler() fed_transport = self.hs.get_federation_transport_client() # Mock out some things, because we don't want to test the whole join fed_transport.client.get_json = Mock( return_value=make_awaitable({"v1": 9999})) handler.federation_handler.do_invite_join = Mock( return_value=make_awaitable(("", 1))) d = handler._remote_join( None, ["other.example.com"], "roomid", UserID.from_string(u1), {"membership": "join"}, ) self.pump() # The request success since the user is an admin self.get_success(d)
def test_mau_limits_parity(self): # Ensure we're not at the unix epoch. self.reactor.advance(1) self.auth_blocking._limit_usage_by_mau = True # Set the server to be at the edge of too many users. self.hs.get_datastore().get_monthly_active_count = Mock( return_value=make_awaitable(self.auth_blocking._max_mau_value)) # If not in monthly active cohort self.get_failure( self.auth_handler.create_access_token_for_user_id( self.user1, device_id=None, valid_until_ms=None), ResourceLimitError, ) self.get_failure( self.auth_handler.validate_short_term_login_token( self._get_macaroon().serialize()), ResourceLimitError, ) # If in monthly active cohort self.hs.get_datastore().user_last_seen_monthly_active = Mock( return_value=make_awaitable(self.clock.time_msec())) self.get_success( self.auth_handler.create_access_token_for_user_id( self.user1, device_id=None, valid_until_ms=None)) self.get_success( self.auth_handler.validate_short_term_login_token( self._get_macaroon().serialize()))
def prepare(self, reactor, clock, hs): self.server_notices_sender = self.hs.get_server_notices_sender() # relying on [1] is far from ideal, but the only case where # ResourceLimitsServerNotices class needs to be isolated is this test, # general code should never have a reason to do so ... self._rlsn = self.server_notices_sender._server_notices[1] if not isinstance(self._rlsn, ResourceLimitsServerNotices): raise Exception( "Failed to find reference to ResourceLimitsServerNotices") self._rlsn._store.user_last_seen_monthly_active = Mock( return_value=make_awaitable(1000)) self._rlsn._server_notices_manager.send_notice = Mock( return_value=defer.succeed(Mock())) self._send_notice = self._rlsn._server_notices_manager.send_notice self.user_id = "@user_id:test" self._rlsn._server_notices_manager.get_or_create_notice_room_for_user = Mock( return_value=defer.succeed("!something:localhost")) self._rlsn._store.add_tag_to_room = Mock( return_value=defer.succeed(None)) self._rlsn._store.get_tags_for_room = Mock( return_value=make_awaitable({}))
def test_auto_create_auto_join_rooms_when_user_is_not_the_first_real_user( self): self.store.count_real_users = Mock(return_value=make_awaitable(2)) self.store.is_real_user = Mock(return_value=make_awaitable(True)) user_id = self.get_success( self.handler.register_user(localpart="real")) rooms = self.get_success(self.store.get_rooms_for_user(user_id)) self.assertEqual(len(rooms), 0)
def _test_3pid_allowed(self, username: str, registration: bool): """Tests that the "is_3pid_allowed" module callback is called correctly, using either /register or /account URLs depending on the arguments. Args: username: The username to use for the test. registration: Whether to test with registration URLs. """ self.hs.get_identity_handler().send_threepid_validation = Mock( return_value=make_awaitable(0), ) m = Mock(return_value=make_awaitable(False)) self.hs.get_password_auth_provider().is_3pid_allowed_callbacks = [m] self.register_user(username, "password") tok = self.login(username, "password") if registration: url = "/register/email/requestToken" else: url = "/account/3pid/email/requestToken" channel = self.make_request( "POST", url, { "client_secret": "foo", "email": "*****@*****.**", "send_attempt": 0, }, access_token=tok, ) self.assertEqual(channel.code, 403, channel.result) self.assertEqual( channel.json_body["errcode"], Codes.THREEPID_DENIED, channel.json_body, ) m.assert_called_once_with("email", "*****@*****.**", registration) m = Mock(return_value=make_awaitable(True)) self.hs.get_password_auth_provider().is_3pid_allowed_callbacks = [m] channel = self.make_request( "POST", url, { "client_secret": "foo", "email": "*****@*****.**", "send_attempt": 0, }, access_token=tok, ) self.assertEqual(channel.code, 200, channel.result) self.assertIn("sid", channel.json_body) m.assert_called_once_with("email", "*****@*****.**", registration)
def prepare(self, reactor, clock, hs): mock_notifier = hs.get_notifier() self.on_new_event = mock_notifier.on_new_event self.handler = hs.get_typing_handler() self.event_source = hs.get_event_sources().sources["typing"] self.datastore = hs.get_datastore() retry_timings_res = { "destination": "", "retry_last_ts": 0, "retry_interval": 0, "failure_ts": None, } self.datastore.get_destination_retry_timings.return_value = defer.succeed( retry_timings_res) self.datastore.get_device_updates_by_remote.side_effect = lambda destination, from_stream_id, limit: make_awaitable( (0, [])) def get_received_txn_response(*args): return defer.succeed(None) self.datastore.get_received_txn_response = get_received_txn_response self.room_members = [] async def check_user_in_room(room_id, user_id): if user_id not in [u.to_string() for u in self.room_members]: raise AuthError(401, "User is not in the room") return None hs.get_auth().check_user_in_room = check_user_in_room def get_joined_hosts_for_room(room_id): return {member.domain for member in self.room_members} self.datastore.get_joined_hosts_for_room = get_joined_hosts_for_room def get_users_in_room(room_id): return defer.succeed({str(u) for u in self.room_members}) self.datastore.get_users_in_room = get_users_in_room self.datastore.get_user_directory_stream_pos.side_effect = ( # we deliberately return a non-None stream pos to avoid doing an initial_spam lambda: make_awaitable(1)) self.datastore.get_current_state_deltas.return_value = (0, None) self.datastore.get_to_device_stream_token = lambda: 0 self.datastore.get_new_device_msgs_for_remote = lambda *args, **kargs: make_awaitable( ([], 0)) self.datastore.delete_device_msgs_for_remote = lambda *args, **kargs: make_awaitable( None) self.datastore.set_received_txn_response = lambda *args, **kwargs: make_awaitable( None)
def test_register_mau_blocked(self): self.store.get_monthly_active_count = Mock( return_value=make_awaitable(self.lots_of_users)) self.get_failure(self.handler.register_user(localpart="local_part"), ResourceLimitError) self.store.get_monthly_active_count = Mock( return_value=make_awaitable(self.hs.config.server.max_mau_value)) self.get_failure(self.handler.register_user(localpart="local_part"), ResourceLimitError)
def test_on_user_deactivation_status_changed(self) -> None: """Tests that the on_user_deactivation_status_changed module callback is called correctly when processing a user's deactivation. """ # Register a mocked callback. deactivation_mock = Mock(return_value=make_awaitable(None)) third_party_rules = self.hs.get_third_party_event_rules() third_party_rules._on_user_deactivation_status_changed_callbacks.append( deactivation_mock, ) # Also register a mocked callback for profile updates, to check that the # deactivation code calls it in a way that let modules know the user is being # deactivated. profile_mock = Mock(return_value=make_awaitable(None)) self.hs.get_third_party_event_rules( )._on_profile_update_callbacks.append(profile_mock, ) # Register a user that we'll deactivate. user_id = self.register_user("altan", "password") tok = self.login("altan", "password") # Deactivate that user. channel = self.make_request( "POST", "/_matrix/client/v3/account/deactivate", { "auth": { "type": LoginType.PASSWORD, "password": "******", "identifier": { "type": "m.id.user", "user": user_id, }, }, "erase": True, }, access_token=tok, ) self.assertEqual(channel.code, 200, channel.json_body) # Check that the mock was called once. deactivation_mock.assert_called_once() args = deactivation_mock.call_args[0] # Check that the mock was called with the right user ID, and with a True # deactivated flag and a False by_admin flag. self.assertEqual(args[0], user_id) self.assertTrue(args[1]) self.assertFalse(args[2]) # Check that the profile update callback was called twice (once for the display # name and once for the avatar URL), and that the "deactivation" boolean is true. self.assertEqual(profile_mock.call_count, 2) args = profile_mock.call_args[0] self.assertTrue(args[3])
def custom_auth_provider_ui_auth_test_body(self): # register the user and log in twice, to get two devices self.register_user("localuser", "localpass") tok1 = self.login("localuser", "localpass") self.login("localuser", "localpass", device_id="dev2") # make the initial request which returns a 401 channel = self._delete_device(tok1, "dev2") self.assertEqual(channel.code, 401) # Ensure that flows are what is expected. self.assertIn({"stages": ["m.login.password"]}, channel.json_body["flows"]) self.assertIn({"stages": ["test.login_type"]}, channel.json_body["flows"]) session = channel.json_body["session"] # missing param body = { "auth": { "type": "test.login_type", "identifier": { "type": "m.id.user", "user": "******" }, "session": session, }, } channel = self._delete_device(tok1, "dev2", body) self.assertEqual(channel.code, 400) # there's a perfectly good M_MISSING_PARAM errcode, but heaven forfend we should # use it... self.assertIn("Missing parameters", channel.json_body["error"]) mock_password_provider.check_auth.assert_not_called() mock_password_provider.reset_mock() # right params, but authing as the wrong user mock_password_provider.check_auth.return_value = make_awaitable( ("@user:bz", None)) body["auth"]["test_field"] = "foo" channel = self._delete_device(tok1, "dev2", body) self.assertEqual(channel.code, 403) self.assertEqual(channel.json_body["errcode"], "M_FORBIDDEN") mock_password_provider.check_auth.assert_called_once_with( "localuser", "test.login_type", {"test_field": "foo"}) mock_password_provider.reset_mock() # and finally, succeed mock_password_provider.check_auth.return_value = make_awaitable( ("@localuser:test", None)) channel = self._delete_device(tok1, "dev2", body) self.assertEqual(channel.code, 200) mock_password_provider.check_auth.assert_called_once_with( "localuser", "test.login_type", {"test_field": "foo"})
def setUp(self): self.mock_store = Mock() self.mock_as_api = Mock() self.mock_scheduler = Mock() hs = Mock() hs.get_datastore.return_value = self.mock_store self.mock_store.get_received_ts.return_value = make_awaitable(0) self.mock_store.set_appservice_last_pos.return_value = make_awaitable(None) hs.get_application_service_api.return_value = self.mock_as_api hs.get_application_service_scheduler.return_value = self.mock_scheduler hs.get_clock.return_value = MockClock() self.handler = ApplicationServicesHandler(hs)
def test_user_email_bound_via_sydent_internal_api(self): """Tests that emails are bound after registration if this option is set""" # Register user with an email address email = "*****@*****.**" # Mock Synapse's threepid validator get_threepid_validation_session = Mock( return_value=make_awaitable( {"medium": "email", "address": email, "validated_at": 0} ) ) self.store.get_threepid_validation_session = get_threepid_validation_session delete_threepid_session = Mock(return_value=make_awaitable(None)) self.store.delete_threepid_session = delete_threepid_session # Mock Synapse's http json post method to check for the internal bind call post_json_get_json = Mock(return_value=make_awaitable(None)) self.hs.get_identity_handler().http_client.post_json_get_json = ( post_json_get_json ) # Retrieve a UIA session ID channel = self.uia_register( 401, {"username": "******", "password": "******"} ) session_id = channel.json_body["session"] # Register our email address using the fake validation session above channel = self.uia_register( 200, { "username": "******", "password": "******", "auth": { "session": session_id, "type": "m.login.email.identity", "threepid_creds": {"sid": "blabla", "client_secret": "blablabla"}, }, }, ) self.assertEqual(channel.json_body["user_id"], "@alice:test") # Check that a bind attempt was made to our fake identity server post_json_get_json.assert_called_with( "https://is.example.com/_matrix/identity/internal/bind", {"address": "*****@*****.**", "medium": "email", "mxid": "@alice:test"}, ) # Check that we stored a mapping of this bind bound_threepids = self.get_success( self.store.user_get_bound_threepids("@alice:test") ) self.assertListEqual(bound_threepids, [{"medium": "email", "address": email}])
def test_maybe_send_server_notice_to_user_not_in_mau_cohort(self): """ Test when user is not part of the MAU cohort - this should not ever happen - but ... """ self._rlsn._auth_blocking.check_auth_blocking = Mock( return_value=make_awaitable(None)) self._rlsn._store.user_last_seen_monthly_active = Mock( return_value=make_awaitable(None)) self.get_success( self._rlsn.maybe_send_server_notice_to_user(self.user_id)) self._send_notice.assert_not_called()
def test_auto_create_auto_join_rooms_when_user_is_the_first_real_user(self): room_alias_str = "#room:test" self.store.count_real_users = Mock(return_value=make_awaitable(1)) self.store.is_real_user = Mock(return_value=make_awaitable(True)) user_id = self.get_success(self.handler.register_user(localpart="real")) rooms = self.get_success(self.store.get_rooms_for_user(user_id)) directory_handler = self.hs.get_directory_handler() room_alias = RoomAlias.from_string(room_alias_str) room_id = self.get_success(directory_handler.get_association(room_alias)) self.assertTrue(room_id["room_id"] in rooms) self.assertEqual(len(rooms), 1)
def test_populate_monthly_users_should_not_update(self): self.store.upsert_monthly_active_user = Mock( return_value=make_awaitable(None)) # type: ignore[assignment] self.store.is_trial_user = Mock( return_value=make_awaitable(False)) # type: ignore[assignment] self.store.user_last_seen_monthly_active = Mock( return_value=make_awaitable(self.hs.get_clock().time_msec())) d = self.store.populate_monthly_active_users("user_id") self.get_success(d) self.store.upsert_monthly_active_user.assert_not_called()
def test_get_or_create_user_mau_blocked(self): self.store.get_monthly_active_count = Mock( return_value=make_awaitable(self.lots_of_users)) self.get_failure( self.get_or_create_user(self.requester, "b", "display_name"), ResourceLimitError, ) self.store.get_monthly_active_count = Mock( return_value=make_awaitable(self.hs.config.server.max_mau_value)) self.get_failure( self.get_or_create_user(self.requester, "b", "display_name"), ResourceLimitError, )
def test_maybe_send_server_notice_to_user_remove_blocked_notice(self): """Test when user has blocked notice, but should have it removed""" self._rlsn._auth_blocking.check_auth_blocking = Mock( return_value=make_awaitable(None)) mock_event = Mock(type=EventTypes.Message, content={"msgtype": ServerNoticeMsgType}) self._rlsn._store.get_events = Mock( return_value=make_awaitable({"123": mock_event})) self.get_success( self._rlsn.maybe_send_server_notice_to_user(self.user_id)) # Would be better to check the content, but once == remove blocking event self._rlsn._server_notices_manager.maybe_get_notice_room_for_user.assert_called_once( ) self._send_notice.assert_called_once()
def test_mau_limits_not_exceeded(self): self.auth_blocking._limit_usage_by_mau = True self.hs.get_datastore().get_monthly_active_count = Mock( return_value=make_awaitable(self.small_number_of_users)) # Ensure does not raise exception self.get_success( self.auth_handler.get_access_token_for_user_id( "user_a", device_id=None, valid_until_ms=None)) self.hs.get_datastore().get_monthly_active_count = Mock( return_value=make_awaitable(self.small_number_of_users)) self.get_success( self.auth_handler.validate_short_term_login_token( self._get_macaroon().serialize()))
def test_send_receipts(self): mock_send_transaction = ( self.hs.get_federation_transport_client().send_transaction) mock_send_transaction.return_value = make_awaitable({}) sender = self.hs.get_federation_sender() receipt = ReadReceipt("room_id", "m.read", "user_id", ["event_id"], {"ts": 1234}) self.successResultOf( defer.ensureDeferred(sender.send_read_receipt(receipt))) self.pump() # expect a call to send_transaction mock_send_transaction.assert_called_once() json_cb = mock_send_transaction.call_args[0][1] data = json_cb() self.assertEqual( data["edus"], [{ "edu_type": "m.receipt", "content": { "room_id": { "m.read": { "user_id": { "event_ids": ["event_id"], "data": { "ts": 1234 }, } } } }, }], )
def test_get_3pe_protocols_multiple_protocol(self): service_one = self._mkservice(False, ["my-protocol"]) service_two = self._mkservice(False, ["other-protocol"]) self.mock_store.get_app_services.return_value = [ service_one, service_two ] self.mock_as_api.get_3pe_protocol.return_value = make_awaitable({ "x-protocol-data": 42, "instances": [] }) response = self.successResultOf( defer.ensureDeferred(self.handler.get_3pe_protocols())) self.mock_as_api.get_3pe_protocol.assert_called() self.assertEqual( response, { "my-protocol": { "x-protocol-data": 42, "instances": [] }, "other-protocol": { "x-protocol-data": 42, "instances": [] }, }, )
def test_complexity_simple(self): u1 = self.register_user("u1", "pass") u1_token = self.login("u1", "pass") room_1 = self.helper.create_room_as(u1, tok=u1_token) self.helper.send_state( room_1, event_type="m.room.topic", body={"topic": "foo"}, tok=u1_token ) # Get the room complexity channel = self.make_request( "GET", "/_matrix/federation/unstable/rooms/%s/complexity" % (room_1,) ) self.assertEquals(200, channel.code) complexity = channel.json_body["v1"] self.assertTrue(complexity > 0, complexity) # Artificially raise the complexity store = self.hs.get_datastore() store.get_current_state_event_counts = lambda x: make_awaitable(500 * 1.23) # Get the room complexity again -- make sure it's our artificial value channel = self.make_request( "GET", "/_matrix/federation/unstable/rooms/%s/complexity" % (room_1,) ) self.assertEquals(200, channel.code) complexity = channel.json_body["v1"] self.assertEqual(complexity, 1.23)
def test_send_event_single_sender(self): """Test that using a single federation sender worker correctly sends a new event. """ mock_client = Mock(spec=["put_json"]) mock_client.put_json.return_value = make_awaitable({}) self.make_worker_hs( "synapse.app.federation_sender", {"send_federation": False}, federation_http_client=mock_client, ) user = self.register_user("user", "pass") token = self.login("user", "pass") room = self.create_room_with_remote_server(user, token) mock_client.put_json.reset_mock() self.create_and_send_event(room, UserID.from_string(user)) self.replicate() # Assert that the event was sent out over federation. mock_client.put_json.assert_called() self.assertEqual(mock_client.put_json.call_args[0][0], "other_server") self.assertTrue(mock_client.put_json.call_args[1]["data"].get("pdus"))
def test_retry_device_list_resync(self): """Tests that device lists are marked as stale if they couldn't be synced, and that stale device lists are retried periodically. """ remote_user_id = "@john:test_remote" remote_origin = "test_remote" # Track the number of attempts to resync the user's device list. self.resync_attempts = 0 # When this function is called, increment the number of resync attempts (only if # we're querying devices for the right user ID), then raise a # NotRetryingDestination error to fail the resync gracefully. def query_user_devices(destination, user_id): if user_id == remote_user_id: self.resync_attempts += 1 raise NotRetryingDestination(0, 0, destination) # Register the mock on the federation client. federation_client = self.homeserver.get_federation_client() federation_client.query_user_devices = Mock( side_effect=query_user_devices) # Register a mock on the store so that the incoming update doesn't fail because # we don't share a room with the user. store = self.homeserver.get_datastore() store.get_rooms_for_user = Mock( return_value=make_awaitable(["!someroom:test"])) # Manually inject a fake device list update. We need this update to include at # least one prev_id so that the user's device list will need to be retried. device_list_updater = self.homeserver.get_device_handler( ).device_list_updater self.get_success( device_list_updater.incoming_device_list_update( origin=remote_origin, edu_content={ "deleted": False, "device_display_name": "Mobile", "device_id": "QBUAZIFURK", "prev_id": [5], "stream_id": 6, "user_id": remote_user_id, }, )) # Check that there was one resync attempt. self.assertEqual(self.resync_attempts, 1) # Check that the resync attempt failed and caused the user's device list to be # marked as stale. need_resync = self.get_success( store.get_user_ids_requiring_device_list_resync()) self.assertIn(remote_user_id, need_resync) # Check that waiting for 30 seconds caused Synapse to retry resyncing the device # list. self.reactor.advance(30) self.assertEqual(self.resync_attempts, 2)
def _mkservice(self, is_interested, protocols=None): service = Mock() service.is_interested.return_value = make_awaitable(is_interested) service.token = "mock_service_token" service.url = "mock_service_url" service.protocols = protocols return service
def test_query_user_exists_unknown_user(self): user_id = "@someone:anywhere" services = [self._mkservice(is_interested=True)] services[0].is_interested_in_user.return_value = True self.mock_store.get_app_services.return_value = services self.mock_store.get_user_by_id.return_value = make_awaitable(None) event = Mock(sender=user_id, type="m.room.message", room_id="!foo:bar") self.mock_as_api.query_user.return_value = make_awaitable(True) self.mock_store.get_new_events_for_appservice.side_effect = [ make_awaitable((0, [event])), ] self.handler.notify_interested_services(RoomStreamToken(None, 0)) self.mock_as_api.query_user.assert_called_once_with(services[0], user_id)
def local_user_fallback_ui_auth_test_body(self): """rejected login should fall back to local db""" self.register_user("localuser", "localpass") # have the auth provider deny the request mock_password_provider.check_password.return_value = make_awaitable( False) # log in twice, to get two devices tok1 = self.login("localuser", "localpass") self.login("localuser", "localpass", device_id="dev2") mock_password_provider.check_password.reset_mock() # first delete should give a 401 session = self._start_delete_device_session(tok1, "dev2") mock_password_provider.check_password.assert_not_called() # Wrong password channel = self._authed_delete_device(tok1, "dev2", session, "localuser", "xxx") self.assertEqual(channel.code, 401) # XXX why not a 403? self.assertEqual(channel.json_body["errcode"], "M_FORBIDDEN") mock_password_provider.check_password.assert_called_once_with( "@localuser:test", "xxx") mock_password_provider.reset_mock() # Right password channel = self._authed_delete_device(tok1, "dev2", session, "localuser", "localpass") self.assertEqual(channel.code, 200) mock_password_provider.check_password.assert_called_once_with( "@localuser:test", "localpass")
def password_only_auth_provider_login_test_body(self): # login flows should only have m.login.password flows = self._get_login_flows() self.assertEqual(flows, [{ "type": "m.login.password" }] + ADDITIONAL_LOGIN_FLOWS) # check_password must return an awaitable mock_password_provider.check_password.return_value = make_awaitable( True) channel = self._send_password_login("u", "p") self.assertEqual(channel.code, 200, channel.result) self.assertEqual("@u:test", channel.json_body["user_id"]) mock_password_provider.check_password.assert_called_once_with( "@u:test", "p") mock_password_provider.reset_mock() # login with mxid should work too channel = self._send_password_login("@u:bz", "p") self.assertEqual(channel.code, 200, channel.result) self.assertEqual("@u:bz", channel.json_body["user_id"]) mock_password_provider.check_password.assert_called_once_with( "@u:bz", "p") mock_password_provider.reset_mock() # try a weird username / pass. Honestly it's unclear what we *expect* to happen # in these cases, but at least we can guard against the API changing # unexpectedly channel = self._send_password_login(" USER🙂NAME ", " pASS\U0001F622word ") self.assertEqual(channel.code, 200, channel.result) self.assertEqual("@ USER🙂NAME :test", channel.json_body["user_id"]) mock_password_provider.check_password.assert_called_once_with( "@ USER🙂NAME :test", " pASS😢word ")
def test_single_service_up_txn_not_sent(self): # Test: The AS is up and the txn is not sent. A Recoverer is made and # started. service = Mock() events = [Mock(), Mock()] txn_id = "foobar" txn = Mock(id=txn_id, service=service, events=events) # mock methods self.store.get_appservice_state = Mock( return_value=defer.succeed(ApplicationServiceState.UP) ) self.store.set_appservice_state = Mock(return_value=defer.succeed(True)) txn.send = Mock(return_value=make_awaitable(False)) # fails to send self.store.create_appservice_txn = Mock(return_value=defer.succeed(txn)) # actual call self.successResultOf(defer.ensureDeferred(self.txnctrl.send(service, events))) self.store.create_appservice_txn.assert_called_once_with( service=service, events=events, ephemeral=[] ) self.assertEquals(1, self.recoverer_fn.call_count) # recoverer made self.assertEquals(1, self.recoverer.recover.call_count) # and invoked self.assertEquals(1, len(self.txnctrl.recoverers)) # and stored self.assertEquals(0, txn.complete.call_count) # txn not completed self.store.set_appservice_state.assert_called_once_with( service, ApplicationServiceState.DOWN # service marked as down )