test_events.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. # Copyright 2016 OpenMarket Ltd
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. from ._base import BaseSlavedStoreTestCase
  15. from synapse.events import FrozenEvent, _EventInternalMetadata
  16. from synapse.events.snapshot import EventContext
  17. from synapse.replication.slave.storage.events import SlavedEventStore
  18. from synapse.storage.roommember import RoomsForUser
  19. from twisted.internet import defer
  20. USER_ID = "@feeling:blue"
  21. USER_ID_2 = "@bright:blue"
  22. OUTLIER = {"outlier": True}
  23. ROOM_ID = "!room:blue"
  24. def dict_equals(self, other):
  25. return self.__dict__ == other.__dict__
  26. def patch__eq__(cls):
  27. eq = getattr(cls, "__eq__", None)
  28. cls.__eq__ = dict_equals
  29. def unpatch():
  30. if eq is not None:
  31. cls.__eq__ = eq
  32. return unpatch
  33. class SlavedEventStoreTestCase(BaseSlavedStoreTestCase):
  34. STORE_TYPE = SlavedEventStore
  35. def setUp(self):
  36. # Patch up the equality operator for events so that we can check
  37. # whether lists of events match using assertEquals
  38. self.unpatches = [
  39. patch__eq__(_EventInternalMetadata),
  40. patch__eq__(FrozenEvent),
  41. ]
  42. return super(SlavedEventStoreTestCase, self).setUp()
  43. def tearDown(self):
  44. [unpatch() for unpatch in self.unpatches]
  45. @defer.inlineCallbacks
  46. def test_room_name_and_aliases(self):
  47. create = yield self.persist(type="m.room.create", key="", creator=USER_ID)
  48. yield self.persist(type="m.room.member", key=USER_ID, membership="join")
  49. yield self.persist(type="m.room.name", key="", name="name1")
  50. yield self.persist(
  51. type="m.room.aliases", key="blue", aliases=["#1:blue"]
  52. )
  53. yield self.replicate()
  54. yield self.check(
  55. "get_room_name_and_aliases", (ROOM_ID,), ("name1", ["#1:blue"])
  56. )
  57. # Set the room name.
  58. yield self.persist(type="m.room.name", key="", name="name2")
  59. yield self.replicate()
  60. yield self.check(
  61. "get_room_name_and_aliases", (ROOM_ID,), ("name2", ["#1:blue"])
  62. )
  63. # Set the room aliases.
  64. yield self.persist(
  65. type="m.room.aliases", key="blue", aliases=["#2:blue"]
  66. )
  67. yield self.replicate()
  68. yield self.check(
  69. "get_room_name_and_aliases", (ROOM_ID,), ("name2", ["#2:blue"])
  70. )
  71. # Leave and join the room clobbering the state.
  72. yield self.persist(type="m.room.member", key=USER_ID, membership="leave")
  73. yield self.persist(
  74. type="m.room.member", key=USER_ID, membership="join",
  75. reset_state=[create]
  76. )
  77. yield self.replicate()
  78. yield self.check(
  79. "get_room_name_and_aliases", (ROOM_ID,), (None, [])
  80. )
  81. @defer.inlineCallbacks
  82. def test_room_members(self):
  83. create = yield self.persist(type="m.room.create", key="", creator=USER_ID)
  84. yield self.replicate()
  85. yield self.check("get_rooms_for_user", (USER_ID,), [])
  86. yield self.check("get_users_in_room", (ROOM_ID,), [])
  87. # Join the room.
  88. join = yield self.persist(type="m.room.member", key=USER_ID, membership="join")
  89. yield self.replicate()
  90. yield self.check("get_rooms_for_user", (USER_ID,), [RoomsForUser(
  91. room_id=ROOM_ID,
  92. sender=USER_ID,
  93. membership="join",
  94. event_id=join.event_id,
  95. stream_ordering=join.internal_metadata.stream_ordering,
  96. )])
  97. yield self.check("get_users_in_room", (ROOM_ID,), [USER_ID])
  98. # Leave the room.
  99. yield self.persist(type="m.room.member", key=USER_ID, membership="leave")
  100. yield self.replicate()
  101. yield self.check("get_rooms_for_user", (USER_ID,), [])
  102. yield self.check("get_users_in_room", (ROOM_ID,), [])
  103. # Add some other user to the room.
  104. join = yield self.persist(type="m.room.member", key=USER_ID_2, membership="join")
  105. yield self.replicate()
  106. yield self.check("get_rooms_for_user", (USER_ID_2,), [RoomsForUser(
  107. room_id=ROOM_ID,
  108. sender=USER_ID,
  109. membership="join",
  110. event_id=join.event_id,
  111. stream_ordering=join.internal_metadata.stream_ordering,
  112. )])
  113. yield self.check("get_users_in_room", (ROOM_ID,), [USER_ID_2])
  114. # Join the room clobbering the state.
  115. # This should remove any evidence of the other user being in the room.
  116. yield self.persist(
  117. type="m.room.member", key=USER_ID, membership="join",
  118. reset_state=[create]
  119. )
  120. yield self.replicate()
  121. yield self.check("get_users_in_room", (ROOM_ID,), [USER_ID])
  122. yield self.check("get_rooms_for_user", (USER_ID_2,), [])
  123. @defer.inlineCallbacks
  124. def test_get_latest_event_ids_in_room(self):
  125. create = yield self.persist(type="m.room.create", key="", creator=USER_ID)
  126. yield self.replicate()
  127. yield self.check(
  128. "get_latest_event_ids_in_room", (ROOM_ID,), [create.event_id]
  129. )
  130. join = yield self.persist(
  131. type="m.room.member", key=USER_ID, membership="join",
  132. prev_events=[(create.event_id, {})],
  133. )
  134. yield self.replicate()
  135. yield self.check(
  136. "get_latest_event_ids_in_room", (ROOM_ID,), [join.event_id]
  137. )
  138. @defer.inlineCallbacks
  139. def test_get_current_state(self):
  140. # Create the room.
  141. create = yield self.persist(type="m.room.create", key="", creator=USER_ID)
  142. yield self.replicate()
  143. yield self.check(
  144. "get_current_state_for_key", (ROOM_ID, "m.room.member", USER_ID), []
  145. )
  146. # Join the room.
  147. join1 = yield self.persist(
  148. type="m.room.member", key=USER_ID, membership="join",
  149. )
  150. yield self.replicate()
  151. yield self.check(
  152. "get_current_state_for_key", (ROOM_ID, "m.room.member", USER_ID),
  153. [join1]
  154. )
  155. # Add some other user to the room.
  156. join2 = yield self.persist(
  157. type="m.room.member", key=USER_ID_2, membership="join",
  158. )
  159. yield self.replicate()
  160. yield self.check(
  161. "get_current_state_for_key", (ROOM_ID, "m.room.member", USER_ID_2),
  162. [join2]
  163. )
  164. # Leave the room, then rejoin the room clobbering state.
  165. yield self.persist(type="m.room.member", key=USER_ID, membership="leave")
  166. join3 = yield self.persist(
  167. type="m.room.member", key=USER_ID, membership="join",
  168. reset_state=[create]
  169. )
  170. yield self.replicate()
  171. yield self.check(
  172. "get_current_state_for_key", (ROOM_ID, "m.room.member", USER_ID_2),
  173. []
  174. )
  175. yield self.check(
  176. "get_current_state_for_key", (ROOM_ID, "m.room.member", USER_ID),
  177. [join3]
  178. )
  179. @defer.inlineCallbacks
  180. def test_redactions(self):
  181. yield self.persist(type="m.room.create", key="", creator=USER_ID)
  182. yield self.persist(type="m.room.member", key=USER_ID, membership="join")
  183. msg = yield self.persist(
  184. type="m.room.message", msgtype="m.text", body="Hello"
  185. )
  186. yield self.replicate()
  187. yield self.check("get_event", [msg.event_id], msg)
  188. redaction = yield self.persist(
  189. type="m.room.redaction", redacts=msg.event_id
  190. )
  191. yield self.replicate()
  192. msg_dict = msg.get_dict()
  193. msg_dict["content"] = {}
  194. msg_dict["unsigned"]["redacted_by"] = redaction.event_id
  195. msg_dict["unsigned"]["redacted_because"] = redaction
  196. redacted = FrozenEvent(msg_dict, msg.internal_metadata.get_dict())
  197. yield self.check("get_event", [msg.event_id], redacted)
  198. @defer.inlineCallbacks
  199. def test_backfilled_redactions(self):
  200. yield self.persist(type="m.room.create", key="", creator=USER_ID)
  201. yield self.persist(type="m.room.member", key=USER_ID, membership="join")
  202. msg = yield self.persist(
  203. type="m.room.message", msgtype="m.text", body="Hello"
  204. )
  205. yield self.replicate()
  206. yield self.check("get_event", [msg.event_id], msg)
  207. redaction = yield self.persist(
  208. type="m.room.redaction", redacts=msg.event_id, backfill=True
  209. )
  210. yield self.replicate()
  211. msg_dict = msg.get_dict()
  212. msg_dict["content"] = {}
  213. msg_dict["unsigned"]["redacted_by"] = redaction.event_id
  214. msg_dict["unsigned"]["redacted_because"] = redaction
  215. redacted = FrozenEvent(msg_dict, msg.internal_metadata.get_dict())
  216. yield self.check("get_event", [msg.event_id], redacted)
  217. @defer.inlineCallbacks
  218. def test_invites(self):
  219. yield self.check("get_invited_rooms_for_user", [USER_ID_2], [])
  220. event = yield self.persist(
  221. type="m.room.member", key=USER_ID_2, membership="invite"
  222. )
  223. yield self.replicate()
  224. yield self.check("get_invited_rooms_for_user", [USER_ID_2], [RoomsForUser(
  225. ROOM_ID, USER_ID, "invite", event.event_id,
  226. event.internal_metadata.stream_ordering
  227. )])
  228. @defer.inlineCallbacks
  229. def test_push_actions_for_user(self):
  230. yield self.persist(type="m.room.create", creator=USER_ID)
  231. yield self.persist(type="m.room.join", key=USER_ID, membership="join")
  232. yield self.persist(
  233. type="m.room.join", sender=USER_ID, key=USER_ID_2, membership="join"
  234. )
  235. event1 = yield self.persist(
  236. type="m.room.message", msgtype="m.text", body="hello"
  237. )
  238. yield self.replicate()
  239. yield self.check(
  240. "get_unread_event_push_actions_by_room_for_user",
  241. [ROOM_ID, USER_ID_2, event1.event_id],
  242. {"highlight_count": 0, "notify_count": 0}
  243. )
  244. yield self.persist(
  245. type="m.room.message", msgtype="m.text", body="world",
  246. push_actions=[(USER_ID_2, ["notify"])],
  247. )
  248. yield self.replicate()
  249. yield self.check(
  250. "get_unread_event_push_actions_by_room_for_user",
  251. [ROOM_ID, USER_ID_2, event1.event_id],
  252. {"highlight_count": 0, "notify_count": 1}
  253. )
  254. yield self.persist(
  255. type="m.room.message", msgtype="m.text", body="world",
  256. push_actions=[(USER_ID_2, [
  257. "notify", {"set_tweak": "highlight", "value": True}
  258. ])],
  259. )
  260. yield self.replicate()
  261. yield self.check(
  262. "get_unread_event_push_actions_by_room_for_user",
  263. [ROOM_ID, USER_ID_2, event1.event_id],
  264. {"highlight_count": 1, "notify_count": 2}
  265. )
  266. event_id = 0
  267. @defer.inlineCallbacks
  268. def persist(
  269. self, sender=USER_ID, room_id=ROOM_ID, type={}, key=None, internal={},
  270. state=None, reset_state=False, backfill=False,
  271. depth=None, prev_events=[], auth_events=[], prev_state=[], redacts=None,
  272. push_actions=[],
  273. **content
  274. ):
  275. """
  276. Returns:
  277. synapse.events.FrozenEvent: The event that was persisted.
  278. """
  279. if depth is None:
  280. depth = self.event_id
  281. event_dict = {
  282. "sender": sender,
  283. "type": type,
  284. "content": content,
  285. "event_id": "$%d:blue" % (self.event_id,),
  286. "room_id": room_id,
  287. "depth": depth,
  288. "origin_server_ts": self.event_id,
  289. "prev_events": prev_events,
  290. "auth_events": auth_events,
  291. }
  292. if key is not None:
  293. event_dict["state_key"] = key
  294. event_dict["prev_state"] = prev_state
  295. if redacts is not None:
  296. event_dict["redacts"] = redacts
  297. event = FrozenEvent(event_dict, internal_metadata_dict=internal)
  298. self.event_id += 1
  299. context = EventContext(current_state=state)
  300. context.push_actions = push_actions
  301. ordering = None
  302. if backfill:
  303. yield self.master_store.persist_events(
  304. [(event, context)], backfilled=True
  305. )
  306. else:
  307. ordering, _ = yield self.master_store.persist_event(
  308. event, context, current_state=reset_state
  309. )
  310. if ordering:
  311. event.internal_metadata.stream_ordering = ordering
  312. defer.returnValue(event)