summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaul "LeoNerd" Evans <paul@matrix.org>2014-09-01 14:45:35 +0100
committerPaul "LeoNerd" Evans <paul@matrix.org>2014-09-01 14:45:41 +0100
commit02f4e3b3ff613a6e9024c0fef416be0bf92bf48f (patch)
treed3f165d0a69df79b10851a82d87f2615b183f196
parentFleshed out joining/leaving rooms. Added M_LIMIT_EXCEEDED standard error code... (diff)
downloadsynapse-02f4e3b3ff613a6e9024c0fef416be0bf92bf48f.tar.xz
Rename 'state' presence key to the much more obvious 'presence'; maintain a legacy 'state' copy for now
-rw-r--r--docs/client-server/specification.rst4
-rw-r--r--docs/specification.rst14
-rw-r--r--synapse/handlers/presence.py42
-rw-r--r--synapse/rest/presence.py6
-rw-r--r--tests/handlers/test_presence.py122
-rw-r--r--tests/handlers/test_presencelike.py19
-rw-r--r--tests/rest/test_presence.py18
7 files changed, 147 insertions, 78 deletions
diff --git a/docs/client-server/specification.rst b/docs/client-server/specification.rst
index ee8bb5c420..4c9e313a6a 100644
--- a/docs/client-server/specification.rst
+++ b/docs/client-server/specification.rst
@@ -1026,7 +1026,7 @@ Getting/Setting your own presence state
   REST Path: /presence/$user_id/status
   Valid methods: GET/PUT
   Required keys:
-    state : [0|1|2|3] - The user's new presence state
+    presence : [0|1|2|3] - The user's new presence state
   Optional keys:
     status_msg : text string provided by the user to explain their status
 
@@ -1039,7 +1039,7 @@ Fetching your presence list
     following keys:
       {
         "user_id" : string giving the observed user's ID
-        "state" : int giving their status
+        "presence" : int giving their status
         "status_msg" : optional text string
         "displayname" : optional text string from the user's profile
         "avatar_url" : optional text string from the user's profile
diff --git a/docs/specification.rst b/docs/specification.rst
index b61994ff35..d47705ca0f 100644
--- a/docs/specification.rst
+++ b/docs/specification.rst
@@ -542,7 +542,7 @@ Each user has the concept of presence information. This encodes the
 "availability" of that user, suitable for display on other user's clients. This
 is transmitted as an ``m.presence`` event and is one of the few events which
 are sent *outside the context of a room*. The basic piece of presence information 
-is represented by the ``state`` key, which is an enum of one of the following:
+is represented by the ``presence`` key, which is an enum of one of the following:
 
   - ``online`` : The default state when the user is connected to an event stream.
   - ``unavailable`` : The user is not reachable at this time.
@@ -552,18 +552,18 @@ is represented by the ``state`` key, which is an enum of one of the following:
   - ``hidden`` : TODO. Behaves as offline, but allows the user to see the client 
     state anyway and generally interact with client features.
 
-This basic ``state`` field applies to the user as a whole, regardless of how many
+This basic ``presence`` field applies to the user as a whole, regardless of how many
 client devices they have connected. The home server should synchronise this
 status choice among multiple devices to ensure the user gets a consistent
 experience.
 
 Idle Time
 ---------
-As well as the basic ``state`` field, the presence information can also show a sense
-of an "idle timer". This should be maintained individually by the user's
-clients, and the home server can take the highest reported time as that to
-report. When a user is offline, the home server can still report when the user was last
-seen online.
+As well as the basic ``presence`` field, the presence information can also show
+a sense of an "idle timer". This should be maintained individually by the
+user's clients, and the home server can take the highest reported time as that
+to report. When a user is offline, the home server can still report when the
+user was last seen online.
 
 Transmission
 ------------
diff --git a/synapse/handlers/presence.py b/synapse/handlers/presence.py
index 93bd07b196..fa5942ba05 100644
--- a/synapse/handlers/presence.py
+++ b/synapse/handlers/presence.py
@@ -135,7 +135,7 @@ class PresenceHandler(BaseHandler):
             return self._user_cachemap[user]
         else:
             statuscache = UserPresenceCache()
-            statuscache.update({"state": PresenceState.OFFLINE}, user)
+            statuscache.update({"presence": PresenceState.OFFLINE}, user)
             return statuscache
 
     def registered_user(self, user):
@@ -177,6 +177,7 @@ class PresenceHandler(BaseHandler):
                 state = yield self.store.get_presence_state(
                     target_user.localpart
                 )
+                state["presence"] = state["state"]
             else:
                 raise SynapseError(404, "Presence information not visible")
         else:
@@ -207,15 +208,20 @@ class PresenceHandler(BaseHandler):
             state["status_msg"] = None
 
         for k in state.keys():
-            if k not in ("state", "status_msg"):
+            if k not in ("presence", "state", "status_msg"):
                 raise SynapseError(
                     400, "Unexpected presence state key '%s'" % (k,)
                 )
 
+        # Handle legacy "state" key for now
+        if "state" in state:
+            state["presence"] = state.pop("state")
+
         logger.debug("Updating presence state of %s to %s",
-                     target_user.localpart, state["state"])
+                     target_user.localpart, state["presence"])
 
         state_to_store = dict(state)
