|
| 1 | +"""Tests for the unified IPForceAdapter / IPForceSession API.""" |
| 2 | +import socket |
| 3 | +import warnings |
| 4 | +import unittest |
| 5 | + |
| 6 | +from requests.adapters import HTTPAdapter |
| 7 | + |
| 8 | +from ipforce import ( |
| 9 | + IPVersion, IPForceMethod, |
| 10 | + IPForceAdapter, IPForceSession, |
| 11 | + IPv4TransportAdapter, IPv6TransportAdapter, |
| 12 | +) |
| 13 | +from ipforce.adapters import _BaseLockAdapter |
| 14 | + |
| 15 | + |
| 16 | +class TestIPForceAdapterFactory(unittest.TestCase): |
| 17 | + """Test that IPForceAdapter returns correct adapter types.""" |
| 18 | + |
| 19 | + def test_v4_lock(self): |
| 20 | + adapter = IPForceAdapter(IPVersion.V4, IPForceMethod.LOCK) |
| 21 | + self.assertIsInstance(adapter, _BaseLockAdapter) |
| 22 | + self.assertEqual(adapter._family, socket.AF_INET) |
| 23 | + |
| 24 | + def test_v6_lock(self): |
| 25 | + adapter = IPForceAdapter(IPVersion.V6, IPForceMethod.LOCK) |
| 26 | + self.assertIsInstance(adapter, _BaseLockAdapter) |
| 27 | + self.assertEqual(adapter._family, socket.AF_INET6) |
| 28 | + |
| 29 | + def test_v4_global(self): |
| 30 | + adapter = IPForceAdapter(IPVersion.V4, IPForceMethod.GLOBAL) |
| 31 | + self.assertIsInstance(adapter, HTTPAdapter) |
| 32 | + |
| 33 | + def test_v6_global(self): |
| 34 | + adapter = IPForceAdapter(IPVersion.V6, IPForceMethod.GLOBAL) |
| 35 | + self.assertIsInstance(adapter, HTTPAdapter) |
| 36 | + |
| 37 | + def test_default_method_is_lock(self): |
| 38 | + adapter = IPForceAdapter(IPVersion.V4) |
| 39 | + self.assertIsInstance(adapter, _BaseLockAdapter) |
| 40 | + |
| 41 | + def test_invalid_combination_raises(self): |
| 42 | + with self.assertRaises((ValueError, KeyError)): |
| 43 | + IPForceAdapter(IPVersion.V4, "not_a_method") |
| 44 | + |
| 45 | + |
| 46 | +class TestIPForceSession(unittest.TestCase): |
| 47 | + """Test IPForceSession class.""" |
| 48 | + |
| 49 | + def test_v4_session_mounts_lock_adapter(self): |
| 50 | + with IPForceSession(IPVersion.V4) as session: |
| 51 | + adapter = session.get_adapter('https://example.com') |
| 52 | + self.assertIsInstance(adapter, _BaseLockAdapter) |
| 53 | + |
| 54 | + def test_v6_session_mounts_lock_adapter(self): |
| 55 | + with IPForceSession(IPVersion.V6) as session: |
| 56 | + adapter = session.get_adapter('https://example.com') |
| 57 | + self.assertIsInstance(adapter, _BaseLockAdapter) |
| 58 | + self.assertEqual(adapter._family, socket.AF_INET6) |
| 59 | + |
| 60 | + def test_session_with_global_method(self): |
| 61 | + with IPForceSession(IPVersion.V4, method=IPForceMethod.GLOBAL) as session: |
| 62 | + adapter = session.get_adapter('https://example.com') |
| 63 | + self.assertIsInstance(adapter, HTTPAdapter) |
| 64 | + |
| 65 | + def test_session_context_manager(self): |
| 66 | + with IPForceSession(IPVersion.V4) as session: |
| 67 | + self.assertIsInstance(session, IPForceSession) |
| 68 | + |
| 69 | + |
| 70 | +class TestDeprecationWarnings(unittest.TestCase): |
| 71 | + """Old v0.1 classes emit DeprecationWarning; new API does not.""" |
| 72 | + |
| 73 | + def test_ipv4_transport_adapter_warns(self): |
| 74 | + with warnings.catch_warnings(record=True) as w: |
| 75 | + warnings.simplefilter("always") |
| 76 | + IPv4TransportAdapter() |
| 77 | + self.assertEqual(len(w), 1) |
| 78 | + self.assertTrue(issubclass(w[0].category, DeprecationWarning)) |
| 79 | + self.assertIn("IPForceAdapter", str(w[0].message)) |
| 80 | + |
| 81 | + def test_ipv6_transport_adapter_warns(self): |
| 82 | + with warnings.catch_warnings(record=True) as w: |
| 83 | + warnings.simplefilter("always") |
| 84 | + IPv6TransportAdapter() |
| 85 | + self.assertEqual(len(w), 1) |
| 86 | + self.assertTrue(issubclass(w[0].category, DeprecationWarning)) |
| 87 | + |
| 88 | + def test_new_api_does_not_warn(self): |
| 89 | + with warnings.catch_warnings(record=True) as w: |
| 90 | + warnings.simplefilter("always") |
| 91 | + IPForceAdapter(IPVersion.V4, IPForceMethod.LOCK) |
| 92 | + IPForceAdapter(IPVersion.V4, IPForceMethod.GLOBAL) |
| 93 | + session = IPForceSession(IPVersion.V4) |
| 94 | + session.close() |
| 95 | + dep_warnings = [x for x in w if issubclass(x.category, DeprecationWarning)] |
| 96 | + self.assertEqual(len(dep_warnings), 0) |
| 97 | + |
| 98 | + |
| 99 | +class TestEnums(unittest.TestCase): |
| 100 | + """Test enum values.""" |
| 101 | + |
| 102 | + def test_ip_version_values(self): |
| 103 | + self.assertEqual(IPVersion.V4.value, "ipv4") |
| 104 | + self.assertEqual(IPVersion.V6.value, "ipv6") |
| 105 | + |
| 106 | + def test_method_values(self): |
| 107 | + self.assertEqual(IPForceMethod.GLOBAL.value, "global") |
| 108 | + self.assertEqual(IPForceMethod.LOCK.value, "lock") |
0 commit comments