Newer
Older
Matthew Hodgson
committed
# Copyright 2014 matrix.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests REST events for /presence paths."""
from twisted.trial import unittest
from twisted.internet import defer
from mock import Mock
import logging
Paul "LeoNerd" Evans
committed
from ..utils import MockHttpResource
from synapse.api.constants import PresenceState
Paul "LeoNerd" Evans
committed
from synapse.handlers.presence import PresenceHandler
from synapse.server import HomeServer
logging.getLogger().addHandler(logging.NullHandler())
OFFLINE = PresenceState.OFFLINE
Paul "LeoNerd" Evans
committed
UNAVAILABLE = PresenceState.UNAVAILABLE
ONLINE = PresenceState.ONLINE
myid = "@apple:test"
PATH_PREFIX = "/matrix/client/api/v1"
Paul "LeoNerd" Evans
committed
class JustPresenceHandlers(object):
def __init__(self, hs):
self.presence_handler = PresenceHandler(hs)
class PresenceStateTestCase(unittest.TestCase):
def setUp(self):
Paul "LeoNerd" Evans
committed
self.mock_resource = MockHttpResource(prefix=PATH_PREFIX)
Paul "LeoNerd" Evans
committed
datastore=Mock(spec=[
"get_presence_state",
"set_presence_state",
]),
Paul "LeoNerd" Evans
committed
resource_for_client=self.mock_resource,
resource_for_federation=self.mock_resource,
Paul "LeoNerd" Evans
committed
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
Paul "LeoNerd" Evans
committed
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()
self.u_apple = hs.parse_userid(myid)
@defer.inlineCallbacks
def test_get_my_status(self):
Paul "LeoNerd" Evans
committed
mocked_get = self.datastore.get_presence_state
Paul "LeoNerd" Evans
committed
{"state": ONLINE, "status_msg": "Available"}
)
Paul "LeoNerd" Evans
committed
(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)
Paul "LeoNerd" Evans
committed
mocked_get.assert_called_with("apple")
@defer.inlineCallbacks
def test_set_my_status(self):
Paul "LeoNerd" Evans
committed
mocked_set = self.datastore.set_presence_state
mocked_set.return_value = defer.succeed({"state": OFFLINE})
Paul "LeoNerd" Evans
committed
(code, response) = yield self.mock_resource.trigger("PUT",
Paul "LeoNerd" Evans
committed
'{"state": "unavailable", "status_msg": "Away"}')
Paul "LeoNerd" Evans
committed
mocked_set.assert_called_with("apple",
{"state": UNAVAILABLE, "status_msg": "Away"})
test_set_my_status.skip = "Presence polling is disabled"
class PresenceListTestCase(unittest.TestCase):
def setUp(self):
Paul "LeoNerd" Evans
committed
self.mock_resource = MockHttpResource(prefix=PATH_PREFIX)
Paul "LeoNerd" Evans
committed
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",
]),
Paul "LeoNerd" Evans
committed
resource_for_client=self.mock_resource,
resource_for_federation=self.mock_resource
Paul "LeoNerd" Evans
committed
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)
Paul "LeoNerd" Evans
committed
room_member_handler = hs.handlers.room_member_handler = Mock(
spec=[
"get_rooms_for_user",
]
)
Paul "LeoNerd" Evans
committed
hs.get_auth().get_user_by_token = _get_user_by_token
hs.register_servlets()
self.u_apple = hs.parse_userid("@apple:test")
self.u_banana = hs.parse_userid("@banana:test")
@defer.inlineCallbacks
def test_get_my_list(self):
Paul "LeoNerd" Evans
committed
self.datastore.get_presence_list.return_value = defer.succeed(
[{"observed_user_id": "@banana:test"}],
Paul "LeoNerd" Evans
committed
(code, response) = yield self.mock_resource.trigger("GET",
"/presence_list/%s" % (myid), None)
self.assertEquals(200, code)
Paul "LeoNerd" Evans
committed
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):
Paul "LeoNerd" Evans
committed
self.datastore.add_presence_list_pending.return_value = (
defer.succeed(())
)
self.datastore.is_presence_visible.return_value = defer.succeed(
True
)
Paul "LeoNerd" Evans
committed
(code, response) = yield self.mock_resource.trigger("POST",
Paul "LeoNerd" Evans
committed
"/presence_list/%s" % (myid),
"""{"invite": ["@banana:test"]}"""
)
Paul "LeoNerd" Evans
committed
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):
Paul "LeoNerd" Evans
committed
self.datastore.del_presence_list.return_value = (
defer.succeed(())
)
Paul "LeoNerd" Evans
committed
(code, response) = yield self.mock_resource.trigger("POST",
Paul "LeoNerd" Evans
committed
"/presence_list/%s" % (myid),
"""{"drop": ["@banana:test"]}"""
)
Paul "LeoNerd" Evans
committed
self.datastore.del_presence_list.assert_called_with(
"apple", "@banana:test"
)
class PresenceEventStreamTestCase(unittest.TestCase):
def setUp(self):
Paul "LeoNerd" Evans
committed
self.mock_resource = MockHttpResource(prefix=PATH_PREFIX)
# HIDEOUS HACKERY
# TODO(paul): This should be injected in via the HomeServer DI system
from synapse.handlers.events import EventStreamHandler
from synapse.handlers.presence import PresenceStreamData
EventStreamHandler.stream_data_classes = [
PresenceStreamData
]
hs = HomeServer("test",
db_pool=None,
http_client=None,
Paul "LeoNerd" Evans
committed
resource_for_client=self.mock_resource,
resource_for_federation=self.mock_resource,
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
datastore=Mock(spec=[
"set_presence_state",
"get_presence_list",
]),
clock=Mock(spec=[
"call_later",
"cancel_call_later",
"time_msec",
]),
)
hs.get_clock().time_msec.return_value = 1000000
def _get_user_by_req(req=None):
return hs.parse_userid(myid)
hs.get_auth().get_user_by_req = _get_user_by_req
hs.register_servlets()
hs.handlers.room_member_handler = Mock(spec=[
"get_rooms_for_user",
])
hs.handlers.room_member_handler.get_rooms_for_user = (
lambda u: defer.succeed([]))
self.mock_datastore = hs.get_datastore()
self.presence = hs.get_handlers().presence_handler
self.u_apple = hs.parse_userid("@apple:test")
self.u_banana = hs.parse_userid("@banana:test")
@defer.inlineCallbacks
def test_shortpoll(self):
self.mock_datastore.set_presence_state.return_value = defer.succeed(
{"state": ONLINE})
self.mock_datastore.get_presence_list.return_value = defer.succeed(
[])
Paul "LeoNerd" Evans
committed
(code, response) = yield self.mock_resource.trigger("GET",
"/events?timeout=0", None)
self.assertEquals(200, code)
# We've forced there to be only one data stream so the tokens will
# all be ours
# I'll already get my own presence state change
self.assertEquals({"start": "1", "end": "1", "chunk": []}, response)
self.mock_datastore.set_presence_state.return_value = defer.succeed(
{"state": ONLINE})
self.mock_datastore.get_presence_list.return_value = defer.succeed(
[])
yield self.presence.set_state(self.u_banana, self.u_banana,
state={"state": ONLINE})
Paul "LeoNerd" Evans
committed
(code, response) = yield self.mock_resource.trigger("GET",
"/events?from=1&timeout=0", None)
self.assertEquals(200, code)
self.assertEquals({"start": "1", "end": "2", "chunk": [
{"type": "m.presence",
Paul "LeoNerd" Evans
committed
"content": {
"user_id": "@banana:test",
"state": ONLINE,
"mtime_age": 0,
}},
test_shortpoll.skip = "Presence polling is disabled"