diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/federation/test_federation.py | 18 | ||||
-rw-r--r-- | tests/handlers/test_presence.py | 436 | ||||
-rw-r--r-- | tests/rest/test_events.py | 16 | ||||
-rw-r--r-- | tests/rest/test_presence.py | 166 | ||||
-rw-r--r-- | tests/rest/test_profile.py | 20 | ||||
-rw-r--r-- | tests/rest/test_rooms.py | 196 | ||||
-rw-r--r-- | tests/rest/utils.py | 14 | ||||
-rw-r--r-- | tests/utils.py | 43 |
8 files changed, 570 insertions, 339 deletions
diff --git a/tests/federation/test_federation.py b/tests/federation/test_federation.py index 478ddd879e..58590e4fcd 100644 --- a/tests/federation/test_federation.py +++ b/tests/federation/test_federation.py @@ -20,7 +20,7 @@ from twisted.trial import unittest from mock import Mock import logging -from ..utils import MockHttpServer, MockClock +from ..utils import MockHttpResource, MockClock from synapse.server import HomeServer from synapse.federation import initialize_http_replication @@ -50,7 +50,7 @@ def make_pdu(prev_pdus=[], **kwargs): class FederationTestCase(unittest.TestCase): def setUp(self): - self.mock_http_server = MockHttpServer() + self.mock_resource = MockHttpResource() self.mock_http_client = Mock(spec=[ "get_json", "put_json", @@ -70,7 +70,7 @@ class FederationTestCase(unittest.TestCase): ) self.clock = MockClock() hs = HomeServer("test", - resource_for_federation=self.mock_http_server, + resource_for_federation=self.mock_resource, http_client=self.mock_http_client, db_pool=None, datastore=self.mock_persistence, @@ -86,7 +86,7 @@ class FederationTestCase(unittest.TestCase): ) # Empty context initially - (code, response) = yield self.mock_http_server.trigger("GET", + (code, response) = yield self.mock_resource.trigger("GET", "/matrix/federation/v1/state/my-context/", None) self.assertEquals(200, code) self.assertFalse(response["pdus"]) @@ -111,7 +111,7 @@ class FederationTestCase(unittest.TestCase): ]) ) - (code, response) = yield self.mock_http_server.trigger("GET", + (code, response) = yield self.mock_resource.trigger("GET", "/matrix/federation/v1/state/my-context/", None) self.assertEquals(200, code) self.assertEquals(1, len(response["pdus"])) @@ -122,7 +122,7 @@ class FederationTestCase(unittest.TestCase): defer.succeed(None) ) - (code, response) = yield self.mock_http_server.trigger("GET", + (code, response) = yield self.mock_resource.trigger("GET", "/matrix/federation/v1/pdu/red/abc123def456/", None) self.assertEquals(404, code) @@ -141,7 +141,7 @@ class FederationTestCase(unittest.TestCase): ) ) - (code, response) = yield self.mock_http_server.trigger("GET", + (code, response) = yield self.mock_resource.trigger("GET", "/matrix/federation/v1/pdu/red/abc123def456/", None) self.assertEquals(200, code) self.assertEquals(1, len(response["pdus"])) @@ -225,7 +225,7 @@ class FederationTestCase(unittest.TestCase): self.federation.register_edu_handler("m.test", recv_observer) - yield self.mock_http_server.trigger("PUT", + yield self.mock_resource.trigger("PUT", "/matrix/federation/v1/send/1001000/", """{ "origin": "remote", @@ -272,7 +272,7 @@ class FederationTestCase(unittest.TestCase): self.federation.register_query_handler("a-question", recv_handler) - code, response = yield self.mock_http_server.trigger("GET", + code, response = yield self.mock_resource.trigger("GET", "/matrix/federation/v1/query/a-question?three=3&four=4", None) self.assertEquals(200, code) diff --git a/tests/handlers/test_presence.py b/tests/handlers/test_presence.py index 86bd8bb3f2..8b88c49a0b 100644 --- a/tests/handlers/test_presence.py +++ b/tests/handlers/test_presence.py @@ -19,8 +19,9 @@ from twisted.internet import defer from mock import Mock, call, ANY import logging +import json -from ..utils import MockClock +from ..utils import MockHttpResource, MockClock, DeferredMockCallable from synapse.server import HomeServer from synapse.api.constants import PresenceState @@ -34,17 +35,27 @@ ONLINE = PresenceState.ONLINE logging.getLogger().addHandler(logging.NullHandler()) +#logging.getLogger().addHandler(logging.StreamHandler()) +#logging.getLogger().setLevel(logging.DEBUG) + + +def _expect_edu(destination, edu_type, content, origin="test"): + return { + "origin": origin, + "ts": 1000000, + "pdus": [], + "edus": [ + { + "origin": origin, + "destination": destination, + "edu_type": edu_type, + "content": content, + } + ], + } - -class MockReplication(object): - def __init__(self): - self.edu_handlers = {} - - def register_edu_handler(self, edu_type, handler): - self.edu_handlers[edu_type] = handler - - def received_edu(self, origin, edu_type, content): - self.edu_handlers[edu_type](origin, content) +def _make_edu_json(origin, edu_type, content): + return json.dumps(_expect_edu("test", edu_type, content, origin=origin)) class JustPresenceHandlers(object): @@ -209,10 +220,13 @@ class PresenceInvitesTestCase(unittest.TestCase): """ Tests presence management. """ def setUp(self): - self.replication = MockReplication() - self.replication.send_edu = Mock() + self.mock_http_client = Mock(spec=[]) + self.mock_http_client.put_json = DeferredMockCallable() + + self.mock_federation_resource = MockHttpResource() hs = HomeServer("test", + clock=MockClock(), db_pool=None, datastore=Mock(spec=[ "has_presence_state", @@ -221,11 +235,17 @@ class PresenceInvitesTestCase(unittest.TestCase): "set_presence_list_accepted", "get_presence_list", "del_presence_list", + + # Bits that Federation needs + "prep_send_transaction", + "delivered_txn", + "get_received_txn_response", + "set_received_txn_response", ]), handlers=None, resource_for_client=Mock(), - http_client=None, - replication_layer=self.replication + resource_for_federation=self.mock_federation_resource, + http_client=self.mock_http_client, ) hs.handlers = JustPresenceHandlers(hs) @@ -236,6 +256,10 @@ class PresenceInvitesTestCase(unittest.TestCase): user_localpart in ("apple", "banana")) self.datastore.has_presence_state = has_presence_state + def get_received_txn_response(*args): + return defer.succeed(None) + self.datastore.get_received_txn_response = get_received_txn_response + # Some local users to test with self.u_apple = hs.parse_userid("@apple:test") self.u_banana = hs.parse_userid("@banana:test") @@ -283,7 +307,19 @@ class PresenceInvitesTestCase(unittest.TestCase): @defer.inlineCallbacks def test_invite_remote(self): - self.replication.send_edu.return_value = defer.succeed((200, "OK")) + put_json = self.mock_http_client.put_json + put_json.expect_call_and_return( + call("elsewhere", + path="/matrix/federation/v1/send/1000000/", + data=_expect_edu("elsewhere", "m.presence_invite", + content={ + "observer_user": "@apple:test", + "observed_user": "@cabbage:elsewhere", + } + ) + ), + defer.succeed((200, "OK")) + ) yield self.handler.send_invite( observer_user=self.u_apple, observed_user=self.u_cabbage) @@ -291,67 +327,79 @@ class PresenceInvitesTestCase(unittest.TestCase): self.datastore.add_presence_list_pending.assert_called_with( "apple", "@cabbage:elsewhere") - self.replication.send_edu.assert_called_with( - destination="elsewhere", - edu_type="m.presence_invite", - content={ - "observer_user": "@apple:test", - "observed_user": "@cabbage:elsewhere", - } - ) + yield put_json.await_calls() @defer.inlineCallbacks def test_accept_remote(self): # TODO(paul): This test will likely break if/when real auth permissions # are added; for now the HS will always accept any invite - self.replication.send_edu.return_value = defer.succeed((200, "OK")) + put_json = self.mock_http_client.put_json + put_json.expect_call_and_return( + call("elsewhere", + path="/matrix/federation/v1/send/1000000/", + data=_expect_edu("elsewhere", "m.presence_accept", + content={ + "observer_user": "@cabbage:elsewhere", + "observed_user": "@apple:test", + } + ) + ), + defer.succeed((200, "OK")) + ) - yield self.replication.received_edu( - "elsewhere", "m.presence_invite", { + yield self.mock_federation_resource.trigger("PUT", + "/matrix/federation/v1/send/1000000/", + _make_edu_json("elsewhere", "m.presence_invite", + content={ "observer_user": "@cabbage:elsewhere", "observed_user": "@apple:test", } + ) ) self.datastore.allow_presence_visible.assert_called_with( "apple", "@cabbage:elsewhere") - self.replication.send_edu.assert_called_with( - destination="elsewhere", - edu_type="m.presence_accept", - content={ - "observer_user": "@cabbage:elsewhere", - "observed_user": "@apple:test", - } - ) + yield put_json.await_calls() @defer.inlineCallbacks def test_invited_remote_nonexistant(self): - self.replication.send_edu.return_value = defer.succeed((200, "OK")) - - yield self.replication.received_edu( - "elsewhere", "m.presence_invite", { - "observer_user": "@cabbage:elsewhere", - "observed_user": "@durian:test", - } + put_json = self.mock_http_client.put_json + put_json.expect_call_and_return( + call("elsewhere", + path="/matrix/federation/v1/send/1000000/", + data=_expect_edu("elsewhere", "m.presence_deny", + content={ + "observer_user": "@cabbage:elsewhere", + "observed_user": "@durian:test", + } + ) + ), + defer.succeed((200, "OK")) ) - self.replication.send_edu.assert_called_with( - destination="elsewhere", - edu_type="m.presence_deny", + yield self.mock_federation_resource.trigger("PUT", + "/matrix/federation/v1/send/1000000/", + _make_edu_json("elsewhere", "m.presence_invite", content={ "observer_user": "@cabbage:elsewhere", "observed_user": "@durian:test", } + ) ) + yield put_json.await_calls() + @defer.inlineCallbacks def test_accepted_remote(self): - yield self.replication.received_edu( - "elsewhere", "m.presence_accept", { + yield self.mock_federation_resource.trigger("PUT", + "/matrix/federation/v1/send/1000000/", + _make_edu_json("elsewhere", "m.presence_accept", + content={ "observer_user": "@apple:test", "observed_user": "@cabbage:elsewhere", } + ) ) self.datastore.set_presence_list_accepted.assert_called_with( @@ -362,11 +410,14 @@ class PresenceInvitesTestCase(unittest.TestCase): @defer.inlineCallbacks def test_denied_remote(self): - yield self.replication.received_edu( - "elsewhere", "m.presence_deny", { + yield self.mock_federation_resource.trigger("PUT", + "/matrix/federation/v1/send/1000000/", + _make_edu_json("elsewhere", "m.presence_deny", + content={ "observer_user": "@apple:test", "observed_user": "@eggplant:elsewhere", } + ) ) self.datastore.del_presence_list.assert_called_with( @@ -384,6 +435,14 @@ class PresenceInvitesTestCase(unittest.TestCase): self.u_apple, target_user=self.u_banana) @defer.inlineCallbacks + def test_drop_remote(self): + yield self.handler.drop( + observer_user=self.u_apple, observed_user=self.u_cabbage) + + self.datastore.del_presence_list.assert_called_with( + "apple", "@cabbage:elsewhere") + + @defer.inlineCallbacks def test_get_presence_list(self): self.datastore.get_presence_list.return_value = defer.succeed( [{"observed_user_id": "@banana:test"}] @@ -424,22 +483,29 @@ class PresencePushTestCase(unittest.TestCase): BE WARNED... """ def setUp(self): - self.replication = MockReplication() - self.replication.send_edu = Mock() - self.replication.send_edu.return_value = defer.succeed((200, "OK")) - self.clock = MockClock() + self.mock_http_client = Mock(spec=[]) + self.mock_http_client.put_json = DeferredMockCallable() + + self.mock_federation_resource = MockHttpResource() + hs = HomeServer("test", clock=self.clock, db_pool=None, datastore=Mock(spec=[ "set_presence_state", + + # Bits that Federation needs + "prep_send_transaction", + "delivered_txn", + "get_received_txn_response", + "set_received_txn_response", ]), handlers=None, resource_for_client=Mock(), - http_client=None, - replication_layer=self.replication, + resource_for_federation=self.mock_federation_resource, + http_client=self.mock_http_client, ) hs.handlers = JustPresenceHandlers(hs) @@ -447,6 +513,11 @@ class PresencePushTestCase(unittest.TestCase): self.mock_update_client.return_value = defer.succeed(None) self.datastore = hs.get_datastore() + + def get_received_txn_response(*args): + return defer.succeed(None) + self.datastore.get_received_txn_response = get_received_txn_response + self.handler = hs.get_handlers().presence_handler self.handler.push_update_to_clients = self.mock_update_client @@ -585,41 +656,54 @@ class PresencePushTestCase(unittest.TestCase): @defer.inlineCallbacks def test_push_remote(self): - self.room_members = [self.u_apple, self.u_onion] - - self.datastore.set_presence_state.return_value = defer.succeed( - {"state": ONLINE}) - - # TODO(paul): Gut-wrenching - self.handler._user_cachemap[self.u_apple] = UserPresenceCache() - apple_set = self.handler._remote_sendmap.setdefault("apple", set()) - apple_set.add(self.u_potato.domain) - - yield self.handler.set_state(self.u_apple, self.u_apple, - {"state": ONLINE}) - - self.replication.send_edu.assert_has_calls([ - call( - destination="remote", - edu_type="m.presence", + put_json = self.mock_http_client.put_json + put_json.expect_call_and_return( + call("remote", + path=ANY, # Can't guarantee which txn ID will be which + data=_expect_edu("remote", "m.presence", content={ "push": [ {"user_id": "@apple:test", "state": "online", "mtime_age": 0}, ], - }), - call( - destination="farm", - edu_type="m.presence", + } + ) + ), + defer.succeed((200, "OK")) + ) + put_json.expect_call_and_return( + call("farm", + path=ANY, # Can't guarantee which txn ID will be which + data=_expect_edu("farm", "m.presence", content={ "push": [ {"user_id": "@apple:test", "state": "online", "mtime_age": 0}, ], - }) - ], any_order=True) + } + ) + ), + defer.succeed((200, "OK")) + ) + + self.room_members = [self.u_apple, self.u_onion] + + self.datastore.set_presence_state.return_value = defer.succeed( + {"state": ONLINE} + ) + + # TODO(paul): Gut-wrenching + self.handler._user_cachemap[self.u_apple] = UserPresenceCache() + apple_set = self.handler._remote_sendmap.setdefault("apple", set()) + apple_set.add(self.u_potato.domain) + + yield self.handler.set_state(self.u_apple, self.u_apple, + {"state": ONLINE} + ) + + yield put_json.await_calls() @defer.inlineCallbacks def test_recv_remote(self): @@ -630,14 +714,17 @@ class PresencePushTestCase(unittest.TestCase): self.room_members = [self.u_banana, self.u_potato] - yield self.replication.received_edu( - "remote", "m.presence", { + yield self.mock_federation_resource.trigger("PUT", + "/matrix/federation/v1/send/1000000/", + _make_edu_json("elsewhere", "m.presence", + content={ "push": [ {"user_id": "@potato:remote", "state": "online", "mtime_age": 1000}, ], } + ) ) self.mock_update_client.assert_has_calls([ @@ -683,6 +770,35 @@ class PresencePushTestCase(unittest.TestCase): @defer.inlineCallbacks def test_join_room_remote(self): ## Sending local user state to a newly-joined remote user + put_json = self.mock_http_client.put_json + put_json.expect_call_and_return( + call("remote", + path=ANY, # Can't guarantee which txn ID will be which + data=_expect_edu("remote", "m.presence", + content={ + "push": [ + {"user_id": "@apple:test", + "state": "online"}, + ], + } + ), + ), + defer.succeed((200, "OK")) + ) + put_json.expect_call_and_return( + call("remote", + path=ANY, # Can't guarantee which txn ID will be which + data=_expect_edu("remote", "m.presence", + content={ + "push": [ + {"user_id": "@banana:test", + "state": "offline"}, + ], + } + ), + ), + defer.succeed((200, "OK")) + ) # TODO(paul): Gut-wrenching self.handler._user_cachemap[self.u_apple] = UserPresenceCache() @@ -694,30 +810,24 @@ class PresencePushTestCase(unittest.TestCase): "a-room" ) - self.replication.send_edu.assert_has_calls([ - call( - destination="remote", - edu_type="m.presence", + yield put_json.await_calls() + + ## Sending newly-joined local user state to remote users + + put_json.expect_call_and_return( + call("remote", + path="/matrix/federation/v1/send/1000002/", + data=_expect_edu("remote", "m.presence", content={ "push": [ - {"user_id": "@apple:test", + {"user_id": "@clementine:test", "state": "online"}, ], - }), - call( - destination="remote", - edu_type="m.presence", - content={ - "push": [ - {"user_id": "@banana:test", - "state": "offline"}, - ], - }), - ], any_order=True) - - self.replication.send_edu.reset_mock() - - ## Sending newly-joined local user state to remote users + } + ), + ), + defer.succeed((200, "OK")) + ) self.handler._user_cachemap[self.u_clementine] = UserPresenceCache() self.handler._user_cachemap[self.u_clementine].update( @@ -728,17 +838,7 @@ class PresencePushTestCase(unittest.TestCase): "a-room" ) - self.replication.send_edu.assert_has_calls( - call( - destination="remote", - edu_type="m.presence", - content={ - "push": [ - {"user_id": "@clementine:test", - "state": "online"}, - ], - }), - ) + put_json.await_calls() class PresencePollingTestCase(unittest.TestCase): @@ -755,21 +855,34 @@ class PresencePollingTestCase(unittest.TestCase): def setUp(self): - self.replication = MockReplication() - self.replication.send_edu = Mock() + self.mock_http_client = Mock(spec=[]) + self.mock_http_client.put_json = DeferredMockCallable() + + self.mock_federation_resource = MockHttpResource() hs = HomeServer("test", + clock=MockClock(), db_pool=None, - datastore=Mock(spec=[]), + datastore=Mock(spec=[ + # Bits that Federation needs + "prep_send_transaction", + "delivered_txn", + "get_received_txn_response", + "set_received_txn_response", + ]), handlers=None, resource_for_client=Mock(), - http_client=None, - replication_layer=self.replication, + resource_for_federation=self.mock_federation_resource, + http_client=self.mock_http_client, ) hs.handlers = JustPresenceHandlers(hs) self.datastore = hs.get_datastore() + def get_received_txn_response(*args): + return defer.succeed(None) + self.datastore.get_received_txn_response = get_received_txn_response + self.mock_update_client = Mock() self.mock_update_client.return_value = defer.succeed(None) @@ -827,8 +940,9 @@ class PresencePollingTestCase(unittest.TestCase): def test_push_local(self): # apple goes online yield self.handler.set_state( - target_user=self.u_apple, auth_user=self.u_apple, - state={"state": ONLINE}) + target_user=self.u_apple, auth_user=self.u_apple, + state={"state": ONLINE} + ) # apple should see both banana and clementine currently offline self.mock_update_client.assert_has_calls([ @@ -885,68 +999,92 @@ class PresencePollingTestCase(unittest.TestCase): @defer.inlineCallbacks def test_remote_poll_send(self): + put_json = self.mock_http_client.put_json + put_json.expect_call_and_return( + call("remote", + path="/matrix/federation/v1/send/1000000/", + data=_expect_edu("remote", "m.presence", + content={ + "poll": [ "@potato:remote" ], + }, + ), + ), + defer.succeed((200, "OK")) + ) + # clementine goes online yield self.handler.set_state( target_user=self.u_clementine, auth_user=self.u_clementine, state={"state": ONLINE}) - self.replication.send_edu.assert_called_with( - destination="remote", - edu_type="m.presence", - content={ - "poll": [ "@potato:remote" ], - }, - ) + yield put_json.await_calls() # Gut-wrenching tests self.assertTrue(self.u_potato in self.handler._remote_recvmap) self.assertTrue(self.u_clementine in self.handler._remote_recvmap[self.u_potato]) - self.replication.send_edu.reset_mock() + put_json.expect_call_and_return( + call("remote", + path="/matrix/federation/v1/send/1000001/", + data=_expect_edu("remote", "m.presence", + content={ + "unpoll": [ "@potato:remote" ], + }, + ), + ), + defer.succeed((200, "OK")) + ) # clementine goes offline yield self.handler.set_state( target_user=self.u_clementine, auth_user=self.u_clementine, state={"state": OFFLINE}) - self.replication.send_edu.assert_called_with( - destination="remote", - edu_type="m.presence", - content={ - "unpoll": [ "@potato:remote" ], - }, - ) + put_json.await_calls() self.assertFalse(self.u_potato in self.handler._remote_recvmap) @defer.inlineCallbacks def test_remote_poll_receive(self): - yield self.replication.received_edu( - "remote", "m.presence", { + put_json = self.mock_http_client.put_json + put_json.expect_call_and_return( + call("remote", + path="/matrix/federation/v1/send/1000000/", + data=_expect_edu("remote", "m.presence", + content={ + "push": [ + {"user_id": "@banana:test", + "state": "offline", + "status_msg": None}, + ], + }, + ), + ), + defer.succeed((200, "OK")) + ) + + yield self.mock_federation_resource.trigger("PUT", + "/matrix/federation/v1/send/1000000/", + _make_edu_json("remote", "m.presence", + content={ "poll": [ "@banana:test" ], - } + }, + ) ) + yield put_json.await_calls() + # Gut-wrenching tests self.assertTrue(self.u_banana in self.handler._remote_sendmap) - self.replication.send_edu.assert_called_with( - destination="remote", - edu_type="m.presence", + yield self.mock_federation_resource.trigger("PUT", + "/matrix/federation/v1/send/1000001/", + _make_edu_json("remote", "m.presence", content={ - "push": [ - {"user_id": "@banana:test", - "state": "offline", - "status_msg": None}, - ], - }, - ) - - yield self.replication.received_edu( - "remote", "m.presence", { "unpoll": [ "@banana:test" ], } + ) ) # Gut-wrenching tests diff --git a/tests/rest/test_events.py b/tests/rest/test_events.py index e1b3cb4ddf..1ab92395f2 100644 --- a/tests/rest/test_events.py +++ b/tests/rest/test_events.py @@ -29,7 +29,7 @@ from synapse.server import HomeServer import json import logging -from ..utils import MockHttpServer, MemoryDataStore +from ..utils import MockHttpResource, MemoryDataStore from .utils import RestTestCase from mock import Mock @@ -116,7 +116,7 @@ class EventStreamPermissionsTestCase(RestTestCase): @defer.inlineCallbacks def setUp(self): - self.mock_server = MockHttpServer(prefix=PATH_PREFIX) + self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) state_handler = Mock(spec=["handle_new_event"]) state_handler.handle_new_event.return_value = True @@ -142,9 +142,9 @@ class EventStreamPermissionsTestCase(RestTestCase): hs.get_clock().time_msec.return_value = 1000000 hs.datastore = MemoryDataStore() - synapse.rest.register.register_servlets(hs, self.mock_server) - synapse.rest.events.register_servlets(hs, self.mock_server) - synapse.rest.room.register_servlets(hs, self.mock_server) + synapse.rest.register.register_servlets(hs, self.mock_resource) + synapse.rest.events.register_servlets(hs, self.mock_resource) + synapse.rest.room.register_servlets(hs, self.mock_resource) # register an account self.user_id = "sid1" @@ -164,12 +164,12 @@ class EventStreamPermissionsTestCase(RestTestCase): @defer.inlineCallbacks def test_stream_basic_permissions(self): # invalid token, expect 403 - (code, response) = yield self.mock_server.trigger_get( + (code, response) = yield self.mock_resource.trigger_get( "/events?access_token=%s" % ("invalid" + self.token)) self.assertEquals(403, code, msg=str(response)) # valid token, expect content - (code, response) = yield self.mock_server.trigger_get( + (code, response) = yield self.mock_resource.trigger_get( "/events?access_token=%s&timeout=0" % (self.token)) self.assertEquals(200, code, msg=str(response)) self.assertTrue("chunk" in response) @@ -186,7 +186,7 @@ class EventStreamPermissionsTestCase(RestTestCase): # invited to room (expect no content for room) yield self.invite(room_id, src=self.other_user, targ=self.user_id, tok=self.other_token) - (code, response) = yield self.mock_server.trigger_get( + (code, response) = yield self.mock_resource.trigger_get( "/events?access_token=%s&timeout=0" % (self.token)) self.assertEquals(200, code, msg=str(response)) diff --git a/tests/rest/test_presence.py b/tests/rest/test_presence.py index 99287823e4..80b5972b4b 100644 --- a/tests/rest/test_presence.py +++ b/tests/rest/test_presence.py @@ -21,9 +21,10 @@ from twisted.internet import defer from mock import Mock import logging -from ..utils import MockHttpServer +from ..utils import MockHttpResource from synapse.api.constants import PresenceState +from synapse.handlers.presence import PresenceHandler from synapse.server import HomeServer @@ -39,29 +40,49 @@ myid = "@apple:test" PATH_PREFIX = "/matrix/client/api/v1" +class JustPresenceHandlers(object): + def __init__(self, hs): + self.presence_handler = PresenceHandler(hs) + + class PresenceStateTestCase(unittest.TestCase): def setUp(self): - self.mock_server = MockHttpServer(prefix=PATH_PREFIX) - self.mock_handler = Mock(spec=[ - "get_state", - "set_state", - ]) + self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) hs = HomeServer("test", db_pool=None, + datastore=Mock(spec=[ + "get_presence_state", + "set_presence_state", + ]), http_client=None, datastore=None, - resource_for_client=self.mock_server, - resource_for_federation=self.mock_server, + resource_for_client=self.mock_resource, + resource_for_federation=self.mock_resource, ) + hs.handlers = JustPresenceHandlers(hs) + + self.datastore = hs.get_datastore() + + def get_presence_list(*a, **kw): + return defer.succeed([]) + self.datastore.get_presence_list = get_presence_list def _get_user_by_token(token=None): return hs.parse_userid(myid) hs.get_auth().get_user_by_token = _get_user_by_token - hs.get_handlers().presence_handler = self.mock_handler + room_member_handler = hs.handlers.room_member_handler = Mock( + spec=[ + "get_rooms_for_user", + ] + ) + + def get_rooms_for_user(user): + return defer.succeed([]) + room_member_handler.get_rooms_for_user = get_rooms_for_user hs.register_servlets() @@ -69,58 +90,75 @@ class PresenceStateTestCase(unittest.TestCase): @defer.inlineCallbacks def test_get_my_status(self): - mocked_get = self.mock_handler.get_state + mocked_get = self.datastore.get_presence_state mocked_get.return_value = defer.succeed( - {"state": ONLINE, "status_msg": "Available"}) + {"state": ONLINE, "status_msg": "Available"} + ) - (code, response) = yield self.mock_server.trigger("GET", + (code, response) = yield self.mock_resource.trigger("GET", "/presence/%s/status" % (myid), None) self.assertEquals(200, code) self.assertEquals({"state": ONLINE, "status_msg": "Available"}, response) - mocked_get.assert_called_with(target_user=self.u_apple, - auth_user=self.u_apple) + mocked_get.assert_called_with("apple") @defer.inlineCallbacks def test_set_my_status(self): - mocked_set = self.mock_handler.set_state - mocked_set.return_value = defer.succeed(()) + mocked_set = self.datastore.set_presence_state + mocked_set.return_value = defer.succeed({"state": OFFLINE}) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", "/presence/%s/status" % (myid), '{"state": "unavailable", "status_msg": "Away"}') self.assertEquals(200, code) - mocked_set.assert_called_with(target_user=self.u_apple, - auth_user=self.u_apple, - state={"state": UNAVAILABLE, "status_msg": "Away"}) + mocked_set.assert_called_with("apple", + {"state": UNAVAILABLE, "status_msg": "Away"}) class PresenceListTestCase(unittest.TestCase): def setUp(self): - self.mock_server = MockHttpServer(prefix=PATH_PREFIX) - self.mock_handler = Mock(spec=[ - "get_presence_list", - "send_invite", - "drop", - ]) + self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) hs = HomeServer("test", db_pool=None, + datastore=Mock(spec=[ + "has_presence_state", + "get_presence_state", + "allow_presence_visible", + "is_presence_visible", + "add_presence_list_pending", + "set_presence_list_accepted", + "del_presence_list", + "get_presence_list", + ]), http_client=None, datastore=None, - resource_for_client=self.mock_server, - resource_for_federation=self.mock_server + resource_for_client=self.mock_resource, + resource_for_federation=self.mock_resource ) + hs.handlers = JustPresenceHandlers(hs) + + self.datastore = hs.get_datastore() + + def has_presence_state(user_localpart): + return defer.succeed( + user_localpart in ("apple", "banana",) + ) + self.datastore.has_presence_state = has_presence_state def _get_user_by_token(token=None): return hs.parse_userid(myid) - hs.get_auth().get_user_by_token = _get_user_by_token + room_member_handler = hs.handlers.room_member_handler = Mock( + spec=[ + "get_rooms_for_user", + ] + ) - hs.get_handlers().presence_handler = self.mock_handler + hs.get_auth().get_user_by_token = _get_user_by_token hs.register_servlets() @@ -129,52 +167,66 @@ class PresenceListTestCase(unittest.TestCase): @defer.inlineCallbacks def test_get_my_list(self): - self.mock_handler.get_presence_list.return_value = defer.succeed( - [{"observed_user": self.u_banana}] + self.datastore.get_presence_list.return_value = defer.succeed( + [{"observed_user_id": "@banana:test"}], ) - (code, response) = yield self.mock_server.trigger("GET", + (code, response) = yield self.mock_resource.trigger("GET", "/presence_list/%s" % (myid), None) self.assertEquals(200, code) - self.assertEquals([{"user_id": "@banana:test"}], response) + self.assertEquals( + [{"user_id": "@banana:test", "state": OFFLINE}], response + ) + + self.datastore.get_presence_list.assert_called_with( + "apple", accepted=True + ) @defer.inlineCallbacks def test_invite(self): - self.mock_handler.send_invite.return_value = defer.succeed(()) + self.datastore.add_presence_list_pending.return_value = ( + defer.succeed(()) + ) + self.datastore.is_presence_visible.return_value = defer.succeed( + True + ) - (code, response) = yield self.mock_server.trigger("POST", - "/presence_list/%s" % (myid), - """{ - "invite": ["@banana:test"] - }""") + (code, response) = yield self.mock_resource.trigger("POST", + "/presence_list/%s" % (myid), + """{"invite": ["@banana:test"]}""" + ) self.assertEquals(200, code) - self.mock_handler.send_invite.assert_called_with( - observer_user=self.u_apple, observed_user=self.u_banana) + self.datastore.add_presence_list_pending.assert_called_with( + "apple", "@banana:test" + ) + self.datastore.set_presence_list_accepted.assert_called_with( + "apple", "@banana:test" + ) @defer.inlineCallbacks def test_drop(self): - self.mock_handler.drop.return_value = defer.succeed(()) + self.datastore.del_presence_list.return_value = ( + defer.succeed(()) + ) - (code, response) = yield self.mock_server.trigger("POST", - "/presence_list/%s" % (myid), - """{ - "drop": ["@banana:test"] - }""") + (code, response) = yield self.mock_resource.trigger("POST", + "/presence_list/%s" % (myid), + """{"drop": ["@banana:test"]}""" + ) self.assertEquals(200, code) - self.mock_handler.drop.assert_called_with( - observer_user=self.u_apple, observed_user=self.u_banana) + self.datastore.del_presence_list.assert_called_with( + "apple", "@banana:test" + ) class PresenceEventStreamTestCase(unittest.TestCase): def setUp(self): - self.mock_server = MockHttpServer(prefix=PATH_PREFIX) - - # TODO: mocked data store + self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) # HIDEOUS HACKERY # TODO(paul): This should be injected in via the HomeServer DI system @@ -187,8 +239,8 @@ class PresenceEventStreamTestCase(unittest.TestCase): hs = HomeServer("test", db_pool=None, http_client=None, - resource_for_client=self.mock_server, - resource_for_federation=self.mock_server, + resource_for_client=self.mock_resource, + resource_for_federation=self.mock_resource, datastore=Mock(spec=[ "set_presence_state", "get_presence_list", @@ -228,7 +280,7 @@ class PresenceEventStreamTestCase(unittest.TestCase): self.mock_datastore.get_presence_list.return_value = defer.succeed( []) - (code, response) = yield self.mock_server.trigger("GET", + (code, response) = yield self.mock_resource.trigger("GET", "/events?timeout=0", None) self.assertEquals(200, code) @@ -254,7 +306,7 @@ class PresenceEventStreamTestCase(unittest.TestCase): yield self.presence.set_state(self.u_banana, self.u_banana, state={"state": ONLINE}) - (code, response) = yield self.mock_server.trigger("GET", + (code, response) = yield self.mock_resource.trigger("GET", "/events?from=1&timeout=0", None) self.assertEquals(200, code) diff --git a/tests/rest/test_profile.py b/tests/rest/test_profile.py index ee47daf4c2..9bd8dc9783 100644 --- a/tests/rest/test_profile.py +++ b/tests/rest/test_profile.py @@ -20,7 +20,7 @@ from twisted.internet import defer from mock import Mock -from ..utils import MockHttpServer +from ..utils import MockHttpResource from synapse.api.errors import SynapseError, AuthError from synapse.server import HomeServer @@ -32,7 +32,7 @@ class ProfileTestCase(unittest.TestCase): """ Tests profile management. """ def setUp(self): - self.mock_server = MockHttpServer(prefix=PATH_PREFIX) + self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) self.mock_handler = Mock(spec=[ "get_displayname", "set_displayname", @@ -43,7 +43,7 @@ class ProfileTestCase(unittest.TestCase): hs = HomeServer("test", db_pool=None, http_client=None, - resource_for_client=self.mock_server, + resource_for_client=self.mock_resource, federation=Mock(), replication_layer=Mock(), datastore=None, @@ -63,7 +63,7 @@ class ProfileTestCase(unittest.TestCase): mocked_get = self.mock_handler.get_displayname mocked_get.return_value = defer.succeed("Frank") - (code, response) = yield self.mock_server.trigger("GET", + (code, response) = yield self.mock_resource.trigger("GET", "/profile/%s/displayname" % (myid), None) self.assertEquals(200, code) @@ -75,7 +75,7 @@ class ProfileTestCase(unittest.TestCase): mocked_set = self.mock_handler.set_displayname mocked_set.return_value = defer.succeed(()) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", "/profile/%s/displayname" % (myid), '{"displayname": "Frank Jr."}') @@ -89,7 +89,7 @@ class ProfileTestCase(unittest.TestCase): mocked_set = self.mock_handler.set_displayname mocked_set.side_effect = AuthError(400, "message") - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", "/profile/%s/displayname" % ("@4567:test"), '"Frank Jr."') self.assertTrue(400 <= code < 499, @@ -100,7 +100,7 @@ class ProfileTestCase(unittest.TestCase): mocked_get = self.mock_handler.get_displayname mocked_get.return_value = defer.succeed("Bob") - (code, response) = yield self.mock_server.trigger("GET", + (code, response) = yield self.mock_resource.trigger("GET", "/profile/%s/displayname" % ("@opaque:elsewhere"), None) self.assertEquals(200, code) @@ -111,7 +111,7 @@ class ProfileTestCase(unittest.TestCase): mocked_set = self.mock_handler.set_displayname mocked_set.side_effect = SynapseError(400, "message") - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", "/profile/%s/displayname" % ("@opaque:elsewhere"), None) self.assertTrue(400 <= code <= 499, @@ -122,7 +122,7 @@ class ProfileTestCase(unittest.TestCase): mocked_get = self.mock_handler.get_avatar_url mocked_get.return_value = defer.succeed("http://my.server/me.png") - (code, response) = yield self.mock_server.trigger("GET", + (code, response) = yield self.mock_resource.trigger("GET", "/profile/%s/avatar_url" % (myid), None) self.assertEquals(200, code) @@ -134,7 +134,7 @@ class ProfileTestCase(unittest.TestCase): mocked_set = self.mock_handler.set_avatar_url mocked_set.return_value = defer.succeed(()) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", "/profile/%s/avatar_url" % (myid), '{"avatar_url": "http://my.server/pic.gif"}') diff --git a/tests/rest/test_rooms.py b/tests/rest/test_rooms.py index 3ac2bbdd0f..e873181044 100644 --- a/tests/rest/test_rooms.py +++ b/tests/rest/test_rooms.py @@ -27,7 +27,7 @@ from synapse.server import HomeServer import json import urllib -from ..utils import MockHttpServer, MemoryDataStore +from ..utils import MockHttpResource, MemoryDataStore from .utils import RestTestCase from mock import Mock @@ -42,7 +42,7 @@ class RoomPermissionsTestCase(RestTestCase): @defer.inlineCallbacks def setUp(self): - self.mock_server = MockHttpServer(prefix=PATH_PREFIX) + self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) state_handler = Mock(spec=["handle_new_event"]) state_handler.handle_new_event.return_value = True @@ -67,7 +67,7 @@ class RoomPermissionsTestCase(RestTestCase): self.auth_user_id = self.rmcreator_id - synapse.rest.room.register_servlets(hs, self.mock_server) + synapse.rest.room.register_servlets(hs, self.mock_resource) self.auth = hs.get_auth() @@ -85,14 +85,14 @@ class RoomPermissionsTestCase(RestTestCase): # send a message in one of the rooms self.created_rmid_msg_path = ("/rooms/%s/messages/%s/midaaa1" % (self.created_rmid, self.rmcreator_id)) - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", self.created_rmid_msg_path, '{"msgtype":"m.text","body":"test msg"}') self.assertEquals(200, code, msg=str(response)) # set topic for public room - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", "/rooms/%s/topic" % self.created_public_rmid, '{"topic":"Public Room Topic"}') @@ -107,31 +107,31 @@ class RoomPermissionsTestCase(RestTestCase): # @defer.inlineCallbacks # def test_get_message(self): # # get message in uncreated room, expect 403 -# (code, response) = yield self.mock_server.trigger_get( +# (code, response) = yield self.mock_resource.trigger_get( # "/rooms/noroom/messages/someid/m1") # self.assertEquals(403, code, msg=str(response)) # # # get message in created room not joined (no state), expect 403 -# (code, response) = yield self.mock_server.trigger_get( +# (code, response) = yield self.mock_resource.trigger_get( # self.created_rmid_msg_path) # self.assertEquals(403, code, msg=str(response)) # # # get message in created room and invited, expect 403 # yield self.invite(room=self.created_rmid, src=self.rmcreator_id, # targ=self.user_id) -# (code, response) = yield self.mock_server.trigger_get( +# (code, response) = yield self.mock_resource.trigger_get( # self.created_rmid_msg_path) # self.assertEquals(403, code, msg=str(response)) # # # get message in created room and joined, expect 200 # yield self.join(room=self.created_rmid, user=self.user_id) -# (code, response) = yield self.mock_server.trigger_get( +# (code, response) = yield self.mock_resource.trigger_get( # self.created_rmid_msg_path) # self.assertEquals(200, code, msg=str(response)) # # # get message in created room and left, expect 403 # yield self.leave(room=self.created_rmid, user=self.user_id) -# (code, response) = yield self.mock_server.trigger_get( +# (code, response) = yield self.mock_resource.trigger_get( # self.created_rmid_msg_path) # self.assertEquals(403, code, msg=str(response)) @@ -142,33 +142,33 @@ class RoomPermissionsTestCase(RestTestCase): (self.created_rmid, self.user_id)) # send message in uncreated room, expect 403 - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", "/rooms/%s/messages/%s/mid1" % (self.uncreated_rmid, self.user_id), msg_content) self.assertEquals(403, code, msg=str(response)) # send message in created room not joined (no state), expect 403 - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", send_msg_path, msg_content) self.assertEquals(403, code, msg=str(response)) # send message in created room and invited, expect 403 yield self.invite(room=self.created_rmid, src=self.rmcreator_id, targ=self.user_id) - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", send_msg_path, msg_content) self.assertEquals(403, code, msg=str(response)) # send message in created room and joined, expect 200 yield self.join(room=self.created_rmid, user=self.user_id) - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", send_msg_path, msg_content) self.assertEquals(200, code, msg=str(response)) # send message in created room and left, expect 403 yield self.leave(room=self.created_rmid, user=self.user_id) - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", send_msg_path, msg_content) self.assertEquals(403, code, msg=str(response)) @@ -178,56 +178,56 @@ class RoomPermissionsTestCase(RestTestCase): topic_path = "/rooms/%s/topic" % self.created_rmid # set/get topic in uncreated room, expect 403 - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", "/rooms/%s/topic" % self.uncreated_rmid, topic_content) self.assertEquals(403, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger_get( + (code, response) = yield self.mock_resource.trigger_get( "/rooms/%s/topic" % self.uncreated_rmid) self.assertEquals(403, code, msg=str(response)) # set/get topic in created PRIVATE room not joined, expect 403 - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", topic_path, topic_content) self.assertEquals(403, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger_get(topic_path) + (code, response) = yield self.mock_resource.trigger_get(topic_path) self.assertEquals(403, code, msg=str(response)) # set topic in created PRIVATE room and invited, expect 403 yield self.invite(room=self.created_rmid, src=self.rmcreator_id, targ=self.user_id) - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", topic_path, topic_content) self.assertEquals(403, code, msg=str(response)) # get topic in created PRIVATE room and invited, expect 200 (or 404) - (code, response) = yield self.mock_server.trigger_get(topic_path) + (code, response) = yield self.mock_resource.trigger_get(topic_path) self.assertEquals(404, code, msg=str(response)) # set/get topic in created PRIVATE room and joined, expect 200 yield self.join(room=self.created_rmid, user=self.user_id) - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", topic_path, topic_content) self.assertEquals(200, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger_get(topic_path) + (code, response) = yield self.mock_resource.trigger_get(topic_path) self.assertEquals(200, code, msg=str(response)) self.assert_dict(json.loads(topic_content), response) # set/get topic in created PRIVATE room and left, expect 403 yield self.leave(room=self.created_rmid, user=self.user_id) - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", topic_path, topic_content) self.assertEquals(403, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger_get(topic_path) + (code, response) = yield self.mock_resource.trigger_get(topic_path) self.assertEquals(403, code, msg=str(response)) # get topic in PUBLIC room, not joined, expect 200 (or 404) - (code, response) = yield self.mock_server.trigger_get( + (code, response) = yield self.mock_resource.trigger_get( "/rooms/%s/topic" % self.created_public_rmid) self.assertEquals(200, code, msg=str(response)) # set topic in PUBLIC room, not joined, expect 403 - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", "/rooms/%s/topic" % self.created_public_rmid, topic_content) @@ -237,7 +237,7 @@ class RoomPermissionsTestCase(RestTestCase): def _test_get_membership(self, room=None, members=[], expect_code=None): path = "/rooms/%s/members/%s/state" for member in members: - (code, response) = yield self.mock_server.trigger_get( + (code, response) = yield self.mock_resource.trigger_get( path % (room, member)) self.assertEquals(expect_code, code) @@ -391,7 +391,7 @@ class RoomsMemberListTestCase(RestTestCase): user_id = "@sid1:red" def setUp(self): - self.mock_server = MockHttpServer(prefix=PATH_PREFIX) + self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) state_handler = Mock(spec=["handle_new_event"]) state_handler.handle_new_event.return_value = True @@ -416,7 +416,7 @@ class RoomsMemberListTestCase(RestTestCase): return hs.parse_userid(self.auth_user_id) hs.get_auth().get_user_by_token = _get_user_by_token - synapse.rest.room.register_servlets(hs, self.mock_server) + synapse.rest.room.register_servlets(hs, self.mock_resource) def tearDown(self): pass @@ -425,13 +425,13 @@ class RoomsMemberListTestCase(RestTestCase): def test_get_member_list(self): room_id = "!aa:test" yield self.create_room_as(room_id, self.user_id) - (code, response) = yield self.mock_server.trigger_get( + (code, response) = yield self.mock_resource.trigger_get( "/rooms/%s/members/list" % room_id) self.assertEquals(200, code, msg=str(response)) @defer.inlineCallbacks def test_get_member_list_no_room(self): - (code, response) = yield self.mock_server.trigger_get( + (code, response) = yield self.mock_resource.trigger_get( "/rooms/roomdoesnotexist/members/list") self.assertEquals(403, code, msg=str(response)) @@ -439,7 +439,7 @@ class RoomsMemberListTestCase(RestTestCase): def test_get_member_list_no_permission(self): room_id = "!bb:test" yield self.create_room_as(room_id, "@some_other_guy:red") - (code, response) = yield self.mock_server.trigger_get( + (code, response) = yield self.mock_resource.trigger_get( "/rooms/%s/members/list" % room_id) self.assertEquals(403, code, msg=str(response)) @@ -452,17 +452,17 @@ class RoomsMemberListTestCase(RestTestCase): yield self.invite(room=room_id, src=room_creator, targ=self.user_id) # can't see list if you're just invited. - (code, response) = yield self.mock_server.trigger_get(room_path) + (code, response) = yield self.mock_resource.trigger_get(room_path) self.assertEquals(403, code, msg=str(response)) yield self.join(room=room_id, user=self.user_id) # can see list now joined - (code, response) = yield self.mock_server.trigger_get(room_path) + (code, response) = yield self.mock_resource.trigger_get(room_path) self.assertEquals(200, code, msg=str(response)) yield self.leave(room=room_id, user=self.user_id) # can no longer see list, you've left. - (code, response) = yield self.mock_server.trigger_get(room_path) + (code, response) = yield self.mock_resource.trigger_get(room_path) self.assertEquals(403, code, msg=str(response)) @@ -471,7 +471,7 @@ class RoomsCreateTestCase(RestTestCase): user_id = "@sid1:red" def setUp(self): - self.mock_server = MockHttpServer(prefix=PATH_PREFIX) + self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) self.auth_user_id = self.user_id state_handler = Mock(spec=["handle_new_event"]) @@ -495,7 +495,7 @@ class RoomsCreateTestCase(RestTestCase): return hs.parse_userid(self.auth_user_id) hs.get_auth().get_user_by_token = _get_user_by_token - synapse.rest.room.register_servlets(hs, self.mock_server) + synapse.rest.room.register_servlets(hs, self.mock_resource) def tearDown(self): pass @@ -503,7 +503,7 @@ class RoomsCreateTestCase(RestTestCase): @defer.inlineCallbacks def test_post_room_no_keys(self): # POST with no config keys, expect new room id - (code, response) = yield self.mock_server.trigger("POST", "/rooms", + (code, response) = yield self.mock_resource.trigger("POST", "/rooms", "{}") self.assertEquals(200, code, response) self.assertTrue("room_id" in response) @@ -511,7 +511,7 @@ class RoomsCreateTestCase(RestTestCase): @defer.inlineCallbacks def test_post_room_visibility_key(self): # POST with visibility config key, expect new room id - (code, response) = yield self.mock_server.trigger("POST", "/rooms", + (code, response) = yield self.mock_resource.trigger("POST", "/rooms", '{"visibility":"private"}') self.assertEquals(200, code) self.assertTrue("room_id" in response) @@ -519,7 +519,7 @@ class RoomsCreateTestCase(RestTestCase): @defer.inlineCallbacks def test_post_room_custom_key(self): # POST with custom config keys, expect new room id - (code, response) = yield self.mock_server.trigger("POST", "/rooms", + (code, response) = yield self.mock_resource.trigger("POST", "/rooms", '{"custom":"stuff"}') self.assertEquals(200, code) self.assertTrue("room_id" in response) @@ -527,7 +527,7 @@ class RoomsCreateTestCase(RestTestCase): @defer.inlineCallbacks def test_post_room_known_and_unknown_keys(self): # POST with custom + known config keys, expect new room id - (code, response) = yield self.mock_server.trigger("POST", "/rooms", + (code, response) = yield self.mock_resource.trigger("POST", "/rooms", '{"visibility":"private","custom":"things"}') self.assertEquals(200, code) self.assertTrue("room_id" in response) @@ -535,18 +535,18 @@ class RoomsCreateTestCase(RestTestCase): @defer.inlineCallbacks def test_post_room_invalid_content(self): # POST with invalid content / paths, expect 400 - (code, response) = yield self.mock_server.trigger("POST", "/rooms", + (code, response) = yield self.mock_resource.trigger("POST", "/rooms", '{"visibili') self.assertEquals(400, code) - (code, response) = yield self.mock_server.trigger("POST", "/rooms", + (code, response) = yield self.mock_resource.trigger("POST", "/rooms", '["hello"]') self.assertEquals(400, code) @defer.inlineCallbacks def test_put_room_no_keys(self): # PUT with no config keys, expect new room id - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", "/rooms/%21aa%3Atest", "{}" ) self.assertEquals(200, code) @@ -555,7 +555,7 @@ class RoomsCreateTestCase(RestTestCase): @defer.inlineCallbacks def test_put_room_visibility_key(self): # PUT with known config keys, expect new room id - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", "/rooms/%21bb%3Atest", '{"visibility":"private"}' ) self.assertEquals(200, code) @@ -564,7 +564,7 @@ class RoomsCreateTestCase(RestTestCase): @defer.inlineCallbacks def test_put_room_custom_key(self): # PUT with custom config keys, expect new room id - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", "/rooms/%21cc%3Atest", '{"custom":"stuff"}' ) self.assertEquals(200, code) @@ -573,7 +573,7 @@ class RoomsCreateTestCase(RestTestCase): @defer.inlineCallbacks def test_put_room_known_and_unknown_keys(self): # PUT with custom + known config keys, expect new room id - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", "/rooms/%21dd%3Atest", '{"visibility":"private","custom":"things"}' ) @@ -584,12 +584,12 @@ class RoomsCreateTestCase(RestTestCase): def test_put_room_invalid_content(self): # PUT with invalid content / room names, expect 400 - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", "/rooms/ee", '{"sdf"' ) self.assertEquals(400, code) - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", "/rooms/ee", '["hello"]' ) self.assertEquals(400, code) @@ -599,7 +599,7 @@ class RoomsCreateTestCase(RestTestCase): yield self.create_room_as("!aa:test", self.user_id) # PUT with conflicting room ID, expect 409 - (code, response) = yield self.mock_server.trigger( + (code, response) = yield self.mock_resource.trigger( "PUT", "/rooms/%21aa%3Atest", "{}" ) self.assertEquals(409, code) @@ -611,7 +611,7 @@ class RoomTopicTestCase(RestTestCase): @defer.inlineCallbacks def setUp(self): - self.mock_server = MockHttpServer(prefix=PATH_PREFIX) + self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) self.auth_user_id = self.user_id self.room_id = "!rid1:test" self.path = "/rooms/%s/topic" % self.room_id @@ -637,7 +637,7 @@ class RoomTopicTestCase(RestTestCase): return hs.parse_userid(self.auth_user_id) hs.get_auth().get_user_by_token = _get_user_by_token - synapse.rest.room.register_servlets(hs, self.mock_server) + synapse.rest.room.register_servlets(hs, self.mock_resource) # create the room yield self.create_room_as(self.room_id, self.user_id) @@ -648,50 +648,50 @@ class RoomTopicTestCase(RestTestCase): @defer.inlineCallbacks def test_invalid_puts(self): # missing keys or invalid json - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", self.path, '{}') self.assertEquals(400, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", self.path, '{"_name":"bob"}') self.assertEquals(400, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", self.path, '{"nao') self.assertEquals(400, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", self.path, '[{"_name":"bob"},{"_name":"jill"}]') self.assertEquals(400, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", self.path, 'text only') self.assertEquals(400, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", self.path, '') self.assertEquals(400, code, msg=str(response)) # valid key, wrong type content = '{"topic":["Topic name"]}' - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", self.path, content) self.assertEquals(400, code, msg=str(response)) @defer.inlineCallbacks def test_rooms_topic(self): # nothing should be there - (code, response) = yield self.mock_server.trigger_get(self.path) + (code, response) = yield self.mock_resource.trigger_get(self.path) self.assertEquals(404, code, msg=str(response)) # valid put content = '{"topic":"Topic name"}' - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", self.path, content) self.assertEquals(200, code, msg=str(response)) # valid get - (code, response) = yield self.mock_server.trigger_get(self.path) + (code, response) = yield self.mock_resource.trigger_get(self.path) self.assertEquals(200, code, msg=str(response)) self.assert_dict(json.loads(content), response) @@ -699,12 +699,12 @@ class RoomTopicTestCase(RestTestCase): def test_rooms_topic_with_extra_keys(self): # valid put with extra keys content = '{"topic":"Seasons","subtopic":"Summer"}' - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", self.path, content) self.assertEquals(200, code, msg=str(response)) # valid get - (code, response) = yield self.mock_server.trigger_get(self.path) + (code, response) = yield self.mock_resource.trigger_get(self.path) self.assertEquals(200, code, msg=str(response)) self.assert_dict(json.loads(content), response) @@ -715,7 +715,7 @@ class RoomMemberStateTestCase(RestTestCase): @defer.inlineCallbacks def setUp(self): - self.mock_server = MockHttpServer(prefix=PATH_PREFIX) + self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) self.auth_user_id = self.user_id self.room_id = "!rid1:test" @@ -740,7 +740,7 @@ class RoomMemberStateTestCase(RestTestCase): return hs.parse_userid(self.auth_user_id) hs.get_auth().get_user_by_token = _get_user_by_token - synapse.rest.room.register_servlets(hs, self.mock_server) + synapse.rest.room.register_servlets(hs, self.mock_resource) yield self.create_room_as(self.room_id, self.user_id) @@ -751,34 +751,34 @@ class RoomMemberStateTestCase(RestTestCase): def test_invalid_puts(self): path = "/rooms/%s/members/%s/state" % (self.room_id, self.user_id) # missing keys or invalid json - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", path, '{}') self.assertEquals(400, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", path, '{"_name":"bob"}') self.assertEquals(400, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", path, '{"nao') self.assertEquals(400, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", path, '[{"_name":"bob"},{"_name":"jill"}]') self.assertEquals(400, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", path, 'text only') self.assertEquals(400, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", path, '') self.assertEquals(400, code, msg=str(response)) # valid keys, wrong types content = ('{"membership":["%s","%s","%s"]}' % (Membership.INVITE, Membership.JOIN, Membership.LEAVE)) - (code, response) = yield self.mock_server.trigger("PUT", path, content) + (code, response) = yield self.mock_resource.trigger("PUT", path, content) self.assertEquals(400, code, msg=str(response)) @defer.inlineCallbacks @@ -789,10 +789,10 @@ class RoomMemberStateTestCase(RestTestCase): # valid join message (NOOP since we made the room) content = '{"membership":"%s"}' % Membership.JOIN - (code, response) = yield self.mock_server.trigger("PUT", path, content) + (code, response) = yield self.mock_resource.trigger("PUT", path, content) self.assertEquals(200, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("GET", path, None) + (code, response) = yield self.mock_resource.trigger("GET", path, None) self.assertEquals(200, code, msg=str(response)) self.assertEquals(json.loads(content), response) @@ -805,10 +805,10 @@ class RoomMemberStateTestCase(RestTestCase): # valid invite message content = '{"membership":"%s"}' % Membership.INVITE - (code, response) = yield self.mock_server.trigger("PUT", path, content) + (code, response) = yield self.mock_resource.trigger("PUT", path, content) self.assertEquals(200, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("GET", path, None) + (code, response) = yield self.mock_resource.trigger("GET", path, None) self.assertEquals(200, code, msg=str(response)) self.assertEquals(json.loads(content), response) @@ -822,10 +822,10 @@ class RoomMemberStateTestCase(RestTestCase): # valid invite message with custom key content = ('{"membership":"%s","invite_text":"%s"}' % (Membership.INVITE, "Join us!")) - (code, response) = yield self.mock_server.trigger("PUT", path, content) + (code, response) = yield self.mock_resource.trigger("PUT", path, content) self.assertEquals(200, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("GET", path, None) + (code, response) = yield self.mock_resource.trigger("GET", path, None) self.assertEquals(200, code, msg=str(response)) self.assertEquals(json.loads(content), response) @@ -836,7 +836,7 @@ class RoomMessagesTestCase(RestTestCase): @defer.inlineCallbacks def setUp(self): - self.mock_server = MockHttpServer(prefix=PATH_PREFIX) + self.mock_resource = MockHttpResource(prefix=PATH_PREFIX) self.auth_user_id = self.user_id self.room_id = "!rid1:test" @@ -861,7 +861,7 @@ class RoomMessagesTestCase(RestTestCase): return hs.parse_userid(self.auth_user_id) hs.get_auth().get_user_by_token = _get_user_by_token - synapse.rest.room.register_servlets(hs, self.mock_server) + synapse.rest.room.register_servlets(hs, self.mock_resource) yield self.create_room_as(self.room_id, self.user_id) @@ -874,27 +874,27 @@ class RoomMessagesTestCase(RestTestCase): urllib.quote(self.room_id), self.user_id ) # missing keys or invalid json - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", path, '{}') self.assertEquals(400, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", path, '{"_name":"bob"}') self.assertEquals(400, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", path, '{"nao') self.assertEquals(400, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", path, '[{"_name":"bob"},{"_name":"jill"}]') self.assertEquals(400, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", path, 'text only') self.assertEquals(400, code, msg=str(response)) - (code, response) = yield self.mock_server.trigger("PUT", + (code, response) = yield self.mock_resource.trigger("PUT", path, '') self.assertEquals(400, code, msg=str(response)) @@ -905,34 +905,34 @@ class RoomMessagesTestCase(RestTestCase): ) content = '{"body":"test","msgtype":{"type":"a"}}' - (code, response) = yield self.mock_server.trigger("PUT", path, content) + (code, response) = yield self.mock_resource.trigger("PUT", path, content) self.assertEquals(400, code, msg=str(response)) # custom message types content = '{"body":"test","msgtype":"test.custom.text"}' - (code, response) = yield self.mock_server.trigger("PUT", path, content) + (code, response) = yield self.mock_resource.trigger("PUT", path, content) self.assertEquals(200, code, msg=str(response)) - # (code, response) = yield self.mock_server.trigger("GET", path, None) - # self.assertEquals(200, code, msg=str(response)) - # self.assert_dict(json.loads(content), response) +# (code, response) = yield self.mock_resource.trigger("GET", path, None) +# self.assertEquals(200, code, msg=str(response)) +# self.assert_dict(json.loads(content), response) # m.text message type path = "/rooms/%s/messages/%s/mid2" % ( urllib.quote(self.room_id), self.user_id ) content = '{"body":"test2","msgtype":"m.text"}' - (code, response) = yield self.mock_server.trigger("PUT", path, content) + (code, response) = yield self.mock_resource.trigger("PUT", path, content) self.assertEquals(200, code, msg=str(response)) - # (code, response) = yield self.mock_server.trigger("GET", path, None) - # self.assertEquals(200, code, msg=str(response)) - # self.assert_dict(json.loads(content), response) +# (code, response) = yield self.mock_resource.trigger("GET", path, None) +# self.assertEquals(200, code, msg=str(response)) +# self.assert_dict(json.loads(content), response) # trying to send message in different user path path = "/rooms/%s/messages/%s/mid2" % ( urllib.quote(self.room_id), "invalid" + self.user_id ) content = '{"body":"test2","msgtype":"m.text"}' - (code, response) = yield self.mock_server.trigger("PUT", path, content) + (code, response) = yield self.mock_resource.trigger("PUT", path, content) self.assertEquals(403, code, msg=str(response)) diff --git a/tests/rest/utils.py b/tests/rest/utils.py index a543f049c4..8ed228b218 100644 --- a/tests/rest/utils.py +++ b/tests/rest/utils.py @@ -27,12 +27,12 @@ class RestTestCase(unittest.TestCase): """Contains extra helper functions to quickly and clearly perform a given REST action, which isn't the focus of the test. - This subclass assumes there are mock_server and auth_user_id attributes. + This subclass assumes there are mock_resource and auth_user_id attributes. """ def __init__(self, *args, **kwargs): super(RestTestCase, self).__init__(*args, **kwargs) - self.mock_server = None + self.mock_resource = None self.auth_user_id = None def mock_get_user_by_token(self, token=None): @@ -48,7 +48,7 @@ class RestTestCase(unittest.TestCase): content = '{"visibility":"private"}' if tok: path = path + "?access_token=%s" % tok - (code, response) = yield self.mock_server.trigger("PUT", path, content) + (code, response) = yield self.mock_resource.trigger("PUT", path, content) self.assertEquals(200, code, msg=str(response)) self.auth_user_id = temp_id @@ -81,11 +81,11 @@ class RestTestCase(unittest.TestCase): path = path + "?access_token=%s" % tok if membership == Membership.LEAVE: - (code, response) = yield self.mock_server.trigger("DELETE", path, + (code, response) = yield self.mock_resource.trigger("DELETE", path, None) self.assertEquals(expect_code, code, msg=str(response)) else: - (code, response) = yield self.mock_server.trigger("PUT", path, + (code, response) = yield self.mock_resource.trigger("PUT", path, '{"membership":"%s"}' % membership) self.assertEquals(expect_code, code, msg=str(response)) @@ -93,7 +93,7 @@ class RestTestCase(unittest.TestCase): @defer.inlineCallbacks def register(self, user_id): - (code, response) = yield self.mock_server.trigger("POST", "/register", + (code, response) = yield self.mock_resource.trigger("POST", "/register", '{"user_id":"%s"}' % user_id) self.assertEquals(200, code) defer.returnValue(response) @@ -111,7 +111,7 @@ class RestTestCase(unittest.TestCase): if tok: path = path + "?access_token=%s" % tok - (code, response) = yield self.mock_server.trigger("PUT", path, content) + (code, response) = yield self.mock_resource.trigger("PUT", path, content) self.assertEquals(expect_code, code, msg=str(response)) def assert_dict(self, required, actual): diff --git a/tests/utils.py b/tests/utils.py index 990380fb1c..c68b17f7b9 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -29,7 +29,8 @@ import json import urlparse -class MockHttpServer(HttpServer): +# This is a mock /resource/ not an entire server +class MockHttpResource(HttpServer): def __init__(self, prefix=""): self.callbacks = [] # 3-tuple of method/pattern/function @@ -210,3 +211,43 @@ class MemoryDataStore(object): def get_room_events_max_id(self): return 0 # TODO (erikj) + +def _format_call(args, kwargs): + return ", ".join( + ["%r" % (a) for a in args] + + ["%s=%r" % (k, v) for k, v in kwargs.items()] + ) + + +class DeferredMockCallable(object): + """A callable instance that stores a set of pending call expectations and + return values for them. It allows a unit test to assert that the given set + of function calls are eventually made, by awaiting on them to be called. + """ + + def __init__(self): + self.expectations = [] + + def __call__(self, *args, **kwargs): + if not self.expectations: + raise ValueError("%r has no pending calls to handle call(%s)" % ( + self, _format_call(args, kwargs)) + ) + + for (call, result, d) in self.expectations: + if args == call[1] and kwargs == call[2]: + d.callback(None) + return result + + raise AssertionError("Was not expecting call(%s)" % + _format_call(args, kwargs) + ) + + def expect_call_and_return(self, call, result): + self.expectations.append((call, result, defer.Deferred())) + + @defer.inlineCallbacks + def await_calls(self): + while self.expectations: + (_, _, d) = self.expectations.pop(0) + yield d |