@@ -207,6 +207,53 @@ def _open_binary_file_stub(file_path, *, open_error_message): # type: ignore[no
207207 assert captured ["open_error_message" ] == "Custom extension open prefix: bad?path.zip"
208208
209209
210+ def test_sync_extension_create_uses_default_open_file_prefix_when_metadata_invalid (
211+ monkeypatch : pytest .MonkeyPatch ,
212+ ):
213+ manager = SyncExtensionManager (_FakeClient (_SyncTransport ()))
214+ manager ._OPERATION_METADATA = type (
215+ "_Metadata" ,
216+ (),
217+ {
218+ "create_operation_name" : "create extension" ,
219+ "open_file_error_prefix" : 123 ,
220+ },
221+ )()
222+ params = CreateExtensionParams (name = "my-extension" , file_path = "/tmp/ignored.zip" )
223+ captured : dict [str , str ] = {}
224+
225+ @contextmanager
226+ def _open_binary_file_stub (file_path , * , open_error_message ): # type: ignore[no-untyped-def]
227+ captured ["file_path" ] = file_path
228+ captured ["open_error_message" ] = open_error_message
229+ yield io .BytesIO (b"content" )
230+
231+ monkeypatch .setattr (
232+ sync_extension_module ,
233+ "normalize_extension_create_input" ,
234+ lambda _ : ("bad\t path.zip" , {"name" : "my-extension" }),
235+ )
236+ monkeypatch .setattr (
237+ sync_extension_module ,
238+ "open_binary_file" ,
239+ _open_binary_file_stub ,
240+ )
241+ monkeypatch .setattr (
242+ sync_extension_module ,
243+ "create_extension_resource" ,
244+ lambda ** kwargs : SimpleNamespace (id = "ext_sync_mock" ),
245+ )
246+
247+ response = manager .create (params )
248+
249+ assert response .id == "ext_sync_mock"
250+ assert captured ["file_path" ] == "bad\t path.zip"
251+ assert (
252+ captured ["open_error_message" ]
253+ == "Failed to open extension file at path: bad?path.zip"
254+ )
255+
256+
210257def test_async_extension_create_does_not_mutate_params_and_closes_file (tmp_path ):
211258 transport = _AsyncTransport ()
212259 manager = AsyncExtensionManager (_FakeClient (transport ))
@@ -323,6 +370,60 @@ async def run():
323370 assert captured ["open_error_message" ] == "Custom extension open prefix: bad?path.zip"
324371
325372
373+ def test_async_extension_create_uses_default_open_file_prefix_when_metadata_invalid (
374+ monkeypatch : pytest .MonkeyPatch ,
375+ ):
376+ manager = AsyncExtensionManager (_FakeClient (_AsyncTransport ()))
377+ manager ._OPERATION_METADATA = type (
378+ "_Metadata" ,
379+ (),
380+ {
381+ "create_operation_name" : "create extension" ,
382+ "open_file_error_prefix" : 123 ,
383+ },
384+ )()
385+ params = CreateExtensionParams (name = "my-extension" , file_path = "/tmp/ignored.zip" )
386+ captured : dict [str , str ] = {}
387+
388+ @contextmanager
389+ def _open_binary_file_stub (file_path , * , open_error_message ): # type: ignore[no-untyped-def]
390+ captured ["file_path" ] = file_path
391+ captured ["open_error_message" ] = open_error_message
392+ yield io .BytesIO (b"content" )
393+
394+ async def _create_extension_resource_async_stub (** kwargs ):
395+ _ = kwargs
396+ return SimpleNamespace (id = "ext_async_mock" )
397+
398+ monkeypatch .setattr (
399+ async_extension_module ,
400+ "normalize_extension_create_input" ,
401+ lambda _ : ("bad\t path.zip" , {"name" : "my-extension" }),
402+ )
403+ monkeypatch .setattr (
404+ async_extension_module ,
405+ "open_binary_file" ,
406+ _open_binary_file_stub ,
407+ )
408+ monkeypatch .setattr (
409+ async_extension_module ,
410+ "create_extension_resource_async" ,
411+ _create_extension_resource_async_stub ,
412+ )
413+
414+ async def run ():
415+ return await manager .create (params )
416+
417+ response = asyncio .run (run ())
418+
419+ assert response .id == "ext_async_mock"
420+ assert captured ["file_path" ] == "bad\t path.zip"
421+ assert (
422+ captured ["open_error_message" ]
423+ == "Failed to open extension file at path: bad?path.zip"
424+ )
425+
426+
326427def test_sync_extension_create_raises_hyperbrowser_error_when_file_missing (tmp_path ):
327428 transport = _SyncTransport ()
328429 manager = SyncExtensionManager (_FakeClient (transport ))
0 commit comments