Files
GmRelayBot/tests/e2e/helpers/test_telegram_init_data.py
T
Toutsu 5319592964 feat(e2e): shared initData / Login Widget payload builder for E2E tests
- Add TelegramAuthPayloadBuilder in GmRelay.Shared for C# tests.
- Refactor TelegramAuthServiceTests to use the shared builder.
- Add Python equivalent (telegram_init_data.py) for E2E runner.
- Add self-contained Python tests and E2E README.

Closes #144

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 11:53:22 +03:00

134 lines
4.1 KiB
Python

"""Self-contained tests for telegram_init_data helper.
Run with: python tests/e2e/helpers/test_telegram_init_data.py
"""
import sys
import urllib.parse
from telegram_init_data import (
build_login_widget,
build_mini_app_init_data,
compute_login_widget_hash,
compute_mini_app_hash,
)
def _parse_init_data(init_data_raw: str) -> dict[str, str]:
return {
k: v for k, v in (pair.split("=", 1) for pair in init_data_raw.split("&"))
}
def test_login_widget_hash_matches_expected_algorithm():
bot_token = "test-bot-token"
values = {"auth_date": "1714300000", "first_name": "Ada", "id": "424242"}
hash_value = compute_login_widget_hash(bot_token, values)
assert len(hash_value) == 64, f"expected 64 hex chars, got {len(hash_value)}"
assert hash_value == hash_value.lower(), "hash must be lowercase hex"
print("PASS test_login_widget_hash_matches_expected_algorithm")
def test_mini_app_hash_matches_expected_algorithm():
bot_token = "test-bot-token"
values = {
"auth_date": "1714300000",
"user": '{"id":424242,"first_name":"Ada"}',
}
hash_value = compute_mini_app_hash(bot_token, values)
assert len(hash_value) == 64, f"expected 64 hex chars, got {len(hash_value)}"
assert hash_value == hash_value.lower(), "hash must be lowercase hex"
print("PASS test_mini_app_hash_matches_expected_algorithm")
def test_build_login_widget_contains_all_fields():
result = build_login_widget(
bot_token="test-bot-token",
telegram_id=424242,
first_name="Ada",
last_name="Lovelace",
username="ada",
photo_url="https://t.me/i/userpic/320/ada.jpg",
auth_date=1714300000,
)
parsed = _parse_init_data(result.query_string)
assert parsed["id"] == "424242"
assert parsed["first_name"] == "Ada"
assert parsed["last_name"] == "Lovelace"
assert parsed["username"] == "ada"
assert urllib.parse.unquote(parsed["photo_url"]) == "https://t.me/i/userpic/320/ada.jpg"
assert parsed["auth_date"] == "1714300000"
assert parsed["hash"] == result.hash
print("PASS test_build_login_widget_contains_all_fields")
def test_build_mini_app_init_data_contains_all_fields():
result = build_mini_app_init_data(
bot_token="test-bot-token",
telegram_id=424242,
first_name="Ada",
last_name="Lovelace",
username="ada",
query_id="AAHdF6IQAAAAAN0XohDhrOrc",
start_param="ref123",
auth_date=1714300000,
)
parsed = _parse_init_data(result.init_data_raw)
assert parsed["auth_date"] == "1714300000"
assert parsed["hash"] == result.hash
assert urllib.parse.unquote(parsed["start_param"]) == "ref123"
assert urllib.parse.unquote(parsed["query_id"]) == "AAHdF6IQAAAAAN0XohDhrOrc"
user = urllib.parse.unquote(parsed["user"])
assert '"id":424242' in user
assert '"first_name":"Ada"' in user
print("PASS test_build_mini_app_init_data_contains_all_fields")
def test_build_mini_app_init_data_with_chat():
result = build_mini_app_init_data(
bot_token="test-bot-token",
telegram_id=424242,
first_name="Ada",
chat_id=-1001234567890,
chat_type="supergroup",
chat_title="Test Club",
auth_date=1714300000,
)
parsed = _parse_init_data(result.init_data_raw)
chat = urllib.parse.unquote(parsed["chat"])
assert '"id":-1001234567890' in chat
assert '"type":"supergroup"' in chat
assert '"title":"Test Club"' in chat
print("PASS test_build_mini_app_init_data_with_chat")
def main():
tests = [
test_login_widget_hash_matches_expected_algorithm,
test_mini_app_hash_matches_expected_algorithm,
test_build_login_widget_contains_all_fields,
test_build_mini_app_init_data_contains_all_fields,
test_build_mini_app_init_data_with_chat,
]
failed = 0
for test in tests:
try:
test()
except Exception as ex:
failed += 1
print(f"FAIL {test.__name__}: {ex}")
print(f"\n{len(tests) - failed}/{len(tests)} tests passed")
sys.exit(0 if failed == 0 else 1)
if __name__ == "__main__":
main()