fix: repair linked panel email during sync

This commit is contained in:
3252a8
2026-05-23 22:27:51 +03:00
parent 60d8c297f9
commit 31eb5c06ad
4 changed files with 291 additions and 9 deletions
+43
View File
@@ -9,6 +9,7 @@ from bot.app.web.webapp import account as account_routes
from bot.app.web.webapp.auth import (
_link_telegram_to_user,
_sync_merged_panel_identity_for_user,
_sync_panel_identity_for_user,
)
@@ -30,6 +31,48 @@ class AccountLinkingPanelTests(unittest.IsolatedAsyncioTestCase):
async def __aexit__(self, exc_type, exc, tb):
return None
async def test_panel_identity_sync_reports_failed_update_response(self):
user = SimpleNamespace(
user_id=42,
panel_user_uuid="panel-42",
email="linked@example.com",
telegram_id=42,
username="alice",
first_name=None,
last_name=None,
)
panel_service = SimpleNamespace(update_user_details_on_panel=AsyncMock(return_value=None))
request = SimpleNamespace(
app={"subscription_service": SimpleNamespace(panel_service=panel_service)}
)
result = await _sync_panel_identity_for_user(request, user)
self.assertFalse(result)
panel_service.update_user_details_on_panel.assert_awaited_once()
async def test_panel_identity_sync_reports_successful_update_response(self):
user = SimpleNamespace(
user_id=42,
panel_user_uuid="panel-42",
email="linked@example.com",
telegram_id=42,
username="alice",
first_name=None,
last_name=None,
)
panel_service = SimpleNamespace(
update_user_details_on_panel=AsyncMock(return_value={"uuid": "panel-42"})
)
request = SimpleNamespace(
app={"subscription_service": SimpleNamespace(panel_service=panel_service)}
)
result = await _sync_panel_identity_for_user(request, user)
self.assertTrue(result)
panel_service.update_user_details_on_panel.assert_awaited_once()
async def test_merged_panel_identity_deletes_source_before_updating_target(self):
calls = []
+105
View File
@@ -7,6 +7,9 @@ from bot.handlers.admin.sync_admin import (
_absorb_duplicate_panel_identity,
_coerce_panel_telegram_id,
_description_matches,
_panel_identity_matches_user,
_panel_identity_needs_full_fetch,
_panel_identity_view_for_comparison,
_should_update_lifetime_used_traffic,
_subscription_update_delta,
)
@@ -36,6 +39,108 @@ def test_panel_telegram_id_is_coerced_to_int():
assert _coerce_panel_telegram_id("") is None
def test_panel_identity_match_treats_missing_list_email_as_unknown():
user = SimpleNamespace(
email="linked@example.com",
telegram_id=42,
)
panel_user = {
"description": "linked@example.com\nalice",
"telegramId": 42,
}
assert _panel_identity_matches_user(
panel_user,
user,
"linked@example.com\nalice",
)
def test_panel_identity_match_treats_missing_full_email_as_mismatch():
user = SimpleNamespace(
email="linked@example.com",
telegram_id=42,
)
panel_user = {
"description": "linked@example.com\nalice",
"telegramId": 42,
}
assert not _panel_identity_matches_user(
panel_user,
user,
"linked@example.com\nalice",
missing_identity_fields_match=False,
)
def test_panel_identity_match_rejects_different_returned_email():
user = SimpleNamespace(
email="linked@example.com",
telegram_id=42,
)
panel_user = {
"description": "linked@example.com\nalice",
"email": "other@example.com",
"telegramId": 42,
}
assert not _panel_identity_matches_user(
panel_user,
user,
"linked@example.com\nalice",
)
def test_panel_identity_needs_full_fetch_for_missing_or_blank_identity_fields():
user = SimpleNamespace(
email="linked@example.com",
telegram_id=42,
)
assert _panel_identity_needs_full_fetch({"telegramId": 42}, user)
assert _panel_identity_needs_full_fetch({"email": "", "telegramId": 42}, user)
assert _panel_identity_needs_full_fetch({"email": "linked@example.com"}, user)
assert not _panel_identity_needs_full_fetch(
{"email": "linked@example.com", "telegramId": "42"},
user,
)
def test_panel_identity_view_fetches_full_user_when_list_email_missing():
panel_service = SimpleNamespace(
get_user_by_uuid=AsyncMock(
return_value={
"uuid": "panel-1",
"description": "linked@example.com\nalice",
"email": "linked@example.com",
"telegramId": 42,
}
)
)
user = SimpleNamespace(
email="linked@example.com",
telegram_id=42,
)
panel_user, missing_fields_match = asyncio.run(
_panel_identity_view_for_comparison(
panel_service,
"panel-1",
{
"uuid": "panel-1",
"description": "linked@example.com\nalice",
"telegramId": 42,
},
user,
)
)
assert panel_user["email"] == "linked@example.com"
assert not missing_fields_match
panel_service.get_user_by_uuid.assert_awaited_once_with("panel-1")
def test_subscription_update_delta_skips_unchanged_fields():
end_date = datetime(2026, 5, 20, 12, 0, tzinfo=timezone.utc)
subscription = Subscription(