"""Tests for torrent metainfo parsing — TDD: tests before implementation.""" import pytest import hashlib from i2p_apps.snark.bencode import bencode from i2p_apps.snark.metainfo import MetaInfo def _make_torrent(name=b"test.txt", length=1024, piece_length=16384): """Create a minimal valid torrent dict.""" pieces = hashlib.sha1(b"fake_piece_data").digest() info = { b"name": name, b"length": length, b"piece length": piece_length, b"pieces": pieces, } return { b"announce": b"http://tracker.postman.i2p/announce.php", b"info": info, } class TestMetaInfo: def test_parse_single_file(self): data = bencode(_make_torrent()) mi = MetaInfo.from_bytes(data) assert mi.name == "test.txt" assert mi.total_size == 1024 assert mi.piece_length == 16384 def test_announce_url(self): data = bencode(_make_torrent()) mi = MetaInfo.from_bytes(data) assert "tracker.postman.i2p" in mi.announce def test_info_hash(self): data = bencode(_make_torrent()) mi = MetaInfo.from_bytes(data) assert len(mi.info_hash) == 20 # SHA-1 hash def test_piece_count(self): data = bencode(_make_torrent(length=32768, piece_length=16384)) mi = MetaInfo.from_bytes(data) assert mi.piece_count >= 1 def test_multi_file(self): info = { b"name": b"mydir", b"piece length": 16384, b"pieces": hashlib.sha1(b"data").digest(), b"files": [ {b"length": 100, b"path": [b"file1.txt"]}, {b"length": 200, b"path": [b"subdir", b"file2.txt"]}, ], } torrent = {b"announce": b"http://tracker.i2p/announce", b"info": info} mi = MetaInfo.from_bytes(bencode(torrent)) assert mi.total_size == 300 assert len(mi.files) == 2 def test_is_i2p(self): data = bencode(_make_torrent()) mi = MetaInfo.from_bytes(data) assert mi.is_i2p is True def test_not_i2p(self): t = _make_torrent() t[b"announce"] = b"http://tracker.example.com/announce" mi = MetaInfo.from_bytes(bencode(t)) assert mi.is_i2p is False