+        state_to_store["state"] = state_to_store.pop("presence")
 
         yield defer.DeferredList([
             self.store.set_presence_state(
@@ -228,7 +234,7 @@ class PresenceHandler(BaseHandler):
 
         state["mtime"] = self.clock.time_msec()
 
-        now_online = state["state"] != PresenceState.OFFLINE
+        now_online = state["presence"] != PresenceState.OFFLINE
         was_polling = target_user in self._user_cachemap
 
         if now_online and not was_polling:
@@ -251,12 +257,12 @@ class PresenceHandler(BaseHandler):
     @log_function
     def started_user_eventstream(self, user):
         # TODO(paul): Use "last online" state
-        self.set_state(user, user, {"state": PresenceState.ONLINE})
+        self.set_state(user, user, {"presence": PresenceState.ONLINE})
 
     @log_function
     def stopped_user_eventstream(self, user):
         # TODO(paul): Save current state as "last online" state
-        self.set_state(user, user, {"state": PresenceState.OFFLINE})
+        self.set_state(user, user, {"presence": PresenceState.OFFLINE})
 
     @defer.inlineCallbacks
     def user_joined_room(self, user, room_id):
@@ -576,6 +582,7 @@ class PresenceHandler(BaseHandler):
     def _push_presence_remote(self, user, destination, state=None):
         if state is None:
             state = yield self.store.get_presence_state(user.localpart)
+            state["presence"] = state["state"]
 
             yield self.distributor.fire(
                 "collect_presencelike_data", user, state
@@ -591,6 +598,8 @@ class PresenceHandler(BaseHandler):
             "user_id": user.to_string(),
         }
         user_state.update(**state)
+        if "state" in user_state and "presence" not in user_state:
+            user_state["presence"] = user_state["state"]
 
         yield self.federation.send_edu(
             destination=destination,
@@ -622,6 +631,11 @@ class PresenceHandler(BaseHandler):
             state = dict(push)
             del state["user_id"]
 
+            # Legacy handling
+            if "presence" not in state:
+                state["presence"] = state["state"]
+            del state["state"]
+
             if "mtime_age" in state:
                 state["mtime"] = int(
                     self.clock.time_msec() - state.pop("mtime_age")
@@ -639,7 +653,7 @@ class PresenceHandler(BaseHandler):
                 statuscache=statuscache,
             )
 
-            if state["state"] == PresenceState.OFFLINE:
+            if state["presence"] == PresenceState.OFFLINE:
                 del self._user_cachemap[user]
 
         for poll in content.get("poll", []):
@@ -672,10 +686,9 @@ class PresenceHandler(BaseHandler):
         yield defer.DeferredList(deferreds)
 
     @defer.inlineCallbacks
-    def push_update_to_local_and_remote(self, observed_user,
+    def push_update_to_local_and_remote(self, observed_user, statuscache,
                                         users_to_push=[], room_ids=[],
-                                        remote_domains=[],
-                                        statuscache=None):
+                                        remote_domains=[]):
 
         localusers, remoteusers = partitionbool(
             users_to_push,
@@ -804,6 +817,7 @@ class UserPresenceCache(object):
 
     def update(self, state, serial):
         assert("mtime_age" not in state)
+        assert("state" not in state)
 
         self.state.update(state)
         # Delete keys that are now 'None'
@@ -820,7 +834,13 @@ class UserPresenceCache(object):
 
     def get_state(self):
         # clone it so caller can't break our cache
-        return dict(self.state)
+        state = dict(self.state)
+
+        # Legacy handling
+        if "presence" in state:
+            state["state"] = state["presence"]
+
+        return state
 
     def make_event(self, user, clock):
         content = self.get_state()
diff --git a/synapse/rest/presence.py b/synapse/rest/presence.py
index e013b20853..bce3943542 100644
--- a/synapse/rest/presence.py
+++ b/synapse/rest/presence.py
@@ -48,7 +48,11 @@ class PresenceStatusRestServlet(RestServlet):
         try:
             content = json.loads(request.content.read())
 
-            state["state"] = content.pop("state")
+            # Legacy handling
+            if "state" in content:
+                state["presence"] = content.pop("state")
+            else:
+                state["presence"] = content.pop("presence")
 
             if "status_msg" in content:
                 state["status_msg"] = content.pop("status_msg")
diff --git a/tests/handlers/test_presence.py b/tests/handlers/test_presence.py
index 451e1eaa22..f37d9917fe 100644
--- a/tests/handlers/test_presence.py
+++ b/tests/handlers/test_presence.py
@@ -35,8 +35,6 @@ 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"):
@@ -141,7 +139,8 @@ class PresenceStateTestCase(unittest.TestCase):
             target_user=self.u_apple, auth_user=self.u_apple
         )
 
-        self.assertEquals({"state": ONLINE, "status_msg": "Online"},
+        self.assertEquals(
+            {"state": ONLINE, "presence": ONLINE, "status_msg": "Online"},
             state
         )
         mocked_get.assert_called_with("apple")
@@ -157,7 +156,8 @@ class PresenceStateTestCase(unittest.TestCase):
             target_user=self.u_apple, auth_user=self.u_banana
         )
 
-        self.assertEquals({"state": ONLINE, "status_msg": "Online"},
+        self.assertEquals(
+            {"state": ONLINE, "presence": ONLINE, "status_msg": "Online"},
             state
         )
         mocked_get.assert_called_with("apple")
@@ -175,7 +175,10 @@ class PresenceStateTestCase(unittest.TestCase):
             target_user=self.u_apple, auth_user=self.u_clementine
         )
 
-        self.assertEquals({"state": ONLINE, "status_msg": "Online"}, state)
+        self.assertEquals(
+            {"state": ONLINE, "presence": ONLINE, "status_msg": "Online"},
+            state
+        )
 
     @defer.inlineCallbacks
     def test_get_disallowed_state(self):
@@ -202,20 +205,20 @@ class PresenceStateTestCase(unittest.TestCase):
 
         yield self.handler.set_state(
                 target_user=self.u_apple, auth_user=self.u_apple,
-                state={"state": UNAVAILABLE, "status_msg": "Away"})
+                state={"presence": UNAVAILABLE, "status_msg": "Away"})
 
         mocked_set.assert_called_with("apple",
                 {"state": UNAVAILABLE, "status_msg": "Away"})
         self.mock_start.assert_called_with(self.u_apple,
                 state={
-                    "state": UNAVAILABLE,
+                    "presence": UNAVAILABLE,
                     "status_msg": "Away",
                     "mtime": 1000000, # MockClock
                 })
 
         yield self.handler.set_state(
                 target_user=self.u_apple, auth_user=self.u_apple,
-                state={"state": OFFLINE})
+                state={"presence": OFFLINE})
 
         self.mock_stop.assert_called_with(self.u_apple)
 
@@ -449,28 +452,35 @@ class PresenceInvitesTestCase(unittest.TestCase):
     @defer.inlineCallbacks
     def test_get_presence_list(self):
         self.datastore.get_presence_list.return_value = defer.succeed(
-                [{"observed_user_id": "@banana:test"}]
+            [{"observed_user_id": "@banana:test"}]
         )
 
         presence = yield self.handler.get_presence_list(
                 observer_user=self.u_apple)
 
-        self.assertEquals([{"observed_user": self.u_banana,
-                            "state": OFFLINE}], presence)
+        self.assertEquals([
+            {"observed_user": self.u_banana,
+             "presence": OFFLINE,
+             "state": OFFLINE},
+        ], presence)
 
         self.datastore.get_presence_list.assert_called_with("apple",
-                accepted=None)
-
+            accepted=None
+        )
 
         self.datastore.get_presence_list.return_value = defer.succeed(
-                [{"observed_user_id": "@banana:test"}]
+            [{"observed_user_id": "@banana:test"}]
         )
 
         presence = yield self.handler.get_presence_list(
-                observer_user=self.u_apple, accepted=True)
+            observer_user=self.u_apple, accepted=True
+        )
 
