Files
drive/tests/test_progress_and_telegram.py
T
2026-10-18 23:48:22 +05:30

108 lines
4.6 KiB
Python

import asyncio
from telethon import errors
from telethon.tl import types
from conftest import RecordingNotifier
from errors import PermanentError, TransientError
from progress import ProgressReporter, TransferProgress, format_bytes, format_duration
from telegram_client import classify_media, map_telegram_error, parse_channel_reference, to_source_message
# -- progress ------------------------------------------------------------------------------
def test_formatting():
assert format_bytes(512) == "512 B"
assert format_bytes(1536) == "1.5 KB"
assert format_bytes(5 * 1024**3) == "5.0 GB"
assert format_duration(42) == "42s"
assert format_duration(125) == "2m 5s"
assert format_duration(3 * 3600 + 120) == "3h 2m"
def test_speed_and_eta():
now = [0.0]
p = TransferProgress(total=100 * 1024 * 1024, clock=lambda: now[0])
p.update(0)
now[0] = 10.0
p.update(50 * 1024 * 1024)
assert round(p.speed) == 5 * 1024 * 1024
assert round(p.eta) == 10
assert p.percent == 50
text = p.describe()
assert "50%" in text and "MB/s" in text and "ETA 10s" in text
def test_reporter_edits_single_message():
notifier = RecordingNotifier()
reporter = ProgressReporter(notifier, [1, 2], interval=60)
async def go():
reporter.board.begin_item(12, 150, "Misc• Grammar Practice", "Class 01 Aman sir.mp4")
reporter.board.start_download(1000)
reporter.board.download.update(640)
await reporter.refresh()
await reporter.refresh() # unchanged -> nothing sent
reporter.board.download.update(900)
await reporter.refresh()
asyncio.run(go())
assert len(notifier.sent) == 2 # one per chat
assert len(notifier.edits) == 2 # then edited
first = notifier.sent[0][1]
assert first.splitlines()[0] == "Processing video 12 of 150"
assert "Topic: Misc• Grammar Practice" in first and "Download: 64%" in first and "Upload: Waiting" in first
# -- telegram media classification ----------------------------------------------------------
def _doc(attributes, mime="video/mp4"):
return types.Document(id=77, access_hash=1, file_reference=b"", date=None, mime_type=mime, size=1234, dc_id=1,
attributes=attributes)
def _msg(media, text="Title: A.mp4"):
return types.Message(id=5, peer_id=types.PeerChannel(1), date=None, message=text, media=media)
def test_classify_video_message():
video = types.DocumentAttributeVideo(duration=60, w=1280, h=720)
info = classify_media(_msg(types.MessageMediaDocument(document=_doc([video]))), include_documents=False)
assert info.kind == "video" and info.size == 1234 and info.media_id == 77
sm = to_source_message(_msg(types.MessageMediaDocument(document=_doc([video]))), -100, False)
assert sm.caption == "Title: A.mp4" and sm.message_id == 5
def test_classify_document_video_only_when_enabled():
doc = _doc([types.DocumentAttributeFilename("lecture.mkv")], mime="application/octet-stream")
message = _msg(types.MessageMediaDocument(document=doc))
assert classify_media(message, include_documents=False) is None
assert classify_media(message, include_documents=True).file_name == "lecture.mkv"
def test_unsupported_media_is_ignored():
gif = _doc([types.DocumentAttributeVideo(duration=1, w=1, h=1), types.DocumentAttributeAnimated()])
note = _doc([types.DocumentAttributeVideo(duration=1, w=1, h=1, round_message=True)])
pdf = _doc([types.DocumentAttributeFilename("notes.pdf")], mime="application/pdf")
for doc in (gif, note, pdf):
assert classify_media(_msg(types.MessageMediaDocument(document=doc)), include_documents=True) is None
photo = types.MessageMediaPhoto(photo=types.PhotoEmpty(id=1))
assert classify_media(_msg(photo), include_documents=True) is None
assert classify_media(_msg(None, text="text only"), include_documents=True) is None
def test_channel_reference_parsing():
assert parse_channel_reference("-1001234567890") == -1001234567890
assert parse_channel_reference("@my_channel") == "my_channel"
assert parse_channel_reference("https://t.me/my_channel") == "my_channel"
assert parse_channel_reference("https://t.me/c/1234567890/55") == -1001234567890
def test_telegram_error_mapping():
flood = map_telegram_error(errors.FloodWaitError(request=None, capture=42))
assert isinstance(flood, TransientError) and flood.retry_after == 42 and flood.rate_limited
assert isinstance(map_telegram_error(errors.ChannelPrivateError(request=None)), PermanentError)
assert isinstance(map_telegram_error(ConnectionError("x")), TransientError)