|
@@ -515,6 +515,21 @@ class ApplyInsteadOfTests(TestCase):
|
|
|
"https://samba.org/", apply_instead_of(config, "https://example.com/")
|
|
|
)
|
|
|
|
|
|
+ def test_apply_preserves_case_in_subsection(self) -> None:
|
|
|
+ """Test that mixed-case URLs (like those with access tokens) are preserved."""
|
|
|
+ config = ConfigDict()
|
|
|
+ # GitHub access tokens have mixed case that must be preserved
|
|
|
+ url_with_token = "https://ghp_AbCdEfGhIjKlMnOpQrStUvWxYz1234567890@github.com/"
|
|
|
+ config.set(("url", url_with_token), "insteadOf", "https://github.com/")
|
|
|
+
|
|
|
+ # Apply the substitution
|
|
|
+ result = apply_instead_of(config, "https://github.com/jelmer/dulwich.git")
|
|
|
+ expected = "https://ghp_AbCdEfGhIjKlMnOpQrStUvWxYz1234567890@github.com/jelmer/dulwich.git"
|
|
|
+ self.assertEqual(expected, result)
|
|
|
+
|
|
|
+ # Verify the token case is preserved
|
|
|
+ self.assertIn("ghp_AbCdEfGhIjKlMnOpQrStUvWxYz1234567890", result)
|
|
|
+
|
|
|
|
|
|
class CaseInsensitiveConfigTests(TestCase):
|
|
|
def test_case_insensitive(self) -> None:
|
|
@@ -562,6 +577,25 @@ class CaseInsensitiveConfigTests(TestCase):
|
|
|
self.assertEqual(1, len(config))
|
|
|
config[("CORE",)] = "value2"
|
|
|
self.assertEqual(1, len(config)) # Same key, case insensitive
|
|
|
+
|
|
|
+ def test_subsection_case_preserved(self) -> None:
|
|
|
+ """Test that subsection names preserve their case."""
|
|
|
+ config = CaseInsensitiveOrderedMultiDict()
|
|
|
+ # Section names should be case-insensitive, but subsection names should preserve case
|
|
|
+ config[("url", "https://Example.COM/Path")] = "value1"
|
|
|
+
|
|
|
+ # Can retrieve with different case section name
|
|
|
+ self.assertEqual("value1", config[("URL", "https://Example.COM/Path")])
|
|
|
+ self.assertEqual("value1", config[("url", "https://Example.COM/Path")])
|
|
|
+
|
|
|
+ # But not with different case subsection name
|
|
|
+ with self.assertRaises(KeyError):
|
|
|
+ config[("url", "https://example.com/path")]
|
|
|
+
|
|
|
+ # Verify the stored key preserves subsection case
|
|
|
+ stored_keys = list(config.keys())
|
|
|
+ self.assertEqual(1, len(stored_keys))
|
|
|
+ self.assertEqual(("url", "https://Example.COM/Path"), stored_keys[0])
|
|
|
config[("other",)] = "value3"
|
|
|
self.assertEqual(2, len(config))
|
|
|
|
|
@@ -630,8 +664,12 @@ class CaseInsensitiveConfigTests(TestCase):
|
|
|
def test_nested_tuple_keys(self) -> None:
|
|
|
config = CaseInsensitiveOrderedMultiDict()
|
|
|
config[("branch", "master")] = "value"
|
|
|
- self.assertEqual("value", config[("BRANCH", "MASTER")])
|
|
|
- self.assertEqual("value", config[("Branch", "Master")])
|
|
|
+ # Section names are case-insensitive
|
|
|
+ self.assertEqual("value", config[("BRANCH", "master")])
|
|
|
+ self.assertEqual("value", config[("Branch", "master")])
|
|
|
+ # But subsection names are case-sensitive
|
|
|
+ with self.assertRaises(KeyError):
|
|
|
+ config[("branch", "MASTER")]
|
|
|
|
|
|
|
|
|
class ConfigFileSetTests(TestCase):
|