A Python port of the Invisible Internet Project (I2P)
1"""Tests for torrent metainfo parsing — TDD: tests before implementation."""
2
3import pytest
4import hashlib
5
6from i2p_apps.snark.bencode import bencode
7from i2p_apps.snark.metainfo import MetaInfo
8
9
10def _make_torrent(name=b"test.txt", length=1024, piece_length=16384):
11 """Create a minimal valid torrent dict."""
12 pieces = hashlib.sha1(b"fake_piece_data").digest()
13 info = {
14 b"name": name,
15 b"length": length,
16 b"piece length": piece_length,
17 b"pieces": pieces,
18 }
19 return {
20 b"announce": b"http://tracker.postman.i2p/announce.php",
21 b"info": info,
22 }
23
24
25class TestMetaInfo:
26 def test_parse_single_file(self):
27 data = bencode(_make_torrent())
28 mi = MetaInfo.from_bytes(data)
29 assert mi.name == "test.txt"
30 assert mi.total_size == 1024
31 assert mi.piece_length == 16384
32
33 def test_announce_url(self):
34 data = bencode(_make_torrent())
35 mi = MetaInfo.from_bytes(data)
36 assert "tracker.postman.i2p" in mi.announce
37
38 def test_info_hash(self):
39 data = bencode(_make_torrent())
40 mi = MetaInfo.from_bytes(data)
41 assert len(mi.info_hash) == 20 # SHA-1 hash
42
43 def test_piece_count(self):
44 data = bencode(_make_torrent(length=32768, piece_length=16384))
45 mi = MetaInfo.from_bytes(data)
46 assert mi.piece_count >= 1
47
48 def test_multi_file(self):
49 info = {
50 b"name": b"mydir",
51 b"piece length": 16384,
52 b"pieces": hashlib.sha1(b"data").digest(),
53 b"files": [
54 {b"length": 100, b"path": [b"file1.txt"]},
55 {b"length": 200, b"path": [b"subdir", b"file2.txt"]},
56 ],
57 }
58 torrent = {b"announce": b"http://tracker.i2p/announce", b"info": info}
59 mi = MetaInfo.from_bytes(bencode(torrent))
60 assert mi.total_size == 300
61 assert len(mi.files) == 2
62
63 def test_is_i2p(self):
64 data = bencode(_make_torrent())
65 mi = MetaInfo.from_bytes(data)
66 assert mi.is_i2p is True
67
68 def test_not_i2p(self):
69 t = _make_torrent()
70 t[b"announce"] = b"http://tracker.example.com/announce"
71 mi = MetaInfo.from_bytes(bencode(t))
72 assert mi.is_i2p is False