test_d_schema_03.py
1 """ 2 Unit tests for D-SCHEMA-03: infohash validation rule 3 """ 4 5 import importlib 6 7 import pytest 8 9 # Import the rule using importlib to handle hyphenated module name 10 rule = importlib.import_module("rules.D-SCHEMA-03") 11 12 13 @pytest.mark.unit 14 def test_accepts_valid_40_char_hex(make_event): 15 """Valid lowercase hex infohash should pass.""" 16 event = make_event(tags=[ 17 ["title", "Test"], 18 ["x", "0123456789abcdef0123456789abcdef01234567"], 19 ["file", "test.mkv", "1000000"], 20 ]) 21 result = rule.main(event) 22 assert result["passed"] is True 23 24 25 @pytest.mark.unit 26 def test_accepts_valid_40_char_uppercase_hex(make_event): 27 """Valid uppercase hex infohash should pass.""" 28 event = make_event(tags=[ 29 ["title", "Test"], 30 ["x", "FEDCBA9876543210FEDCBA9876543210FEDCBA98"], 31 ["file", "test.mkv", "1000000"], 32 ]) 33 result = rule.main(event) 34 assert result["passed"] is True 35 36 37 @pytest.mark.unit 38 def test_accepts_valid_mixed_case_hex(make_event): 39 """Valid mixed case hex infohash should pass.""" 40 event = make_event(tags=[ 41 ["title", "Test"], 42 ["x", "AbCdEf0123456789aBcDeF0123456789AbCdEf01"], 43 ["file", "test.mkv", "1000000"], 44 ]) 45 result = rule.main(event) 46 assert result["passed"] is True 47 48 49 @pytest.mark.unit 50 def test_accepts_valid_base32(make_event): 51 """Valid 32-char base32 infohash should pass.""" 52 event = make_event(tags=[ 53 ["title", "Test"], 54 ["x", "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"], 55 ["file", "test.mkv", "1000000"], 56 ]) 57 result = rule.main(event) 58 assert result["passed"] is True 59 60 61 @pytest.mark.unit 62 def test_rejects_missing_x_tag(make_event): 63 """Event with no x tag should fail.""" 64 event = make_event(tags=[ 65 ["title", "Test"], 66 ["file", "test.mkv", "1000000"], 67 ]) 68 result = rule.main(event) 69 assert result["passed"] is False 70 71 72 @pytest.mark.unit 73 def test_rejects_invalid_length(make_event): 74 """Infohash that's too short should fail.""" 75 event = make_event(tags=[ 76 ["title", "Test"], 77 ["x", "abc123"], # Only 6 chars, needs 40 or 32 78 ["file", "test.mkv", "1000000"], 79 ]) 80 result = rule.main(event) 81 assert result["passed"] is False 82 83 84 @pytest.mark.unit 85 def test_rejects_invalid_characters(make_event): 86 """40-char string with non-hex characters should fail.""" 87 event = make_event(tags=[ 88 ["title", "Test"], 89 ["x", "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"], # 40 chars but not hex 90 ["file", "test.mkv", "1000000"], 91 ]) 92 result = rule.main(event) 93 assert result["passed"] is False 94 95 96 @pytest.mark.unit 97 def test_rejects_empty_infohash(make_event): 98 """X tag with empty string should fail.""" 99 event = make_event(tags=[ 100 ["title", "Test"], 101 ["x", ""], 102 ["file", "test.mkv", "1000000"], 103 ]) 104 result = rule.main(event) 105 assert result["passed"] is False 106 107 108 @pytest.mark.unit 109 def test_rejects_x_tag_without_value(make_event): 110 """X tag with no second element should fail.""" 111 event = make_event(tags=[ 112 ["title", "Test"], 113 ["x"], 114 ["file", "test.mkv", "1000000"], 115 ]) 116 result = rule.main(event) 117 assert result["passed"] is False 118 119 120 @pytest.mark.unit 121 def test_uses_first_x_tag_when_multiple(make_event): 122 """If multiple x tags exist, use the first one.""" 123 event = make_event(tags=[ 124 ["title", "Test"], 125 ["x", "0123456789abcdef0123456789abcdef01234567"], # Valid 126 ["x", "invalid"], # Invalid but ignored 127 ["file", "test.mkv", "1000000"], 128 ]) 129 result = rule.main(event) 130 assert result["passed"] is True