diff --git a/openslides/utils/cache.py b/openslides/utils/cache.py index f42df338b..7fd4124ad 100644 --- a/openslides/utils/cache.py +++ b/openslides/utils/cache.py @@ -189,7 +189,9 @@ class ElementCache: if change_id == 0: return (await self.get_all_full_data(), []) + # This raises a Runtime Exception, if there is no change_id lowest_change_id = await self.get_lowest_change_id() + if change_id < lowest_change_id: # When change_id is lower then the lowest change_id in redis, we can # not inform the user about deleted elements. diff --git a/tests/integration/utils/test_consumers.py b/tests/integration/utils/test_consumers.py index 6ed3e3884..e319d4ca6 100644 --- a/tests/integration/utils/test_consumers.py +++ b/tests/integration/utils/test_consumers.py @@ -333,6 +333,48 @@ async def test_send_get_elements_to_small_change_id(communicator): assert response.get('content')['all_data'] +@pytest.mark.asyncio +async def test_send_connect_twice_with_clear_change_id_cache(communicator): + """ + Test, that a second request with change_id+1 from the first request, returns + an error. + """ + await set_config('general_system_enable_anonymous', True) + element_cache.cache_provider.change_id_data = {} # type: ignore + await communicator.connect() + await communicator.send_json_to({'type': 'getElements', 'content': {'change_id': 0}, 'id': 'test_id'}) + response1 = await communicator.receive_json_from() + first_change_id = response1.get('content')['to_change_id'] + + await communicator.send_json_to({'type': 'getElements', 'content': {'change_id': first_change_id+1}, 'id': 'test_id'}) + response2 = await communicator.receive_json_from() + + assert response2['type'] == 'error' + assert response2.get('content') == 'Requested change_id is higher this highest change_id.' + + +@pytest.mark.asyncio +async def test_send_connect_twice_with_clear_change_id_cache_same_change_id_then_first_request(communicator): + """ + Test, that a second request with the change_id from the first request, returns + all data. + + A client should not do this but request for change_id+1 + """ + await set_config('general_system_enable_anonymous', True) + element_cache.cache_provider.change_id_data = {} # type: ignore + await communicator.connect() + await communicator.send_json_to({'type': 'getElements', 'content': {'change_id': 0}, 'id': 'test_id'}) + response1 = await communicator.receive_json_from() + first_change_id = response1.get('content')['to_change_id'] + + await communicator.send_json_to({'type': 'getElements', 'content': {'change_id': first_change_id}, 'id': 'test_id'}) + response2 = await communicator.receive_json_from() + + assert response2['type'] == 'autoupdate' + assert response2.get('content')['all_data'] + + @pytest.mark.asyncio async def test_send_invalid_get_elements(communicator): await set_config('general_system_enable_anonymous', True)