aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/requests-mock/py3
diff options
context:
space:
mode:
authormaxim-yurchuk <maxim-yurchuk@yandex-team.com>2024-10-09 12:29:46 +0300
committermaxim-yurchuk <maxim-yurchuk@yandex-team.com>2024-10-09 13:14:22 +0300
commit9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80 (patch)
treea8fb3181d5947c0d78cf402aa56e686130179049 /contrib/python/requests-mock/py3
parenta44b779cd359f06c3ebbef4ec98c6b38609d9d85 (diff)
downloadydb-9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80.tar.gz
publishFullContrib: true for ydb
<HIDDEN_URL> commit_hash:c82a80ac4594723cebf2c7387dec9c60217f603e
Diffstat (limited to 'contrib/python/requests-mock/py3')
-rw-r--r--contrib/python/requests-mock/py3/patches/01-fix-tests.patch13
-rw-r--r--contrib/python/requests-mock/py3/patches/02-support-python-3.12.patch5
-rw-r--r--contrib/python/requests-mock/py3/tests/__init__.py0
-rw-r--r--contrib/python/requests-mock/py3/tests/base.py17
-rw-r--r--contrib/python/requests-mock/py3/tests/pytest/__init__.py0
-rw-r--r--contrib/python/requests-mock/py3/tests/pytest/pytest.ini2
-rw-r--r--contrib/python/requests-mock/py3/tests/pytest/test_with_pytest.py119
-rw-r--r--contrib/python/requests-mock/py3/tests/test_adapter.py724
-rw-r--r--contrib/python/requests-mock/py3/tests/test_custom_matchers.py74
-rw-r--r--contrib/python/requests-mock/py3/tests/test_fixture.py39
-rw-r--r--contrib/python/requests-mock/py3/tests/test_matcher.py324
-rw-r--r--contrib/python/requests-mock/py3/tests/test_mocker.py646
-rw-r--r--contrib/python/requests-mock/py3/tests/test_request.py139
-rw-r--r--contrib/python/requests-mock/py3/tests/test_response.py151
-rw-r--r--contrib/python/requests-mock/py3/tests/ya.make26
15 files changed, 2279 insertions, 0 deletions
diff --git a/contrib/python/requests-mock/py3/patches/01-fix-tests.patch b/contrib/python/requests-mock/py3/patches/01-fix-tests.patch
new file mode 100644
index 0000000000..dc5164a523
--- /dev/null
+++ b/contrib/python/requests-mock/py3/patches/01-fix-tests.patch
@@ -0,0 +1,13 @@
+--- contrib/python/requests-mock/py3/tests/base.py (index)
++++ contrib/python/requests-mock/py3/tests/base.py (working tree)
+@@ -10,8 +10,8 @@
+ # License for the specific language governing permissions and limitations
+ # under the License.
+
+-import testtools
++import unittest
+
+
+-class TestCase(testtools.TestCase):
++class TestCase(unittest.TestCase):
+ pass
diff --git a/contrib/python/requests-mock/py3/patches/02-support-python-3.12.patch b/contrib/python/requests-mock/py3/patches/02-support-python-3.12.patch
new file mode 100644
index 0000000000..c876bc8243
--- /dev/null
+++ b/contrib/python/requests-mock/py3/patches/02-support-python-3.12.patch
@@ -0,0 +1,5 @@
+--- contrib/python/requests-mock/py3/tests/test_mocker.py (index)
++++ contrib/python/requests-mock/py3/tests/test_mocker.py (working tree)
+@@ -222 +222 @@ class MockerTests(base.TestCase):
+- self.assertEquals(
++ self.assertEqual(
diff --git a/contrib/python/requests-mock/py3/tests/__init__.py b/contrib/python/requests-mock/py3/tests/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/contrib/python/requests-mock/py3/tests/__init__.py
diff --git a/contrib/python/requests-mock/py3/tests/base.py b/contrib/python/requests-mock/py3/tests/base.py
new file mode 100644
index 0000000000..ecc872ecb7
--- /dev/null
+++ b/contrib/python/requests-mock/py3/tests/base.py
@@ -0,0 +1,17 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import unittest
+
+
+class TestCase(unittest.TestCase):
+ pass
diff --git a/contrib/python/requests-mock/py3/tests/pytest/__init__.py b/contrib/python/requests-mock/py3/tests/pytest/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/contrib/python/requests-mock/py3/tests/pytest/__init__.py
diff --git a/contrib/python/requests-mock/py3/tests/pytest/pytest.ini b/contrib/python/requests-mock/py3/tests/pytest/pytest.ini
new file mode 100644
index 0000000000..58c87f21b7
--- /dev/null
+++ b/contrib/python/requests-mock/py3/tests/pytest/pytest.ini
@@ -0,0 +1,2 @@
+[pytest]
+requests_mock_case_sensitive=false
diff --git a/contrib/python/requests-mock/py3/tests/pytest/test_with_pytest.py b/contrib/python/requests-mock/py3/tests/pytest/test_with_pytest.py
new file mode 100644
index 0000000000..d74908bc38
--- /dev/null
+++ b/contrib/python/requests-mock/py3/tests/pytest/test_with_pytest.py
@@ -0,0 +1,119 @@
+try:
+ from http import HTTPStatus
+ HTTP_STATUS_FOUND = HTTPStatus.FOUND
+except ImportError:
+ from httplib import FOUND as HTTP_STATUS_FOUND
+
+import pytest
+import requests
+import requests_mock
+
+
+def test_simple(requests_mock):
+ requests_mock.get('https://httpbin.org/get', text='data')
+ assert 'data' == requests.get('https://httpbin.org/get').text
+
+
+def test_redirect_and_nesting():
+ url_inner = "inner-mock://example.test/"
+ url_middle = "middle-mock://example.test/"
+ url_outer = "outer-mock://example.test/"
+ url_base = "https://www.example.com/"
+
+ text_middle = 'middle' + url_middle
+ text_outer = 'outer' + url_outer
+ text_base = 'outer' + url_base
+
+ with requests_mock.Mocker() as outer_mock:
+ outer_mock.get(url_base, text=text_base)
+ outer_mock.get(url_outer, text=text_outer)
+
+ with requests_mock.Mocker(real_http=True) as middle_mock:
+ middle_mock.get(url_middle, text=text_middle)
+
+ with requests_mock.Mocker() as inner_mock:
+ inner_mock.post(url_inner,
+ status_code=HTTP_STATUS_FOUND,
+ headers={'location': url_base})
+ inner_mock.get(url_base, real_http=True)
+
+ assert text_base == requests.post(url_inner).text # nosec
+
+ with pytest.raises(requests_mock.NoMockAddress):
+ requests.get(url_middle)
+
+ with pytest.raises(requests_mock.NoMockAddress):
+ requests.get(url_outer)
+
+ # back to middle mock
+ with pytest.raises(requests_mock.NoMockAddress):
+ requests.post(url_inner)
+
+ assert text_middle == requests.get(url_middle).text # nosec
+ assert text_outer == requests.get(url_outer).text # nosec
+
+ # back to outter mock
+ with pytest.raises(requests_mock.NoMockAddress):
+ requests.post(url_inner)
+
+ with pytest.raises(requests_mock.NoMockAddress):
+ requests.get(url_middle)
+
+ assert text_outer == requests.get(url_outer).text # nosec
+
+
+def test_mixed_mocks():
+ url = 'mock://example.test/'
+ with requests_mock.Mocker() as global_mock:
+ global_mock.get(url, text='global')
+ session = requests.Session()
+ text = session.get(url).text
+ assert text == 'global' # nosec
+ with requests_mock.Mocker(session=session) as session_mock:
+ session_mock.get(url, real_http=True)
+ text = session.get(url).text
+ assert text == 'global' # nosec
+
+
+def test_threaded_sessions():
+ """
+ When using requests_futures.FuturesSession() with a ThreadPoolExecutor
+ there is a race condition where one threaded request removes the
+ monkeypatched get_adapter() method from the Session before another threaded
+ request is finished using it.
+ """
+ from requests_futures.sessions import FuturesSession
+
+ url1 = 'http://www.example.com/requests-mock-fake-url1'
+ url2 = 'http://www.example.com/requests-mock-fake-url2'
+
+ with requests_mock.Mocker() as m:
+ # respond with 204 so we know its us
+ m.get(url1, status_code=204)
+ m.get(url2, status_code=204)
+
+ # NOTE(phodge): just firing off two .get() requests right after each
+ # other was a pretty reliable way to reproduce the race condition on my
+ # intel Macbook Pro but YMMV. Guaranteeing the race condition to
+ # reappear might require replacing the Session.send() with a wrapper
+ # that delays kicking off the request for url1 until the request for
+ # url2 has restored the original session.get_adapter(), but replacing
+ # Session.send() could be difficult because the requests_mock.Mocker()
+ # context manager has *already* monkeypatched this method.
+ session = FuturesSession()
+ future1 = session.get(url1)
+ future2 = session.get(url2)
+
+ # verify both requests were handled by the mock dispatcher
+ assert future1.result().status_code == 204
+ assert future2.result().status_code == 204
+
+
+class TestClass(object):
+
+ def configure(self, requests_mock):
+ requests_mock.get('https://httpbin.org/get', text='data')
+
+ def test_one(self, requests_mock):
+ self.configure(requests_mock)
+ assert 'data' == requests.get('https://httpbin.org/get').text
diff --git a/contrib/python/requests-mock/py3/tests/test_adapter.py b/contrib/python/requests-mock/py3/tests/test_adapter.py
new file mode 100644
index 0000000000..4d6a0b4df2
--- /dev/null
+++ b/contrib/python/requests-mock/py3/tests/test_adapter.py
@@ -0,0 +1,724 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import http.client
+import io
+import json
+import re
+import urllib.parse
+
+import purl
+import requests
+from urllib3 import HTTPResponse
+
+import requests_mock
+from . import base
+
+
+class MyExc(Exception):
+ pass
+
+
+class SessionAdapterTests(base.TestCase):
+
+ PREFIX = "mock"
+
+ def setUp(self):
+ super(SessionAdapterTests, self).setUp()
+
+ self.adapter = requests_mock.Adapter()
+ self.session = requests.Session()
+ self.session.mount(self.PREFIX, self.adapter)
+
+ self.url = '%s://example.com/test' % self.PREFIX
+ self.headers = {'header_a': 'A', 'header_b': 'B'}
+
+ def assertHeaders(self, resp):
+ for k, v in self.headers.items():
+ self.assertEqual(v, resp.headers[k])
+
+ def assertLastRequest(self, method='GET', body=None):
+ self.assertEqual(self.url, self.adapter.last_request.url)
+ self.assertEqual(method, self.adapter.last_request.method)
+ self.assertEqual(body, self.adapter.last_request.body)
+
+ url_parts = urllib.parse.urlparse(self.url)
+ qs = urllib.parse.parse_qs(url_parts.query)
+ self.assertEqual(url_parts.scheme, self.adapter.last_request.scheme)
+ self.assertEqual(url_parts.netloc, self.adapter.last_request.netloc)
+ self.assertEqual(url_parts.path, self.adapter.last_request.path)
+ self.assertEqual(url_parts.query, self.adapter.last_request.query)
+ self.assertEqual(url_parts.query, self.adapter.last_request.query)
+ self.assertEqual(qs, self.adapter.last_request.qs)
+
+ def test_content(self):
+ data = b'testdata'
+
+ self.adapter.register_uri('GET',
+ self.url,
+ content=data,
+ headers=self.headers)
+ resp = self.session.get(self.url)
+ self.assertEqual(data, resp.content)
+ self.assertHeaders(resp)
+ self.assertLastRequest()
+
+ def test_content_callback(self):
+ status_code = 401
+ data = b'testdata'
+
+ def _content_cb(request, context):
+ context.status_code = status_code
+ context.headers.update(self.headers)
+ return data
+
+ self.adapter.register_uri('GET',
+ self.url,
+ content=_content_cb)
+ resp = self.session.get(self.url)
+ self.assertEqual(status_code, resp.status_code)
+ self.assertEqual(data, resp.content)
+ self.assertHeaders(resp)
+ self.assertLastRequest()
+
+ def test_text(self):
+ data = u'testdata'
+
+ self.adapter.register_uri('GET',
+ self.url,
+ text=data,
+ headers=self.headers)
+ resp = self.session.get(self.url)
+ self.assertEqual(data.encode('utf-8'), resp.content)
+ self.assertEqual(data, resp.text)
+ self.assertEqual('utf-8', resp.encoding)
+ self.assertHeaders(resp)
+ self.assertLastRequest()
+
+ def test_text_callback(self):
+ status_code = 401
+ data = u'testdata'
+
+ def _text_cb(request, context):
+ context.status_code = status_code
+ context.headers.update(self.headers)
+ return data
+
+ self.adapter.register_uri('GET', self.url, text=_text_cb)
+ resp = self.session.get(self.url)
+ self.assertEqual(status_code, resp.status_code)
+ self.assertEqual(data, resp.text)
+ self.assertEqual(data.encode('utf-8'), resp.content)
+ self.assertEqual('utf-8', resp.encoding)
+ self.assertHeaders(resp)
+ self.assertLastRequest()
+
+ def test_raw_callback(self):
+ status_code = 401
+ data = 'testdata'
+
+ def _raw_cb(request, context):
+ return HTTPResponse(
+ status=status_code,
+ headers=self.headers,
+ body=io.BytesIO(data.encode('utf-8')),
+ preload_content=False,
+ reason=http.client.responses.get(status_code),
+ )
+
+ self.adapter.register_uri('GET', self.url, raw=_raw_cb)
+ resp = self.session.get(self.url)
+ self.assertEqual(status_code, resp.status_code)
+ self.assertEqual(data, resp.text)
+ self.assertEqual(data.encode('utf-8'), resp.content)
+ self.assertHeaders(resp)
+ self.assertLastRequest()
+
+ def test_json(self):
+ json_data = {'hello': 'world'}
+ self.adapter.register_uri('GET',
+ self.url,
+ json=json_data,
+ headers=self.headers)
+ resp = self.session.get(self.url)
+ self.assertEqual(b'{"hello": "world"}', resp.content)
+ self.assertEqual(u'{"hello": "world"}', resp.text)
+ self.assertEqual(json_data, resp.json())
+ self.assertEqual('utf-8', resp.encoding)
+ self.assertHeaders(resp)
+ self.assertLastRequest()
+
+ def test_json_callback(self):
+ status_code = 401
+ json_data = {'hello': 'world'}
+ data = u'{"hello": "world"}'
+
+ def _json_cb(request, context):
+ context.status_code = status_code
+ context.headers.update(self.headers)
+ return json_data
+
+ self.adapter.register_uri('GET', self.url, json=_json_cb)
+ resp = self.session.get(self.url)
+ self.assertEqual(status_code, resp.status_code)
+ self.assertEqual(json_data, resp.json())
+ self.assertEqual(data, resp.text)
+ self.assertEqual(data.encode('utf-8'), resp.content)
+ self.assertEqual('utf-8', resp.encoding)
+ self.assertHeaders(resp)
+ self.assertLastRequest()
+
+ def test_no_body(self):
+ self.adapter.register_uri('GET', self.url)
+ resp = self.session.get(self.url)
+ self.assertEqual(b'', resp.content)
+ self.assertEqual(200, resp.status_code)
+
+ def test_multiple_body_elements(self):
+ self.assertRaises(RuntimeError,
+ self.adapter.register_uri,
+ self.url,
+ 'GET',
+ content=b'b',
+ text=u'u')
+
+ def test_multiple_responses(self):
+ inp = [{'status_code': 400, 'text': 'abcd'},
+ {'status_code': 300, 'text': 'defg'},
+ {'status_code': 200, 'text': 'hijk'}]
+
+ self.adapter.register_uri('GET', self.url, inp)
+ out = [self.session.get(self.url) for i in range(0, len(inp))]
+
+ for i, o in zip(inp, out):
+ for k, v in i.items():
+ self.assertEqual(v, getattr(o, k))
+
+ last = self.session.get(self.url)
+ for k, v in inp[-1].items():
+ self.assertEqual(v, getattr(last, k))
+
+ def test_callback_optional_status(self):
+ headers = {'a': 'b'}
+
+ def _test_cb(request, context):
+ context.headers.update(headers)
+ return ''
+
+ self.adapter.register_uri('GET',
+ self.url,
+ text=_test_cb,
+ status_code=300)
+ resp = self.session.get(self.url)
+ self.assertEqual(300, resp.status_code)
+
+ for k, v in headers.items():
+ self.assertEqual(v, resp.headers[k])
+
+ def test_callback_optional_headers(self):
+ headers = {'a': 'b'}
+
+ def _test_cb(request, context):
+ context.status_code = 300
+ return ''
+
+ self.adapter.register_uri('GET',
+ self.url,
+ text=_test_cb,
+ headers=headers)
+
+ resp = self.session.get(self.url)
+ self.assertEqual(300, resp.status_code)
+
+ for k, v in headers.items():
+ self.assertEqual(v, resp.headers[k])
+
+ def test_latest_register_overrides(self):
+ self.adapter.register_uri('GET', self.url, text='abc')
+ self.adapter.register_uri('GET', self.url, text='def')
+
+ resp = self.session.get(self.url)
+ self.assertEqual('def', resp.text)
+
+ def test_no_last_request(self):
+ self.assertIsNone(self.adapter.last_request)
+ self.assertEqual(0, len(self.adapter.request_history))
+
+ def test_dont_pass_list_and_kwargs(self):
+ self.assertRaises(RuntimeError,
+ self.adapter.register_uri,
+ 'GET',
+ self.url,
+ [{'text': 'a'}],
+ headers={'a': 'b'})
+
+ def test_empty_string_return(self):
+ # '' evaluates as False, so make sure an empty string is not ignored.
+ self.adapter.register_uri('GET', self.url, text='')
+ resp = self.session.get(self.url)
+ self.assertEqual('', resp.text)
+
+ def test_dont_pass_multiple_bodies(self):
+ self.assertRaises(RuntimeError,
+ self.adapter.register_uri,
+ 'GET',
+ self.url,
+ json={'abc': 'def'},
+ text='ghi')
+
+ def test_dont_pass_unexpected_kwargs(self):
+ self.assertRaises(TypeError,
+ self.adapter.register_uri,
+ 'GET',
+ self.url,
+ unknown='argument')
+
+ def test_dont_pass_unicode_as_content(self):
+ self.assertRaises(TypeError,
+ self.adapter.register_uri,
+ 'GET',
+ self.url,
+ content=u'unicode')
+
+ def test_dont_pass_empty_string_as_content(self):
+ self.assertRaises(TypeError,
+ self.adapter.register_uri,
+ 'GET',
+ self.url,
+ content=u'')
+
+ def test_dont_pass_bytes_as_text(self):
+ self.assertRaises(TypeError,
+ self.adapter.register_uri,
+ 'GET',
+ self.url,
+ text=b'bytes')
+
+ def test_dont_pass_empty_string_as_text(self):
+ self.assertRaises(TypeError,
+ self.adapter.register_uri,
+ 'GET',
+ self.url,
+ text=b'')
+
+ def test_dont_pass_non_str_as_content(self):
+ self.assertRaises(TypeError,
+ self.adapter.register_uri,
+ 'GET',
+ self.url,
+ content=5)
+
+ def test_dont_pass_non_str_as_text(self):
+ self.assertRaises(TypeError,
+ self.adapter.register_uri,
+ 'GET',
+ self.url,
+ text=5)
+
+ def test_with_any_method(self):
+ self.adapter.register_uri(requests_mock.ANY, self.url, text='resp')
+
+ for m in ('GET', 'HEAD', 'POST', 'UNKNOWN'):
+ resp = self.session.request(m, self.url)
+ self.assertEqual('resp', resp.text)
+
+ def test_with_any_url(self):
+ self.adapter.register_uri('GET', requests_mock.ANY, text='resp')
+
+ for u in ('mock://a', 'mock://b', 'mock://c'):
+ resp = self.session.get(u)
+ self.assertEqual('resp', resp.text)
+
+ def test_with_regexp(self):
+ self.adapter.register_uri('GET', re.compile('tester.com'), text='resp')
+
+ for u in ('mock://www.tester.com/a', 'mock://abc.tester.com'):
+ resp = self.session.get(u)
+ self.assertEqual('resp', resp.text)
+
+ def test_with_purl(self):
+ self.adapter.register_uri('GET',
+ purl.URL('mock://www.tester.com/a'),
+ text='resp')
+
+ resp = self.session.get('mock://www.tester.com/a')
+ self.assertEqual('resp', resp.text)
+
+ def test_requests_in_history_on_no_match(self):
+ self.assertRaises(requests_mock.NoMockAddress,
+ self.session.get,
+ self.url)
+
+ self.assertEqual(self.url, self.adapter.last_request.url)
+
+ def test_requests_in_history_on_exception(self):
+
+ def _test_cb(request, ctx):
+ raise MyExc()
+
+ self.adapter.register_uri('GET', self.url, text=_test_cb)
+
+ self.assertRaises(MyExc,
+ self.session.get,
+ self.url)
+
+ self.assertEqual(self.url, self.adapter.last_request.url)
+
+ def test_not_called_and_called_count(self):
+ m = self.adapter.register_uri('GET', self.url, text='resp')
+ self.assertEqual(0, m.call_count)
+ self.assertFalse(m.called)
+ self.assertFalse(m.called_once)
+
+ self.assertEqual(0, self.adapter.call_count)
+ self.assertFalse(self.adapter.called)
+ self.assertFalse(m.called_once)
+
+ def test_called_and_called_count(self):
+ m = self.adapter.register_uri('GET', self.url, text='resp')
+
+ resps = [self.session.get(self.url) for i in range(0, 3)]
+
+ for r in resps:
+ self.assertEqual('resp', r.text)
+ self.assertEqual(200, r.status_code)
+
+ self.assertEqual(len(resps), m.call_count)
+ self.assertTrue(m.called)
+ self.assertFalse(m.called_once)
+
+ self.assertEqual(len(resps), self.adapter.call_count)
+ self.assertTrue(self.adapter.called)
+ self.assertFalse(m.called_once)
+
+ def test_reset_reverts_call_count(self):
+ # Create matchers and add calls to history
+ call_count = 3
+ matcher_count = 3
+ for i in range(matcher_count):
+ url = self.url + str(i)
+ self.adapter.register_uri('GET', url, text='resp')
+ for _ in range(call_count):
+ self.session.get(url)
+
+ # Verify call counts on adapter and matchers
+ self.assertEqual(self.adapter.call_count, matcher_count * call_count)
+ for matcher in self.adapter._matchers:
+ self.assertEqual(matcher.call_count, call_count)
+
+ self.adapter.reset()
+
+ # Verify call counts are 0 after reset
+ self.assertEqual(self.adapter.call_count, 0)
+ for matcher in self.adapter._matchers:
+ self.assertEqual(matcher.call_count, 0)
+
+ def test_adapter_picks_correct_adapter(self):
+ good = '%s://test3.url/' % self.PREFIX
+ self.adapter.register_uri('GET',
+ '%s://test1.url' % self.PREFIX,
+ text='bad')
+ self.adapter.register_uri('GET',
+ '%s://test2.url' % self.PREFIX,
+ text='bad')
+ self.adapter.register_uri('GET', good, text='good')
+ self.adapter.register_uri('GET',
+ '%s://test4.url' % self.PREFIX,
+ text='bad')
+
+ resp = self.session.get(good)
+
+ self.assertEqual('good', resp.text)
+
+ def test_adapter_is_connection(self):
+ url = '%s://test.url' % self.PREFIX
+ text = 'text'
+ self.adapter.register_uri('GET', url, text=text)
+ resp = self.session.get(url)
+
+ self.assertEqual(text, resp.text)
+ self.assertIs(self.adapter, resp.connection)
+
+ def test_send_to_connection(self):
+ url1 = '%s://test1.url/' % self.PREFIX
+ url2 = '%s://test2.url/' % self.PREFIX
+
+ text1 = 'text1'
+ text2 = 'text2'
+
+ self.adapter.register_uri('GET', url1, text=text1)
+ self.adapter.register_uri('GET', url2, text=text2)
+
+ req = requests.Request(method='GET', url=url2).prepare()
+
+ resp1 = self.session.get(url1)
+ self.assertEqual(text1, resp1.text)
+
+ resp2 = resp1.connection.send(req)
+ self.assertEqual(text2, resp2.text)
+
+ def test_request_json_with_str_data(self):
+ dict_req = {'hello': 'world'}
+ dict_resp = {'goodbye': 'world'}
+
+ m = self.adapter.register_uri('POST', self.url, json=dict_resp)
+
+ data = json.dumps(dict_req)
+ resp = self.session.post(self.url, data=data)
+
+ self.assertIs(data, m.last_request.body)
+ self.assertEqual(dict_resp, resp.json())
+ self.assertEqual(dict_req, m.last_request.json())
+
+ def test_request_json_with_bytes_data(self):
+ dict_req = {'hello': 'world'}
+ dict_resp = {'goodbye': 'world'}
+
+ m = self.adapter.register_uri('POST', self.url, json=dict_resp)
+
+ data = json.dumps(dict_req).encode('utf-8')
+ resp = self.session.post(self.url, data=data)
+
+ self.assertIs(data, m.last_request.body)
+ self.assertEqual(dict_resp, resp.json())
+ self.assertEqual(dict_req, m.last_request.json())
+
+ def test_request_json_with_cb(self):
+ dict_req = {'hello': 'world'}
+ dict_resp = {'goodbye': 'world'}
+ data = json.dumps(dict_req)
+
+ def _cb(req, context):
+ self.assertEqual(dict_req, req.json())
+ return dict_resp
+
+ m = self.adapter.register_uri('POST', self.url, json=_cb)
+ resp = self.session.post(self.url, data=data)
+
+ self.assertEqual(1, m.call_count)
+ self.assertTrue(m.called_once)
+ self.assertEqual(dict_resp, resp.json())
+
+ def test_raises_exception(self):
+ self.adapter.register_uri('GET', self.url, exc=MyExc)
+
+ self.assertRaises(MyExc,
+ self.session.get,
+ self.url)
+
+ self.assertTrue(self.adapter.called_once)
+ self.assertEqual(self.url, self.adapter.last_request.url)
+
+ def test_raises_exception_with_body_args_fails(self):
+ self.assertRaises(TypeError,
+ self.adapter.register_uri,
+ 'GET',
+ self.url,
+ exc=MyExc,
+ text='fail')
+
+ def test_sets_request_matcher_in_history(self):
+ url1 = '%s://test1.url/' % self.PREFIX
+ url2 = '%s://test2.url/' % self.PREFIX
+
+ text1 = 'text1'
+ text2 = 'text2'
+
+ m1 = self.adapter.register_uri('GET', url1, text=text1)
+ m2 = self.adapter.register_uri('GET', url2, text=text2)
+
+ resp1 = self.session.get(url1)
+ resp2 = self.session.get(url2)
+
+ self.assertEqual(text1, resp1.text)
+ self.assertEqual(text2, resp2.text)
+
+ self.assertEqual(2, self.adapter.call_count)
+ self.assertFalse(self.adapter.called_once)
+
+ self.assertEqual(url1, self.adapter.request_history[0].url)
+ self.assertEqual(url2, self.adapter.request_history[1].url)
+
+ self.assertIs(m1, self.adapter.request_history[0].matcher)
+ self.assertIs(m2, self.adapter.request_history[1].matcher)
+
+ def test_sets_request_matcher_on_exception(self):
+ m = self.adapter.register_uri('GET', self.url, exc=MyExc)
+
+ self.assertRaises(MyExc,
+ self.session.get,
+ self.url)
+
+ self.assertEqual(self.url, self.adapter.last_request.url)
+ self.assertIs(m, self.adapter.last_request.matcher)
+
+ def test_cookies_from_header(self):
+ headers = {'Set-Cookie': 'fig=newton; Path=/test; domain=.example.com'}
+ self.adapter.register_uri('GET',
+ self.url,
+ text='text',
+ headers=headers)
+
+ resp = self.session.get(self.url)
+
+ self.assertEqual('newton', resp.cookies['fig'])
+ self.assertEqual(['/test'], resp.cookies.list_paths())
+ self.assertEqual(['.example.com'], resp.cookies.list_domains())
+
+ def test_cookies_from_dict(self):
+ # This is a syntax we get from requests. I'm not sure i like it.
+ self.adapter.register_uri('GET',
+ self.url,
+ text='text',
+ cookies={'fig': 'newton', 'sugar': 'apple'})
+
+ resp = self.session.get(self.url)
+
+ self.assertEqual('newton', resp.cookies['fig'])
+ self.assertEqual('apple', resp.cookies['sugar'])
+
+ def test_cookies_with_jar(self):
+ jar = requests_mock.CookieJar()
+ jar.set('fig', 'newton', path='/foo', domain='.example.com')
+ jar.set('sugar', 'apple', path='/bar', domain='.example.com')
+
+ self.adapter.register_uri('GET', self.url, text='text', cookies=jar)
+ resp = self.session.get(self.url)
+
+ self.assertEqual('newton', resp.cookies['fig'])
+ self.assertEqual('apple', resp.cookies['sugar'])
+ self.assertEqual({'/foo', '/bar'}, set(resp.cookies.list_paths()))
+ self.assertEqual(['.example.com'], resp.cookies.list_domains())
+
+ def test_cookies_header_with_cb(self):
+
+ def _cb(request, context):
+ val = 'fig=newton; Path=/test; domain=.example.com'
+ context.headers['Set-Cookie'] = val
+ return 'text'
+
+ self.adapter.register_uri('GET', self.url, text=_cb)
+ resp = self.session.get(self.url)
+
+ self.assertEqual('newton', resp.cookies['fig'])
+ self.assertEqual(['/test'], resp.cookies.list_paths())
+ self.assertEqual(['.example.com'], resp.cookies.list_domains())
+
+ def test_cookies_from_dict_with_cb(self):
+ def _cb(request, context):
+ # converted into a jar by now
+ context.cookies.set('sugar', 'apple', path='/test')
+ return 'text'
+
+ self.adapter.register_uri('GET',
+ self.url,
+ text=_cb,
+ cookies={'fig': 'newton'})
+
+ resp = self.session.get(self.url)
+
+ self.assertEqual('newton', resp.cookies['fig'])
+ self.assertEqual('apple', resp.cookies['sugar'])
+ self.assertEqual(['/', '/test'], resp.cookies.list_paths())
+
+ def test_cookies_with_jar_cb(self):
+ def _cb(request, context):
+ context.cookies.set('sugar',
+ 'apple',
+ path='/bar',
+ domain='.example.com')
+ return 'text'
+
+ jar = requests_mock.CookieJar()
+ jar.set('fig', 'newton', path='/foo', domain='.example.com')
+
+ self.adapter.register_uri('GET', self.url, text=_cb, cookies=jar)
+ resp = self.session.get(self.url)
+
+ self.assertEqual('newton', resp.cookies['fig'])
+ self.assertEqual('apple', resp.cookies['sugar'])
+ self.assertEqual({'/foo', '/bar'}, set(resp.cookies.list_paths()))
+ self.assertEqual(['.example.com'], resp.cookies.list_domains())
+
+ def test_reading_closed_fp(self):
+ self.adapter.register_uri('GET', self.url, text='abc')
+ resp = self.session.get(self.url)
+
+ # raw will have been closed during the request reading
+ self.assertTrue(resp.raw.closed)
+
+ data = resp.raw.read()
+
+ self.assertIsInstance(data, bytes)
+ self.assertEqual(0, len(data))
+
+ def test_case_sensitive_headers(self):
+ data = 'testdata'
+ headers = {'aBcDe': 'FgHiJ'}
+
+ self.adapter.register_uri('GET', self.url, text=data)
+ resp = self.session.get(self.url, headers=headers)
+
+ self.assertEqual('GET', self.adapter.last_request.method)
+ self.assertEqual(200, resp.status_code)
+ self.assertEqual(data, resp.text)
+
+ for k, v in headers.items():
+ self.assertEqual(v, self.adapter.last_request.headers[k])
+
+ def test_case_sensitive_history(self):
+ self.adapter._case_sensitive = True
+
+ data = 'testdata'
+ netloc = 'examPlE.CoM'
+ path = '/TesTER'
+ query = 'aBC=deF'
+
+ mock_url = '%s://%s%s' % (self.PREFIX, netloc.lower(), path)
+ request_url = '%s://%s%s?%s' % (self.PREFIX, netloc, path, query)
+
+ # test that the netloc is ignored when actually making the request
+ self.adapter.register_uri('GET', mock_url, text=data)
+ resp = self.session.get(request_url)
+
+ self.assertEqual('GET', self.adapter.last_request.method)
+ self.assertEqual(200, resp.status_code)
+ self.assertEqual(data, resp.text)
+
+ # but even still the mixed case parameters come out in history
+ self.assertEqual(netloc, self.adapter.last_request.netloc)
+ self.assertEqual(path, self.adapter.last_request.path)
+ self.assertEqual(query, self.adapter.last_request.query)
+
+ def test_stream_none(self):
+ text = 'hello world'
+
+ self.adapter.register_uri('GET',
+ self.url,
+ text=text,
+ headers=self.headers)
+
+ resp = self.session.get(self.url, stream=True)
+ resps = [c for c in resp.iter_content(None, decode_unicode=True)]
+ self.assertEqual([text], resps)
+
+ def test_stream_size(self):
+ text = 'hello world'
+
+ self.adapter.register_uri('GET',
+ self.url,
+ text=text,
+ headers=self.headers)
+
+ resp = self.session.get(self.url, stream=True)
+ resps = [c for c in resp.iter_content(3, decode_unicode=True)]
+ self.assertEqual(['hel', 'lo ', 'wor', 'ld'], resps)
diff --git a/contrib/python/requests-mock/py3/tests/test_custom_matchers.py b/contrib/python/requests-mock/py3/tests/test_custom_matchers.py
new file mode 100644
index 0000000000..73e23822f5
--- /dev/null
+++ b/contrib/python/requests-mock/py3/tests/test_custom_matchers.py
@@ -0,0 +1,74 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import requests
+
+import requests_mock
+from . import base
+
+
+class FailMatcher(object):
+
+ def __init___(self):
+ self.called = False
+
+ def __call__(self, request):
+ self.called = True
+ return None
+
+
+def match_all(request):
+ return requests_mock.create_response(request, content=b'data')
+
+
+class CustomMatchersTests(base.TestCase):
+
+ def assertMatchAll(self, resp):
+ self.assertEqual(200, resp.status_code)
+ self.assertEqual(resp.text, u'data')
+
+ @requests_mock.Mocker()
+ def test_custom_matcher(self, mocker):
+ mocker.add_matcher(match_all)
+
+ resp = requests.get('http://any/thing')
+ self.assertMatchAll(resp)
+
+ @requests_mock.Mocker()
+ def test_failing_matcher(self, mocker):
+ failer = FailMatcher()
+
+ mocker.add_matcher(match_all)
+ mocker.add_matcher(failer)
+
+ resp = requests.get('http://any/thing')
+
+ self.assertMatchAll(resp)
+ self.assertTrue(failer.called)
+
+ @requests_mock.Mocker()
+ def test_some_pass(self, mocker):
+
+ def matcher_a(request):
+ if 'a' in request.url:
+ return match_all(request)
+
+ return None
+
+ mocker.add_matcher(matcher_a)
+
+ resp = requests.get('http://any/thing')
+ self.assertMatchAll(resp)
+
+ self.assertRaises(requests_mock.NoMockAddress,
+ requests.get,
+ 'http://other/thing')
diff --git a/contrib/python/requests-mock/py3/tests/test_fixture.py b/contrib/python/requests-mock/py3/tests/test_fixture.py
new file mode 100644
index 0000000000..63cbb99141
--- /dev/null
+++ b/contrib/python/requests-mock/py3/tests/test_fixture.py
@@ -0,0 +1,39 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import requests
+import requests_mock
+from requests_mock.contrib import fixture
+from . import base
+
+
+class MockingTests(base.TestCase):
+
+ def setUp(self):
+ super(MockingTests, self).setUp()
+ self.mocker = self.useFixture(fixture.Fixture())
+
+ def test_failure(self):
+ self.assertRaises(requests_mock.NoMockAddress,
+ requests.get,
+ 'http://www.google.com')
+
+ def test_basic(self):
+ test_url = 'http://www.google.com/'
+ self.mocker.register_uri('GET', test_url, text='response')
+
+ resp = requests.get(test_url)
+ self.assertEqual('response', resp.text)
+ self.assertEqual(test_url, self.mocker.last_request.url)
+
+ def test_fixture_has_normal_attr_error(self):
+ self.assertRaises(AttributeError, lambda: self.mocker.unknown)
diff --git a/contrib/python/requests-mock/py3/tests/test_matcher.py b/contrib/python/requests-mock/py3/tests/test_matcher.py
new file mode 100644
index 0000000000..a30e195966
--- /dev/null
+++ b/contrib/python/requests-mock/py3/tests/test_matcher.py
@@ -0,0 +1,324 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import re
+
+from requests_mock import adapter
+from . import base
+from requests_mock.response import _MatcherResponse
+
+ANY = adapter.ANY
+
+
+class TestMatcher(base.TestCase):
+
+ def match(self,
+ target,
+ url,
+ matcher_method='GET',
+ request_method='GET',
+ complete_qs=False,
+ headers=None,
+ request_data=None,
+ request_headers={},
+ additional_matcher=None,
+ real_http=False,
+ case_sensitive=False):
+ matcher = adapter._Matcher(matcher_method,
+ target,
+ [],
+ complete_qs=complete_qs,
+ additional_matcher=additional_matcher,
+ request_headers=request_headers,
+ real_http=real_http,
+ case_sensitive=case_sensitive)
+ request = adapter._RequestObjectProxy._create(request_method,
+ url,
+ headers,
+ data=request_data)
+ return matcher._match(request)
+
+ def assertMatch(self,
+ target=ANY,
+ url='http://example.com/requests-mock',
+ matcher_method='GET',
+ request_method='GET',
+ **kwargs):
+ self.assertEqual(True,
+ self.match(target,
+ url,
+ matcher_method=matcher_method,
+ request_method=request_method,
+ **kwargs),
+ 'Matcher %s %s failed to match %s %s' %
+ (matcher_method, target, request_method, url))
+
+ def assertMatchBoth(self,
+ target=ANY,
+ url='http://example.com/requests-mock',
+ matcher_method='GET',
+ request_method='GET',
+ **kwargs):
+ self.assertMatch(target,
+ url,
+ matcher_method=matcher_method,
+ request_method=request_method,
+ **kwargs)
+ self.assertMatch(url,
+ target,
+ matcher_method=request_method,
+ request_method=matcher_method,
+ **kwargs)
+
+ def assertNoMatch(self,
+ target=ANY,
+ url='http://example.com/requests-mock',
+ matcher_method='GET',
+ request_method='GET',
+ **kwargs):
+ self.assertEqual(False,
+ self.match(target,
+ url,
+ matcher_method=matcher_method,
+ request_method=request_method,
+ **kwargs),
+ 'Matcher %s %s unexpectedly matched %s %s' %
+ (matcher_method, target, request_method, url))
+
+ def assertNoMatchBoth(self,
+ target=ANY,
+ url='http://example.com/requests-mock',
+ matcher_method='GET',
+ request_method='GET',
+ **kwargs):
+ self.assertNoMatch(target,
+ url,
+ matcher_method=matcher_method,
+ request_method=request_method,
+ **kwargs)
+ self.assertNoMatch(url,
+ target,
+ matcher_method=request_method,
+ request_method=matcher_method,
+ **kwargs)
+
+ def assertMatchMethodBoth(self, matcher_method, request_method, **kwargs):
+ url = 'http://www.test.com'
+
+ self.assertMatchBoth(url,
+ url,
+ request_method=request_method,
+ matcher_method=matcher_method,
+ **kwargs)
+
+ def assertNoMatchMethodBoth(self,
+ matcher_method,
+ request_method,
+ **kwargs):
+ url = 'http://www.test.com'
+
+ self.assertNoMatchBoth(url,
+ url,
+ request_method=request_method,
+ matcher_method=matcher_method,
+ **kwargs)
+
+ def test_url_matching(self):
+ self.assertMatchBoth('http://www.test.com',
+ 'http://www.test.com')
+ self.assertMatchBoth('http://www.test.com',
+ 'http://www.test.com/')
+ self.assertMatchBoth('http://www.test.com/abc',
+ 'http://www.test.com/abc')
+ self.assertMatchBoth('http://www.test.com:5000/abc',
+ 'http://www.test.com:5000/abc')
+ self.assertNoMatchBoth('https://www.test.com',
+ 'http://www.test.com')
+ self.assertNoMatchBoth('http://www.test.com/abc',
+ 'http://www.test.com')
+ self.assertNoMatchBoth('http://test.com',
+ 'http://www.test.com')
+ self.assertNoMatchBoth('http://test.com',
+ 'http://www.test.com')
+ self.assertNoMatchBoth('http://test.com/abc',
+ 'http://www.test.com/abc/')
+ self.assertNoMatchBoth('http://test.com/abc/',
+ 'http://www.test.com/abc')
+ self.assertNoMatchBoth('http://test.com:5000/abc/',
+ 'http://www.test.com/abc')
+ self.assertNoMatchBoth('http://test.com/abc/',
+ 'http://www.test.com:5000/abc')
+
+ def test_quotation(self):
+ self.assertMatchBoth('http://www.test.com/a string%url',
+ 'http://www.test.com/a string%url')
+ self.assertMatchBoth('http://www.test.com/ABC 123',
+ 'http://www.test.com/ABC%20123')
+ self.assertMatchBoth('http://www.test.com/user@example.com',
+ 'http://www.test.com/user@example.com')
+
+ def test_subset_match(self):
+ self.assertMatch('/path', 'http://www.test.com/path')
+ self.assertMatch('/path', 'http://www.test.com/path')
+ self.assertMatch('//www.test.com/path', 'http://www.test.com/path')
+ self.assertMatch('//www.test.com/path', 'https://www.test.com/path')
+
+ def test_query_string(self):
+ self.assertMatch('/path?a=1&b=2',
+ 'http://www.test.com/path?a=1&b=2')
+ self.assertMatch('/path?a=1',
+ 'http://www.test.com/path?a=1&b=2',
+ complete_qs=False)
+ self.assertNoMatch('/path?a=1',
+ 'http://www.test.com/path?a=1&b=2',
+ complete_qs=True)
+ self.assertNoMatch('/path?a=1&b=2',
+ 'http://www.test.com/path?a=1')
+
+ def test_query_empty_string(self):
+ self.assertMatch('/path?a',
+ 'http://www.test.com/path?a')
+ self.assertMatch('/path?bob&paul',
+ 'http://www.test.com/path?paul&bob')
+ self.assertNoMatch('/path?bob',
+ 'http://www.test.com/path?paul')
+ self.assertNoMatch('/path?pual&bob',
+ 'http://www.test.com/path?bob')
+
+ def test_method_match(self):
+ self.assertNoMatchMethodBoth('GET', 'POST')
+ self.assertMatchMethodBoth('GET', 'get')
+ self.assertMatchMethodBoth('GeT', 'geT')
+
+ def test_match_ANY_url(self):
+ self.assertMatch(ANY, 'http://anything')
+ self.assertMatch(ANY, 'http://somethingelse')
+ self.assertNoMatch(ANY, 'http://somethingelse', request_method='POST')
+
+ def test_match_ANY_method(self):
+ for m in ('GET', 'POST', 'HEAD', 'OPTION'):
+ self.assertMatch('http://www.test.com',
+ 'http://www.test.com',
+ matcher_method=ANY,
+ request_method=m)
+
+ self.assertNoMatch('http://www.test.com',
+ 'http://another',
+ matcher_method=ANY)
+
+ def test_match_with_regex(self):
+ r1 = re.compile('test.com/a')
+ r2 = re.compile('/b/c')
+
+ self.assertMatch(r1, 'http://mock.test.com/a/b')
+ self.assertMatch(r1, 'http://test.com/a/')
+ self.assertMatch(r1, 'mock://test.com/a/b')
+ self.assertNoMatch(r1, 'mock://test.com/')
+
+ self.assertMatch(r2, 'http://anything/a/b/c/d')
+ self.assertMatch(r2, 'mock://anything/a/b/c/d')
+
+ def test_match_with_headers(self):
+ self.assertMatch('/path',
+ 'http://www.test.com/path',
+ headers={'A': 'abc', 'b': 'def'},
+ request_headers={'a': 'abc'})
+
+ self.assertMatch('/path',
+ 'http://www.test.com/path',
+ headers={'A': 'abc', 'b': 'def'})
+
+ self.assertNoMatch('/path',
+ 'http://www.test.com/path',
+ headers={'A': 'abc', 'b': 'def'},
+ request_headers={'b': 'abc'})
+
+ self.assertNoMatch('/path',
+ 'http://www.test.com/path',
+ headers={'A': 'abc', 'b': 'def'},
+ request_headers={'c': 'ghi'})
+
+ # headers should be key insensitive and value sensitive, we have no
+ # choice here because they go into an insensitive dict.
+ self.assertMatch('/path',
+ 'http://www.test.com/path',
+ headers={'aBc': 'abc', 'DEF': 'def'},
+ request_headers={'abC': 'abc'})
+
+ self.assertNoMatch('/path',
+ 'http://www.test.com/path',
+ headers={'abc': 'aBC', 'DEF': 'def'},
+ request_headers={'abc': 'Abc'})
+
+ def test_case_sensitive_ignored_for_netloc_and_protocol(self):
+ for case_sensitive in (True, False):
+ self.assertMatch('http://AbC.CoM',
+ 'http://aBc.CoM',
+ case_sensitive=case_sensitive)
+
+ self.assertMatch('htTP://abc.com',
+ 'hTTp://abc.com',
+ case_sensitive=case_sensitive)
+
+ self.assertMatch('htTP://aBC.cOm',
+ 'hTTp://AbC.Com',
+ case_sensitive=case_sensitive)
+
+ def assertSensitiveMatch(self, target, url, **kwargs):
+ self.assertMatch(target, url, case_sensitive=False, **kwargs)
+ self.assertNoMatch(target, url, case_sensitive=True, **kwargs)
+
+ def test_case_sensitive_paths(self):
+ self.assertSensitiveMatch('http://abc.com/pAtH', 'http://abc.com/path')
+ self.assertSensitiveMatch('/pAtH', 'http://abc.com/path')
+
+ def test_case_sensitive_query(self):
+ self.assertSensitiveMatch('http://abc.com/path?abCD=efGH',
+ 'http://abc.com/path?abCd=eFGH')
+
+ self.assertSensitiveMatch('http://abc.com/path?abcd=efGH',
+ 'http://abc.com/path?abcd=eFGH')
+
+ def test_additional_matcher(self):
+
+ def test_match_body(request):
+ return 'hello' in request.text
+
+ self.assertMatch(request_method='POST',
+ matcher_method='POST',
+ request_data='hello world',
+ additional_matcher=test_match_body)
+
+ self.assertNoMatch(request_method='POST',
+ matcher_method='POST',
+ request_data='goodbye world',
+ additional_matcher=test_match_body)
+
+ def test_reset_reverts_count(self):
+ url = 'mock://test/site/'
+ matcher = adapter._Matcher('GET',
+ url,
+ [_MatcherResponse()],
+ complete_qs=False,
+ additional_matcher=None,
+ request_headers={},
+ real_http=False,
+ case_sensitive=False)
+ request = adapter._RequestObjectProxy._create('GET', url)
+
+ call_count = 3
+ for _ in range(call_count):
+ matcher(request)
+
+ self.assertEqual(matcher.call_count, call_count)
+ matcher.reset()
+ self.assertEqual(matcher.call_count, 0)
diff --git a/contrib/python/requests-mock/py3/tests/test_mocker.py b/contrib/python/requests-mock/py3/tests/test_mocker.py
new file mode 100644
index 0000000000..c2e88813ed
--- /dev/null
+++ b/contrib/python/requests-mock/py3/tests/test_mocker.py
@@ -0,0 +1,646 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import json
+import pickle
+
+try:
+ from unittest import mock
+except ImportError:
+ import mock
+import requests
+
+import requests_mock
+from requests_mock import adapter
+from requests_mock import exceptions
+from requests_mock import response
+from . import base
+
+original_send = requests.Session.send
+
+
+class MockerTests(base.TestCase):
+
+ def assertMockStarted(self):
+ self.assertNotEqual(original_send, requests.Session.send)
+
+ def assertMockStopped(self):
+ self.assertEqual(original_send, requests.Session.send)
+
+ def _do_test(self, m):
+ self.assertMockStarted()
+ matcher = m.register_uri('GET', 'http://www.test.com', text='resp')
+ resp = requests.get('http://www.test.com')
+ self.assertEqual('resp', resp.text)
+ return matcher
+
+ def test_multiple_starts(self):
+ mocker = requests_mock.Mocker()
+ self.assertMockStopped()
+ mocker.start()
+ self.assertMockStarted()
+ self.assertRaises(RuntimeError, mocker.start)
+ mocker.stop()
+ self.assertMockStopped()
+ mocker.stop()
+
+ def test_with_session(self):
+ url = 'http://test.url/path'
+ url_inner = 'http://test.url/inner'
+ url_outer = 'http://test.url/outer'
+ with requests_mock.Mocker() as global_mock:
+ global_mock.get(url_outer, text='global')
+
+ session_a = requests.Session()
+ session_b = requests.Session()
+
+ session_a_original_send = session_a.send
+ session_b_original_send = session_b.send
+ self.assertNotEqual(session_a_original_send,
+ session_b_original_send)
+
+ mocker_a = requests_mock.Mocker(session=session_a)
+ mocker_b = requests_mock.Mocker(session=session_b)
+
+ mocker_a.start()
+ mocker_b.start()
+
+ mocker_a.register_uri('GET', url, text='resp_a')
+ mocker_a.register_uri('GET', url_outer, real_http=True)
+ mocker_b.register_uri('GET', url, text='resp_b')
+
+ with requests_mock.Mocker(session=session_b) as mocker_b_inner:
+ mocker_b_inner.register_uri('GET', url, real_http=True)
+ mocker_b_inner.register_uri('GET',
+ url_inner,
+ text='resp_b_inner')
+
+ self.assertEqual('resp_a', session_a.get(url).text)
+ self.assertEqual('resp_b', session_b.get(url).text)
+ self.assertRaises(exceptions.NoMockAddress,
+ session_a.get,
+ url_inner)
+ self.assertEqual('resp_b_inner', session_b.get(url_inner).text)
+
+ self.assertEqual('resp_a', session_a.get(url).text)
+ self.assertEqual('resp_b', session_b.get(url).text)
+ self.assertRaises(exceptions.NoMockAddress,
+ session_a.get,
+ url_inner)
+ self.assertRaises(exceptions.NoMockAddress,
+ session_b.get,
+ url_inner)
+ self.assertEqual('global', session_a.get(url_outer).text)
+ self.assertRaises(exceptions.NoMockAddress,
+ session_b.get,
+ url_outer)
+
+ self.assertNotEqual(session_a.send, session_a_original_send)
+ self.assertNotEqual(session_b.send, session_b_original_send)
+ self.assertNotEqual(session_a.send, session_b.send)
+
+ mocker_a.stop()
+ mocker_b.stop()
+
+ self.assertEqual(session_a.send, session_a_original_send)
+ self.assertEqual(session_b.send, session_b_original_send)
+
+ self.assertEqual(requests.Session.send, original_send)
+
+ def test_with_context_manager(self):
+ self.assertMockStopped()
+ with requests_mock.Mocker() as m:
+ self._do_test(m)
+ self.assertMockStopped()
+
+ @mock.patch('requests.adapters.HTTPAdapter.send')
+ @requests_mock.mock(real_http=True)
+ def test_real_http(self, real_send, mocker):
+ url = 'http://www.google.com/'
+ test_text = 'real http data'
+ test_bytes = test_text.encode('utf-8')
+
+ # using create_response is a bit bootstrappy here but so long as it's
+ # coming from HTTPAdapter.send it's ok
+ req = requests.Request(method='GET', url=url)
+ real_send.return_value = response.create_response(req.prepare(),
+ status_code=200,
+ content=test_bytes)
+ resp = requests.get(url)
+
+ self.assertEqual(1, real_send.call_count)
+ self.assertEqual(url, real_send.call_args[0][0].url)
+
+ self.assertEqual(test_text, resp.text)
+ self.assertEqual(test_bytes, resp.content)
+
+ @mock.patch('requests.adapters.HTTPAdapter.send')
+ def test_real_http_changes(self, real_send):
+ url = 'http://www.google.com/'
+ test_text = 'real http data'
+ test_bytes = test_text.encode('utf-8')
+
+ req = requests.Request(method='GET', url=url)
+ real_send.return_value = response.create_response(req.prepare(),
+ status_code=200,
+ content=test_bytes)
+
+ with requests_mock.Mocker() as m:
+ # real_http defaults to false so should raise NoMockAddress
+
+ self.assertRaises(exceptions.NoMockAddress,
+ requests.get,
+ url)
+
+ self.assertEqual(1, m.call_count)
+ self.assertEqual(0, real_send.call_count)
+
+ # change the value of real_http mid test
+ m.real_http = True
+
+ # fetch the url again and it should go through to the real url that
+ # we've mocked out at a lower level.
+ resp = requests.get(url)
+
+ self.assertEqual(1, real_send.call_count)
+ self.assertEqual(url, real_send.call_args[0][0].url)
+
+ self.assertEqual(test_text, resp.text)
+ self.assertEqual(test_bytes, resp.content)
+
+ @mock.patch('requests.adapters.HTTPAdapter.send')
+ def test_real_http_and_session(self, real_send):
+ url = 'http://www.google.com/'
+ test_text = 'real http data'
+ test_bytes = test_text.encode('utf-8')
+
+ req = requests.Request(method='GET', url=url)
+ real_send.return_value = response.create_response(req.prepare(),
+ status_code=200,
+ content=test_bytes)
+
+ session = requests.Session()
+ with requests_mock.Mocker(session=session, real_http=True):
+ resp = session.get(url)
+
+ self.assertEqual(test_text, resp.text)
+ self.assertEqual(test_bytes, resp.content)
+
+ @requests_mock.mock()
+ def test_with_test_decorator(self, m):
+ self._do_test(m)
+
+ @requests_mock.mock(kw='mock')
+ def test_with_mocker_kwargs(self, **kwargs):
+ self._do_test(kwargs['mock'])
+
+ def test_with_decorator(self):
+
+ @requests_mock.mock()
+ def inner(m):
+ self.assertMockStarted()
+ self._do_test(m)
+
+ self.assertMockStopped()
+ inner()
+ self.assertMockStopped()
+
+ def test_with_decorator_called_multiple_times(self):
+
+ @requests_mock.Mocker()
+ def inner(arg1, m):
+ self._do_test(m)
+ self.assertEqual(
+ len(m.request_history), 1,
+ "Failed to provide clean mock on subsequent calls"
+ )
+
+ inner('a')
+ # if we call the same decorated method again should get
+ # a new request mock
+ inner('b')
+
+ def test_with_class_decorator(self):
+ outer = self
+
+ @requests_mock.mock()
+ class Decorated(object):
+
+ def test_will_be_decorated(self, m):
+ outer.assertMockStarted()
+ outer._do_test(m)
+
+ def will_not_be_decorated(self):
+ outer.assertMockStopped()
+
+ decorated_class = Decorated()
+
+ self.assertMockStopped()
+ decorated_class.test_will_be_decorated()
+ self.assertMockStopped()
+ decorated_class.will_not_be_decorated()
+ self.assertMockStopped()
+
+ def test_with_class_decorator_and_custom_kw(self):
+ outer = self
+
+ @requests_mock.mock(kw='custom_m')
+ class Decorated(object):
+
+ def test_will_be_decorated(self, **kwargs):
+ outer.assertMockStarted()
+ outer._do_test(kwargs['custom_m'])
+
+ def will_not_be_decorated(self):
+ outer.assertMockStopped()
+
+ decorated_class = Decorated()
+
+ self.assertMockStopped()
+ decorated_class.test_will_be_decorated()
+ self.assertMockStopped()
+ decorated_class.will_not_be_decorated()
+ self.assertMockStopped()
+
+ @mock.patch.object(requests_mock.mock, 'TEST_PREFIX', 'foo')
+ def test_with_class_decorator_and_custom_test_prefix(self):
+ outer = self
+
+ @requests_mock.mock()
+ class Decorated(object):
+
+ def foo_will_be_decorated(self, m):
+ outer.assertMockStarted()
+ outer._do_test(m)
+
+ def will_not_be_decorated(self):
+ outer.assertMockStopped()
+
+ decorated_class = Decorated()
+
+ self.assertMockStopped()
+ decorated_class.foo_will_be_decorated()
+ self.assertMockStopped()
+ decorated_class.will_not_be_decorated()
+ self.assertMockStopped()
+
+ @requests_mock.mock()
+ def test_query_string(self, m):
+ url = 'http://test.url/path'
+ qs = 'a=1&b=2'
+ m.register_uri('GET', url, text='resp')
+ resp = requests.get("%s?%s" % (url, qs))
+
+ self.assertEqual('resp', resp.text)
+
+ self.assertEqual(qs, m.last_request.query)
+ self.assertEqual(['1'], m.last_request.qs['a'])
+ self.assertEqual(['2'], m.last_request.qs['b'])
+
+ @requests_mock.mock()
+ def test_mock_matcher_attributes(self, m):
+ matcher = self._do_test(m)
+
+ self.assertEqual(1, matcher.call_count)
+ self.assertEqual(1, m.call_count)
+
+ self.assertTrue(matcher.called)
+ self.assertTrue(matcher.called_once)
+ self.assertTrue(m.called)
+ self.assertTrue(m.called_once)
+
+ self.assertEqual(m.request_history, matcher.request_history)
+ self.assertIs(m.last_request, matcher.last_request)
+
+ def test_copy(self):
+ mocker = requests_mock.mock(kw='foo', real_http=True)
+ copy_of_mocker = mocker.copy()
+ self.assertIsNot(copy_of_mocker, mocker)
+ self.assertEqual(copy_of_mocker._kw, mocker._kw)
+ self.assertEqual(copy_of_mocker.real_http, mocker.real_http)
+
+ @requests_mock.mock()
+ def test_reset_mock_reverts_call_count(self, request_mock):
+ url = 'http://test.url/path'
+ request_mock.get(url, text='resp')
+ requests.get(url)
+
+ self.assertEqual(request_mock.call_count, 1)
+
+ # reset count and verify it is 0
+ request_mock.reset_mock()
+ self.assertEqual(request_mock.call_count, 0)
+
+
+class MockerHttpMethodsTests(base.TestCase):
+
+ URL = 'http://test.com/path'
+ TEXT = 'resp'
+
+ def assertResponse(self, resp):
+ self.assertEqual(self.TEXT, resp.text)
+
+ @requests_mock.Mocker()
+ def test_mocker_request(self, m):
+ method = 'XXX'
+ mock_obj = m.request(method, self.URL, text=self.TEXT)
+ resp = requests.request(method, self.URL)
+ self.assertResponse(resp)
+ self.assertTrue(mock_obj.called)
+ self.assertTrue(mock_obj.called_once)
+ self.assertTrue(m.called)
+ self.assertTrue(m.called_once)
+
+ @requests_mock.Mocker()
+ def test_mocker_get(self, m):
+ mock_obj = m.get(self.URL, text=self.TEXT)
+ self.assertResponse(requests.get(self.URL))
+ self.assertTrue(mock_obj.called)
+ self.assertTrue(mock_obj.called_once)
+ self.assertTrue(m.called)
+ self.assertTrue(m.called_once)
+
+ @requests_mock.Mocker()
+ def test_mocker_options(self, m):
+ mock_obj = m.options(self.URL, text=self.TEXT)
+ self.assertResponse(requests.options(self.URL))
+ self.assertTrue(mock_obj.called)
+ self.assertTrue(mock_obj.called_once)
+ self.assertTrue(m.called)
+ self.assertTrue(m.called_once)
+
+ @requests_mock.Mocker()
+ def test_mocker_head(self, m):
+ mock_obj = m.head(self.URL, text=self.TEXT)
+ self.assertResponse(requests.head(self.URL))
+ self.assertTrue(mock_obj.called)
+ self.assertTrue(mock_obj.called_once)
+ self.assertTrue(m.called)
+ self.assertTrue(m.called_once)
+
+ @requests_mock.Mocker()
+ def test_mocker_post(self, m):
+ mock_obj = m.post(self.URL, text=self.TEXT)
+ self.assertResponse(requests.post(self.URL))
+ self.assertTrue(mock_obj.called)
+ self.assertTrue(mock_obj.called_once)
+ self.assertTrue(m.called)
+ self.assertTrue(m.called_once)
+
+ @requests_mock.Mocker()
+ def test_mocker_put(self, m):
+ mock_obj = m.put(self.URL, text=self.TEXT)
+ self.assertResponse(requests.put(self.URL))
+ self.assertTrue(mock_obj.called)
+ self.assertTrue(mock_obj.called_once)
+ self.assertTrue(m.called)
+ self.assertTrue(m.called_once)
+
+ @requests_mock.Mocker()
+ def test_mocker_patch(self, m):
+ mock_obj = m.patch(self.URL, text=self.TEXT)
+ self.assertResponse(requests.patch(self.URL))
+ self.assertTrue(mock_obj.called)
+ self.assertTrue(mock_obj.called_once)
+ self.assertTrue(m.called)
+ self.assertTrue(m.called_once)
+
+ @requests_mock.Mocker()
+ def test_mocker_delete(self, m):
+ mock_obj = m.delete(self.URL, text=self.TEXT)
+ self.assertResponse(requests.delete(self.URL))
+ self.assertTrue(mock_obj.called)
+ self.assertTrue(mock_obj.called_once)
+ self.assertTrue(m.called)
+ self.assertTrue(m.called_once)
+
+ @requests_mock.Mocker()
+ def test_mocker_real_http_and_responses(self, m):
+ self.assertRaises(RuntimeError,
+ m.get,
+ self.URL,
+ text='abcd',
+ real_http=True)
+
+ @requests_mock.Mocker()
+ def test_mocker_real_http(self, m):
+ data = 'testdata'
+
+ uri1 = 'fake://example.com/foo'
+ uri2 = 'fake://example.com/bar'
+ uri3 = 'fake://example.com/baz'
+
+ m.get(uri1, text=data)
+ m.get(uri2, real_http=True)
+
+ self.assertEqual(data, requests.get(uri1).text)
+
+ # This should fail because requests can't get an adapter for mock://
+ # but it shows that it has tried and would have made a request.
+ self.assertRaises(requests.exceptions.InvalidSchema,
+ requests.get,
+ uri2)
+
+ # This fails because real_http is not set on the mocker
+ self.assertRaises(exceptions.NoMockAddress,
+ requests.get,
+ uri3)
+
+ # do it again to make sure the mock is still in place
+ self.assertEqual(data, requests.get(uri1).text)
+
+ @requests_mock.Mocker(case_sensitive=True)
+ def test_case_sensitive_query(self, m):
+ data = 'testdata'
+ query = {'aBcDe': 'FgHiJ'}
+
+ m.get(self.URL, text=data)
+ resp = requests.get(self.URL, params=query)
+
+ self.assertEqual('GET', m.last_request.method)
+ self.assertEqual(200, resp.status_code)
+ self.assertEqual(data, resp.text)
+
+ for k, v in query.items():
+ self.assertEqual([v], m.last_request.qs[k])
+
+ @mock.patch.object(requests_mock.Mocker, 'case_sensitive', True)
+ def test_global_case_sensitive(self):
+ with requests_mock.mock() as m:
+ data = 'testdata'
+ query = {'aBcDe': 'FgHiJ'}
+
+ m.get(self.URL, text=data)
+ resp = requests.get(self.URL, params=query)
+
+ self.assertEqual('GET', m.last_request.method)
+ self.assertEqual(200, resp.status_code)
+ self.assertEqual(data, resp.text)
+
+ for k, v in query.items():
+ self.assertEqual([v], m.last_request.qs[k])
+
+ def test_nested_mocking(self):
+ url1 = 'http://url1.com/path1'
+ url2 = 'http://url2.com/path2'
+ url3 = 'http://url3.com/path3'
+
+ data1 = 'data1'
+ data2 = 'data2'
+ data3 = 'data3'
+
+ with requests_mock.mock() as m1:
+
+ r1 = m1.get(url1, text=data1)
+
+ resp1a = requests.get(url1)
+ self.assertRaises(exceptions.NoMockAddress, requests.get, url2)
+ self.assertRaises(exceptions.NoMockAddress, requests.get, url3)
+
+ self.assertEqual(data1, resp1a.text)
+
+ # call count = 3 because there are 3 calls above, url 1-3
+ self.assertEqual(3, m1.call_count)
+ self.assertEqual(1, r1.call_count)
+
+ with requests_mock.mock() as m2:
+
+ r2 = m2.get(url2, text=data2)
+
+ self.assertRaises(exceptions.NoMockAddress, requests.get, url1)
+ resp2a = requests.get(url2)
+ self.assertRaises(exceptions.NoMockAddress, requests.get, url3)
+
+ self.assertEqual(data2, resp2a.text)
+
+ with requests_mock.mock() as m3:
+
+ r3 = m3.get(url3, text=data3)
+
+ self.assertRaises(exceptions.NoMockAddress,
+ requests.get,
+ url1)
+ self.assertRaises(exceptions.NoMockAddress,
+ requests.get,
+ url2)
+ resp3 = requests.get(url3)
+
+ self.assertEqual(data3, resp3.text)
+
+ self.assertEqual(3, m3.call_count)
+ self.assertEqual(1, r3.call_count)
+
+ resp2b = requests.get(url2)
+ self.assertRaises(exceptions.NoMockAddress, requests.get, url1)
+ self.assertEqual(data2, resp2b.text)
+ self.assertRaises(exceptions.NoMockAddress, requests.get, url3)
+
+ self.assertEqual(3, m1.call_count)
+ self.assertEqual(1, r1.call_count)
+ self.assertEqual(6, m2.call_count)
+ self.assertEqual(2, r2.call_count)
+ self.assertEqual(3, m3.call_count)
+ self.assertEqual(1, r3.call_count)
+
+ resp1b = requests.get(url1)
+ self.assertEqual(data1, resp1b.text)
+ self.assertRaises(exceptions.NoMockAddress, requests.get, url2)
+ self.assertRaises(exceptions.NoMockAddress, requests.get, url3)
+
+ self.assertEqual(6, m1.call_count)
+ self.assertEqual(2, r1.call_count)
+
+ @requests_mock.mock()
+ def test_mocker_additional(self, m):
+ url = 'http://www.example.com'
+ good_text = 'success'
+
+ def additional_cb(req):
+ return 'hello' in req.text
+
+ m.post(url, additional_matcher=additional_cb, text=good_text)
+
+ self.assertEqual(good_text,
+ requests.post(url, data='hello world').text)
+ self.assertRaises(exceptions.NoMockAddress,
+ requests.post,
+ url,
+ data='goodbye world')
+
+ @requests_mock.mock()
+ def test_mocker_pickle(self, m):
+ url = 'http://www.example.com'
+ text = 'hello world'
+ m.get(url, text=text)
+
+ orig_resp = requests.get(url)
+ self.assertEqual(text, orig_resp.text)
+
+ d = pickle.dumps(orig_resp)
+ new_resp = pickle.loads(d)
+
+ self.assertEqual(text, new_resp.text)
+ self.assertIsInstance(orig_resp.request.matcher, adapter._Matcher)
+ self.assertIsNone(new_resp.request.matcher)
+
+ @requests_mock.mock()
+ def test_stream_zero_bytes(self, m):
+ content = b'blah'
+
+ m.get("http://test", content=content)
+ res = requests.get("http://test", stream=True)
+ zero_val = res.raw.read(0)
+ self.assertEqual(b'', zero_val)
+ self.assertFalse(res.raw.closed)
+
+ full_val = res.raw.read()
+ self.assertEqual(content, full_val)
+
+ def test_with_json_encoder_on_mocker(self):
+ test_val = 'hello world'
+
+ class MyJsonEncoder(json.JSONEncoder):
+ def encode(s, o):
+ return test_val
+
+ with requests_mock.Mocker(json_encoder=MyJsonEncoder) as m:
+ m.get("http://test", json={"a": "b"})
+ res = requests.get("http://test")
+ self.assertEqual(test_val, res.text)
+
+ @requests_mock.mock()
+ def test_with_json_encoder_on_endpoint(self, m):
+ test_val = 'hello world'
+
+ class MyJsonEncoder(json.JSONEncoder):
+ def encode(s, o):
+ return test_val
+
+ m.get("http://test", json={"a": "b"}, json_encoder=MyJsonEncoder)
+ res = requests.get("http://test")
+ self.assertEqual(test_val, res.text)
+
+ @requests_mock.mock()
+ def test_mismatch_content_length_streaming(self, m):
+ url = "https://test/package.tar.gz"
+
+ def f(request, context):
+ context.headers["Content-Length"] = "300810"
+ return None
+
+ m.head(
+ url=url,
+ status_code=200,
+ text=f,
+ )
+
+ requests.head(url)
diff --git a/contrib/python/requests-mock/py3/tests/test_request.py b/contrib/python/requests-mock/py3/tests/test_request.py
new file mode 100644
index 0000000000..69a71556e2
--- /dev/null
+++ b/contrib/python/requests-mock/py3/tests/test_request.py
@@ -0,0 +1,139 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import uuid
+
+import requests
+import requests_mock
+from . import base
+
+
+class RequestTests(base.TestCase):
+
+ def setUp(self):
+ super(RequestTests, self).setUp()
+
+ self.mocker = requests_mock.Mocker()
+ self.addCleanup(self.mocker.stop)
+ self.mocker.start()
+
+ def do_request(self, **kwargs):
+ method = kwargs.pop('method', 'GET')
+ url = kwargs.pop('url', 'http://test.example.com/path')
+ status_code = kwargs.pop('status_code', 200)
+ data = uuid.uuid4().hex
+
+ m = self.mocker.register_uri(method,
+ url,
+ text=data,
+ status_code=status_code)
+
+ resp = requests.request(method, url, **kwargs)
+
+ self.assertEqual(status_code, resp.status_code)
+ self.assertEqual(data, resp.text)
+
+ self.assertTrue(m.called_once)
+ return m.last_request
+
+ def test_base_params(self):
+ req = self.do_request(method='GET', status_code=200)
+
+ self.assertIs(None, req.allow_redirects)
+ self.assertIs(None, req.timeout)
+ self.assertIs(True, req.verify)
+ self.assertIs(None, req.cert)
+ self.assertIs(False, req.stream)
+
+ # actually it's an OrderedDict, but equality works fine
+ # Skipping this check - it's problematic based on people's environments
+ # and in CI systems where there are proxies set up at the environment
+ # level. gh #127
+ # self.assertEqual({}, req.proxies)
+
+ def test_allow_redirects(self):
+ req = self.do_request(allow_redirects=False, status_code=300)
+ self.assertFalse(req.allow_redirects)
+
+ def test_timeout(self):
+ timeout = 300
+ req = self.do_request(timeout=timeout)
+ self.assertEqual(timeout, req.timeout)
+
+ def test_verify_false(self):
+ verify = False
+ req = self.do_request(verify=verify)
+ self.assertIs(verify, req.verify)
+
+ def test_verify_path(self):
+ verify = '/path/to/cacerts.pem'
+ req = self.do_request(verify=verify)
+ self.assertEqual(verify, req.verify)
+
+ def test_stream(self):
+ req = self.do_request()
+ self.assertIs(False, req.stream)
+ req = self.do_request(stream=False)
+ self.assertIs(False, req.stream)
+ req = self.do_request(stream=True)
+ self.assertIs(True, req.stream)
+
+ def test_certs(self):
+ cert = ('/path/to/cert.pem', 'path/to/key.pem')
+ req = self.do_request(cert=cert)
+ self.assertEqual(cert, req.cert)
+ self.assertTrue(req.verify)
+
+ def test_proxies(self):
+ proxies = {'http': 'foo.bar:3128',
+ 'http://host.name': 'foo.bar:4012'}
+
+ req = self.do_request(proxies=proxies)
+
+ self.assertEqual(proxies, req.proxies)
+ self.assertIsNot(proxies, req.proxies)
+
+ def test_hostname_port_http(self):
+ req = self.do_request(url='http://host.example.com:81/path')
+
+ self.assertEqual('host.example.com:81', req.netloc)
+ self.assertEqual('host.example.com', req.hostname)
+ self.assertEqual(81, req.port)
+
+ def test_hostname_port_https(self):
+ req = self.do_request(url='https://host.example.com:8080/path')
+
+ self.assertEqual('host.example.com:8080', req.netloc)
+ self.assertEqual('host.example.com', req.hostname)
+ self.assertEqual(8080, req.port)
+
+ def test_hostname_default_port_http(self):
+ req = self.do_request(url='http://host.example.com/path')
+
+ self.assertEqual('host.example.com', req.netloc)
+ self.assertEqual('host.example.com', req.hostname)
+ self.assertEqual(80, req.port)
+
+ def test_hostname_default_port_https(self):
+ req = self.do_request(url='https://host.example.com/path')
+
+ self.assertEqual('host.example.com', req.netloc)
+ self.assertEqual('host.example.com', req.hostname)
+ self.assertEqual(443, req.port)
+
+ def test_to_string(self):
+ req = self.do_request(url='https://host.example.com/path')
+ self.assertEqual('GET https://host.example.com/path', str(req))
+
+ def test_empty_query_string(self):
+ req = self.do_request(url='https://host.example.com/path?key')
+ self.assertEqual([''], req.qs['key'])
diff --git a/contrib/python/requests-mock/py3/tests/test_response.py b/contrib/python/requests-mock/py3/tests/test_response.py
new file mode 100644
index 0000000000..b560eea8d7
--- /dev/null
+++ b/contrib/python/requests-mock/py3/tests/test_response.py
@@ -0,0 +1,151 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import io
+import pickle
+
+from requests_mock import exceptions
+from requests_mock import request
+from requests_mock import response
+from . import base
+
+
+class ResponseTests(base.TestCase):
+
+ def setUp(self):
+ super(ResponseTests, self).setUp()
+ self.method = 'GET'
+ self.url = 'http://test.url/path'
+ self.request = request._RequestObjectProxy._create(self.method,
+ self.url,
+ {})
+
+ def create_response(self, **kwargs):
+ return response.create_response(self.request, **kwargs)
+
+ def test_create_response_body_args(self):
+ self.assertRaises(RuntimeError,
+ self.create_response,
+ raw='abc',
+ body='abc')
+
+ self.assertRaises(RuntimeError,
+ self.create_response,
+ text='abc',
+ json={'a': 1})
+
+ def test_content_type(self):
+ self.assertRaises(TypeError, self.create_response, text=55)
+ self.assertRaises(TypeError, self.create_response, text={'a': 1})
+ self.assertRaises(TypeError, self.create_response, text=b'')
+
+ def test_text_type(self):
+ self.assertRaises(TypeError, self.create_response, content=u't')
+ self.assertRaises(TypeError, self.create_response, content={'a': 1})
+ self.assertRaises(TypeError, self.create_response, content=u'')
+
+ def test_json_body(self):
+ data = {'a': 1}
+ resp = self.create_response(json=data)
+
+ self.assertEqual('{"a": 1}', resp.text)
+ self.assertIsInstance(resp.text, str)
+ self.assertIsInstance(resp.content, bytes)
+ self.assertEqual(data, resp.json())
+
+ def test_body_body(self):
+ value = b'data'
+ body = io.BytesIO(value)
+ resp = self.create_response(body=body)
+
+ self.assertEqual(value.decode(), resp.text)
+ self.assertIsInstance(resp.text, str)
+ self.assertIsInstance(resp.content, bytes)
+
+ def test_setting_connection(self):
+ conn = object()
+ resp = self.create_response(connection=conn)
+ self.assertIs(conn, resp.connection)
+
+ def test_send_from_no_connection(self):
+ resp = self.create_response()
+ self.assertRaises(exceptions.InvalidRequest,
+ resp.connection.send, self.request)
+
+ def test_cookies_from_header(self):
+ # domain must be same as request url to pass policy check
+ headers = {'Set-Cookie': 'fig=newton; Path=/test; domain=.test.url'}
+ resp = self.create_response(headers=headers)
+
+ self.assertEqual('newton', resp.cookies['fig'])
+ self.assertEqual(['/test'], resp.cookies.list_paths())
+ self.assertEqual(['.test.url'], resp.cookies.list_domains())
+
+ def test_cookies_from_dict(self):
+ # This is a syntax we get from requests. I'm not sure i like it.
+ resp = self.create_response(cookies={'fig': 'newton',
+ 'sugar': 'apple'})
+
+ self.assertEqual('newton', resp.cookies['fig'])
+ self.assertEqual('apple', resp.cookies['sugar'])
+
+ def test_cookies_with_jar(self):
+ jar = response.CookieJar()
+ jar.set('fig', 'newton', path='/foo', domain='.test.url')
+ jar.set('sugar', 'apple', path='/bar', domain='.test.url')
+ resp = self.create_response(cookies=jar)
+
+ self.assertEqual('newton', resp.cookies['fig'])
+ self.assertEqual('apple', resp.cookies['sugar'])
+ self.assertEqual({'/foo', '/bar'}, set(resp.cookies.list_paths()))
+ self.assertEqual(['.test.url'], resp.cookies.list_domains())
+
+ def test_response_pickle(self):
+ text = 'hello world'
+ jar = response.CookieJar()
+ jar.set('fig', 'newton', path='/foo', domain='.test.url')
+ orig_resp = self.create_response(cookies=jar, text=text)
+
+ d = pickle.dumps(orig_resp)
+ new_resp = pickle.loads(d)
+
+ self.assertEqual(text, new_resp.text)
+ self.assertEqual('newton', new_resp.cookies['fig'])
+ self.assertIsNone(new_resp.request.matcher)
+
+ def test_response_encoding(self):
+ headers = {"content-type": "text/html; charset=ISO-8859-1"}
+ resp = self.create_response(headers=headers,
+ text="<html><body></body></html")
+ self.assertEqual('ISO-8859-1', resp.encoding)
+
+ def test_default_reason(self):
+ resp = self.create_response()
+ self.assertEqual('OK', resp.reason)
+
+ def test_custom_reason(self):
+ reason = 'Live long and prosper'
+ resp = self.create_response(status_code=201, reason=reason)
+
+ self.assertEqual(201, resp.status_code)
+ self.assertEqual(reason, resp.reason)
+
+ def test_some_other_response_reasons(self):
+ reasons = {
+ 301: 'Moved Permanently',
+ 410: 'Gone',
+ 503: 'Service Unavailable',
+ }
+
+ for code, reason in reasons.items():
+ self.assertEqual(reason,
+ self.create_response(status_code=code).reason)
diff --git a/contrib/python/requests-mock/py3/tests/ya.make b/contrib/python/requests-mock/py3/tests/ya.make
new file mode 100644
index 0000000000..f52ec22dba
--- /dev/null
+++ b/contrib/python/requests-mock/py3/tests/ya.make
@@ -0,0 +1,26 @@
+PY3TEST()
+
+SUBSCRIBER(g:python-contrib)
+
+PEERDIR(
+ contrib/python/mock
+ contrib/python/requests-futures
+ contrib/python/requests-mock
+)
+
+TEST_SRCS(
+ base.py
+ pytest/__init__.py
+ pytest/test_with_pytest.py
+ #test_adapter.py - need purl
+ test_custom_matchers.py
+ #test_fixture.py - need fixtures
+ test_matcher.py
+ test_mocker.py
+ test_request.py
+ test_response.py
+)
+
+NO_LINT()
+
+END()