diff --git a/server/lobbyconnection.py b/server/lobbyconnection.py index bf028d8b8..ad87aeca7 100644 --- a/server/lobbyconnection.py +++ b/server/lobbyconnection.py @@ -18,6 +18,7 @@ import server.metrics as metrics from server.db import FAFDatabase +from server.timing import datetime_now from .config import TRACE, config from .db.models import ( @@ -693,6 +694,7 @@ async def on_player_login( await self.send({ "command": "welcome", "me": self.player.to_dict(), + "current_time": datetime_now().isoformat(), # For backwards compatibility for old clients. For now. "id": self.player.id, diff --git a/tests/integration_tests/conftest.py b/tests/integration_tests/conftest.py index 4008037bb..60f2c5b89 100644 --- a/tests/integration_tests/conftest.py +++ b/tests/integration_tests/conftest.py @@ -1,4 +1,5 @@ import asyncio +import datetime import hashlib import json import logging @@ -240,6 +241,37 @@ def lobby_contexts_proxy(lobby_setup_proxy): return contexts +@pytest.fixture +def fixed_time(monkeypatch): + """ + Fixture to fix server.timing value. By default, fixes all timings at 1970-01-01T00:00:00+00:00. Additionally, returned function can be called unbound times to change timing value, e.g.: + + def test_time(fixed_time): + assert server.lobbyconnection.datetime_now().timestamp == 0. + fixed_time(1) + assert server.lobbyconnection.datetime_now().timestamp == 1. + """ + + def fix_time(iso_utc_time: str | float | int | datetime.datetime = 0): + """ + Fix server.timing value. + + :param iso_utc_time: UTC time to use. Can be isoformat, timestamp or native object. + """ + if isinstance(iso_utc_time, str): + iso_utc_time = datetime.datetime.fromisoformat(iso_utc_time) + elif isinstance(iso_utc_time, (float, int)): + iso_utc_time = datetime.datetime.fromtimestamp(iso_utc_time, datetime.timezone.utc) + + def mock_datetime_now() -> datetime: + return iso_utc_time + + monkeypatch.setattr("server.lobbyconnection.datetime_now", mock_datetime_now) + + fix_time() + return fix_time + + # TODO: This fixture is poorly named since it returns a ServerContext, however, # it is used in almost every tests, so renaming it is a large task. @pytest.fixture(params=("qstream", "json")) diff --git a/tests/integration_tests/test_login.py b/tests/integration_tests/test_login.py index 179d71214..d51a9205d 100644 --- a/tests/integration_tests/test_login.py +++ b/tests/integration_tests/test_login.py @@ -92,7 +92,7 @@ async def test_server_ban_revoked_or_expired(lobby_server, user): assert msg["login"] == user -async def test_server_login_valid(lobby_server): +async def test_server_login_valid(lobby_server, fixed_time): proto = await connect_client(lobby_server) await perform_login(proto, ("Rhiza", "puff_the_magic_dragon")) msg = await proto.read_message() @@ -118,6 +118,7 @@ async def test_server_login_valid(lobby_server): assert msg == { "command": "welcome", "me": me, + "current_time": "1970-01-01T00:00:00+00:00", "id": 3, "login": "Rhiza" } @@ -137,7 +138,7 @@ async def test_server_login_valid(lobby_server): } -async def test_server_login_valid_admin(lobby_server): +async def test_server_login_valid_admin(lobby_server, fixed_time): proto = await connect_client(lobby_server) await perform_login(proto, ("test", "test_password")) msg = await proto.read_message() @@ -163,6 +164,7 @@ async def test_server_login_valid_admin(lobby_server): assert msg == { "command": "welcome", "me": me, + "current_time": "1970-01-01T00:00:00+00:00", "id": 1, "login": "test" } @@ -182,7 +184,7 @@ async def test_server_login_valid_admin(lobby_server): } -async def test_server_login_valid_moderator(lobby_server): +async def test_server_login_valid_moderator(lobby_server, fixed_time): proto = await connect_client(lobby_server) await perform_login(proto, ("moderator", "moderator")) msg = await proto.read_message() @@ -207,6 +209,7 @@ async def test_server_login_valid_moderator(lobby_server): assert msg == { "command": "welcome", "me": me, + "current_time": "1970-01-01T00:00:00+00:00", "id": 20, "login": "moderator" } @@ -261,7 +264,7 @@ async def test_server_login_double(lobby_server): } -async def test_server_login_token_valid(lobby_server, jwk_priv_key, jwk_kid): +async def test_server_login_token_valid(lobby_server, jwk_priv_key, jwk_kid, fixed_time): proto = await connect_client(lobby_server) await proto.send_message({ "command": "auth", @@ -305,6 +308,7 @@ async def test_server_login_token_valid(lobby_server, jwk_priv_key, jwk_kid): assert msg == { "command": "welcome", "me": me, + "current_time": "1970-01-01T00:00:00+00:00", "id": 3, "login": "Rhiza" }