-        self.assertEquals([{"observed_user": self.u_banana,
-                            "state": OFFLINE}], presence)
+        self.assertEquals([
+            {"observed_user": self.u_banana,
+             "presence": OFFLINE,
+             "state": OFFLINE},
+        ], presence)
 
         self.datastore.get_presence_list.assert_called_with("apple",
                 accepted=True)
@@ -618,7 +628,8 @@ class PresencePushTestCase(unittest.TestCase):
         self.assertEquals(self.event_source.get_current_key(), 0)
 
         yield self.handler.set_state(self.u_apple, self.u_apple,
-                {"state": ONLINE})
+            {"presence": ONLINE}
+        )
 
         self.assertEquals(self.event_source.get_current_key(), 1)
         self.assertEquals(
@@ -627,6 +638,7 @@ class PresencePushTestCase(unittest.TestCase):
                 {"type": "m.presence",
                  "content": {
                     "user_id": "@apple:test",
+                    "presence": ONLINE,
                     "state": ONLINE,
                     "mtime_age": 0,
                 }},
@@ -636,13 +648,21 @@ class PresencePushTestCase(unittest.TestCase):
         presence = yield self.handler.get_presence_list(
                 observer_user=self.u_apple, accepted=True)
 
-        self.assertEquals([
-                {"observed_user": self.u_banana, "state": OFFLINE},
-                {"observed_user": self.u_clementine, "state": OFFLINE}],
-            presence)
+        self.assertEquals(
+            [
+                {"observed_user": self.u_banana, 
+                 "presence": OFFLINE,
+                 "state": OFFLINE},
+                {"observed_user": self.u_clementine,
+                 "presence": OFFLINE,
+                 "state": OFFLINE},
+            ],
+            presence
+        )
 
         yield self.handler.set_state(self.u_banana, self.u_banana,
-                {"state": ONLINE})
+            {"presence": ONLINE}
+        )
 
         self.clock.advance_time(2)
 
