55from contextlib import AbstractContextManager , nullcontext
66from json import load
77from os .path import join
8+ from pathlib import Path
89from typing import TYPE_CHECKING , Any , Literal , NamedTuple , Union , cast
910
1011import pytest
@@ -301,7 +302,10 @@ def psf_responses(request: pytest.FixtureRequest) -> Generator[RequestsMock, Non
301302 psf_fire_all_responses = _psf_configs .psf_fire_all_responses
302303 with RequestsMock (assert_all_requests_are_fired = psf_fire_all_responses ) as rsps :
303304 for one_response in request .param :
304- rsps .add (** one_response )
305+ if isinstance (one_response , Path ):
306+ rsps ._add_from_file (one_response )
307+ else :
308+ rsps .add (** one_response )
305309 yield rsps
306310
307311
@@ -403,6 +407,7 @@ def _extract_responses(
403407 :param fixture_key: name of the fixture key that will be added
404408 :type fixture_key: value must be "psf_responses_indirect" or "psf_respx_mock_indirect"
405409 """
410+ # TODO: once we hit a minimum of Python 3.11, switch fixture_key to be a StrEnum
406411 # for each scenario
407412 # for each fixture
408413 # check if fixture name ends with _responses or _response
@@ -421,18 +426,32 @@ def _extract_responses(
421426 # Need to differentiate between the case where responses are not specified
422427 # at all and where there are only null responses
423428 if len (responses_fixture_names ) > 0 :
424- psf_responses_data = []
429+ psf_responses_data : list [ dict [ str , str ] | Path ] = []
425430 for one_fixture_name in responses_fixture_names :
426431 current_fixture_data = one_scenario .pop (one_fixture_name )
427432 # TODO: once Python 3.9 is EOL, change this to the cleaner structural
428433 # pattern matching form.
429434 # It's entirely possible that the contents of either the list
430435 # or the dict are not usable, but that will be caught when the
431436 # mocks are constructed.
437+ # breakpoint()
432438 if isinstance (current_fixture_data , list ):
433439 psf_responses_data .extend (current_fixture_data )
434440 elif isinstance (current_fixture_data , dict ):
435441 psf_responses_data .append (current_fixture_data )
442+ elif isinstance (current_fixture_data , str ) and fixture_key == "psf_responses_indirect" :
443+ # if it doesn't find the Responses file (or it finds it more than once) raise an exception
444+ file_loc = tuple (Path .cwd ().rglob (current_fixture_data ))
445+ if len (file_loc ) == 0 :
446+ raise RuntimeError (
447+ f"Pytest-Scenario-Files: { one_fixture_name } : file '{ current_fixture_data } ' not found."
448+ )
449+ elif len (file_loc ) > 1 :
450+ raise RuntimeError (
451+ f"Pytest-Scenario-Files: { one_fixture_name } : file '{ current_fixture_data } ' multiple copies found."
452+ )
453+ file_abs_path_obj = file_loc [0 ].resolve (strict = True )
454+ psf_responses_data .append (file_abs_path_obj )
436455 elif current_fixture_data is None :
437456 pass
438457 else :
0 commit comments