Skip to content

Commit e279ed4

Browse files
committed
Add test that required state is immediately returned
1 parent d201b45 commit e279ed4

2 files changed

Lines changed: 82 additions & 4 deletions

File tree

tests/rest/client/sliding_sync/test_rooms_required_state.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2245,3 +2245,58 @@ def test_lazy_loading_room_members_state_reset_non_limited_timeline(self) -> Non
22452245
response_body["rooms"][room_id]["required_state"][0]["event_id"],
22462246
first_event_id,
22472247
)
2248+
2249+
def test_changing_required_state_returns_immediately(self) -> None:
2250+
"""Test that if we change the required state, then we return immediately
2251+
with the new required state."""
2252+
2253+
user1_id = self.register_user("user1", "pass")
2254+
user1_tok = self.login(user1_id, "pass")
2255+
2256+
room_id1 = self.helper.create_room_as(user1_id, tok=user1_tok)
2257+
2258+
# Make an initial sync request with no required state
2259+
sync_body = {
2260+
"lists": {
2261+
"foo-list": {
2262+
"ranges": [[0, 1]],
2263+
"required_state": [],
2264+
"timeline_limit": 0,
2265+
}
2266+
}
2267+
}
2268+
response_body, from_token = self.do_sync(sync_body, tok=user1_tok)
2269+
2270+
# We should see no required state
2271+
self.assertIsNone(response_body["rooms"][room_id1].get("required_state"))
2272+
2273+
# Get the state_map before we change the state as this is the final state we
2274+
# expect to see when we update the required state.
2275+
state_map = self.get_success(
2276+
self.storage_controllers.state.get_current_state(room_id1)
2277+
)
2278+
2279+
# There is no new data, and so making another sync request will block.
2280+
channel = self.make_sync_request(
2281+
sync_body, since=from_token, tok=user1_tok, timeout_ms=10000
2282+
)
2283+
self.assertFalse(channel.is_finished())
2284+
2285+
# Now update the sliding sync requests to include a required state
2286+
# event, and make another sync request.
2287+
sync_body["lists"]["foo-list"]["required_state"] = [
2288+
[EventTypes.Create, ""],
2289+
]
2290+
2291+
response_body, _ = self.do_sync(
2292+
sync_body, since=from_token, tok=user1_tok, timeout_ms=10000
2293+
)
2294+
2295+
# We should see the new required state immediately without waiting.
2296+
self._assertRequiredStateIncludes(
2297+
response_body["rooms"][room_id1]["required_state"],
2298+
{
2299+
state_map[(EventTypes.Create, "")],
2300+
},
2301+
exact=True,
2302+
)

tests/rest/client/sliding_sync/test_sliding_sync.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# <https://www.gnu.org/licenses/agpl-3.0.html>.
1313
#
1414
import logging
15+
import urllib.parse
1516
from typing import Any, Iterable, Literal
1617
from unittest.mock import AsyncMock
1718

@@ -81,22 +82,36 @@ def default_config(self) -> JsonDict:
8182
return config
8283

8384
def make_sync_request(
84-
self, sync_body: JsonDict, *, since: str | None = None, tok: str
85+
self,
86+
sync_body: JsonDict,
87+
*,
88+
since: str | None = None,
89+
tok: str,
90+
timeout_ms: int | None = None,
8591
) -> FakeChannel:
8692
"""Make a sliding sync request with given body.
8793
8894
Attributes:
8995
sync_body: The full request body to use
9096
since: Optional since token
9197
tok: Access token to use
98+
timeout_ms: Optional timeout in milliseconds to use for the request.
9299
93100
Returns:
94101
A tuple of the response body and the `pos` field.
95102
"""
96103

97104
sync_path = self.sync_endpoint
105+
106+
query_params: dict[str, Any] = {}
98107
if since:
99-
sync_path += f"?pos={since}"
108+
query_params["pos"] = since
109+
if timeout_ms is not None:
110+
query_params["timeout"] = timeout_ms
111+
112+
if query_params:
113+
query_str = urllib.parse.urlencode(query_params)
114+
sync_path += f"?{query_str}"
100115

101116
channel = self.make_request(
102117
method="POST",
@@ -107,7 +122,12 @@ def make_sync_request(
107122
return channel
108123

109124
def do_sync(
110-
self, sync_body: JsonDict, *, since: str | None = None, tok: str
125+
self,
126+
sync_body: JsonDict,
127+
*,
128+
since: str | None = None,
129+
tok: str,
130+
timeout_ms: int | None = None,
111131
) -> tuple[JsonDict, str]:
112132
"""Do a sliding sync request with given body.
113133
@@ -117,11 +137,14 @@ def do_sync(
117137
sync_body: The full request body to use
118138
since: Optional since token
119139
tok: Access token to use
140+
timeout_ms: Optional timeout in milliseconds to use for the request.
120141
121142
Returns:
122143
A tuple of the response body and the `pos` field.
123144
"""
124-
channel = self.make_sync_request(sync_body, since=since, tok=tok)
145+
channel = self.make_sync_request(
146+
sync_body, since=since, tok=tok, timeout_ms=timeout_ms
147+
)
125148
self.assertEqual(channel.code, 200, channel.json_body)
126149

127150
return channel.json_body, channel.json_body["pos"]

0 commit comments

Comments
 (0)