@@ -651,9 +671,11 @@ class PresencePushTestCase(unittest.TestCase):
 
         self.assertEquals([
                 {"observed_user": self.u_banana,
+                 "presence": ONLINE,
                  "state": ONLINE,
                  "mtime_age": 2000},
                 {"observed_user": self.u_clementine,
+                 "presence": OFFLINE,
                  "state": OFFLINE},
         ], presence)
 
@@ -666,6 +688,7 @@ class PresencePushTestCase(unittest.TestCase):
                 {"type": "m.presence",
                  "content": {
                      "user_id": "@banana:test",
+                     "presence": ONLINE,
                      "state": ONLINE,
                      "mtime_age": 2000
                 }},
@@ -682,6 +705,7 @@ class PresencePushTestCase(unittest.TestCase):
                     content={
                         "push": [
                             {"user_id": "@apple:test",
+                             "presence": u"online",
                              "state": u"online",
                              "mtime_age": 0},
                         ],
@@ -703,7 +727,7 @@ class PresencePushTestCase(unittest.TestCase):
         apple_set.add(self.u_potato.domain)
 
         yield self.handler.set_state(self.u_apple, self.u_apple,
-            {"state": ONLINE}
+            {"presence": ONLINE}
         )
 
         yield put_json.await_calls()
@@ -741,6 +765,7 @@ class PresencePushTestCase(unittest.TestCase):
                 {"type": "m.presence",
                  "content": {
                      "user_id": "@potato:remote",
+                     "presence": ONLINE,
                      "state": ONLINE,
                      "mtime_age": 1000,
                 }}
@@ -751,7 +776,10 @@ class PresencePushTestCase(unittest.TestCase):
 
         state = yield self.handler.get_state(self.u_potato, self.u_apple)
 
-        self.assertEquals({"state": ONLINE, "mtime_age": 3000}, state)
+        self.assertEquals(
+            {"state": ONLINE, "presence": ONLINE, "mtime_age": 3000},
+            state
+        )
 
     @defer.inlineCallbacks
     def test_join_room_local(self):
@@ -763,7 +791,7 @@ class PresencePushTestCase(unittest.TestCase):
         self.handler._user_cachemap[self.u_clementine] = UserPresenceCache()
         self.handler._user_cachemap[self.u_clementine].update(
             {
-                "state": PresenceState.ONLINE,
+                "presence": PresenceState.ONLINE,
                 "mtime": self.clock.time_msec(),
             }, self.u_clementine
         )
@@ -781,6 +809,7 @@ class PresencePushTestCase(unittest.TestCase):
                 {"type": "m.presence",
                  "content": {
                      "user_id": "@clementine:test",
+                     "presence": ONLINE,
                      "state": ONLINE,
                      "mtime_age": 0,
                 }}
@@ -798,7 +827,8 @@ class PresencePushTestCase(unittest.TestCase):
                     content={
                         "push": [
                             {"user_id": "@apple:test",
-                            "state": "online"},
+                             "presence": "online",
+                             "state": "online"},
                         ],
                     }
                 ),
