| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 | import timeimport uuidfrom urllib.parse import urlencodeimport pytestfrom core.app.entities.app_invoke_entities import InvokeFromfrom core.workflow.entities.node_entities import UserFromfrom core.workflow.entities.variable_pool import VariablePoolfrom core.workflow.enums import SystemVariableKeyfrom core.workflow.graph_engine.entities.graph import Graphfrom core.workflow.graph_engine.entities.graph_init_params import GraphInitParamsfrom core.workflow.graph_engine.entities.graph_runtime_state import GraphRuntimeStatefrom core.workflow.nodes.http_request.http_request_node import HttpRequestNodefrom models.workflow import WorkflowTypefrom tests.integration_tests.workflow.nodes.__mock.http import setup_http_mockdef init_http_node(config: dict):    graph_config = {        "edges": [            {                "id": "start-source-next-target",                "source": "start",                "target": "1",            },        ],        "nodes": [{"data": {"type": "start"}, "id": "start"}, config],    }    graph = Graph.init(graph_config=graph_config)    init_params = GraphInitParams(        tenant_id="1",        app_id="1",        workflow_type=WorkflowType.WORKFLOW,        workflow_id="1",        graph_config=graph_config,        user_id="1",        user_from=UserFrom.ACCOUNT,        invoke_from=InvokeFrom.DEBUGGER,        call_depth=0,    )    # construct variable pool    variable_pool = VariablePool(        system_variables={SystemVariableKey.FILES: [], SystemVariableKey.USER_ID: "aaa"},        user_inputs={},        environment_variables=[],        conversation_variables=[],    )    variable_pool.add(["a", "b123", "args1"], 1)    variable_pool.add(["a", "b123", "args2"], 2)    return HttpRequestNode(        id=str(uuid.uuid4()),        graph_init_params=init_params,        graph=graph,        graph_runtime_state=GraphRuntimeState(variable_pool=variable_pool, start_at=time.perf_counter()),        config=config,    )@pytest.mark.parametrize("setup_http_mock", [["none"]], indirect=True)def test_get(setup_http_mock):    node = init_http_node(        config={            "id": "1",            "data": {                "title": "http",                "desc": "",                "method": "get",                "url": "http://example.com",                "authorization": {                    "type": "api-key",                    "config": {                        "type": "basic",                        "api_key": "ak-xxx",                        "header": "api-key",                    },                },                "headers": "X-Header:123",                "params": "A:b",                "body": None,            },        }    )    result = node._run()    assert result.process_data is not None    data = result.process_data.get("request", "")    assert "?A=b" in data    assert "X-Header: 123" in data@pytest.mark.parametrize("setup_http_mock", [["none"]], indirect=True)def test_no_auth(setup_http_mock):    node = init_http_node(        config={            "id": "1",            "data": {                "title": "http",                "desc": "",                "method": "get",                "url": "http://example.com",                "authorization": {                    "type": "no-auth",                    "config": None,                },                "headers": "X-Header:123",                "params": "A:b",                "body": None,            },        }    )    result = node._run()    assert result.process_data is not None    data = result.process_data.get("request", "")    assert "?A=b" in data    assert "X-Header: 123" in data@pytest.mark.parametrize("setup_http_mock", [["none"]], indirect=True)def test_custom_authorization_header(setup_http_mock):    node = init_http_node(        config={            "id": "1",            "data": {                "title": "http",                "desc": "",                "method": "get",                "url": "http://example.com",                "authorization": {                    "type": "api-key",                    "config": {                        "type": "custom",                        "api_key": "Auth",                        "header": "X-Auth",                    },                },                "headers": "X-Header:123",                "params": "A:b",                "body": None,            },        }    )    result = node._run()    assert result.process_data is not None    data = result.process_data.get("request", "")    assert "?A=b" in data    assert "X-Header: 123" in data@pytest.mark.parametrize("setup_http_mock", [["none"]], indirect=True)def test_template(setup_http_mock):    node = init_http_node(        config={            "id": "1",            "data": {                "title": "http",                "desc": "",                "method": "get",                "url": "http://example.com/{{#a.b123.args2#}}",                "authorization": {                    "type": "api-key",                    "config": {                        "type": "basic",                        "api_key": "ak-xxx",                        "header": "api-key",                    },                },                "headers": "X-Header:123\nX-Header2:{{#a.b123.args2#}}",                "params": "A:b\nTemplate:{{#a.b123.args2#}}",                "body": None,            },        }    )    result = node._run()    assert result.process_data is not None    data = result.process_data.get("request", "")    assert "?A=b" in data    assert "Template=2" in data    assert "X-Header: 123" in data    assert "X-Header2: 2" in data@pytest.mark.parametrize("setup_http_mock", [["none"]], indirect=True)def test_json(setup_http_mock):    node = init_http_node(        config={            "id": "1",            "data": {                "title": "http",                "desc": "",                "method": "post",                "url": "http://example.com",                "authorization": {                    "type": "api-key",                    "config": {                        "type": "basic",                        "api_key": "ak-xxx",                        "header": "api-key",                    },                },                "headers": "X-Header:123",                "params": "A:b",                "body": {"type": "json", "data": '{"a": "{{#a.b123.args1#}}"}'},            },        }    )    result = node._run()    assert result.process_data is not None    data = result.process_data.get("request", "")    assert '{"a": "1"}' in data    assert "X-Header: 123" in datadef test_x_www_form_urlencoded(setup_http_mock):    node = init_http_node(        config={            "id": "1",            "data": {                "title": "http",                "desc": "",                "method": "post",                "url": "http://example.com",                "authorization": {                    "type": "api-key",                    "config": {                        "type": "basic",                        "api_key": "ak-xxx",                        "header": "api-key",                    },                },                "headers": "X-Header:123",                "params": "A:b",                "body": {"type": "x-www-form-urlencoded", "data": "a:{{#a.b123.args1#}}\nb:{{#a.b123.args2#}}"},            },        }    )    result = node._run()    assert result.process_data is not None    data = result.process_data.get("request", "")    assert "a=1&b=2" in data    assert "X-Header: 123" in datadef test_form_data(setup_http_mock):    node = init_http_node(        config={            "id": "1",            "data": {                "title": "http",                "desc": "",                "method": "post",                "url": "http://example.com",                "authorization": {                    "type": "api-key",                    "config": {                        "type": "basic",                        "api_key": "ak-xxx",                        "header": "api-key",                    },                },                "headers": "X-Header:123",                "params": "A:b",                "body": {"type": "form-data", "data": "a:{{#a.b123.args1#}}\nb:{{#a.b123.args2#}}"},            },        }    )    result = node._run()    assert result.process_data is not None    data = result.process_data.get("request", "")    assert 'form-data; name="a"' in data    assert "1" in data    assert 'form-data; name="b"' in data    assert "2" in data    assert "X-Header: 123" in datadef test_none_data(setup_http_mock):    node = init_http_node(        config={            "id": "1",            "data": {                "title": "http",                "desc": "",                "method": "post",                "url": "http://example.com",                "authorization": {                    "type": "api-key",                    "config": {                        "type": "basic",                        "api_key": "ak-xxx",                        "header": "api-key",                    },                },                "headers": "X-Header:123",                "params": "A:b",                "body": {"type": "none", "data": "123123123"},            },        }    )    result = node._run()    assert result.process_data is not None    data = result.process_data.get("request", "")    assert "X-Header: 123" in data    assert "123123123" not in datadef test_mock_404(setup_http_mock):    node = init_http_node(        config={            "id": "1",            "data": {                "title": "http",                "desc": "",                "method": "get",                "url": "http://404.com",                "authorization": {                    "type": "no-auth",                    "config": None,                },                "body": None,                "params": "",                "headers": "X-Header:123",            },        }    )    result = node._run()    assert result.outputs is not None    resp = result.outputs    assert 404 == resp.get("status_code")    assert "Not Found" in resp.get("body", "")def test_multi_colons_parse(setup_http_mock):    node = init_http_node(        config={            "id": "1",            "data": {                "title": "http",                "desc": "",                "method": "get",                "url": "http://example.com",                "authorization": {                    "type": "no-auth",                    "config": None,                },                "params": "Referer:http://example1.com\nRedirect:http://example2.com",                "headers": "Referer:http://example3.com\nRedirect:http://example4.com",                "body": {"type": "form-data", "data": "Referer:http://example5.com\nRedirect:http://example6.com"},            },        }    )    result = node._run()    assert result.process_data is not None    assert result.outputs is not None    resp = result.outputs    assert urlencode({"Redirect": "http://example2.com"}) in result.process_data.get("request", "")    assert 'form-data; name="Redirect"\n\nhttp://example6.com' in result.process_data.get("request", "")    assert "http://example3.com" == resp.get("headers", {}).get("referer")
 |