from typing import ( Any, Dict, Optional, ) from galaxy.tool_util.parameters import ( DataRequestCollectionUri, DataRequestInternalHda, DataRequestInternalHdca, DataRequestUri, decode, dereference, encode, fill_static_defaults, input_models_for_tool_source, landing_decode, landing_encode, LandingRequestToolState, RelaxedRequestToolState, RequestInternalDereferencedToolState, RequestInternalToolState, RequestToolState, strictify, ) from galaxy.tool_util.parser.util import parse_profile_version from .test_parameter_test_cases import tool_source_for EXAMPLE_ID_1_ENCODED = "123456789abcde" EXAMPLE_ID_1 = 13 EXAMPLE_ID_2_ENCODED = "123456789abcd2" EXAMPLE_ID_2 = 14 ID_MAP: Dict[int, str] = { EXAMPLE_ID_1: EXAMPLE_ID_1_ENCODED, EXAMPLE_ID_2: EXAMPLE_ID_2_ENCODED, } def test_decode_data(): tool_source = tool_source_for("parameters/gx_data") bundle = input_models_for_tool_source(tool_source) request_state = RequestToolState({"parameter": {"src": "hda", "id": EXAMPLE_ID_1_ENCODED}}) request_state.validate(bundle) decoded_state = decode(request_state, bundle, _fake_decode) assert decoded_state.input_state["parameter"]["src"] == "hda" assert decoded_state.input_state["parameter"]["id"] == EXAMPLE_ID_1 def test_decode_data_batch(): tool_source = tool_source_for("parameters/gx_data") bundle = input_models_for_tool_source(tool_source) request_state = RequestToolState( {"parameter": {"__class__": "Batch", "values": [{"src": "hda", "id": EXAMPLE_ID_1_ENCODED}]}} ) request_state.validate(bundle) decoded_state = decode(request_state, bundle, _fake_decode) assert decoded_state.input_state["parameter"]["values"][0]["src"] == "hda" assert decoded_state.input_state["parameter"]["values"][0]["id"] == EXAMPLE_ID_1 def test_decode_collection(): tool_source = tool_source_for("parameters/gx_data_collection") bundle = input_models_for_tool_source(tool_source) request_state = RequestToolState({"parameter": {"src": "hdca", "id": EXAMPLE_ID_1_ENCODED}}) request_state.validate(bundle) decoded_state = decode(request_state, bundle, _fake_decode) assert decoded_state.input_state["parameter"]["src"] == "hdca" assert decoded_state.input_state["parameter"]["id"] == EXAMPLE_ID_1 def test_decode_repeat(): tool_source = tool_source_for("parameters/gx_repeat_data") bundle = input_models_for_tool_source(tool_source) request_state = RequestToolState({"parameter": [{"data_parameter": {"src": "hda", "id": EXAMPLE_ID_1_ENCODED}}]}) request_state.validate(bundle) decoded_state = decode(request_state, bundle, _fake_decode) assert decoded_state.input_state["parameter"][0]["data_parameter"]["src"] == "hda" assert decoded_state.input_state["parameter"][0]["data_parameter"]["id"] == EXAMPLE_ID_1 def test_decode_section(): tool_source = tool_source_for("parameters/gx_section_data") bundle = input_models_for_tool_source(tool_source) request_state = RequestToolState({"parameter": {"data_parameter": {"src": "hda", "id": EXAMPLE_ID_1_ENCODED}}}) request_state.validate(bundle) decoded_state = decode(request_state, bundle, _fake_decode) assert decoded_state.input_state["parameter"]["data_parameter"]["src"] == "hda" assert decoded_state.input_state["parameter"]["data_parameter"]["id"] == EXAMPLE_ID_1 def test_decode_conditional(): tool_source = tool_source_for("identifier_in_conditional") bundle = input_models_for_tool_source(tool_source) request_state = RequestToolState( {"outer_cond": {"multi_input": False, "input1": {"src": "hda", "id": EXAMPLE_ID_1_ENCODED}}} ) request_state.validate(bundle) decoded_state = decode(request_state, bundle, _fake_decode) assert decoded_state.input_state["outer_cond"]["input1"]["src"] == "hda" assert decoded_state.input_state["outer_cond"]["input1"]["id"] == EXAMPLE_ID_1 def test_multi_data(): tool_source = tool_source_for("parameters/gx_data_multiple") bundle = input_models_for_tool_source(tool_source) request_state = RequestToolState( {"parameter": [{"src": "hda", "id": EXAMPLE_ID_1_ENCODED}, {"src": "hda", "id": EXAMPLE_ID_2_ENCODED}]} ) request_state.validate(bundle) decoded_state = decode(request_state, bundle, _fake_decode) assert decoded_state.input_state["parameter"][0]["src"] == "hda" assert decoded_state.input_state["parameter"][0]["id"] == EXAMPLE_ID_1 assert decoded_state.input_state["parameter"][1]["src"] == "hda" assert decoded_state.input_state["parameter"][1]["id"] == EXAMPLE_ID_2 encoded_state = encode(decoded_state, bundle, _fake_encode) assert encoded_state.input_state["parameter"][0]["src"] == "hda" assert encoded_state.input_state["parameter"][0]["id"] == EXAMPLE_ID_1_ENCODED assert encoded_state.input_state["parameter"][1]["src"] == "hda" assert encoded_state.input_state["parameter"][1]["id"] == EXAMPLE_ID_2_ENCODED def test_landing_encode_data(): tool_source = tool_source_for("parameters/gx_data") bundle = input_models_for_tool_source(tool_source) request_state = LandingRequestToolState({"parameter": {"src": "hda", "id": EXAMPLE_ID_1_ENCODED}}) request_state.validate(bundle) decoded_state = landing_decode(request_state, bundle, _fake_decode) assert decoded_state.input_state["parameter"]["src"] == "hda" assert decoded_state.input_state["parameter"]["id"] == EXAMPLE_ID_1 encoded_state = landing_encode(decoded_state, bundle, _fake_encode) assert encoded_state.input_state["parameter"]["src"] == "hda" assert encoded_state.input_state["parameter"]["id"] == EXAMPLE_ID_1_ENCODED def test_landing_encode_data_batch(): tool_source = tool_source_for("parameters/gx_data") bundle = input_models_for_tool_source(tool_source) request_state = LandingRequestToolState( {"parameter": {"__class__": "Batch", "values": [{"src": "hda", "id": EXAMPLE_ID_1_ENCODED}]}} ) request_state.validate(bundle) decoded_state = landing_decode(request_state, bundle, _fake_decode) assert decoded_state.input_state["parameter"]["values"][0]["src"] == "hda" assert decoded_state.input_state["parameter"]["values"][0]["id"] == EXAMPLE_ID_1 encoded_state = landing_encode(decoded_state, bundle, _fake_encode) assert encoded_state.input_state["parameter"]["values"][0]["src"] == "hda" assert encoded_state.input_state["parameter"]["values"][0]["id"] == EXAMPLE_ID_1_ENCODED def test_dereference(): tool_source = tool_source_for("parameters/gx_data") bundle = input_models_for_tool_source(tool_source) raw_request_state = {"parameter": {"src": "url", "url": "gxfiles://mystorage/1.bed", "ext": "bed"}} request_state = RequestInternalToolState(raw_request_state) request_state.validate(bundle) exception: Optional[Exception] = None try: # quickly verify this request needs to be dereferenced bad_state = RequestInternalDereferencedToolState(raw_request_state) bad_state.validate(bundle) except Exception as e: exception = e assert exception is not None dereferenced_state = dereference(request_state, bundle, _fake_dereference, _fake_collection_deference) assert isinstance(dereferenced_state, RequestInternalDereferencedToolState) dereferenced_state.validate(bundle) def test_fill_defaults(): with_defaults = fill_state_for({}, "parameters/gx_int") assert with_defaults["parameter"] == 1 with_defaults = fill_state_for({}, "parameters/gx_float") assert with_defaults["parameter"] == 1.0 with_defaults = fill_state_for({}, "parameters/gx_boolean") assert with_defaults["parameter"] is False with_defaults = fill_state_for({}, "parameters/gx_boolean_optional") # This is False unfortunately - see comments in gx_boolean_optional XML. assert with_defaults["parameter"] is False with_defaults = fill_state_for({}, "parameters/gx_boolean_checked") assert with_defaults["parameter"] is True with_defaults = fill_state_for({}, "parameters/gx_boolean_optional_checked") assert with_defaults["parameter"] is True with_defaults = fill_state_for({}, "parameters/gx_conditional_boolean") assert with_defaults["conditional_parameter"]["test_parameter"] is False assert with_defaults["conditional_parameter"]["boolean_parameter"] is False with_defaults = fill_state_for({"conditional_parameter": {}}, "parameters/gx_conditional_boolean") assert with_defaults["conditional_parameter"]["test_parameter"] is False assert with_defaults["conditional_parameter"]["boolean_parameter"] is False with_defaults = fill_state_for({}, "parameters/gx_repeat_boolean") assert len(with_defaults["parameter"]) == 0 with_defaults = fill_state_for({"parameter": [{}]}, "parameters/gx_repeat_boolean") assert len(with_defaults["parameter"]) == 1 instance_state = with_defaults["parameter"][0] assert instance_state["boolean_parameter"] is False with_defaults = fill_state_for({}, "parameters/gx_repeat_boolean_min") assert len(with_defaults["parameter"]) == 2 assert with_defaults["parameter"][0]["boolean_parameter"] is False assert with_defaults["parameter"][1]["boolean_parameter"] is False with_defaults = fill_state_for({"parameter": [{}, {}]}, "parameters/gx_repeat_boolean_min") assert len(with_defaults["parameter"]) == 2 assert with_defaults["parameter"][0]["boolean_parameter"] is False assert with_defaults["parameter"][1]["boolean_parameter"] is False with_defaults = fill_state_for({"parameter": [{}]}, "parameters/gx_repeat_boolean_min") assert with_defaults["parameter"][0]["boolean_parameter"] is False assert with_defaults["parameter"][1]["boolean_parameter"] is False with_defaults = fill_state_for({}, "parameters/gx_section_boolean") assert with_defaults["parameter"]["boolean_parameter"] is False with_defaults = fill_state_for({}, "parameters/gx_drill_down_exact_with_selection") assert with_defaults["parameter"] == "aba" with_defaults = fill_state_for({}, "parameters/gx_hidden") assert with_defaults["parameter"] == "moo" with_defaults = fill_state_for({}, "parameters/gx_genomebuild_optional") assert with_defaults["parameter"] is None with_defaults = fill_state_for({}, "parameters/gx_select") assert with_defaults["parameter"] == "--ex1" with_defaults = fill_state_for({}, "parameters/gx_select_optional") assert with_defaults["parameter"] is None with_defaults = fill_state_for({}, "parameters/gx_select_multiple") assert with_defaults["parameter"] is None with_defaults = fill_state_for({}, "parameters/gx_select_multiple_optional") assert with_defaults["parameter"] is None with_defaults = fill_state_for({}, "parameters/gx_select_multiple_one_default") assert with_defaults["parameter"] == ["--ex3"] # Do not fill in dynamic defaults... these require a Galaxy runtime. with_defaults = fill_state_for({}, "remove_value", partial=True) assert "choose_value" not in with_defaults with_defaults = fill_state_for( {"single": {"src": "hda", "id": 4}}, "select_from_dataset_in_conditional", partial=True ) assert with_defaults["cond"]["cond"] == "single" assert with_defaults["cond"]["inner_cond"]["inner_cond"] == "single" # dynamic parameters should just stay empty - null would cause runtime to skip over population with_defaults = fill_state_for({}, "parameters/gx_select_dynamic", partial=True) assert "parameter" not in with_defaults # dynamic parameters should just stay empty - null would cause runtime to skip over population with_defaults = fill_state_for( {"conditional_parameter": {"test_parameter": False}}, "parameters/gx_conditional_boolean_discriminate_on_string_value", ) assert "conditional_parameter" in with_defaults assert "boolean_parameter" in with_defaults["conditional_parameter"] assert with_defaults["conditional_parameter"]["boolean_parameter"] is False def test_strictify(): strict_state = strictify_for({"parameter": 1}, "parameters/gx_int") assert strict_state["parameter"] == 1 strict_state = strictify_for({}, "parameters/gx_text_optional_false") assert strict_state["parameter"] == "" strict_state = strictify_for({"parameter": None}, "parameters/gx_text_optional_false") assert strict_state["parameter"] == "" def strictify_for(tool_state: Dict[str, Any], tool_path: str) -> Dict[str, Any]: tool_source = tool_source_for(tool_path) bundle = input_models_for_tool_source(tool_source) relaxed_state = RelaxedRequestToolState(tool_state) relaxed_state.validate(bundle) return strictify(relaxed_state, bundle).input_state def _fake_dereference(input: DataRequestUri) -> DataRequestInternalHda: return DataRequestInternalHda(id=EXAMPLE_ID_1, src="hda") def _fake_collection_deference(input: DataRequestCollectionUri) -> DataRequestInternalHdca: return DataRequestInternalHdca(id=EXAMPLE_ID_1, src="hdca") def _fake_decode(input: str) -> int: return next(key for key, value in ID_MAP.items() if value == input) def _fake_encode(input: int) -> str: return ID_MAP[input] def fill_state_for(tool_state: Dict[str, Any], tool_path: str, partial: bool = False) -> Dict[str, Any]: tool_source = tool_source_for(tool_path) bundle = input_models_for_tool_source(tool_source) profile = parse_profile_version(tool_source) internal_state = fill_static_defaults(tool_state, bundle, profile, partial=partial) return internal_state