bugfix: POST content-type is application/x-www-form-urlencoded

This commit is contained in:
debugtalk
2018-11-30 14:20:44 +08:00
parent 630b9e7e8a
commit 26c7e0f5f8
4 changed files with 66 additions and 9 deletions

View File

@@ -14,6 +14,7 @@ import time
from httprunner.compat import basestring, builtin_str, integer_types, str
from httprunner.exceptions import ParamsError
from httprunner.utils import convert_dict_to_params, lower_dict_keys
from requests_toolbelt import MultipartEncoder
@@ -134,14 +135,23 @@ def endswith(check_value, expect_value):
"""
def setup_hook_prepare_kwargs(request):
if request["method"] == "POST":
content_type = request.get("headers", {}).get("content-type")
req_headers = lower_dict_keys(request.get("headers", {}))
content_type = req_headers.get("content-type")
if content_type and "data" in request:
# if request content-type is application/json, request data should be dumped
if content_type.startswith("application/json") and isinstance(request["data"], (dict, list)):
request["data"] = json.dumps(request["data"])
req_data = request["data"]
if isinstance(request["data"], str):
request["data"] = request["data"].encode('utf-8')
# if request content-type is application/json, request data should be dumped
if content_type.startswith("application/json") and isinstance(req_data, (dict, list)):
req_data = json.dumps(req_data)
# if request content-type is application/x-www-form-urlencoded, request data should be in params format
elif content_type.startswith("application/x-www-form-urlencoded") and isinstance(req_data, dict):
req_data = convert_dict_to_params(req_data)
if isinstance(req_data, str):
req_data = req_data.encode('utf-8')
request["data"] = req_data
def sleep_N_secs(n_secs):
""" sleep n seconds

View File

@@ -5,7 +5,7 @@ import time
import requests
import urllib3
from httprunner import logger
from httprunner.utils import build_url
from httprunner.utils import build_url, lower_dict_keys
from requests import Request, Response
from requests.exceptions import (InvalidSchema, InvalidURL, MissingSchema,
RequestException)
@@ -138,11 +138,13 @@ class HttpSession(requests.Session):
self.meta_data["response"]["url"] = response.url
self.meta_data["response"]["status_code"] = response.status_code
self.meta_data["response"]["reason"] = response.reason
self.meta_data["response"]["headers"] = dict(response.headers)
self.meta_data["response"]["cookies"] = response.cookies or {}
self.meta_data["response"]["encoding"] = response.encoding
resp_headers = dict(response.headers)
self.meta_data["response"]["headers"] = resp_headers
content_type = response.headers.get("Content-Type", "")
lower_resp_headers = lower_dict_keys(resp_headers)
content_type = lower_resp_headers.get("content-type", "")
self.meta_data["response"]["content_type"] = content_type
if "image" in content_type:

View File

@@ -152,6 +152,7 @@ def get_uniform_comparator(comparator):
else:
return comparator
def deep_update_dict(origin_dict, override_dict):
""" update origin dict with override dict recursively
e.g. origin_dict = {'a': 1, 'b': {'c': 2, 'd': 4}}
@@ -173,6 +174,31 @@ def deep_update_dict(origin_dict, override_dict):
return origin_dict
def convert_dict_to_params(src_dict):
""" convert dict to params string
Args:
src_dict (dict): source mapping data structure
Returns:
str: string params data
Examples:
>>> src_dict = {
"a": 1,
"b": 2
}
>>> convert_dict_to_params(src_dict)
>>> "a=1&b=2"
"""
return "&".join([
"{}={}".format(key, value)
for key, value in src_dict.items()
])
def lower_dict_keys(origin_dict):
""" convert keys in dict to lower case
@@ -210,6 +236,7 @@ def lower_dict_keys(origin_dict):
for key, value in origin_dict.items()
}
def lower_test_dict_keys(test_dict):
""" convert keys in test_dict to lower case, convertion will occur in two places:
1, all keys in test_dict;

View File

@@ -70,3 +70,21 @@ class TestHttpClient(ApiServerUnittest):
}
setup_hook_prepare_kwargs(request)
self.assertIsInstance(request["data"], bytes)
def test_prepare_kwargs_content_type_x_www_form_urlencoded(self):
request = {
"url": "/path",
"method": "POST",
"headers": {
"content-type": "application/x-www-form-urlencoded; charset=utf-8"
},
"data": {
"a": 1,
"b": 2
}
}
setup_hook_prepare_kwargs(request)
self.assertIsInstance(request["data"], bytes)
self.assertIn(b'a=1', request["data"])
self.assertIn(b'&', request["data"])
self.assertIn(b'b=2', request["data"])