@@ -812,7 +842,8 @@ class PresencePushTestCase(unittest.TestCase):
                     content={
                         "push": [
                             {"user_id": "@banana:test",
-                            "state": "offline"},
+                             "presence": "offline",
+                             "state": "offline"},
                         ],
                     }
                 ),
@@ -823,7 +854,7 @@ class PresencePushTestCase(unittest.TestCase):
         # TODO(paul): Gut-wrenching
         self.handler._user_cachemap[self.u_apple] = UserPresenceCache()
         self.handler._user_cachemap[self.u_apple].update(
-                {"state": PresenceState.ONLINE}, self.u_apple)
+                {"presence": PresenceState.ONLINE}, self.u_apple)
         self.room_members = [self.u_apple, self.u_banana]
 
         yield self.distributor.fire("user_joined_room", self.u_potato,
@@ -841,7 +872,8 @@ class PresencePushTestCase(unittest.TestCase):
                     content={
                         "push": [
                             {"user_id": "@clementine:test",
-                            "state": "online"},
+                             "presence": "online",
+                             "state": "online"},
                         ],
                     }
                 ),
@@ -851,7 +883,7 @@ class PresencePushTestCase(unittest.TestCase):
 
         self.handler._user_cachemap[self.u_clementine] = UserPresenceCache()
         self.handler._user_cachemap[self.u_clementine].update(
-                {"state": ONLINE}, self.u_clementine)
+                {"presence": ONLINE}, self.u_clementine)
         self.room_members.append(self.u_potato)
 
         yield self.distributor.fire("user_joined_room", self.u_clementine,
@@ -969,7 +1001,7 @@ class PresencePollingTestCase(unittest.TestCase):
         # apple goes online
         yield self.handler.set_state(
             target_user=self.u_apple, auth_user=self.u_apple,
-            state={"state": ONLINE}
+            state={"presence": ONLINE}
         )
 
         # apple should see both banana and clementine currently offline
@@ -992,8 +1024,9 @@ class PresencePollingTestCase(unittest.TestCase):
 
         # banana goes online
         yield self.handler.set_state(
-                target_user=self.u_banana, auth_user=self.u_banana,
-                state={"state": ONLINE})
+            target_user=self.u_banana, auth_user=self.u_banana,
+            state={"presence": ONLINE}
+        )
 
         # apple and banana should now both see each other online
         self.mock_update_client.assert_has_calls([
@@ -1013,8 +1046,9 @@ class PresencePollingTestCase(unittest.TestCase):
 
         # apple goes offline
         yield self.handler.set_state(
-                target_user=self.u_apple, auth_user=self.u_apple,
-                state={"state": OFFLINE})
+            target_user=self.u_apple, auth_user=self.u_apple,
+            state={"presence": OFFLINE}
+        )
 
         # banana should now be told apple is offline
         self.mock_update_client.assert_has_calls([
@@ -1027,7 +1061,6 @@ class PresencePollingTestCase(unittest.TestCase):
         self.assertFalse("banana" in self.handler._local_pushmap)
         self.assertFalse("clementine" in self.handler._local_pushmap)
 
-
     @defer.inlineCallbacks
     def test_remote_poll_send(self):
         put_json = self.mock_http_client.put_json
@@ -1057,8 +1090,9 @@ class PresencePollingTestCase(unittest.TestCase):
 
         # clementine goes online
         yield self.handler.set_state(
-                target_user=self.u_clementine, auth_user=self.u_clementine,
-                state={"state": ONLINE})
+            target_user=self.u_clementine, auth_user=self.u_clementine,
+            state={"presence": ONLINE}
+        )
 
         yield put_json.await_calls()
 
@@ -1085,7 +1119,7 @@ class PresencePollingTestCase(unittest.TestCase):
         # fig goes online; shouldn't send a second poll
         yield self.handler.set_state(
             target_user=self.u_fig, auth_user=self.u_fig,
-            state={"state": ONLINE}
+            state={"presence": ONLINE}
         )
 
         # reactor.iterate(delay=0)
@@ -1095,7 +1129,7 @@ class PresencePollingTestCase(unittest.TestCase):
         # fig goes offline
         yield self.handler.set_state(
             target_user=self.u_fig, auth_user=self.u_fig,
-            state={"state": OFFLINE}
+            state={"presence": OFFLINE}
         )
 
         reactor.iterate(delay=0)
@@ -1116,8 +1150,9 @@ class PresencePollingTestCase(unittest.TestCase):
 
         # clementine goes offline
         yield self.handler.set_state(
-                target_user=self.u_clementine, auth_user=self.u_clementine,
-                state={"state": OFFLINE})
+            target_user=self.u_clementine, auth_user=self.u_clementine,
+            state={"presence": OFFLINE}
+        )
 
         yield put_json.await_calls()
 
@@ -1135,6 +1170,7 @@ class PresencePollingTestCase(unittest.TestCase):
                     content={
                         "push": [
                             {"user_id": "@banana:test",
+                             "presence": "offline",
                              "state": "offline",
                              "status_msg": None},
                         ],
diff --git a/tests/handlers/test_presencelike.py b/tests/handlers/test_presencelike.py
index e81d7ce101..2402bed8d5 100644
--- a/tests/handlers/test_presencelike.py
+++ b/tests/handlers/test_presencelike.py
@@ -182,11 +182,13 @@ class PresenceProfilelikeDataTestCase(unittest.TestCase):
 
         self.assertEquals([
             {"observed_user": self.u_banana,
+                "presence": ONLINE,
                 "state": ONLINE,
                 "mtime_age": 0,
                 "displayname": "Frank",
                 "avatar_url": "http://foo"},
             {"observed_user": self.u_clementine,
+                "presence": OFFLINE,
                 "state": OFFLINE}],
         presence)
 
@@ -199,7 +201,7 @@ class PresenceProfilelikeDataTestCase(unittest.TestCase):
 
         statuscache = self.mock_update_client.call_args[1]["statuscache"]
         self.assertEquals({
-            "state": ONLINE,
+            "presence": ONLINE,
             "mtime": 1000000, # MockClock
             "displayname": "Frank",
             "avatar_url": "http://foo",
@@ -222,7 +224,7 @@ class PresenceProfilelikeDataTestCase(unittest.TestCase):
 
         statuscache = self.mock_update_client.call_args[1]["statuscache"]
         self.assertEquals({
-            "state": ONLINE,
+            "presence": ONLINE,
             "mtime": 1000000, # MockClock
             "displayname": "I am an Apple",
             "avatar_url": "http://foo",
@@ -255,6 +257,7 @@ class PresenceProfilelikeDataTestCase(unittest.TestCase):
                 content={
                     "push": [
                         {"user_id": "@apple:test",
+                         "presence": "online",
                          "state": "online",
                          "mtime_age": 0,
                          "displayname": "Frank",
@@ -293,14 +296,16 @@ class PresenceProfilelikeDataTestCase(unittest.TestCase):
             statuscache=ANY)
 
         statuscache = self.mock_update_client.call_args[1]["statuscache"]
-        self.assertEquals({"state": ONLINE,
+        self.assertEquals({"presence": ONLINE,
                            "displayname": "Frank",
                            "avatar_url": "http://foo"}, statuscache.state)
 
         state = yield self.handlers.presence_handler.get_state(self.u_potato,
                 self.u_apple)
 
-        self.assertEquals({"state": ONLINE,
-                           "displayname": "Frank",
-                           "avatar_url": "http://foo"},
-                state)
+        self.assertEquals(
+                {"presence": ONLINE,
+                 "state": ONLINE,
+                 "displayname": "Frank",
+                 "avatar_url": "http://foo"},
+            state)
diff --git a/tests/rest/test_presence.py b/tests/rest/test_presence.py
index 61692f02c2..f5afa4a256 100644
--- a/tests/rest/test_presence.py
+++ b/tests/rest/test_presence.py
@@ -98,8 +98,10 @@ class PresenceStateTestCase(unittest.TestCase):
                 "/presence/%s/status" % (myid), None)
 
         self.assertEquals(200, code)
-        self.assertEquals({"state": ONLINE, "status_msg": "Available"},
-                response)
+        self.assertEquals(
+            {"presence": ONLINE, "state": ONLINE, "status_msg": "Available"},
+            response
+        )
         mocked_get.assert_called_with("apple")
 
     @defer.inlineCallbacks
@@ -109,7 +111,7 @@ class PresenceStateTestCase(unittest.TestCase):
 
         (code, response) = yield self.mock_resource.trigger("PUT",
                 "/presence/%s/status" % (myid),
-                '{"state": "unavailable", "status_msg": "Away"}')
+                '{"presence": "unavailable", "status_msg": "Away"}')
 
         self.assertEquals(200, code)
         mocked_set.assert_called_with("apple",
@@ -173,9 +175,9 @@ class PresenceListTestCase(unittest.TestCase):
                 "/presence/list/%s" % (myid), None)
 
         self.assertEquals(200, code)
-        self.assertEquals(
-            [{"user_id": "@banana:test", "state": OFFLINE}], response
-        )
+        self.assertEquals([
+            {"user_id": "@banana:test", "presence": OFFLINE, "state": OFFLINE},
+        ], response)
 
         self.datastore.get_presence_list.assert_called_with(
             "apple", accepted=True
@@ -314,7 +316,8 @@ class PresenceEventStreamTestCase(unittest.TestCase):
                 [])
 
         yield self.presence.set_state(self.u_banana, self.u_banana,
-                state={"state": ONLINE})
+            state={"presence": ONLINE}
+        )
 
         (code, response) = yield self.mock_resource.trigger("GET",
                 "/events?from=0_1_0&timeout=0", None)
@@ -324,6 +327,7 @@ class PresenceEventStreamTestCase(unittest.TestCase):
             {"type": "m.presence",
              "content": {
                  "user_id": "@banana:test",
+                 "presence": ONLINE,
                  "state": ONLINE,
                  "displayname": "Frank",
                  "mtime_age": 0,