@@ -163,6 +163,50 @@ def _open_binary_file_stub(file_path, *, open_error_message): # type: ignore[no
163163 )
164164
165165
166+ def test_sync_extension_create_uses_metadata_open_file_prefix (
167+ monkeypatch : pytest .MonkeyPatch ,
168+ ):
169+ manager = SyncExtensionManager (_FakeClient (_SyncTransport ()))
170+ manager ._OPERATION_METADATA = type (
171+ "_Metadata" ,
172+ (),
173+ {
174+ "create_operation_name" : "create extension" ,
175+ "open_file_error_prefix" : "Custom extension open prefix" ,
176+ },
177+ )()
178+ params = CreateExtensionParams (name = "my-extension" , file_path = "/tmp/ignored.zip" )
179+ captured : dict [str , str ] = {}
180+
181+ @contextmanager
182+ def _open_binary_file_stub (file_path , * , open_error_message ): # type: ignore[no-untyped-def]
183+ captured ["file_path" ] = file_path
184+ captured ["open_error_message" ] = open_error_message
185+ yield io .BytesIO (b"content" )
186+
187+ monkeypatch .setattr (
188+ sync_extension_module ,
189+ "normalize_extension_create_input" ,
190+ lambda _ : ("bad\t path.zip" , {"name" : "my-extension" }),
191+ )
192+ monkeypatch .setattr (
193+ sync_extension_module ,
194+ "open_binary_file" ,
195+ _open_binary_file_stub ,
196+ )
197+ monkeypatch .setattr (
198+ sync_extension_module ,
199+ "create_extension_resource" ,
200+ lambda ** kwargs : SimpleNamespace (id = "ext_sync_mock" ),
201+ )
202+
203+ response = manager .create (params )
204+
205+ assert response .id == "ext_sync_mock"
206+ assert captured ["file_path" ] == "bad\t path.zip"
207+ assert captured ["open_error_message" ] == "Custom extension open prefix: bad?path.zip"
208+
209+
166210def test_async_extension_create_does_not_mutate_params_and_closes_file (tmp_path ):
167211 transport = _AsyncTransport ()
168212 manager = AsyncExtensionManager (_FakeClient (transport ))
@@ -228,6 +272,57 @@ async def run():
228272 )
229273
230274
275+ def test_async_extension_create_uses_metadata_open_file_prefix (
276+ monkeypatch : pytest .MonkeyPatch ,
277+ ):
278+ manager = AsyncExtensionManager (_FakeClient (_AsyncTransport ()))
279+ manager ._OPERATION_METADATA = type (
280+ "_Metadata" ,
281+ (),
282+ {
283+ "create_operation_name" : "create extension" ,
284+ "open_file_error_prefix" : "Custom extension open prefix" ,
285+ },
286+ )()
287+ params = CreateExtensionParams (name = "my-extension" , file_path = "/tmp/ignored.zip" )
288+ captured : dict [str , str ] = {}
289+
290+ @contextmanager
291+ def _open_binary_file_stub (file_path , * , open_error_message ): # type: ignore[no-untyped-def]
292+ captured ["file_path" ] = file_path
293+ captured ["open_error_message" ] = open_error_message
294+ yield io .BytesIO (b"content" )
295+
296+ async def _create_extension_resource_async_stub (** kwargs ):
297+ _ = kwargs
298+ return SimpleNamespace (id = "ext_async_mock" )
299+
300+ monkeypatch .setattr (
301+ async_extension_module ,
302+ "normalize_extension_create_input" ,
303+ lambda _ : ("bad\t path.zip" , {"name" : "my-extension" }),
304+ )
305+ monkeypatch .setattr (
306+ async_extension_module ,
307+ "open_binary_file" ,
308+ _open_binary_file_stub ,
309+ )
310+ monkeypatch .setattr (
311+ async_extension_module ,
312+ "create_extension_resource_async" ,
313+ _create_extension_resource_async_stub ,
314+ )
315+
316+ async def run ():
317+ return await manager .create (params )
318+
319+ response = asyncio .run (run ())
320+
321+ assert response .id == "ext_async_mock"
322+ assert captured ["file_path" ] == "bad\t path.zip"
323+ assert captured ["open_error_message" ] == "Custom extension open prefix: bad?path.zip"
324+
325+
231326def test_sync_extension_create_raises_hyperbrowser_error_when_file_missing (tmp_path ):
232327 transport = _SyncTransport ()
233328 manager = SyncExtensionManager (_FakeClient (transport ))
0 commit comments