5319592964
- 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>
134 lines
4.1 KiB
Python
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()
|