aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-09 09:18:49 +0200
committerDanilo M. <danix@danix.xyz>2026-09-09 09:18:49 +0200
commita3ff8f3b056c708872c5aedb4750d5cd32c5833d (patch)
treef7a8dd396dd7ebb776b371d2ba2cc21e6a9f4b56 /tests
parent66fc4c8354d7acd9e50329283844ccb0ceac63a7 (diff)
downloadabusectl-a3ff8f3b056c708872c5aedb4750d5cd32c5833d.tar.gz
abusectl-a3ff8f3b056c708872c5aedb4750d5cd32c5833d.zip
feat: select an RDAP server by longest prefix and by TLD
Longest prefix rather than first match: a block delegated to a new operator appears as a more specific range inside its parent, and the wider range would name the operator that gave it away. A TLD that publishes no RDAP service selects nothing, which is a normal outcome for many TLDs rather than a defect. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wrfqr2xqQfhtXCscU7zrdz
Diffstat (limited to 'tests')
-rw-r--r--tests/test_rdap.py51
1 files changed, 51 insertions, 0 deletions
diff --git a/tests/test_rdap.py b/tests/test_rdap.py
index 3fc2c65..14a1fd4 100644
--- a/tests/test_rdap.py
+++ b/tests/test_rdap.py
@@ -125,5 +125,56 @@ class Bootstrap(unittest.TestCase):
rdap.bootstrap("ipv4", cache_root=self.cache, fetch=fetch)
+class ServerSelection(unittest.TestCase):
+ IPV4 = {
+ "services": [
+ [["192.0.2.0/24"], ["https://wide.example.invalid/"]],
+ [["192.0.2.128/25"], ["https://narrow.example.invalid/"]],
+ [["198.51.100.0/24"], ["https://other.example.invalid/"]],
+ ]
+ }
+ DNS = {
+ "services": [
+ [["invalid"], ["https://registry.example.invalid/"]],
+ [["test"], ["https://test.example.invalid/"]],
+ ]
+ }
+
+ def test_an_address_selects_its_range(self):
+ self.assertEqual(
+ rdap.server_for_ip("198.51.100.7", self.IPV4),
+ "https://other.example.invalid/",
+ )
+
+ def test_the_longest_prefix_wins(self):
+ """192.0.2.200 is in both /24 and /25; the /25 is more specific.
+
+ Choosing the wider range would ask a registry that has delegated
+ the block away, and its answer would name the wrong operator.
+ """
+ self.assertEqual(
+ rdap.server_for_ip("192.0.2.200", self.IPV4),
+ "https://narrow.example.invalid/",
+ )
+
+ def test_an_unlisted_address_selects_nothing(self):
+ self.assertIsNone(rdap.server_for_ip("203.0.113.9", self.IPV4))
+
+ def test_a_tld_selects_its_registry(self):
+ self.assertEqual(
+ rdap.server_for_tld("invalid", self.DNS),
+ "https://registry.example.invalid/",
+ )
+
+ def test_tld_matching_ignores_case(self):
+ self.assertEqual(
+ rdap.server_for_tld("INVALID", self.DNS),
+ "https://registry.example.invalid/",
+ )
+
+ def test_an_unlisted_tld_selects_nothing(self):
+ self.assertIsNone(rdap.server_for_tld("example", self.DNS))
+
+
if __name__ == "__main__":
unittest.main()