44import urllib .request
55from typing import Optional
66
7+ import docker
78from testcontainers .core .container import DockerContainer
89from testcontainers .core .waiting_utils import wait_container_is_ready
910
@@ -35,13 +36,20 @@ class TransportOptionsTest(unittest.TestCase):
3536 host : Optional [str ] = None
3637 http_port : Optional [str ] = None
3738 https_port : Optional [str ] = None
39+ proxy_port : Optional [str ] = None
3840 ca_cert_path : Optional [str ] = None
3941 wiremock : DockerContainer = None
42+ proxy : DockerContainer = None
43+ docker_network = None
4044
4145 @classmethod
4246 def setup_class (cls ) -> None :
4347 cls .ca_cert_path = os .path .join (FIXTURES_DIR , "ca.pem" )
4448 keystore_path = os .path .join (FIXTURES_DIR , "keystore.p12" )
49+ tinyproxy_conf = os .path .join (FIXTURES_DIR , "tinyproxy.conf" )
50+
51+ docker_client = docker .from_env ()
52+ cls .docker_network = docker_client .networks .create ("zitadel-proxy-test" )
4553
4654 cls .wiremock = (
4755 DockerContainer ("wiremock/wiremock:3.3.1" )
@@ -57,9 +65,23 @@ def setup_class(cls) -> None:
5765 )
5866 cls .wiremock .start ()
5967
68+ cls .proxy = (
69+ DockerContainer ("vimagick/tinyproxy" )
70+ .with_exposed_ports (8888 )
71+ .with_volume_mapping (tinyproxy_conf , "/etc/tinyproxy/tinyproxy.conf" , mode = "ro" )
72+ )
73+ cls .proxy .start ()
74+
75+ # Connect both containers to the shared network
76+ wiremock_id = cls .wiremock ._container .id
77+ proxy_id = cls .proxy ._container .id
78+ cls .docker_network .connect (wiremock_id , aliases = ["wiremock" ])
79+ cls .docker_network .connect (proxy_id )
80+
6081 cls .host = cls .wiremock .get_container_host_ip ()
6182 cls .http_port = cls .wiremock .get_exposed_port (8080 )
6283 cls .https_port = cls .wiremock .get_exposed_port (8443 )
84+ cls .proxy_port = cls .proxy .get_exposed_port (8888 )
6385
6486 _wait_for_wiremock (cls .host , cls .http_port )
6587
@@ -141,8 +163,12 @@ def setup_class(cls) -> None:
141163
142164 @classmethod
143165 def teardown_class (cls ) -> None :
166+ if cls .proxy is not None :
167+ cls .proxy .stop ()
144168 if cls .wiremock is not None :
145169 cls .wiremock .stop ()
170+ if cls .docker_network is not None :
171+ cls .docker_network .remove ()
146172
147173 def test_custom_ca_cert (self ) -> None :
148174 zitadel = Zitadel .with_client_credentials (
@@ -193,12 +219,14 @@ def test_default_headers(self) -> None:
193219 self .assertGreaterEqual (result ["count" ], 1 , "Custom header should be present on API call" )
194220
195221 def test_proxy_url (self ) -> None :
222+ # Use Docker-internal hostname — only resolvable through the proxy's network
196223 zitadel = Zitadel .with_access_token (
197- f "http://{ self . host } : { self . http_port } " ,
224+ "http://wiremock:8080 " ,
198225 "test-token" ,
199- transport_options = TransportOptions (proxy_url = f"http://{ self .host } :{ self .http_port } " ),
226+ transport_options = TransportOptions (proxy_url = f"http://{ self .host } :{ self .proxy_port } " ),
200227 )
201228 self .assertIsNotNone (zitadel )
229+ zitadel .settings .get_general_settings ({})
202230
203231 def test_no_ca_cert_fails (self ) -> None :
204232 with self .assertRaises (Exception ): # noqa: B017
0 commit comments