perf: batch authorization and activity updates
This commit is contained in:
100
tests/test_auth_activity_touches.py
Normal file
100
tests/test_auth_activity_touches.py
Normal file
@@ -0,0 +1,100 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from types import SimpleNamespace
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from govoplan_access.backend.security.api_keys import authenticate_api_key
|
||||
from govoplan_access.backend.security.sessions import authenticate_session_token
|
||||
|
||||
|
||||
class AuthenticationActivityTouchTests(TestCase):
|
||||
def test_session_activity_is_touched_only_after_the_interval(self) -> None:
|
||||
now = datetime(2026, 7, 29, 10, 0, tzinfo=timezone.utc)
|
||||
for age_seconds, should_touch in ((60, False), (301, True)):
|
||||
with self.subTest(age_seconds=age_seconds):
|
||||
model = SimpleNamespace(
|
||||
expires_at=now + timedelta(hours=1),
|
||||
last_seen_at=now - timedelta(seconds=age_seconds),
|
||||
)
|
||||
session = MagicMock()
|
||||
(
|
||||
session.query.return_value.options.return_value
|
||||
.filter.return_value.one_or_none
|
||||
).return_value = model
|
||||
|
||||
with (
|
||||
patch(
|
||||
"govoplan_access.backend.security.sessions.hash_session_token",
|
||||
return_value="hashed",
|
||||
),
|
||||
patch(
|
||||
"govoplan_access.backend.security.sessions.utc_now",
|
||||
return_value=now,
|
||||
),
|
||||
):
|
||||
result = authenticate_session_token(
|
||||
session,
|
||||
"token",
|
||||
touch_interval_seconds=300,
|
||||
)
|
||||
|
||||
self.assertIs(model, result)
|
||||
if should_touch:
|
||||
self.assertEqual(now, model.last_seen_at)
|
||||
session.add.assert_called_once_with(model)
|
||||
else:
|
||||
self.assertEqual(
|
||||
now - timedelta(seconds=age_seconds),
|
||||
model.last_seen_at,
|
||||
)
|
||||
session.add.assert_not_called()
|
||||
|
||||
def test_api_key_activity_is_touched_only_after_the_interval(self) -> None:
|
||||
now = datetime(2026, 7, 29, 10, 0, tzinfo=timezone.utc)
|
||||
for age_seconds, should_touch in ((60, False), (301, True)):
|
||||
with self.subTest(age_seconds=age_seconds):
|
||||
model = SimpleNamespace(
|
||||
expires_at=None,
|
||||
last_used_at=now - timedelta(seconds=age_seconds),
|
||||
key_hash="hashed",
|
||||
)
|
||||
session = MagicMock()
|
||||
(
|
||||
session.query.return_value.options.return_value
|
||||
.filter.return_value.all
|
||||
).return_value = [model]
|
||||
|
||||
with (
|
||||
patch(
|
||||
"govoplan_access.backend.security.api_keys.verify_api_key",
|
||||
return_value=True,
|
||||
),
|
||||
patch(
|
||||
"govoplan_access.backend.security.api_keys.utc_now",
|
||||
return_value=now,
|
||||
),
|
||||
):
|
||||
result = authenticate_api_key(
|
||||
session,
|
||||
"mm_test-token",
|
||||
touch_interval_seconds=300,
|
||||
)
|
||||
|
||||
self.assertIs(model, result)
|
||||
if should_touch:
|
||||
self.assertEqual(now, model.last_used_at)
|
||||
session.add.assert_called_once_with(model)
|
||||
else:
|
||||
self.assertEqual(
|
||||
now - timedelta(seconds=age_seconds),
|
||||
model.last_used_at,
|
||||
)
|
||||
session.add.assert_not_called()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import unittest
|
||||
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user