From 4ea5d668127addfef678f509127196ac4ff60a99 Mon Sep 17 00:00:00 2001 From: su-fang Date: Mon, 6 Feb 2023 15:37:15 +0800 Subject: [PATCH] Import Upstream version 1.1.4 --- COPYING | 22 + MANIFEST.in | 9 + Makefile | 83 + PKG-INFO | 190 ++ README.rst | 163 ++ development.txt | 31 + docs/build/doctrees/acks.doctree | Bin 0 -> 7320 bytes docs/build/doctrees/api.doctree | Bin 0 -> 358293 bytes docs/build/doctrees/changelog.doctree | Bin 0 -> 53976 bytes docs/build/doctrees/contributing.doctree | Bin 0 -> 12444 bytes docs/build/doctrees/environment.pickle | Bin 0 -> 1891131 bytes docs/build/doctrees/guides.doctree | Bin 0 -> 26801 bytes docs/build/doctrees/index.doctree | Bin 0 -> 14644 bytes docs/build/doctrees/introduction.doctree | Bin 0 -> 20215 bytes docs/make.bat | 36 + .../guide-callback-regex-ipdb.cpython-38.pyc | Bin 0 -> 901 bytes .../read-timeout.cpython-38-pytest-6.2.4.pyc | Bin 0 -> 1789 bytes .../__pycache__/read-timeout.cpython-38.pyc | Bin 0 -> 887 bytes .../__pycache__/regex-example.cpython-38.pyc | Bin 0 -> 619 bytes .../_static/guide-callback-regex-ipdb.py | 20 + docs/source/_static/logo.svg | 65 + docs/source/_static/read-timeout.py | 39 + docs/source/_static/regex-example.py | 14 + docs/source/_static/tmplun_dcms-ascii.cast | 235 ++ docs/source/acks.rst | 21 + docs/source/api.rst | 191 ++ docs/source/changelog.rst | 212 ++ docs/source/conf.py | 87 + docs/source/contributing.rst | 71 + docs/source/guides.rst | 119 + docs/source/index.rst | 80 + docs/source/introduction.rst | 182 ++ httpretty.egg-info/PKG-INFO | 190 ++ httpretty.egg-info/SOURCES.txt | 82 + httpretty.egg-info/dependency_links.txt | 1 + httpretty.egg-info/not-zip-safe | 1 + httpretty.egg-info/top_level.txt | 1 + httpretty/__init__.py | 94 + httpretty/compat.py | 60 + httpretty/core.py | 2082 +++++++++++++++++ httpretty/errors.py | 48 + httpretty/http.py | 153 ++ httpretty/utils.py | 37 + httpretty/version.py | 1 + requirements.txt | 1 + setup.cfg | 18 + setup.py | 83 + tests/__init__.py | 4 + tests/bugfixes/nosetests/__init__.py | 0 .../nosetests/test_242_ssl_bad_handshake.py | 25 + .../bugfixes/nosetests/test_387_regex_port.py | 26 + .../test_388_unmocked_error_with_url.py | 56 + tests/bugfixes/nosetests/test_413_regex.py | 39 + tests/bugfixes/nosetests/test_414_httpx.py | 13 + tests/bugfixes/nosetests/test_416_boto3.py | 33 + tests/bugfixes/nosetests/test_417_openssl.py | 33 + .../nosetests/test_425_latest_requests.py | 29 + .../nosetests/test_430_respect_timeout.py | 54 + tests/bugfixes/nosetests/test_eventlet.py | 11 + tests/bugfixes/nosetests/test_redis.py | 52 + .../test_tornado_bind_unused_port.py | 18 + .../bugfixes/pytest/test_426_mypy_segfault.py | 81 + tests/compat.py | 4 + tests/functional/__init__.py | 28 + tests/functional/base.py | 118 + tests/functional/fixtures/playback-1.json | 58 + tests/functional/test_bypass.py | 212 ++ tests/functional/test_debug.py | 91 + tests/functional/test_decorator.py | 116 + tests/functional/test_fakesocket.py | 75 + tests/functional/test_httplib2.py | 306 +++ tests/functional/test_passthrough.py | 78 + tests/functional/test_requests.py | 949 ++++++++ tests/functional/test_urllib2.py | 341 +++ tests/functional/testserver.py | 162 ++ tests/pyopenssl/__init__.py | 28 + tests/pyopenssl/test_mock.py | 45 + tests/unit/__init__.py | 25 + tests/unit/test_core.py | 668 ++++++ tests/unit/test_http.py | 17 + tests/unit/test_httpretty.py | 429 ++++ tests/unit/test_main.py | 33 + tox.ini | 7 + 83 files changed, 8986 insertions(+) create mode 100644 COPYING create mode 100644 MANIFEST.in create mode 100644 Makefile create mode 100644 PKG-INFO create mode 100644 README.rst create mode 100644 development.txt create mode 100644 docs/build/doctrees/acks.doctree create mode 100644 docs/build/doctrees/api.doctree create mode 100644 docs/build/doctrees/changelog.doctree create mode 100644 docs/build/doctrees/contributing.doctree create mode 100644 docs/build/doctrees/environment.pickle create mode 100644 docs/build/doctrees/guides.doctree create mode 100644 docs/build/doctrees/index.doctree create mode 100644 docs/build/doctrees/introduction.doctree create mode 100644 docs/make.bat create mode 100644 docs/source/_static/__pycache__/guide-callback-regex-ipdb.cpython-38.pyc create mode 100644 docs/source/_static/__pycache__/read-timeout.cpython-38-pytest-6.2.4.pyc create mode 100644 docs/source/_static/__pycache__/read-timeout.cpython-38.pyc create mode 100644 docs/source/_static/__pycache__/regex-example.cpython-38.pyc create mode 100644 docs/source/_static/guide-callback-regex-ipdb.py create mode 100644 docs/source/_static/logo.svg create mode 100644 docs/source/_static/read-timeout.py create mode 100644 docs/source/_static/regex-example.py create mode 100644 docs/source/_static/tmplun_dcms-ascii.cast create mode 100644 docs/source/acks.rst create mode 100644 docs/source/api.rst create mode 100644 docs/source/changelog.rst create mode 100644 docs/source/conf.py create mode 100644 docs/source/contributing.rst create mode 100644 docs/source/guides.rst create mode 100644 docs/source/index.rst create mode 100644 docs/source/introduction.rst create mode 100644 httpretty.egg-info/PKG-INFO create mode 100644 httpretty.egg-info/SOURCES.txt create mode 100644 httpretty.egg-info/dependency_links.txt create mode 100644 httpretty.egg-info/not-zip-safe create mode 100644 httpretty.egg-info/top_level.txt create mode 100644 httpretty/__init__.py create mode 100644 httpretty/compat.py create mode 100644 httpretty/core.py create mode 100644 httpretty/errors.py create mode 100644 httpretty/http.py create mode 100644 httpretty/utils.py create mode 100644 httpretty/version.py create mode 100644 requirements.txt create mode 100644 setup.cfg create mode 100644 setup.py create mode 100644 tests/__init__.py create mode 100644 tests/bugfixes/nosetests/__init__.py create mode 100644 tests/bugfixes/nosetests/test_242_ssl_bad_handshake.py create mode 100644 tests/bugfixes/nosetests/test_387_regex_port.py create mode 100644 tests/bugfixes/nosetests/test_388_unmocked_error_with_url.py create mode 100644 tests/bugfixes/nosetests/test_413_regex.py create mode 100644 tests/bugfixes/nosetests/test_414_httpx.py create mode 100644 tests/bugfixes/nosetests/test_416_boto3.py create mode 100644 tests/bugfixes/nosetests/test_417_openssl.py create mode 100644 tests/bugfixes/nosetests/test_425_latest_requests.py create mode 100644 tests/bugfixes/nosetests/test_430_respect_timeout.py create mode 100644 tests/bugfixes/nosetests/test_eventlet.py create mode 100644 tests/bugfixes/nosetests/test_redis.py create mode 100644 tests/bugfixes/nosetests/test_tornado_bind_unused_port.py create mode 100644 tests/bugfixes/pytest/test_426_mypy_segfault.py create mode 100644 tests/compat.py create mode 100644 tests/functional/__init__.py create mode 100644 tests/functional/base.py create mode 100644 tests/functional/fixtures/playback-1.json create mode 100644 tests/functional/test_bypass.py create mode 100644 tests/functional/test_debug.py create mode 100644 tests/functional/test_decorator.py create mode 100644 tests/functional/test_fakesocket.py create mode 100644 tests/functional/test_httplib2.py create mode 100644 tests/functional/test_passthrough.py create mode 100644 tests/functional/test_requests.py create mode 100644 tests/functional/test_urllib2.py create mode 100644 tests/functional/testserver.py create mode 100644 tests/pyopenssl/__init__.py create mode 100644 tests/pyopenssl/test_mock.py create mode 100644 tests/unit/__init__.py create mode 100644 tests/unit/test_core.py create mode 100644 tests/unit/test_http.py create mode 100644 tests/unit/test_httpretty.py create mode 100644 tests/unit/test_main.py create mode 100644 tox.ini diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..16ca34c --- /dev/null +++ b/COPYING @@ -0,0 +1,22 @@ +Copyright (C) <2011-2021> Gabriel Falcão + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..29295ae --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,9 @@ +include COPYING +include Makefile +include README.rst +include requirements.txt +include tests/functional/fixtures/playback-*.json +include tox.ini +recursive-include docs *.* +recursive-include tests *.py +include *.cfg *.rst *.txt \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d3d337d --- /dev/null +++ b/Makefile @@ -0,0 +1,83 @@ +.PHONY: tests all unit functional clean dependencies tdd docs html purge dist setup + +GIT_ROOT := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST)))) +DOCS_ROOT := $(GIT_ROOT)/docs +HTML_ROOT := $(DOCS_ROOT)/build/html +VENV_ROOT := $(GIT_ROOT)/.venv +VENV ?= $(VENV_ROOT) +DOCS_INDEX := $(HTML_ROOT)/index.html + +export VENV +export PYTHONASYNCIODEBUG :=1 + + +all: dependencies tests + +$(VENV): # creates $(VENV) folder if does not exist + python3 -mvenv $(VENV) + $(VENV)/bin/pip install -U pip setuptools + +$(VENV)/bin/sphinx-build $(VENV)/bin/twine $(VENV)/bin/nosetests $(VENV)/bin/pytest $(VENV)/bin/python $(VENV)/bin/pip: # installs latest pip + test -e $(VENV)/bin/pip || make $(VENV) + $(MAKE) setup + +setup: | $(VENV)/bin/pip + $(VENV)/bin/pip install -r development.txt + $(VENV)/bin/pip install -e . + +# Runs the unit and functional tests +tests: unit bugfixes functional pyopenssl + + +tdd: $(VENV)/bin/nosetests # runs all tests + $(VENV)/bin/nosetests tests --with-watch --cover-erase + +# Install dependencies +dependencies: | setup $(VENV)/bin/nosetests + +# runs unit tests +unit: $(VENV)/bin/nosetests # runs only unit tests + $(VENV)/bin/nosetests --cover-erase tests/unit + + +pyopenssl: $(VENV)/bin/nosetests + $(VENV)/bin/nosetests --cover-erase tests/pyopenssl + +bugfixes: $(VENV)/bin/nosetests $(VENV)/bin/pytest # runs tests for specific bugfixes + $(VENV)/bin/nosetests tests/bugfixes/nosetests + $(VENV)/bin/pytest --maxfail=1 --mypy tests/bugfixes/pytest + +# runs functional tests +functional: $(VENV)/bin/nosetests # runs functional tests + $(VENV)/bin/nosetests tests/functional + + + +$(DOCS_INDEX): $(VENV)/bin/sphinx-build + cd docs && make html + +html: $(DOCS_INDEX) $(VENV)/bin/sphinx-build + +docs: $(DOCS_INDEX) $(VENV)/bin/sphinx-build + open $(DOCS_INDEX) + +release: | clean tests html + @rm -rf dist/* + @./.release + @make pypi + +dist: | clean + $(VENV)/bin/python setup.py build sdist + +pypi: dist | $(VENV)/bin/twine + $(VENV)/bin/twine upload dist/*.tar.gz + +# cleanup temp files +clean: + rm -rf $(HTML_ROOT) build dist + + +# purge all virtualenv and temp files, causes everything to be rebuilt +# from scratch by other tasks +purge: clean + rm -rf $(VENV) diff --git a/PKG-INFO b/PKG-INFO new file mode 100644 index 0000000..df3fece --- /dev/null +++ b/PKG-INFO @@ -0,0 +1,190 @@ +Metadata-Version: 1.2 +Name: httpretty +Version: 1.1.4 +Summary: HTTP client mock for Python +Home-page: https://httpretty.readthedocs.io/en/latest/ +Author: Gabriel Falcao +Author-email: gabriel@nacaolivre.org +License: MIT +Project-URL: Documentation, https://httpretty.readthedocs.io/en/latest/ +Project-URL: Source Code, https://github.com/gabrielfalcao/httpretty +Project-URL: Issue Tracker, https://github.com/gabrielfalcao/httpretty/issues +Project-URL: Continuous Integration, https://github.com/gabrielfalcao/HTTPretty/actions/workflows/pyenv.yml?query=branch%3Amaster+event%3Apush +Project-URL: Test Coverage, https://codecov.io/gh/gabrielfalcao/httpretty +Description: HTTPretty 1.1.4 + =============== + + .. image:: https://github.com/gabrielfalcao/HTTPretty/raw/master/docs/source/_static/logo.svg?sanitize=true + + HTTP Client mocking tool for Python created by `Gabriel Falcão `_ . It provides a full fake TCP socket module. Inspired by `FakeWeb `_ + + + - `Github Repository `_ + - `Documentation `_ + - `PyPI Package `_ + + + **Python Support:** + + - **3.6** + - **3.7** + - **3.8** + - **3.9** + + .. image:: https://img.shields.io/pypi/dm/HTTPretty + :target: https://pypi.org/project/HTTPretty + + .. image:: https://img.shields.io/codecov/c/github/gabrielfalcao/HTTPretty + :target: https://codecov.io/gh/gabrielfalcao/HTTPretty + + .. image:: https://img.shields.io/github/workflow/status/gabrielfalcao/HTTPretty/HTTPretty%20Tests?label=Python%203.6%20-%203.9 + :target: https://github.com/gabrielfalcao/HTTPretty/actions + + .. image:: https://img.shields.io/readthedocs/httpretty + :target: https://httpretty.readthedocs.io/ + + .. image:: https://img.shields.io/github/license/gabrielfalcao/HTTPretty?label=Github%20License + :target: https://github.com/gabrielfalcao/HTTPretty/blob/master/COPYING + + .. image:: https://img.shields.io/pypi/v/HTTPretty + :target: https://pypi.org/project/HTTPretty + + .. image:: https://img.shields.io/pypi/l/HTTPretty?label=PyPi%20License + :target: https://pypi.org/project/HTTPretty + + .. image:: https://img.shields.io/pypi/format/HTTPretty + :target: https://pypi.org/project/HTTPretty + + .. image:: https://img.shields.io/pypi/status/HTTPretty + :target: https://pypi.org/project/HTTPretty + + .. image:: https://img.shields.io/pypi/pyversions/HTTPretty + :target: https://pypi.org/project/HTTPretty + + .. image:: https://img.shields.io/pypi/implementation/HTTPretty + :target: https://pypi.org/project/HTTPretty + + .. image:: https://img.shields.io/snyk/vulnerabilities/github/gabrielfalcao/HTTPretty + :target: https://github.com/gabrielfalcao/HTTPretty/network/alerts + + .. image:: https://img.shields.io/github/v/tag/gabrielfalcao/HTTPretty + :target: https://github.com/gabrielfalcao/HTTPretty/releases + + .. |Join the chat at https://gitter.im/gabrielfalcao/HTTPretty| image:: https://badges.gitter.im/gabrielfalcao/HTTPretty.svg + :target: https://gitter.im/gabrielfalcao/HTTPretty?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge + + Install + ------- + + .. code:: bash + + pip install httpretty + + + + Common Use Cases + ================ + + - Test-driven development of API integrations + - Fake responses of external APIs + - Record and playback HTTP requests + + + Simple Example + -------------- + + .. code:: python + + import sure + import httpretty + import requests + + + @httpretty.activate(verbose=True, allow_net_connect=False) + def test_httpbin(): + httpretty.register_uri( + httpretty.GET, + "https://httpbin.org/ip", + body='{"origin": "127.0.0.1"}' + ) + + response = requests.get('https://httpbin.org/ip') + response.json().should.equal({'origin': '127.0.0.1'}) + + httpretty.latest_requests().should.have.length_of(1) + httpretty.last_request().should.equal(httpretty.latest_requests()[0]) + httpretty.last_request().body.should.equal('{"origin": "127.0.0.1"}') + + + checking multiple responses + --------------------------- + + .. code:: python + + @httpretty.activate(verbose=True, allow_net_connect=False) + def test_post_bodies(): + url = 'http://httpbin.org/post' + httpretty.register_uri(httpretty.POST, url, status=200) + httpretty.register_uri(httpretty.POST, url, status=400) + requests.post(url, data={'foo': 'bar'}) + requests.post(url, data={'zoo': 'zoo'}) + assert 'foo=bar' in httpretty.latest_requests()[0].body + assert 'zoo=bar' in httpretty.latest_requests()[1].body + + + License + ======= + + :: + + + Copyright (C) <2011-2021> Gabriel Falcão + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + Main contributors + ================= + + HTTPretty has received `many contributions `_ + but some folks made remarkable contributions and deserve extra credit: + + - Andrew Gross ~> `@andrewgross `_ + - Hugh Saunders ~> `@hughsaunders `_ + - James Rowe ~> `@JNRowe `_ + - Matt Luongo ~> `@mhluongo `_ + - Steve Pulec ~> `@spulec `_ + - Miro Hrončok ~> `@hroncok `_ + Mario Jonke ~> `@mariojonke `_ + +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP +Classifier: Topic :: Software Development :: Testing +Requires-Python: >=3 diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..c88556c --- /dev/null +++ b/README.rst @@ -0,0 +1,163 @@ +HTTPretty 1.1.4 +=============== + +.. image:: https://github.com/gabrielfalcao/HTTPretty/raw/master/docs/source/_static/logo.svg?sanitize=true + +HTTP Client mocking tool for Python created by `Gabriel Falcão `_ . It provides a full fake TCP socket module. Inspired by `FakeWeb `_ + + +- `Github Repository `_ +- `Documentation `_ +- `PyPI Package `_ + + +**Python Support:** + +- **3.6** +- **3.7** +- **3.8** +- **3.9** + +.. image:: https://img.shields.io/pypi/dm/HTTPretty + :target: https://pypi.org/project/HTTPretty + +.. image:: https://img.shields.io/codecov/c/github/gabrielfalcao/HTTPretty + :target: https://codecov.io/gh/gabrielfalcao/HTTPretty + +.. image:: https://img.shields.io/github/workflow/status/gabrielfalcao/HTTPretty/HTTPretty%20Tests?label=Python%203.6%20-%203.9 + :target: https://github.com/gabrielfalcao/HTTPretty/actions + +.. image:: https://img.shields.io/readthedocs/httpretty + :target: https://httpretty.readthedocs.io/ + +.. image:: https://img.shields.io/github/license/gabrielfalcao/HTTPretty?label=Github%20License + :target: https://github.com/gabrielfalcao/HTTPretty/blob/master/COPYING + +.. image:: https://img.shields.io/pypi/v/HTTPretty + :target: https://pypi.org/project/HTTPretty + +.. image:: https://img.shields.io/pypi/l/HTTPretty?label=PyPi%20License + :target: https://pypi.org/project/HTTPretty + +.. image:: https://img.shields.io/pypi/format/HTTPretty + :target: https://pypi.org/project/HTTPretty + +.. image:: https://img.shields.io/pypi/status/HTTPretty + :target: https://pypi.org/project/HTTPretty + +.. image:: https://img.shields.io/pypi/pyversions/HTTPretty + :target: https://pypi.org/project/HTTPretty + +.. image:: https://img.shields.io/pypi/implementation/HTTPretty + :target: https://pypi.org/project/HTTPretty + +.. image:: https://img.shields.io/snyk/vulnerabilities/github/gabrielfalcao/HTTPretty + :target: https://github.com/gabrielfalcao/HTTPretty/network/alerts + +.. image:: https://img.shields.io/github/v/tag/gabrielfalcao/HTTPretty + :target: https://github.com/gabrielfalcao/HTTPretty/releases + +.. |Join the chat at https://gitter.im/gabrielfalcao/HTTPretty| image:: https://badges.gitter.im/gabrielfalcao/HTTPretty.svg + :target: https://gitter.im/gabrielfalcao/HTTPretty?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge + +Install +------- + +.. code:: bash + + pip install httpretty + + + +Common Use Cases +================ + +- Test-driven development of API integrations +- Fake responses of external APIs +- Record and playback HTTP requests + + +Simple Example +-------------- + +.. code:: python + + import sure + import httpretty + import requests + + + @httpretty.activate(verbose=True, allow_net_connect=False) + def test_httpbin(): + httpretty.register_uri( + httpretty.GET, + "https://httpbin.org/ip", + body='{"origin": "127.0.0.1"}' + ) + + response = requests.get('https://httpbin.org/ip') + response.json().should.equal({'origin': '127.0.0.1'}) + + httpretty.latest_requests().should.have.length_of(1) + httpretty.last_request().should.equal(httpretty.latest_requests()[0]) + httpretty.last_request().body.should.equal('{"origin": "127.0.0.1"}') + + +checking multiple responses +--------------------------- + + .. code:: python + + @httpretty.activate(verbose=True, allow_net_connect=False) + def test_post_bodies(): + url = 'http://httpbin.org/post' + httpretty.register_uri(httpretty.POST, url, status=200) + httpretty.register_uri(httpretty.POST, url, status=400) + requests.post(url, data={'foo': 'bar'}) + requests.post(url, data={'zoo': 'zoo'}) + assert 'foo=bar' in httpretty.latest_requests()[0].body + assert 'zoo=bar' in httpretty.latest_requests()[1].body + + +License +======= + +:: + + + Copyright (C) <2011-2021> Gabriel Falcão + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + +Main contributors +================= + +HTTPretty has received `many contributions `_ +but some folks made remarkable contributions and deserve extra credit: + +- Andrew Gross ~> `@andrewgross `_ +- Hugh Saunders ~> `@hughsaunders `_ +- James Rowe ~> `@JNRowe `_ +- Matt Luongo ~> `@mhluongo `_ +- Steve Pulec ~> `@spulec `_ +- Miro Hrončok ~> `@hroncok `_ + Mario Jonke ~> `@mariojonke `_ diff --git a/development.txt b/development.txt new file mode 100644 index 0000000..08eeb36 --- /dev/null +++ b/development.txt @@ -0,0 +1,31 @@ +check-manifest==0.41 +coverage>=5.0.3 +cryptography>=2.8 +eventlet==0.25.1 # issue #254 +flake8>=3.7.9 +freezegun>=0.3.15 +httplib2>=0.17.0 +httpx>=0.18.1 +ipdb>=0.13.2 +mccabe>=0.6.1 +mock>=3.0.5;python_version<"3.3" +ndg-httpsclient>=0.5.1 +nose-randomly>=1.2.6 +nose>=1.3.7 +pathlib2>=2.3.5 +pyOpenSSL>=19.1.0 +redis==3.4.1 +rednose>=1.3.0 +requests-toolbelt>=0.9.1 +singledispatch>=3.4.0.3 +sphinx-rtd-theme>=0.5.2 +sphinx>=4.0.2 +sure>=1.4.11 +tornado>=6.0.4 +tox>=3.14.5 +twine>=1.15.0 +urllib3>=1.25.8 +boto3>=1.17.72 +ndg-httpsclient>=0.5.1 +pytest-mypy==0.8.1 +sphinxcontrib.asciinema==0.3.2 diff --git a/docs/build/doctrees/acks.doctree b/docs/build/doctrees/acks.doctree new file mode 100644 index 0000000000000000000000000000000000000000..fc578aa7cd63c671c1f2b3ec20dbb2163cf3fd9b GIT binary patch literal 7320 zcmcgx%Wot{8DH<(9*@_rU1!Zgs*g9srcxbR0HaY1kh3W|jI1GoZ54*b6A=d{=M1VSuLyX&i} z@BOIy`iBcYdFR?W^QYHkB)s5ghq-PLx?HAu$qk)k%mbCao8J0S`ewSV+c7(oVG=t$ z)#tFn5uWeHJV+m<8hY z&)p#>sxqauSUUfZ9}y2vS@BkC_yXchy%;fYqEc~5%!vznG3Rqn&--4$)4in6^fFT_ z_WFr}d?e2W&y~b`%ki0%0OEZiVB_p<$xWha&}Ytm%m=h4(JjS>G?j{VaaF7kMR85P z(*2I)vFr|6KlZpkV7|k`ZWMFqb=+=F9z*(W9t!i8;>K^Qw;Fti0{E(GiKtUFe(cRvgitk8Ll2SX)#J!3>Nc+2+` zkC|UL`Q}rwWLDqO>ka&ACE6lHd-W`VzJf(BLx?SX0gP3A3H$Vl1a=h66HjprbKXr>{$2C%g5a%3+^)3#4k*W-_lEk zLsdMOkosj)s%<@Q$msLYBt^=fbl{IEZ)P(J{`Z=D>x=Xvm__nU^*p8B6qSv}W99{^ z_^obXq$Uxn+y%m~FJjD(BHwd7l|C`khb#{8+Rj2EK`qWfs&QVN=s;r)QvXjX#r#l76*8KbxnRPM-HWPM-07lkrnl zR2OYEk`dDIv9+}dMCzzlAWD3vl)%kzCs7o}io4cpUO#3ixcP};OFwn4)SUPmDE+mb zSI#btAJ#JRIv5Mea`DG6bB86!b!Abv4#Rj~T3%pstPGuft}LG)aNqKjC1G>lHEUpX zB`g+9%wEg!JycH1FQmC^F<)WzP|!Y4TD?AwFFrCjQZK~*f>0`wyWQ>(Xp;Vp6OJ1v zkCLUXiaGC&8TQ3p+Ah0;BrvBl=D*alEjEPbOSN03>Cq=ARu%L5lcWkK_rtC#Y@C?K zwQ2oAdGN}Vi`b_N#7;Cpo(MWcmDvg7VV4J8pOK2Xi0@2;Wzrhmf&AG`?4LyK03$X80cvescw{3}3*=@WtL*3aVh>uZR7!7=DO# znc;8bhChYR(%_E__GyDZH?Su2*+bampy^eG2&oO^5NTTb4B zs_C`@HPGY@vZAw8L$iVF*L2sf!uPbf2I31;FV&{2hFx?yK{4Nuw>|gtO3djtWt)3S`ry1?7Px&B z!v%ebA9>J~Vk(gpbiw8QWC#h?=sHYI0N~|p3`kqW%;6+d`dF`dL6j&PC+m<}1-Nb} zYS4M1BR#xdo1V0J9EY(j81;@~=$Tk`aEo3K6E%%x!C*=C^~OvC#pvIN6}^_>t#~MQ zUz?t2Y}OkjgM^|4ROCaZRImCh7$$7Up>Y@E^XP!<&6qo3?Ak7;h6u>eg>+9Z;?6sO zn9zvl+7Zs2-cc$R^%_f5XjdS8-h)%Ey2&`QOUHv^4ZuTFHAd%{5Uv{tv>Qk=e+7yp zPu$Qx8k0+Hpj{D4Zr67jFL9K8;7KoY(RJJPBxIR?>u+!b5P4#Ja8Ih2vU)`R*+F)h%XQxR|7+aY9dIq73(7eTqV*6OZqw- zYHXLWRkCl(h|K#$Zy9cIA?7hj4!d@RYs{Rx~T zMCW|~Qy1}nnKFV*`qS$+__)tqgyaOY1n1Pcy5gWqyKi%Jx_ldbV6cl zk%SKarmsRNY{Nrq4}Pue?1E=(ehGx&6$%Lvx^d}~$eYMjQ_$?Q3BbTMCg#2JLbzgU;4wGPSF;cFBeY}^n1(p$~aXBxnA zb$be9yP#?|U7o^^OdcyL9aoyT@)_KZk(`_`q11y8s1xGGYC1+JP_6qp{9V}ct@K-n lP<)_3%;U?ML|)7YmN{w)e6a)rFDju+X*16-RL#-J`VTQ_dVT-^ literal 0 HcmV?d00001 diff --git a/docs/build/doctrees/api.doctree b/docs/build/doctrees/api.doctree new file mode 100644 index 0000000000000000000000000000000000000000..24a70794fac129565aff940337dfdef8b6737a06 GIT binary patch literal 358293 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

l7LErdRxfl7HDY%Avkx`2! zxr?|L`I9MHRJr2j>cUf;-_h5v9R<}-q4rG{s(o+F?&@mo@#YbDIyRObY}55nA_BZA)F z!ISqP{O7~)kA5W376d8EK%6*Brskn7TVvfh3DOQpjpRP;d)wqhPg>yz^Ater`arOH>fp zDQh?w6H_cV@SyaF!=NkTu`CKlnt^<>4xXKC0BEqA#P+hSU9*K`5!z^g{R@C#S~aXS zLWjz4Z4ScxfWwt_=VCF>FnJ>+am16Bbin!iA?X7i!h_dv49%_NOU=p3S%Eehmy8UP zsx#JM-iuMf^X;F$l$h4cfYeoh#y)YDY1C~9QjLMAp9b?D;2@$Gn$cDPKrH)e3(M*z z+6pky05OrlM6;IqDGjtgg{qo?whX&TiY2m{XJTNe8%;CpREaql|E4fgD_mH=%GxI0 z&$2S4ITtLX_-jRqtxE40)f7BLo4>W-R;Nv}`TSRw7E)5@<0f@FFrOnwn?SHFHi4p0 zb6x;tZmbd#TXMrUjGKb+B-lRjwD5A&-jfhl z;27`mVf`UC$01$5964x0NV-|!B3l3D)K+2c}={J|2*HFc{$OZ48 zz+m=W;xx+XD)m(BM!DeOrD80(e=ni58UM2^`Ac%I6 ziH%E)5qOEL~j)$6~`ke2{>`gZDaYCJ-c$%!#B&-;n@8T$q3r z0u?5(l%G(M!cIswF~0;=aeLF&);w-+YI;`?GID=Yfi`dZo1XD6y>)n0tpfjV4#Rz2 zn1v4YD)U35TN)=K%Sq>P)>{s&t5^@#gD=Nf}#8Yp~@7>+m!3b3Z}(*bRmZe zw2YR%R}C%XNxH~FB3))DdXmn!G+@wJWD5=->bw-HYC=1mCrL_eZv|9m;(Ch>J-RcA z^UNlRXk5?-sVsRn{7Kf!A{?=|z69(bU!MbIpr~MGSWq%>LkmhBtyqyo&wIkafr`?G zHsMTOiB2LeX(d|4Ct8WpQ)nehE3WWLR9fn4DXP8FZh{N0MR5ffvli_sH-?4tj2j>N zD@il&xeSZP@lU1|>20zGtw>Mna7C(`OJ0#`Q&bI;FF10g4i=@alVh?i$#gyv%NJaf zzDCyaU$B6SQiTeBhgqBJ(s#(=*pLvvE>)=T-j2-#)}=ZN#&IQS!G{yzh+Can;b?Pp zYHMpASErg#)+ideKvmGq+XD4lKnReVv_M@n3{E!m1Dr+DtWnR{S8{P_Ij+K_aDy=* zBoj(0x%n7&?Rftd%cQ!*K+VHku8T)X5E6f+kl0RmZufPR0$!&6mA@sfXf`kDiMMGH zJv{I4ZxNtgE zqR~E2#0C$=66CRlV)-vj5qH%e&MmJbORgUi%46u2eZ3b-OCPLi+*z|&z>(A^-a9{m zhI1I^^K0bYZCB$eOAs!JCAc{%WSQjrkR6+Bjvj=8GIR70K9M;}Pa$)Z%&o9F3JQ8q zNJM3k>S{Z7g9MGh7^8Fz93ht%8i?s?zLbRX3NQk|;xPWnWSHJ8Ymi~u+o55qnoBlJ z*XaY425Fmi*mLDLvfE*|%eww^=F}t|9xhkQ&Eesg%XM`ea7$DjUo@%BZ9wy-WC5DH zFO?&)VhkA;HK~;Lh}9~@8tk$q`9ZS$ZqcGC#&$NRcQq~ zV1*rW`;Oy@?1Ec4=B>t6TPJy>X~5|&f14!#2ZSf!4-Z;W+*J4w!q_XIhFZ2WJcg<8 zc-)0R7FA~8b?h!65=c4laIBI=G(VK~5~R`>Ic}s^n#wyhQhiGxpMkkC`eAR#pyHb_V{4Dyq4a1qNENSFW@x%j5a zh&4*k0EjV4)(7rc5_U=Gy%bX3c`z0b0z>#GlW8&_YmjNu*P&^mn)9D~;NFj}A#(+6{xa91GXTx{C#I%0de99oGb*_mUq;5e&;A+0hYa zCnOIKjbot=ao3OkA6iPXVW9P@TN$uK_7X4mE6 z?yL)0CL3@BVg@t6PC{mHv4JZcDd`GJF7RHCa5&yeIXJ>JiFY#aAix7yiS0|jL=Gpu zCSSIS(Sx3lykp%(iPaNtf==1O_09N1dV-!pdSU><>-8AGpp!~6NRx>i8F1upU>nhc z(!5aWLj)oD%gYTs#XvEGJrI9WJHcWU#3u0&jf#Q++DZ=u31z1W<@&6@k&XFD>NxnU z_fEvviffy*1!Uf*1B-~>7HYsc)%>;jyfa(?3*s20Io`vxZ&XU8(&_$6Q55$nOFe+U zA!9_P?YaTwbEzpTh=$?;@kw5=2%lp1+fY}>SP=>=F0R!JHABCNlz<&e{FBLU_=>DS zcEhd??FOy66-?O2=xsF+rqSEuTn2ze)I+qW=40M zlfFMAi=j7w%`#G*E{Hl~qp?Z8JX8yMBeJcqcUW3Txx(HJRkN?K&wyI`3Ojzdzz2MJ z4eZL)5mF$?Xgb7Lg;@@=%9&6Fg<23*!D`%W5S#|8Jc_Yd%86BQk5j!2*Au(8_2n~h zq!fSgEPNunfu2Hk1IfHz1lKSc{7tBS1Ut|iPu4;5DnTX_gd%z(@UA9W4MhYwZD4Ns z%gV*`U>sr703NiXuIKkgT29y z*qeBj6&MAd8iBWRE_gFYV8@%rKbe$QQ`R8mb#aHvOEt$7NhwBm{SSk%Ib5;sy%tU{ zLvq_JsSuUQ)2^>0At#*$q9ZO)lx!mv@G6Od?8@&xS$DB1KR>`L2^>V2c(WXh9TRcN zP+`J*6E+iArtZv2UheQ!S@2fL7WgNXm#_;z32L(+a%#}P{stfl$v%7b!4FW;blC?# zWoy=+`;Ikh=DzDfZkJ%w4-@RKSlVwV^BwElG);8TFXE-%4kF~eZ2SuECm=cG&n)AN zNKNplw&lFQ=hDVtbq+vB!1yfZn3noey`z7<$L((R^TVdC8! zK`wT!qTOdpJyJSIu}6u$iUkW3{D z+?H&qhC7^yJUu;~@XYWnP2Kb9y$Cy_9f2W#TSD8)cuFn`G`JU65uoP zuH47rgY91}08@-86#jod^=Udt^+h3u|6}*&ngy3lJWt*$EDh-T(wt$&uIuZesEGzp#CnFrGyY zNCQNB3Egji?nA2=*k>0WaX2Mbm~>~o$3Z!74}j*Mivk3*;l-ndgbL59fnx+^BR6dP z{?rI&OBk^&ppQs}1ZX3Yo_rFcm?Fe;uyfoo;QkYi^K@P=A=y?!Ex}MAr1W!}H$G7% zMZ}D1J>&J-r1B*@fjC|A9QE`(S%_iw8?K8cyJVOy<{6fB%k}RGq(2O&Ms(mm(b`O2 zrboorlokQgoAazaVK&uR$SKg(Q0Ha>$kVa}0jY`YR^twboQ)_Q-6y>1@| z>Cns#!1_7SQy$;%D>Pg#=cOLtLO0iNE93kdN&+S44LzV9h}ln(ekCFqj8K+@rm`W2|14@#Jdq?IIy=3J4SX-w4k zDb6<(g(pZZ)WSREJcm85m+|fdb8XJzRbK%^W&4S*#3$NMq^Hn+B5gzQcva1$U4z?+ z`~*$%Mq;-(YeS+97TlM?z|{tq8OxIMO6YonEyP{g7GhuzhV3JUUPf#tUL4p=d@~OE z+0cvJOvEnP8_)+a@h@^DeBmvBOIGsU1&zb--id$Gy38o|**jzn+Cbb7kaTi~n$}!$ z^otw^b6%;PKrK0n*k93K$zhWz_J|yTeb*~4_~jpEUH|yP1;5;8iGBGegp37LNHm$_ z{+5K@KJK{PJ~eLdo7l`;g}xxvINc!K7H^omp`YNOrU-o*l+h|lp(ud0Op!0Y3gF9h zYM!0CJ2UX*r1g?crzsP`4AMdRnzUOAwSq1I-Nl)FvgEgj>6mjoF+R>U(7ER0OnI{8 zXV9VU*(6ZE0*bRFVucgc(aM@+Pl#{@FDs%&byBhyw(pLv$4boQ!JJeUIIVMEo z0$$G7X_R>31|8iF-}kwKtyP3t6F((pNTnT>gS3fueS<)3{bQ<>30Z4#C^Mzc+l=hF zO%BM0hWKPD3K`xEHbe0&>L7^8m+{O>B)KO6mN;!|g+(2eUA(t`{xJ+XBz*00H?O6l z>B0)$VQbbNR=}Dy!wM2_{e0Ncemg-0tn=sscoANs*0q}Bf$KG=<|~IiUc$%{1mV#Dxo^P|8|F+;@nTD) zf6fMrT(s=y4MI8QFrMoq`n?2!<{O!xB>G@oUZ|YOxM68ao)4y_+6%l8Av2xH9M~cM zagjuq_D@V1n6=oFZZDcMMK_FadNBv}!W%<0>CWV!!=!sY?6Ax2=O-lu?AU^VxM#~2 z3-mPXW`1IUu1CrSVu4Oi2G0luI>N!j&3s`_&*b@dLXkkj)ME#cKsQ+$(7D7E$wnkl z8LDclC!2TY(2F=1HY`jH6PWF%ya9y`ozHqBK9Qq} zov_T#Pm_SQHm%{wi}F z&YV`kcM+beg8|Rg2M`InpbzP}!VcM+c+XWh4-j_Qgafv2?GWZzucD}dB1DL_Mp;3Tz+00v4_L++L7G=) zAk75_m#N$x zs$iL8cPRFXrYgEanc^hR%-6WuOXCiG=sI@_R(^2*Rs+tTpm88lOXZ!bnobk1|Ar68 zAc~>rOtvb`@*rF`?hf>fjNDwmxjHi9G~B5I+|LbHiSw)|w92KHxN36>)gs(9RA)DS zPdc?$6OK@T3D$#0#L88;#2l|FAE6>5!_El5%AEU8K~C>(7gQzPJ7@!V>id9h-841= zC;XKHBVzh=A%axjq^^HrnKrtah+M-DePM54N)P!@nL89KXy&w43vS?);QD5{S#g1$ z{I*g3#Nhe>u?5aRbOM_Q9#G&C@|JG0*gBd4gUCAx%5ZQ9c`GFwN%`fgcNV~-#S1pi zJ+O;}I!%Rx|u$E6|Dy{D=ZT#?z7R+OpMK0xzUb zx|zwrLg}o7bEhki}hT!NN;&wI#L=62BBKoNsB8Yak0TEp693ZG_ z6mNYFezZYqoQ^%k&JYB+ApyOo0=Rr-)}vTQbx&hDXc<$sNU^IeE$A}T)We1k{FzWy z^MR*~6#EX$G3EqEh0C1a`T$Wdu$05zX@~-r(O>e&vop+{NAG-1=GmhJ+szqzYGam$ zXIUCyspBL{TAc+GzXS=w8nsE+fjhvDxz#fGX+VZZcI9roAwN}Fi4*Tuq=@4k!#|pQ zF!x||_EBP9K)wpY136>1`Kz^_g%pW!65IoW4~4x16eqVj zo=-)=>Uh>Xjz&^vUV8zm;b?TKXW`e?F;p*(j7-&Q&DvP4!pM#^6K^ohT@!CbEY%v# z0U$TnKXovV>5L~8tks)6REVcasLY^Bq{}xC?>oe=#uR}A`gWtgM(TXE;!+L7wE&g;66_`TAV4a^ z?cpS>^`oLbSIOhrM__NNC;p)^A!zz_D-E`GPh;P)>^M&R^e zeTF%H7?O3v22DA%Yf!sYAb~kwVS;+;QHEXKIaG1sG%H>lTn3Ym>?OE(Z>H9Ql_OB7 z;GnMv(r$ngs^u~@TIivUh06)cPM1NPPz5lrCS0(y(2}mU@OEM7{U}ct9k8O-2ZkW% zyILDqfXGisPvl*K$gf8tFJ{yz)>`zS0z)ER+hyp-$1pS~dECKL;(|*Bit=$_fdafp zsh^_+Evqe<$hIAJeR}RWD7Z)J?Pzcm{ZbSL3}D;sV(^R@4DLrQ1uneea10_@31@W1 z;iZMck5{r{7iOx_vOw}`?QLMDPNm0nMc{gy5XT0t6~w9wKd~s_3ES22Y_8!>v5#L2 zZ4-5CAV+mi-juuB7~zth+wy=kj@6RUaTrk#*+h#e@M=U(L8B9uRvfbuzv z#^T#^Kn==JIy_jv(c}Sv;Yu{ldiDDsrO@q1MYE+ zMQeng@vjJpG@O5t!--}{^icAsOEG%b0FI&rPh=rxhAolBNn60JO@Wt7@QDI1=_wR= zN%EuDV*o>h=Nt(m#)5HYRnHBH0Hzx?oszqyA;S37T-X>YCJ1c#BB@D&ek{VpOMNlTI&Vm_ znKz09aJ&&djx3j!E!JsBggK%J^HI=$V%r*|5ZX81r!4Ot(cbxb;##is^;Z&sB-UEc zS!kYWlMi{6=d!IMT)liQrOIWy`Id%5nQS$=Oq`H2li9{fk{2gHs3)?$8Oo}?S%jS@ zvwa~o0{%5?GF$m|ZGmw#V_hZE{J;lbJFKJYgA{8d$GbaWEC?}AX^YrSI&8sH+SaIO zGGoX)lQ~z&-zH1EF9ndCCEf!?v$4c_=JrDQUt`UKejICh+E1K06Bl44*S z`#7*n*pDYaPbe&Awh&eEmAFwSauo@`l_$q>QM^spCF}aLi^ZnX@x@Pa zD5Fjb%~xif_EH&k+RGtp5dSt9dq`>6jl0uqMK%4R8+Th%mPO-Eq2D_NDKXE+-B~F( zl${cXl&Q1c1E7ylmUHV)0Xz5B-F`$Gx9%7w$cR{iNJ(kkJ?m1)q&qnU!6`L|3_Z5x z4_ngCC~U`*}xW#u>0n- z3puB~>v7PI_cT6sA!f~`ntj#1XeTjI^IApC`7#ObUvm=ZT($vP9D*Nj0#Z%T7ygo@6YG5D4gKyn^9Eb@<6A}01AyN*vf?cNwhZE{$IDT+j0rRjrPysfDK@K_lD^Ntg zBYUC@af2w&3X>#}*un$oTsl#`YU_s+*C%k}2aph&acu4~LGV%XzT}4kO~i{(9xWK` zH`OfopD7rO8|BDgnPx#e0Nf}SvQ=n{_)6R;7wT2=dmBdizr%2tQT{W0BBPw1PJ~hJ zzjzTCtvqOwo2oHeK93KZU$Sodn?5T~G3QA%lM5>qH+{Nftwo4KppnN%`UPyz9 zwER{%9%h`HSV&j|$-3St_&C>FKQVNdHZS$dY+epcip`&1R3;)&)*AXHEY}nzB|g1f z2!Z46bN_srj8Nq#b=N4P7<6Z(6B^*_6c;8tn2^b!VBaO zN=^1_BUPW;hVbJ_Ag1#qB825fzLDc5c{<;?9F{Io@pQDJEsEF?wm1dT5-+rM%Husj z#&C)?w}GeDj#g{a5VSw7R>kFJ-oazAV=ai_uQn?)J&o4X6ol_LXxWT$jkKsK7McYX zxHyfcSfHr70}+BpF$@ykjnF!JL>%g1@r;c<5Cm12nyQq?$iN-KTv8B#R;xor{r#&~aE5Mj5MrPCcFc&%82+|7MF$;3nkR&4R`Ofs6zKV*As*dhu=eUr= z?F$xO-Qb}OG8yASJ+=e|G-j~lYx%Z9y*|YWo@|`yR{zIjEq_sAPFXE<28LTJmh&)Q zl>^9brKrJsU%_VP+RV4pSeOK?OS16)fe#|tB=FBc3*T}y2kx%Gzy-clA|!6g($etr zeu4I4R-woMTFbm)lv@C$(jDjo^pzVD`Ho#{EvH=btTHXqM$!vhw zF?$2rJm$8glY{bfD7@D=32hb+XnX!&}EG2VFTb z8$RMw4l1m8MQnyBsZ?vktl;E{_-azCkpNv>fVB;}`3q$9S^#QfprV3>VL2e!z1PA9 zp7$X9V@9F89^UxYK=0BD52L)PSE2D44M;&Az(T&^20p7im^sgc-?9zsQdf_Fpkz|NSST!Wvi5!p(6Ab0?M-%Q?WyJ#;JOPFVM#{bI=y(iw%zvB2-j`9Gi9yCfu)X3 zy7T0KvYT`Y8QxB8CScN;9M9FG`BF{;GPnOn0xWR`oDG(FG~g};P)$9HGM&dFDp=;& zfWuye0mm>-2Ha^JZz&A8<2ZGAz9R>vFNXV!)yq@OT0QUFP=!?P6a-YN)gTW9SZTD; z0;!cSjUa5PK%`I)Y`lPhR;xoIEox%GfjA)CnSuNd1@QVnX3;>)PPH{T>eksQb5O4f z429%6ZyYh_ctwuDWPhcmxlhGP%)wod1c)~exc5fT3lyrHHyJhe?a(9B+|R)$(%keE z(%dB1dp!m%I=7YP-h>_;lBL&QgUZ`&CadnXn$%7ZgenntC#zsb7vL_@S<;u|xJIUQ@3%MlV!#;H_ep2a(Q>_Zs|@ zNmoB0Ymlyxcz_$YuwaO zwi#v}b{9_a(5RR0ki*7D6SP0Dfo30fUvS(@d1qi{;G@~_6KxIK$IKeeGUnv6c&Nt4 z<@0E#eigVd(oR*d%(0z{y$U;(NfxqG-vh6igTs3>_#@3zw`S&uUDuZ&=%<9KoiT}Z zjC)R)3@R>Xomp4$fFJw<^zeWsbX{)x1hO3?8Jd?Ndroao~4CFVg>o zU9vavR&_TYvrs?sx0J@--y=mG??d<}lO_GPvIbewcXen^ z39Ci^F}jPWP5bye5>Ga}P!|)zXu-hyZ^&ByttWh8A-RU^P-PkSC=nw#N`EDpip1(q zn7K(U4xv#;##slQd!Mi;n_7E9DCl`v)vTiCFDi&LBvI{ioZSwPT+(n*sYpOWW;W zpLN_W_BGKS#=iI{u`gek*gtL=N(A<2GGPBDwr1_vXU%57{%b64w}XAwahurh#v=fr zOGB9N!Vd!L?1zc*cU!=Z!1!Ne!1#x3&Dt@}nhju_4+U4L@Mwbk8B5#kV4QW_CdNU2 zFr&qSa`>W9jz3KJe_(+>0_ES!fbw72nzf^xHEW`L85m#!YI-(-UUphoE471k)^)o` z7xrNY>C5ShfS>;|M{v4j1QBR|92HHcS9jQ&wWFOiYoa|?ukN#fc;5J+wEYVb=)TQSIMopszM-ZzF8nj!qJ(TfNwm@iFQ{Iz9Z z5wv)J23ma5)~uZttXY#5iI?Dh+0uSH^kAK5p+|CAbQ#+gh4bh#{x4X+nyy21M|P(xOPKfLl$wQAaJ-8Vd86_Ef4*~Y5q7cd>Sci6 z-6?9_4TFKAVtC-pXAOWe-}`8IpK5NC!`_erK%V^RIviFncTGkm0Q-Ij;GFlP&^v=9 z{u<%B!(3rZ>X^x6l`BtdYKa}!e{ z<9Ou+XmE1<5EYT*jZ@KNObM@AB&I|GVJ}7b;qFg>EfuC-5sNAIH5H~_ngC53m=Yea zNKAxVpocqL64=2Eu3RCZk#T5IR3RCY%fF?VpR-y|l3QLLpt#2p5lL|XukHrrA znhHB#Nr0vu?0|zQ8aoNDsID{Ol}0M;oJ5U8$s_hP6?T3z=h#_AZlNgjq;MMb&jo_c ziA50mnhHVN6QIe?K5K;kCJIN&pCeS8s1Z|f3ING3lM4~WddPq3F%$FwCUY!7EDy+@M zVvT)Gg|$~CKoi1Re5>DM_SIMl(Z^FzqM4f%BE+-uA576IPeG}ydmiY~N#gZTV{vKG zcvwRoZ=)WDbzlzuKLEFTH0v_gx;mD=W(-)Y!LI3&S8ACrP3HLykSkpTjS=S|Yx#FA zRGf!I2v1O>&VqwXW~h>;p?qNu{-<&n_F#|LPzzbtdkh~b*h7U{^e8H^6_FOn3#nhq z3^Wz~pxzDn^lU=9{7j1>Vh?&)Vk@foNCX`*NZ>aBIrueHkic@{s~~XtTUb`HGA4j$ z*m|`C_;_26xAviIklgocYLe{z0)5Fy+JCDB)5y|q(FOF%* zJfM8ARuAa>J4BwIz+I?+xI^T6D2fgd1bEwAIz-mO1V{BAoi{yUy5Ev82wkOL4P~u< zkV$GJYTY5fiX7>3KKtSg2nZ~ttB2^BhjQAB#R1%%V-5*37h*jf?PgSY zZ%kAEmlPr!avDpX~BnZxA~`Y{(SowN<)Cc8rupD09s2|k5F^vPTo3CvEE z-G8n$FItrf*!>j@8y_Zr4O1(757%3+i0;;nUtXRWaYOz}%&>UVM#{Sptc1N(Ze!nxpu&xm z40x#JeLG<{acf}8q1889tMP=grj-|(hTOsly*K&%)d}$HmfsANwVKzn)JT-&C%?iC zNdUX-A1`aeu{a)<(B*IRbU{AjM!+i)AjhIyT_fgGs_Wxabj~g$`bY{OIeUB=-Fz)fZt*cQShw*Q1R9n z&rcp4Nh(hMd9btH`!zVI4>1lBo zo{txX=Y-oFCfkwC7MUnZ*_!JEMTBh;dN0KvG1=KLY@PE>CX2T`9a-1EXTdzrpSSxnO04@41%UG^9MvLim8pR?g9hSylEbHT z%=*9=)g4XnR-j>Xg6q~j+ACa(1fc;{HjoJ;QpjYiXTe0g0^zn;IR(RT4TcPpQiI)) zqE)WJuFHgGuEE6olKk6-274QH%v>jbhEJry=qXl%#UoXCc6j_WfG5vTn-vptFT7tu z_W=nVJ%ym7)BD1)qk?;K5!xB zLcLsrjD<6McM1=i+G7{F-bE-2ZMi!E5%?=PTn1k>f`l!A`4fI7Yx%b?gmoiXfDD>8 zQz&%x#_>jc3I&A#Zy7d2a43UQ=Shx!{gq@>(n6aO;E3DZx5A-z_s^5N`)S#T>ucqI zR6BsFg8*_cppb=P_bQ%kD;lxK?oe4R2%sC*$#obQlLQJp^Zk%7f17xJvaN4Bm>1iM zrUi3r#O&p$R&Z|&6%;bg^2Hp>jWz)7V>!&wm@3`DxUE^cBbPO6I&znjloEsBzf8cJ zmLA%1<+AQg4Xhh*LVBSqH^fLiN{ohx0(YG<5i5qFUYH~KL(51aP6ghZfdmiQnzfUF zHEWV!3Ckq_Mk+j+0Kd)BayzJJ-DW|3a#>t(+GN}OEjYa`fR0GNxq_whwWT-@h#m5U z-j@CKgw0Pi=-QwH1xf@4v-qtH&aCQ8v2(gxX6uCrTwu=+3ltY1i1N z+KQ%yuG_etPNC3z4@QzGXM*_zTi^YukgUPP(~ z1!CvwffNx7oV*z^%C}Y7&`D7LkWX=|pf-;@miEnzLGt@%sa|VMl$^q`Lb*~Hg*R}F zd#YA#;No($)pTmr$_)H7=H`1Yt6WerqR{97qFkj~L5#jW@ed`0FO?9|QwT!x zbcCH$J?Ny`kLotrKgEL~k>z_J()E=tE@q8srx&0OR46V zz>0HA9VO~XgNIxScscoiQz#bUK8)d#TY&pC8kEL!0P`4+h2KIbY_rwayK5)p35B>Y zw=fB1_Hr-Qjvc%SVLxSbV*R5;j?G@uCx=)Dq7&=mvX+1Bggdbar`!N-(|`3f3BPUB z@%}3{cJHg$Ou&B?&&A}m`e8!vab7EH@5(kT3fpi#S#3^D&EEntLTbZqCH>k~RMRkm zL(x(3A5>QJc(vh-JLRm@plz}hO$!>t3l&*}yB3zHy#y6KUS}2(CQb0QIf5%}VA)4-85K%2|E z^eA;5A_tthK~*lOAby(2|4Yj#B9Q-%49NeWtyw$rS+gecmx1{q;HGC2=ucZ(ZwK|P z>o!rpK42Y%@V`nH5JS=4m;?G}%YY)N@ZAhl_=T-mI~7>7CKXcb3M@H0thCyp1na&{ zO01G*DW`$jGKsy`hB5U>bq|rtgV`E(HWhg+hov` z-ZK)suUZ{GtGg5BM$@h1iTx2cwO9nvUxN^2@M}Ah?qm(_J}flg2NZ!kXW;G$CIBor zc=>e?cM}Z>zY^THI9{%nF+Cc)4iO`kS8Kqj%_#FVu-3DHyY%73-#*kyNx~^RP)W=SV z1o`R1g)=r zVd(_CJJ+XW?kA*22LK_6{5Zrb5w2eDI*1A^{k{d_ABEnT{_58ukHeL$IWThi@kGtR zDxIHJ9DC*d!vl``dFTf7=fUfZ-8&s0_npwxvP?Qh45{wkMYXo`tPJ&nDa-PkInyA=WD)TMTHyee^3E z#4wet5X1Wb#3!9&b{;P?xFVbzh&SmtJ_NH}fxJ#389xMI-n?)yZ_#095=lY5K|#$v z1>in+;ovrKjdD{#t>GF!1YmyR!oduu0Te<>wkx352fhTLzGmT|K3RvFDw3~Aqhoa;#|}Kz@+EoIuy<~^74Q_sm*c$+1|9O` z2P}J@OZUxGG%+U(hH{fV^PIYyKU9F* z9su;kK^w0$xn1!}YQ$<+uum4d!uuEuUMjwIU`1%769z@_wP{noQQfxi zz5$SBur2-^+KxvPw=E=^LbiqcVzn*g*9{?pON990Z!q()ratphG4RV0aD`~i#=w`E z+agY`SRQK<2k*bNSuZ%;Wrch^>f)X-cn{ziLqvo(z{c9aZ56Q`H+xglnrx--C5$ef zlAPhcO^sL?o_$JW_%1|&U~~3E(vsl(&jdI%=KfVe(N38A*U)x6N;q>%l!TaDez7vQ z{Mw(M7bK?q43%IyU|*T1!#5JJn|(T57}$=|=EK2bZhab#<0!@#lf$}n3~gZXDG+)u zF-E+#^V~TQ`UBL6bq=skozH>&32tNq3u+2K%yix2jmy)9FSj6i=)4! zp&wfe_#E5I%;)_H7|hP+m$7|5CkM`7X|M2iW3{477nbWnegJ*Gg;oXb#sKjTTWwaR z7yE_6U&412C3=X(k0*>Ko}OIH&rl;)7H6LlS$r7`T}XL)HlciF0+bqqzbv6>Ck#Fd zZO0>o3weo<5QEDvRtA?}^Ju}OX91{tR5WS^r?lY7BV4)gWUJbgw9e5h{SX_RWMN|8s~8Ri)7=hU3B zQmcBj;T$U$oC&uIE<)J&u})cSf0@r(?TtAlzL7A*cs}J5_bb$hb>gy5i4&J6FJc=! z?1u^G&l2F&rtV`2MLU_gzks&mQNpLLL`i7s$}iTbE5GjTj4LGe{0+j!w9tY*YA#yUIX7CoOE^0&kpskHvS zIk4K!p+;b4Scxsa=2DMG!sw^310=+rGLvw70tP}PjAsm<81xM(95y_=1@2m<%x>{A zDmrI5TM8+L&bQW{ji^o9S~GIC^pDl5O-K_40o7c}!^w?CbC6CG<4f36D-;XO0%Kp` zo(we?^rp)VXuCG) zQYelyRw+YU4QC7zc9#k;|I1Y#jN?{jm<%vB-M!BN>X6?tL}z_qNSX~F`UKPb3xsvk zG>0vi5E{gMN^os_Jq5k_b|UK;AU-<{inU>+D<3g7*b)oUN(^nC`9bwa(&Di;Mt0MD zvVoKm{=9Z0@fbhd%+Qxppw=TP5cVpVj8IffQXV@4=i@p$uC5wPJ{`4{bXi;N72KL>uAtm{92VNN%hIN@iV)G42( z<3|}1)M;<|N}b7&uOPkwDwz0r0*o=V{bdh>-DNAP?d$2sZt^M1Vi>GKvp0wspXbBL zn=RZHoe@z1*Lhs5N8yBTfY2Q8X2cIamdplCL3@wG@uv(^&6AtF!4%eY{4BDAMk?t? z2WJwv6B}do@)Wow#B9l0O|pyUA#iX;n8PUac?z?%chSrrc1l@cIUEw0V!<+1fP{`> z>cO%9L;SZy6-l1s&`W4$Y10L5G;ZA9h5+??$M8@1b{cpX2XU7gOA|cl%51E{-9dp6+4o-`)R=ok)H{seD{51jR z^{Z?`G4$gMyUnfF!c_3yh5b`#=_7hz+lFArf;4M%cml%teT1<1VSfgC0W7_Tih?b7 zNrxknY|(K`5~@^o3ume2Q0tv3hRy93MQuKN(w^%Vk`|_&R5~V{$*Bjv1#q&|1K-9c zNY>&6z_kI44HkF>p3C-~)Od!PhW| zE;GIthfajPlr1ZEN?!#;>?KHOZCPZxA2tNx6=GnGJ`B}0Nq{R8SPluw9S_($olRLK z5uqCMwU=oiwIC4iw?==h8Yf7fl@(G`G3ZB+a8S%9T2!Ko82L$@#=yv7Gk2~}zO+){ zlv}%XgbUK?;GeLy3lu^>t>Kt%2$%lk@EJ%32^G}*F8{HodZKs z^WD`KQX{}+);%QoH4xS2^N=^k!xH-JOTk}`cXtBh2p>1J5yPnrZO5xo(G-gw=Gm8L z*1N@T(+qfD3LrTfya$SAV}rPmL519pW4oGYi#MOSm;56s;O59hxHBO)p1OS5A||U? zw!~L@6H|;rRY^34tlwlK_Gd60X2kv+pU8-%rxRhs`p;b;zuGadh{06?n^a`x#pJKt zzzjrD!E!aqO7Tr-N%g{<9IJN3ab~7Yr+jK+}K12$k^-_h>)|=m#-|4 z#!F!C2wQ@~+eRe4h>tW0EH1kR2S~nXLw38+C6nFb_(Zaso+4zo$G{Es6trkLh#%Q5 zBW@07Bj*3L*KE#tG48n$lke)&iQaU~1B2gD~Y{1-yg{d-Z;TBsJw~?FyaW#}4 z>ET*iEsWgC<_qso25{!oK|lC@WGb&$R35|{lF|mNuOX!&h zi!~@|yziAYXuNL(7}|0A<-8BC2F5&vG4qqOBl|RB|77-IP@Qe0_oWrrHfIaS9Zv^b zC|DL^6J~O%IddJR!EH1TumC}@xUOE(E<)hGdI%J$xU>G?{&3Syj@{3KUYKSRvaB?l zGjuh0|E#~=e3Q3SpI!8b1Hm1aWpuN3P!yGtF&pTQB?Bk1yl^^VHqal)T8oC&5MwGg zs21miGerjTh2BdUK>ng%%W>JT5uYVg;l%sj*bFTxXp{rnF2vtUf_g$!0Kn47Befu4yCDdo#2lG@s4kbl_6*Ghq^MCQ{&{;$lJ;C&&%boB?f3!j7Ao z(p@rl4N8vi^2iNv)+v@Lf~Fm}Tfc|6V0LRiub$ZVx2Gz#xU%8ikI!If99$DqZz+@2c!HjLKaMk~QM9kC^-BiIcW5$cq&Zk#+` z{8^umq~;x6&OcMuTEMh!b0XO*awOR$yTXEZ6q_+6yPqQe^KA*e$K`*v_O4tqzkB(g zUk=C!i6Hw%sBbG8u@QO?mF+D5^IL8G*+F}wt!P@%v{cV(A6a{8&;R@(TbFj|{>D}` zEp+pj|M@F6uNu> z=XuTlymlb)bew=+8-7=KsJhm`7=yo|-t6 zmia#|6ChJs=3iPG(CrqJ*Nj7wO9z1!;kvwWIw zd|KupCr3*>nD!zq^A;dG_d5L$@W5yOM?=oIxeiV{7y1pYEwyzIg2-)D$i0_htBw~hK@7;VCt*G*Zwl0QWuGlkS`hFQ zrWVBA!Jv~&9-hPYA}YF|Ntn+8^u<9NuQa(8(Mye3tqArh(TWIWTNdl6KyGHKQz<%N zPXg?kZE;aTQQfxijsjWCB+U1pbkdTO@IQ8CO~g$P7egoU_~J%}#8=43kYB7uhWr}N zxGXVa&&G^3b+aQCC!d*sG{kQD;#{32W`irgwFwqlF%HGU#xRLevM7D zthhe581Ol^mzmE$kbuGLe7=y`nAZ%=fq}D<8nLoC`;^Gy3E7x?6QI->{LF-+oiO-W z&~_>Ymk0?lxcp*eaQQWBPG!aOS!=>Hz+UxfV7f3;WMjS}&_Jq1MzB|4AKM}$SS*!k zwmg9evd_^)myP*o!Vu&6lD>?tz|-<5!Y5DDWMgJ)yDAcg0KA4SK_D*ZH>I60=B5c56>yK68& zhdFsZW!YYDa7+ z4xe@vEou)$L8zz+<^>60cA&n(UB?SCuFG~NK!k|n3^ACZC}#-7aVCa{mo7ZdgxGf% zc_z&Cc>hhZF^>T1kl)+L#ym<`H%)Wci)l9-vzLP2{G2-L8Tdb4c4av!QkDl1W*b}E zC-9HAF|v70ldKRjuiZ#I#!okX&WcC8U^eDwr$89bYN#fu#~SGH=+mH)H#yhu)RHtg;WvS1SHhzOtoz{)CMQ?NP5Eu@%*Vru1V8A4*vkqh1x7y}v_@&vOEpZ0VjA zaG@~Rw*s*3hQWFiu}GPpA462}gfMLU6bbuhh>EDgsewq?tSOwi>6f*d6sX?+Mc^Fo z*BnM+JD8J85B-!D&mznG{J#{I!%>GRlAxu_{Jj3W)Q0pLC<=!3O8m1e6mB^0nV-+X zejTqj1;AXPaY!*S^BE~>aa$ILnaY-xsK5?ZA#^k+;yI0*wt~2VJx$Yg{xd)CLvYdR z^g7S{d>{pGdFJQ+R21ySMV0xPL6yoz;w-fsD1K>*VRIWvQJc>mu#w`s<5`V_q=jiG z^^aLGIceS$z{yUq--1tcf}Ng1C)mj_5^0S(IK6&eC|_=}8F#MD$_wX%4&*(_V#=M+ z6w@yTRJUu}y-?O&RC!v_u2=S*d2&e^dFFd%>6z~%Q=UEqV-NXt>^9%)Y(*n%zSpEI zi#DG^zxQgS#5~)4*;7m_07G`)T>$VL*nJ;IbaA_n;ehPEyAd5J?Y`gHY|~%hgOr-t z2sdvl+w?aOo#_$)V()b1MoTO$ZQDS$=|o8Nw9@M8+_-GhKg|lMsf;4b>U$O_acW2n zQ9du2;-BR-J|Wqrdv+yLpS!BNp(v<&KIMQByl-p!9pLx|i_J{9IfvP%w7!EDd6VFMYuB|H=eqDsU#+= zfI7YsH=Kp4l4uNB+{uRX3t>3SaDEX!k>N~F^JX~bM7G;xd-)8jy)5cSn#qeLA@hkz zV*L=%Et=uuJ*=;jbr%cHl<}P@iM1Mt_f8zsJlnIWlUOUbLT2o%0M0ouV?PGX2s4%q zoy^$Ra?1X<&u9I4K2RY!&7H!wchkO(XiaC%A_Qd4%H-9`n3b=;k~Uw{2I*Vo35y3M%sg{KG9mr*gG zy|k>rcbxE*L;x__<%&^Wj!{0>07MKpI|}uQ2K?D^bXweFmNCceIY7W@MW(Zm*y+L? zx4p8Kzc>)radz7a992Af(F@pozCdXA&7EXa=18W{tWW zMr>yC!KFXHnNPtIvNunIdhObqB9SxpEsRYjU&z=z6JDd_PGM~By1rDa!xenhq5~mZ z&Yr26J(SRS&&VACZ8;8V7U%W|=d>Yzomp3LLg))nq-Hjf`bI+qllw`<*27|S~)c{NJEB;BQ!ySMC5^I-?Frz7d5GGgjfC>RMql0 zal6Spwam_QP8aIc*?YY%$TQ-74r(z^7ZR8ya@ra}4!qaFqd3c6?+hr-jZ;K-l3RqE zv|6ptV*@ERl)1eq_zdhtsol&u%1zp6dvWarFu>11T5E3|K9NOBPZ9PaA0zGyb+B1@ zF6muh<}2_H@R(Z>P77dNuNQ4G9$y%Xk&h?&%C2?#Fyw_@8O_5S&?~!nc($zNFA6Mm zY#m-C2bA49RLJn2fXxJ~!!*tgJ{4DX~hdpY(}XwBnD8MwTbR-6z!>N-WYF;*{6HEZ>}b3?W0*6CjKQmqEJ zB2+34T%}iV;2!nqdbtU=*}^@zJq4!;HzL&Ph58KLoIZfJsKezgPPyq6;F^R&gig{6~;MvsQ9YU=B_%;GJpuK*h)pyW%cj3HEYK?Yu3bh z;&lrbS=w(0@2vAS@qTKwmIx7Itx;AmRN$@2TZb%Tj3CW58A$VNTeEi3ux3rttkIRB z7>D`N97e^`Upu5?z+@p+a#?ht*~IreE(RV3X%x8_P_Tp+1FwX7oh}BjZ?PC)>XQ}& zv+z37g%&t&^3ZiI+@;uXtIY;j?x=3XEoXV>s;1LK#~FN}I0ax!QE= zRah~MP?2GN$=Zm+POPyN10MF=-7cs~#&^&LaMm9K=j&br!=2}^6c`bcs0$IK`X;;N zEtbin>jhj~aL*m~Mq9y8nL89KX#BZs)rOlTn=}{c`T%VOia=fhR|t|T=m=L2r@+-o z&nSrFFwMplKl!(1&?8a0@_QS05=4lxBLk(_t$?O^BwM8Uu}ExrIn!2yJ)n60o;^yi-JGGPHfCvfmZcGvo`#bsX>}G%{89l$%cKief>)2Z)iPd?uJJOz zBz(wERaWA}+lfr+czOJjEpoS4K)wp`Sk&&r-tyvqZ zRT$ZkX5x)g8wa9;f4o#{GzWm(<8HkU*6?_}HVGe~AZ$|iP$Ac8p?keDgDPL=SUJ|@Xg+NG{NtFfumcg$8`d*bDefNdX7Y&RBebI$s_}F&4=-V8FzO!NK z!={B|K>WpUC-p@X@3D#kcU|~1fV}snN8VowDpl%Qp`1ryo!z*b)rUjOQ=SIrjhrlMerOT8Tpj-p?R!hiv6 zyIl;P5re_~sHMP#R~(K(BrD;J&N#fZaQN{`R_ww|HCh%(Uah?i%+y?ZT%Rp)y-kQ? z1J?>-)rFr}6!3)Y>UcKI`BUuU7em`b-5SVI-P6kMNo|bKmJmD$W|oE0Hj^FRt{u4c zk6d!eC1Np~*FbtTqS}(g5IQUT+E7baq9PhzOQ?PZ=v{k){)jV?3 z&LaX(^W2M^TZHoK6HxB20gq|3S}T$lVAfxWKOxShP}JEmMztxtOHS zkEA;2;!+9bA?us=TUvZHDdH;6MmGvF6yJift~Uhxq$?~j>%AG_aJ)BiaKyGpG;^U{ z!J`zLScyd`J|u?|Uz0~EiqT7)81%q|(u(h!k~ zYC>+b0KvqQ<%?t{Qfpu0oM7jq_>=yhlXd<37CeeEj4B@2s3P{3-olT%sn|RDN`Oi@!aYC&9vjTi%Pc zv03i{5UeP2_|Y*1YbfsJ(*S$tLfqT5n>r+U&Co&e`ZI``sMBMC(3dCE?14pI)w$vD z6@$ASiVp@4gyCz@wr|k;#$#N_y&;5o=M70_^Bfo#5c^F0lX3rQu}(%J%xQc;z_T9( zUJ>V8K^CE@m7FxF=MaP*fa&Sh<*`-$l|xAT!X0>|cpi*BAeXeYwe%V$(5M=Jx* z47J#NOT!r)1lNG3T8I;J-Y>P0kr3gQQdpiGNPtk!9d#;{Rr}F6%Xsdn%c&7?7+CLD zkzd!Eph{Hvfe*lTSVw0&WqjFgA0hj~@h(jm3qs5j9wD}Mlg`#E&n7iUMUxprW{={y zmcQjVi6xpTfaEN33lz=966=|(59Na)7((wQOn&GSVE+Z!akfeCc+X2QFphm3SSIYp zlb@%X5;I#^67iL|Whvye#B-EoDHa*V`Br9Ez7vMS?8?8yC$cN)DZ;Mgc31~TFZVKg zi@S=*dzHzk+?CF#)Z6dCs_c)@;Ck~pblZguOPeQ(&oA32$<{R0J_*!_X5)C%@}sh@ zKf72=OC4V!+miWw2{+2R)Ltt4QhN!RCJ^rd8}mCb_K?=HAD8%st!RXe`IVGq(Z*Eh z_r8pjm}eXFtP~s?ZDcB7Lq_I@0QfmDGFLniD8iir3?F36{5_&3rIGopOX1Aq3iLsXjKYzI^5=z$8q;e zn4k06g`C;m7Qh8?$R_-gO-J=E+Nn&`T+c^zLM+ohDdTZFQ130EYo!;RM0kM zixittnka-WP5@9hOxHnKt6{pE8i_JY<<}J)PRV4xcms@vrF2G%H!HX)dSL?enkkCt zO=%4EQqegxMN27wG)o{=csydGHCDo{OpHHtAPO4|RE&av*hD&x zfv3OS`v1?~o50CcRSDx{?{xN%5QG3PVd+Xtx|0BcfuI-yiNO#d0TiLS()Bu3FV$6T zRdtdkMnOaee6F;(j2k-QxQru;GwS%cFzzBEZsV?qelX*xpE~*tI?Q*@x%+$fZMCHP z{~z;H`qg{)o_p>&_nz(Edv3WaJJZt8M<~W zXxre1QL)IDv>?|nphlYi{_Ru1Jm!01lasbQDM$>hgRL*M-48t0CuQ`E(wEx4C~HkY z8mid7+U3g~FZDv|OLDiqFZ;vHV3P{*?v|p3_dNs?Sa7=!-nDN=`!U=X)-`LL?6J@B z{-juPTZKwVOqJO6wiG2LRlPqT29Ec8j);(ACSil|M84SeS**ks+y0O2NPJBm5)u6d z`Dfup+Qqhcn}r0Nk5424=_x`2dJN$<7u(L$Vxh@`P;LfR5a1I%VQ(_OrDTv|1%u+u5Zf->*bIB@3ZtWy@(@|`174$shqP;TsHnd` zy#COkL+jy)=E!>3TF+O$_?;(s*!n#kB?p~z>k>gUm*CwUMY?-D#Pgz0m-CmYZPTMT zw$;uEQP zdWur>4C6M{d_NxFN%CEEKj-u$RgA}aO2%cw+D^h-Ctt4-en}?6vY-w?I`P;@OM3_> z_?SwzJaxzB)v}g9r6{M&BRa*!%_7T*u6N1~WcOrL=e>6zn1Cm9JG|?F4PxiCusvAA zAw7jK?9`PJ13_W44OW-NS4g~c(xos*Fi8xD_VrS|R#OE3 z8Tc9Po9QD;m%;y6*7Bzo-P+FbIPZcudc@x(p{U~ZA{gSNQVYwiLt03@h_6z@k(u|T z1nlB=o!hYM-o{GrWI#1?CG}azAPwS#w=s-8Z&~R&&=S0n>{#)j<)8QF0&z^ zjDFw#9W>xYfg$1ZnL=>rW-!(sDwAau6(Iw?2lPGo`>AR%q&{S>Yg@TZTC!wI6q zr2dy#Am|dw99~9BoV`#rdrF+mP>Zef;s|0XaT1gJq9MWa$CUg#IMwUjK3!s4vzNDD8V82MQ zYBrf@zuboGq$><=$0xF|=qbW}@ffyk`jM;lUb$mOb+{I1wVV*JT6mR6JB7*1xJd3n z4k8DM03hMuh)YSLaj(rGFtzE2$g07So+J}L&9U}QJ`|Geb=~}Uo2=y@KIUed`EWo!x+bhsHNyP|`44}u989CIY9Ok&I5CJ#QHfI*y5VZ}flNf|k& zW01!p)CR?QTJ!v)+NjtgJ_-v=y)fzXZJd&E~>8SrC8(2H_ z8Q2We@3X*eh5D@FR;jNE`7rgxM@fD8!leGwEnSHi`xj=Q{w^C>JM|gZ4Ag&~1$Hac zXAQSV{W-Ya1zI&k`I-1ZP@VlSDL!UFKZ4@V&p`28Y+&saXJ7*q=UoAlaXLJjD8I%6 zyA_JFhFhd~52kBE^Tk4PObo@n7F(96_ge6eAo<-HNd8e9SUbrXSd-*4L|=gB^lTFS z^A_l>5S=yMD$#|d7$W*C`XZ>#f0;e_v84wQWdD8!vj4jctexx(tV#A*z4|8$>{f`* z8g7y3^E9J8ME4%?QIKA}FsZ+6OKQEkn2M&;tE+8b?bK&rGf;nn1$HacXAQSV{khT$ z3ekQx`y?nYewuXOVd+G~sNa@>?$_AB+Ud@~W}v%kf!zw-S;H;TeM!jW4AFnSUPN%g zd};FHg_e#*@Z!b{yzp&c?Yv-MO#9KhgRhnVg>ajM_HupQPg0k!xjWMEo) z{e(ZWT-%B(+gWCC>Jk7?Z~PGeTiet+!^Zn@NJ4p!gkI&m$3pK6miY5UJPnWLF{xu_ics-2-XHbC z?9HZx-sp$(z6h*gOEz2-i>wj-1O&v0HERU>8m-QdU^EUK@5u?+V9`f`Ho*KG6-}m; z2z5nLN)!-A3^=zee6PeI@%@?v+)`2Ms#r>~uc;`tI{}*(C?&#Dk(3ezB&FmFb43?Ivh(W_B9oy#uBi}PN^P@D@9Q$G3azx0zRpz^OjiZu&=48^QHuBTA>bvfTF3B z5Fh${0zRpzb6+fV*w<9l`BVZn*{L&^Vl`3ZNfF8Uw*-_@5$J!%5{P|GMW9C#u*puK z`68$iMI#kt5vonp2ng)OPm5R7sVFs{fJCV__B9oy<|bg1ol?Cl1QJCj5fb5459HJ4NH z5w`~1M`bnCX3@9`BB#Fvzm1hK5q#Lzsy%tsk8DL_5sa2WqB9uXv~i?+(M^AGXdFhy zIu&N2Sm&F87_G)SJ@l+S%qi{lJRQad%M>*=W+a7_-U^+IjJ9?^_;NB5C9u&|gzzwQ zhq{gjUrvOg5PV@XIV#yvE5VlqFqhGkh)#)=F!P_1&B?g?0}0q`=EgcIni!)wg`^LX6!PYZTVgTumU1M^R zVa#XMa}vlKnpN?0l^gMEQb6TKJc`RCT)7dyJOxy4#4m-S`cRLyMX`hY5S`F5QhJ9@ z-|X)vgF6HJdIB=@_ku%GN-ESXu!f>W}_6d zoYhv_=t8-YGX56@Krtu-e(1d^r~d%-3E4MxoBOv^G~G_2nHO8Y+ILAXuz_6?IATN( zX3`H6?WGp@t?ZIujYo?%;Txc%^D7&vEItSN5o*|Z|BfRN`F>3N2r<%3?TE6D@0n1T zh5U$b1EwADBc6)9;TdOH=gE-&7o+l8ML`#E7l`TQsFY4evAGmk@2#c~Gg)KoxhTsxz7qcQQxN?+mc{Yb z?!U>plW+xJ1Z6_k4NT{>Dv9lJ!BkVi=t4tE^~n1#>|B=(sTEP3h_t5^f+2hA7l3dF z?5SnXQ1%p~0ohZJa$bXV65fVtv8OtwDbGTD(uG7%hoT^LIM!(lsoheK(JkkYRS2}A zBXr;9Be)ahDCPk7#vlhcrX6C^0q+x_Oscq3rrdDO-++bAIp=JtA(vYrD^=o06o5f^ z9(E&A>m3hTkLzZRpVDiK0$)^fq`96R0Gvv51+fA3xh@k$q`b*k&q9fKrN!;Pb5aZ# zt~GJMq|};D3aDIbo|1{oTx*K?CC6_ITC)iaGp#v>Poy>JDOPL76P2SUcA*1$@_4ve zF)?w%izRlqNbKk-gk7f+Kb;K*ZK3JrhYJVXJS2Fmxa!H1B+B0}JId^U zAd%ws0VpDQ??W(wDB*eS@n1y}=kVbndM1CHUHK&75U1dUeTG4?k5gG~^?yag5EX4k zem8Nrza1Qox6B67zV(~g_V+TkZ3;d?a&F zE`>_LNvSWW&Vh_uNES2GE=J*az+<5WfId>qp<=A3u7s-Edg@GS$Dap>mfXXbrn}sn zxQ)IaD%7hJw|O&XfUz?TDp3q_7h6g_F{-Pyhk_^BdL0fBmShV_pJWP>fw{`lYE6e) zY=oHtSnnwkgK|(Z9v_8%nhh8Zb_!o?qHQ19u|SbSKtt?bA}5e z<;pmjMQAGx9l$&4_)ofggFg>f3i}(KwVtl!BhsD)E8cqABkNAW>Sd6ip*@m|!zGwh z3x6=*Vu}t#crN9>o{Q*mb2MMVU~%XCLRCI z*1R3l_b}T0PADQp`&v(Ko zTtY7JE~wY83yf_G7noTp{Zzo#T)VYT0!K54AG5x?bJC`9bsxe`lB@d-d?Htuo}ye`hH#s%?tt(#(AM5J zju~JQoZVG{HG?pKXm|IPNpp8q_mb};Ju%!Ra(Tr@+qT30|IWu(D~{`9vaUacsHsB! zOT)wy=78;!X&d}mb}qa7stDu#3Bd&1SIx6jVSDYR@}IPqb{}-H^PfrnA|8>)jn|2)j z^BCrBs(%^jMw+Hj{!x)`Q9WAqPhO;3;g%HXHWU=22KR8=R{3}G!PSb&f32)LiLvSc z6_vu5A!$`25UZ9SOlAKr*{$r#UXjH68w3+j_L(+9+F*52m%bbDjnt(Imyj;?p8p^0>2zr(&si|OgPQc4991!oQh3fL7N#EkF@g(u&Z0(0i~bbp7ucYg zNsIo_0wARp{WqwZS&Kdhm2@qtdCsDfx(rR$x)hHCP3~ZFpRjdBNRIN{u-O8?76-m5v5lld}!hYy@zH*C6IoZcsYOs)i^0}kS z4EWY>W`8dSM1yiUYE8jbG{Pglgvx5G!n0`n@*ZjnqH9@y2K;Gj0}G->TXXhhi9yzy zBFaphECMq7VRpN218!f$Wx!3@sw*CS!86qDnK)lVy`H{Sb{ii})NZ$-X7Be)gZ-Y) z8-s0T_-F!tgAK5~&kS&uJ|~yO;EQdBbkSfuA9@^VFe+R^2IDDEuU&%?+ZF~RlLllk zI`BHB!MHIh_@Xu&HY)v^C{xCwlT=j=4L`XoFz!nnZD~ACTdJKjUNYFQVFIIYQQ(7W zmo_LrghUEhh5FnA0(!?mOB{ogR@G^UEQ@D+UXt6?ZNWzP);qx+u&Sg4H%E4w^@v|X zqbxG<8+;Bha3TyZv#6WeEc7M4C`+Zp2;x*eluvn;#tl2>8qW zF5(VG?kI?#rd*nP8JiMfY(;ZQh+0h5H%r#?$0ucNgprMOeA_XO6J=-YR!7{OjEWH6 z3IszKsUSm-V2@CT>V?UMvl4KKJ1k(sp^I`o2dGBMb%jevt{(^W+Li0rwvg+L-Xzzj zbLv@lkq0i|SdJ{AJ>zh?NNgEb!h05dR+7@^FJRE`>(bWbo3X;Z52|W@`V4F)X-D^E zP>0-f4;jODb&HN6R$re9{arP=B7z18vM#0mYC=)2zqaEeMFrZ~mAyvDfPTjEI1O=X zgofZ%1Byc6CkAAkqVNJ(CZR5Ig1HCVODlK5>#?_1=3cf(iJ%*L9!C%3WTSIG}_MOi|KQj`u*{f>KeJ zYQi$XU9W#fWi{V7aTE)*k_(zxeX1R-=J1kfJ#Hon?U8}qbDDcUjKnQeVPb6ciy zZsQ2Lowh;RJ@dq06cBXmE~R2^Xu`X5I#~~5yPrZVWUIUkXwj;z!gL`e(ESsVlqbGo z6O^>kZSXqM4Gowpk$xze89uNbmy2k-$_8-ZPL@@lilx0y>DcXC_MK)l^yQr#`*@j)TzEaqQ z^wn0twq<=qVvF?EZAdGwuNVPHRBS_9M6I(&CT&8Y$0K_J07UjAT}|VGNA_aU>An?^ zU~#>-;S-w*p5+Y5KD3pp!%BIfBwyyyNQp&ck*osETwlAbCi?U5I z!TUV&qsy|*s!|o*O)CsV1wVtM&Oy+)U#8SL1E`2hZAEH1vabKqNtar@s{u!@mNR?r@QFkhJ#|fVZRS&6nv+>%*g%r`!niGA zw;{|fjF`I;cCPM1*7in|=NjSxCu0>&nLCSvy%rKL{J|7`kML2_is<`^tn0sK@{OPn zYXbJrNzwG=)}xA6&DYEFuUgECe-$*IBYvBt{S%NUrF8rw6-}3qW9~C8VC}mQ8Q6?T zAy!!6w~`csHEs$FJ=U%-%>9n_Ut@qi+`|muUnK*?Z<7HVEIo+`8m^U%K%UR>51c*|m_gLDrl|@;u#+dg(sMc*+ z9t!-L!z$8=QfP(*`5OW44hZr;Bhk1ZXOtj8{?|y9b_BTq0D@c+*kog}AYZam2=b-) zM1q{2x+cgsu-!pfBzQ3Geo)Xdh;4{&%3!0%3oU=P~;Q9@jO`>MFUh#DW+TA(k(uGx+HYbQO7Vj)35u&jun zCl|xY?pt6KWLBXHqS(F;_<^@3k?#aTrL+NGYbzQNZhj?|)pi9>Ut8dvNp&3d1Gcv8 zHspI*Q;G`HSW9po51!24e!>RUekhcIHN}d};=?`Aq29J|5cZok)a*TeFxcbRgRl?V z0NeY_0B7lQa#^&9)ok=$0oZg~6~caZb4@Ee0VB1dLN%ln4+82P(26~mE3L?=L0a)J z5~dxiSO5U6D2Z&cC)p}K1#n|p@l<>wtw>K@(~9Rp0@6{}tq-~NW)^+8HbEb1VB64y zX9h=-1~wP1^yX>Bn2a9qjd!M0IuB^ws@Z(Dtn2%euIP+z2UJ{-AXiAIWmFBjpvNJN zWfzpsq@vmt?J=t1c{Z?iG0DK1b1OT8oUM7(6pgu@9}7`$FZv6#Wuk9J~O~s z`kY)ARf8J8-ZsFd+p6K@m(vDIP06-~7 z@|uiERto@X@xR0QYIkjHvILU=d_&fn0w)z12}sB*Z!a+=?k{8)*i6cDP(yX! z`#FNaw$)hn9)Nf4&qUwOYcV%j!!$P^8tmxbM}o5H_A73Eu~JN0O*mcf?UC>F9IdqgSz zMMVQ<;uk?i_QNFMW*|ezp0pc5PobjeR>8L0z}k&A2G(2!n*n1)U`@{^(pOucx3UJt znpRRY>LPfIa%^I~SElSdIfR{!A-d1uA4MnRZ?hvcOGhI1lN?~}Yw@G#`=yTBz}l(L zzy_$lp7#iXNHg%+MEd0x=&ewnHJyd}$z{=~Rx{h%2&i`3s1B_nN$C|CW>FZ1Eb1o# z#_j8I??cEVZc#HLkk(#_^oX*k14qFJu5_DY^=bpIwTJucQKZwwg>JL2;nWUQou)f7 zih2-5`LJ8>7ejqxRK169dSgUQIljD4BZ7|iNsec-g$SMW_${0#VTq-aHng1+$l6*5wHyRf)|}b@UB8q5_ra5_7>g7P`y0bgd1SN z(FcN*D;1~!7sSds3|g_!EI9jIh`Ir3+;Vk)Z=DF~7A1)$8x2M82N=EYZ-d@5fM1H< z(Nh#T#SdtTVFFKF{OBpd^7Gj6XfyHJQ($vXCEswX#X_Z$ z#R7bCf(59hP9@3J1Ir%1vcPzE0_T{rIjsYfi`2P+bx7Yud<y z+8?<*vc^~f*4hiN0-e-wa7sJP8ksG1ccj(?OUA7q1oO<#YfXO`rvd41r4VM!j@1BPMU9dgSD!3x|r-UNyjz~Vbp zFE^V&Qm_ljZf4tn!DJTZaxXKNfwGLkiuOZbkTO%zDL0+M&`_;j1d3P29b{5(6&hyk;gxWq+k?E*C1hD;Bv zEV&b-`Yf!v=mK(}u{_eTqb%OSdqCFp-#A4~=`is^XKgcWyi{HEeuBM46TOQ`g&^mn zx!WX?&5`<5VI0!0UxFTVK)?PGzzF@yh(h}HD||Fq^=q1=_yPb(AW7@25@`MvLIN$o zCz3$)6d{55EWJkL-G(`VI|>&ch1IyF@Bj-Zx;g64!Kei2^9fi`@qWA(QqJ{*+B%rU zcTHMfM0jmTm9xV`2=HTSlGX?y;j4Bd3fl7FHG`Q93AVYC{V>JGSwP)rLm*yktd@1B zz|te@D0$w>Av`6PTp{OhzFwSvRqhfuQIPgRIP0%Wx^4m5q+CFFDiuw)fUwgB*6#K& zux1E*+6I9+JedeT#{#*P@HK1JobLL}(@&$G%X+T7^X&d_-GX+>PLL{VO))g_ij@B>5S*Jp%8mb${TFx+50{b?E7r3L0HcaKg}_5x2*wt|5*cB`k!1D zePJbIymJ7XZtLyPLO+R>NFA-P3+d=n0NW1e==+fc+y`a^ART=g(jscbB2w#VUV;Ds zI$F}zY9!|8`+UBSDUpgiaH^|DJgye+J?5a_y7XaL?t~} z_DV=+?TtAj|HS!j_uJ#u^&e$j|Mn?h<#Y0c%=$$EdT~A6j*?iq+oFu^f^s1h)pmy_ zDhbC1+%6;;aC4eP>Be4$i0XEWO5%JQdiK7b6YRUt3Or}D_-PKwOKlC<`_CH4(*NYL zs3g?L_T~aM-BuD$vRUR#fJABvg<#=O(;``>$QKWfua|YF!2U1Q;ecP)1s(Ar=y=Fsv&+d3P|++p;?p+Zb{WZl zn-eTbN4%FI(zcHH7aMx^zJD{=ccBzwb;K`h4cPn78pzWBeU_>AlF@f}G$C(fSKt)K}np{a%5vu?Y9o;Pp~AjLy?q3#{k@hvIy-MHUPs}GkG7fJ^Hu6C@-9gz*|#yTmZyxRd<{x>rR0@ zI)SctUx8c+y-%q?c2UtR3S`g*+%7;FaC7=aDUfF}MA}v$hi&ND6-YDK_f!hxrM3p_ z{bvni>3?!rR3K_}dpiJ|ZYz*b1|M@kM`{s;W=M-{0<=4zMc$9R;Eo2P1Zk0TkSOhF z5di?Sh$OJdnq)2V89;(*k^At8vr+k#=3U#~1@Yn_$diK7r3-&#g=DNt%fW7~$ zfh_$`E{mE=O+4>0oP#*(ySVouw1z@+EmC1A>_Q6bA;7i+3af}L;0lWofE3m@krwSJ zECB!%mZYo6kz|E64!ALebt68J!lI|HDXfjij*Q#%ldc@#Alpz|q4g7iWk@8417mY! z^GtEc-=^-m0|?xzYx62ucM4oSAiEn-UtQb&{$A*PO4W6@t!RYmdIyzlOLg66YtAmd zKgn9lu>Aj^4Y*x&GvMark5XNsZnv=g{ZSig_I^JS?04+;_dnPG+xyG_XX$ftSyWeQ zu6cI>Hr-ZNp_?Ye^orD23c--Zx*ZVifW}&RmC{&@2BfikBu6_MO8@|kB}r>CC0S!_ z1l*X$+JsM}vFNF58fyb`B-@gIQj$~#u?>CI7hD76I3~vAW{akot`a{@Rkaf++p4O% zOxB$OIa5Vv1DdJ}>o@zL+aVogmxwn|(JW5Ps13MXDl*{aq>9o6&t-_T9e(>O8+!J> zza-fAR8GvDwg&9|XANZOe{xyW3Tjw;&jD<@trbFoGr|Hg+vD^a=sE$jL( zpY&Z}dZz;_W4V=Zq1fCkD#n(&l&P=39q{=tlZMmxSoDWo#61Bd3#pn2ALnr@tNA!{ zIOl^Xn(yI$Zc)xe^Q81>o?t7Q7R^~SE`vzwZ-I`ijEUeTTdQ_D_S=faB4~;wn_5Lx zp@y{gpE$a^9Pc_QdbUSr4^%jY)WySqa|hJLwMbpAE*Kd|T|9ymX-8cM0H7`;bxpn` ztBVo9jj4+&K9Rbhr>?4tW*JWHj&)jHaHwsl3yUw&6u4I1LwWveR}!*$r6j~Fb7H;> zDBY@0af_@wHI#(tAx&-VdYpM0xtQ!ywsrWM(huQpkegSBWs>r(K#q_Cu*FABE`6jV`Ly1cN0>i9T_J8fQ*yW z%_`%*3rH{-_dR?f8AnfDlX2@CjZDdRRwvoQjY=C*?W~Ym1nkgaH`bxULTv{0g3Vn> zvxd*+-1{BpZ7a6!uVr2TC6jOKVmAXu?vfCFh!Q!?ew>L#f_9nq5)#-@36pBQds9oS z*|wq)5^Fk@)v(KcfN!;}IeYBlRMwgj+lgm0HrRmM1vLY1PI8-pi3w~%-EJX*zuktK zz2BDv`yCs>zuE@a-e(3lOP`a=qH?7mbXGKq?P^^Ae*nQMQ>CIeN2(Dv(>ymbdtA61%rc?C2?k-F9qYRgiiBE6$&_-%2CIA9 zj=X;Xd?Q^Eg-cLmc%OuNtqT3pZ10`ZL5yPCLgF*Jk;MNrk}%2-31lie7h|84pp4IV zc*gnea5u|=%&A&NGWM|{4CNMU%Yoy~xf)P)yjl21oBih4(We=TR+eFQs!c5-{dC?D zP_~}~4hbQ|(!zLO4!z2GU(??Cb9lC1L0|b>QjC%=odm6f0s)$>j6`|>-~we=AVRD7 ztl9~+ydP@~a=eUOYBS)RyJ(-DW!pace3hAH{4-SGav7*aTK>aK$ zDtIGQjAZciia*&m;xn&n5FkI)rM!?#kd=<E?s%WFXNXz`LO#p&_`vabKaWA3~g^b4u)1%b~@V+Y>K*-Mh+g|au?I+i#~9{H2>g@ga^oiK*%ojnX}fITR5L?33-4-@U5Tj00C9@cn^>{(z4#SmBK@Xw+j z^0(QQCoElw;K1Vga=@#(f2J|dYk~_k3l5RzO zAvrv}T`)9&1DE5Utlq=qD|4dV4vsq*<}X>G90vcwiz|?mxNxvgt`zn`q-CsHbb(xu z=D1KP7aGpy(ecelx6OmX2pI1#3^mIK;o^)znomZCWbb-x2MmN9WL-Ng0k+bC$wh(u zc>oRQKQvQA|CAK?Et#Pzcx8?sptmgCBM9qAu9F>efZ8lPSr(0~|%vROQ*)r$ApySq?_E7+TEUCw0vmC3<3ra+MUuy-Oc zR&k>PJuG3;|yYY)BC;V{rb$1x{lBy&oy`;HV)x!0{m z7gI@wSn{{KhYKU4DBl`|{gAJ{3>W?kR>1>A1~!}vah5bT4-DWd$XQe_D9x1}(h$*JLi4{! zAgDhRw{1>%zk+h!Wg{fX|2OvUf56PW0)=Z(+104`!3FOoJw0V5(Q>Ptw zTzO=)R);GR#_Db_Cbm**6Au3*BrZiYdV8O4{)X@;StI$e2Bi7VOP1xd7pC~;J z!*GAO0YWYhoy*ZT^ZRAn_N6u-{$1*;%cwH`u&p zHI+EZc0!Z}{zAmIh$y8tnJ2y1;_x=j6ERU}Zp=ryRfXFinGMl{KZo#gNPqVJdTneJ z6NG!8gfU(~&)xeJJb9nS|9l4ibCf3ad*Ml{?47;l^e`g2*H}d2;8+!}#sKS^FXc&5 zOX78OyjiNT!Fu*UrM#~WH(d;fD*dJANTmZZ_Y|O#uFy=Gdr8Mo1QEPQ;Lf|N3F6Qv zpyXLe{A1!c43^1en(R2~Q_@lw(nu6TNN-X?IwiP^EYkYifV2+vIv}&pLo`g8%`i)0 zbx8Adr8y`Knf*c~vjuOM+(rp5L^c@I?ohKOc}|P{&K?-y*ML#6dweg9_nc^{AKz~+ zK!}+McPae2l+HEW$}sJE1iHc--(vj2m}9Rm-MWj<1k9(1OP7c*Yr1QA%Txo z;)OnzP=fz2oJgf}k!bj@8=Nq;$Ic|_({b%_sxeXHr#N326G0#8n65g-3%1f)oZjlB31{gFbs~$TK>_=Tkj$o(*jf5i+`_{9kMTZ z#V!6RVtB7YFocoXKQmwFrC^5n(qze76L5KZ=`QQ0qB{)6Xt=05N6t(&ln6%Ur>>&)8EW0tN&to{6)VUTL|?T& z=;GSX+kxO_U>d`BFGWXC$0fA(a~SHiyY_=^qeD;vh0kOm1#)hL*QjJ5By%_5Av6@* zSQOZ6HaZBKJ(}*}=K7IB6(SP#IL`*d>2S3i+L<2VgY75v8Rhw+dli zyc1IfIoMXuoat6x+btx7{9hD6PW_`(Qc#0;Mj^g@FK33#D95jE2b<=77RCq{Bz>fD$zKzW3u+egt;9%mWf zbU5iY5zV@DIO;I#j8(%65?1zXt8z4N+@fvKa6dNFokhbkayGDNxH1_%W6iL^(Zi^} zu*Amud4EDnhGW#CX#{6lGJL)TfH6~N!}Nm?&4hO+NJ3-D@I_EH^OE7&P>GfdJ(Rs{ z*>FjypEQ&Cs$mgo@Kr-b-!wzo(`va1UBrpNR}IAw1a-gw;Hse!;kimhcrZfU8wkUX z_x7sJv=UZX=j^K$$G0Ht{^HokXd`!|uU0SbFIW3EJALPD>KFg(JGy2~FD)&p2IVMW z0U!}q$q<5vvm`DoI4F>8F)A-Y_}8u9czyp^z2a=y5*ZolL9JgkFNBKyMi%(Z_Z zZ+FNmwFgD=-;yvR{LaN<_&l5is!2?)q$M&QixEbcG|i%7G0{h$K8C{Pfm!gMkK+>s zV(6)Bff$vLIxY%xqMBbAmyuDJ@isy*^CV1pTqt8`sugO~e zjguBy0m5}AuJW+#P4>8oqJ;NT1QUp>%#{ohMz!|FoS(l*z#=Z9V#A_~-rH{h)kyD6 z;S%!Rz6|x+_1>^;;k_}6lO1_Kr(PQG?Q-U{HI#qV*Kpvhh+D4~Dq`V!Kxi^}fve>8 zai>r%im%Q{p*d6nA59*@+Z6)(@J(-Q1FRez-iqhKxN^MZ_$TY$z{#DR#F?cWZ&(U! z;~?jzEBV#}%S{1tjyWuP3>&vfwIT$*SIIB^rpWCV&;qho;3^K*#9dl{Q~?*za%je_ zb6ETQdw}W^^QrHwX-5bf^Q9b8WDh(w^?1@H|GBc3f6L@aevN+tf!iZ^AxNNJnBCtl zJ7O35apG1H!MhB>5DqGUT|Q>RfI6uM!DnLAtn1p56ZI03ThI@a7B@gAQpUBPYb&Z9 z*b`#~W58EaSuMH6JZ)xh)D@Pq*+;=Q@zccgpsjg(1isE%PZj@ti4Ckh{>#9c@!!P5 zF|W12ZzcN68jtpcW2xUGL{W(JGjMYoUqGN|lj!fWU>^~5e|H9=f6NBfPILw~BhkNL zf!_+zS>r7d{rEyy>WApR&@3ca5qxcO8P|e)l73OZ z&kc7 z9!5D>W|T*f0c^E;s(4)F)^CFDrClyBUsZw=4MSs1r&)7`z@2Tv;lC=K{3EY*^WY1W zGfkfQwkiZ%2H})o0qPVExQ$*sFo>>;14jmj%XQf9Jz8s&o8=nDY~c3Ru@Sf0C*k-EcnVDnQSk#*jjcbc~Jhq;65b!t9AY0X=(MpE_wG)qukJ`fC zlp4awW{64+_?uc7Xj0*|RNFGhqJ^PawD(TMVRRZzz~Ayg3OxYkHCz`GjnpRYP<#3c zIAuoVK}M$r$AU^_m_2Zs6z2_#VZu8&kp>@Wh9wSd2lhFD9WXWo=bqVYGmpU?qek)Y z@7XQ%PtCg4ssrCP&`j-sNVoub86y(5P($W|Og545R0{-sNhd}mTn1H-jYtq@!v&aH(qP*hAbSd(Pa&wi>nmz)$!KSRtpufLMLB#khd z0z-bRcmxq$#bc3C$BG}ZY-)Qf^v;~k{iJboFyYrYa0Ypg(7~X_VFUSCy^7kn&Li{v zVwakEGC3*u`0|8)>L-&;m4iIur;}esKw#iZcXDcu6CK$nW4^+Bn0Mai&rsX^AX9R) zF8msLHo5Wk0G6+tejIEHfq%A)nV$o|FmT=ys1q!z>tJ@+-*WVxj@5a0iG4UtFm>GK zg!c}B9ZwnBN#l5uGSh;Y2jmy)iEjBdnd_2LesWnL3qsbds}xh$@m`WZOB@T20+9gz z%~aG&8ryH-YbA1YUr|LhsBMFxqfp8)-Mtr1Mrl8{Gkb=~oF@B0Kpk`nQCl`YiH30)=gMYs4)24HS71r!i0Po8u z4{w9kC?yrv8m;j|0O$PV;e5PKYm(#&X)OUWeFsWJjqwv=D;PP()%x~=m z=H8hIHA&_fm~*XY#hiZ&VE+0JVLq*20rt+CV?{ib0rOCT8q03L?2vM!eGGR>VgMh}DWY;j>mQBXx;1?5Q zodZ{*R-M&b@l0a1x&Csuy1!XkZS^5Tdl&fZ2)&oYr0H>WLT}^80@nvu5)kY3V4vEb z9tRTe)TT!%p=dkPV+3HwlZ4BDNs`d?kYB9RLw@a5Lqi!VzWx>lIF{B2xc4$y$|2?7R~a4{BAe@N&}{OIHp_Co~3I$_zT#0eXH1p|$%uOwipP1i3b6m4g^eidNH6NFD! zNs!QVm0zsWRetTyHU!i(^t0B435cy4(_UYZ_U8-^!U$6?m1SSjZvp_~r#%lK1zUyT zV{@W{#Zt}DzfTwh+2`o9!NXwN>mAs=U#pP$c})pU5Wt~+mWPn5Chx8ki;BFh+^@77cXNDqXGcdyZ5I-fsNK@=fz&?Hq zaD8?I0fA{@<+S{IdWzm?k~vjz;2Of$xn|5kzolJ8M-XJp7J{P|s%6_kFm8dM2ZCa@ z5WEbk9@{Mh%QY$|9XO^e7>;*cLjOXuB7Uy@j4eUFFh#JB=c>lF`y^cX4N)EyP2Of8 z@7m%+L;g0W)W=hFoo_JsM<|-O!NADWx(4&1K$3Ylx5gDGr6z=YIqcjd9+E3yJ{+bm zVNPbKA^VY~5{!+nU^lWIp>(`2rXUmNC6cMbyqw4GQFCYklk?MfCuu=q^05@ia-RMI ziIKEv#Nes6%%Oz2A;ka(CXGTxO*EfKK(h^tK))rEVHvL)xMlx%0!AnYxXAcpilTf# zAdNE(hjSES4L1=RuZJzuF#+z^Pvjtc^pzT6P|Z8H+)e+Bk~) zOrT~uxg-wwVG@Q*Wi9{3lXw(Y5;brVcaHqPM1uTnih}3JUSvOqt0>@Ii(mrha5G)D zYJ=6qQwG}7tDuuDm{qGLF5NU2Y$ zp^QAFvj!){j4~-1{kT$=5fN`T@asoD3@Grk124lzHnH?XXa0Zi%w~1Cz%((_8B08t zThn_w1n0@Rhtmd-N(_S6CAj%vf5{n!lRFL@Z@n^ppWphib}{aLt7>B7Ze3rpqwr3(DNna42D#L)?~ zPS_0}c;N?5M1HjgA9|P&OdEP<&DB<+w(r5SDSS_Eu?Fm|)|zzZ6_e8tk=1XABg+oP z6o_r7FxG?%&6?#QNE|)RWVNx4-Fpa!JBU9#HF8pPJ4z;nPSCN26&G z%Rl0H0a_=h@vgcS%KZ2f3v+ZajhDqC2_xn74=eyu%ISZFs+ydhN$s>EsDo$3h>O}8 zF^`XyrIOGkUOQ56)SQ-Y%8?E zY<*?3nt0~eS%4Tn?1X~w!&cxE`C;_bH9u^F5cWsVDhEYo2I(&U4&o) zZraq%_rDjg4O+z!X$+oCMbl;S7_x!2AJ%7J%`^sy`Tn18f!|6J1J<}HoOG!sf)SYO z=~=A*ozC}vyQM1;9C#_iAXUDnH`u`1Il#c097vH!;%-X|t?+;~pM?j>WihFOZBBME z+@T#t;Nm4R+MzHDMLYU{s2zxQd=+`aqa9O19#gPm4Pccv*s*jQUJ(E`a^QvlFqCYc zq$u}(fQ>lb_jp?(q7ZHFqvgUA#!nqmeMgb%bKq!*oosCNA$fgFKXc2YBKj*yEmC~H zhPFaFKufED1mY_yzeKcFaUIvmW4L#O%o|*D#~m6jq|tzlC~*6tTZbHxaNXQ6T(C`x zY_M5cB=8O|#uu3LTy>kUY<~a`TUX(FI!p?1#g*i~AJU@eZoOWsH~RNhM=(xS+=f4S zNX%TxUlPJoxYm|0CYgKp#gkcI#Q7G`Sw(-40epRbHUWW2U|rvrU-Mn2oaRS%y(yT? z*e~5CHQmy+T1p4aY__nJ-%&wa z#){zpRMlM7l=)1|Va0AKNa{2WJ{D~B9>v+uE;<(+p@5%l^P4Cj;W!S5sVY~#pTwTpjTMdol z3)VQiRCl8Og}~h+uoM!c@a{;My&b$>gKL`Ep!>z-g0%NZT zRkP4iE&AH*GtsfI9d?qW96H6}L9H>v_Epw4>3+I(K$>&Gve5Hg#flY5?-I~E8jx$|?AJ8js{k-be|*fN_yQ6%#1-y@iI3Nj6stBgF8LK0cn^@L*A zT)FzJS|tFCk^v#(R={{}4AjQL)~g zAiHqvy&mjQC@L&e2#hiSX&1^xJX}UpLlu)3%Eyt*bQj!>_(Tik^whP5@(W-W3s|G& z;c;<&VwSDTYn6N><3Rlkfo)^?{QMZOIi7TbUrE^qo-G>qbX!pe*3a(%Ht2zo=!FNd zxQIKQUnOh#{v@uSTX+yyN?&3r!lI{^FQzg64%x@-3+#$M-dzYLu)uzD3{OdY>Ng0@ z;f3i#No9#Q-w*imx7m%4Li?fR5_`V*du>Ivl@&1paC!NIR93r6XbweV`uaHj3Qz3@ zB>QDY589fwV|YJnHPw>xk8EJ=OUewaxuiUucLkgkd^CyrOAG8)7L!@S(ZW8K;&Y`O z2-6%tu>k`#ryphqW))M9ifL3d-A0PzZD8#*XJAd5CtlmM$^yR?y0gZ!&^@^kh2vZ$~!q_57)(A82XchkmAA+FxH79d)Zk zjKQ%z)eufAI2EueC|w9%&0L3X&3f5ASdb_5GuD!`)4K*}2P0`O{>gSSa@Ca6#YF2X zc~1g&c>6!^(xu&f5VKFZk((IV=!eA3Ia*d|z`6p?rG4dUf33cMpgf9!|4v-PErjs@ zklxC1Oul>(<-opZld^*$_#qr+Y_V4jxM-n`;_zM5X{HHT0B()6)y#^?Zp}^5I&*7o z#wT)X=&5UN%{k>po(E8}_%rHe?BE_?1+NW9M%y&6;8||MHm^bDp&|37Ig;Ll>`f&O zg~^0&%AK;7f9oW=DT);Qf^2mqNU#2lIVSomlL+sT-O28eC{lQTi(mpCNv4yTHdtM> zaG$+B3*k2A0cTj-9BY&$;D%p!)j{@F3O0g zET5DKrQ`thet=EGMn;Z-*jx}T{80q+jf_)^h~H5}{2Zu=teY8Sat}^H`CHP8bmOm~ zl{npqG!jF^C5yrfhcT0s;~nRw6{?a~j`v?F@D|%wsHmw+^*}sA z{Ss5ckEMVrwyz*HG*w`1U-4fWXH~MX4d)g^mYotTpiQ@Iad5ke{m5ft)l1>pCs&w# zQw1G!?5zUE$Bn%X+GUR-w@%xM2MyJ{iXRf(E)%j$j{FwF&0C@y$ z7t&VWJUSD3NRSMBhZR-Gb|=OUPZRkzUOBo7m+BSAgl zI}=wbW*hi0;HwuV@-Ki^Lz2WEyFF|x8WCM?Qdup!JQGJ^5KHYPL^-L1iQR;)NjrA0 zwiS)VE?S6*L5vYW8;81RE3b^3*wGO7z~22t@wRl>B78NOm5R0t2}l%e<=0*~*CcRN)YabteX(?A z`p!$}MToxfT;sd!zn_9@+)csRlyaB-7Z`)T9C8bD-q*BuzV!LxeZXg?=sNcSFGJEM zO?kryTn-$AJ4l{|`5j?}0(Rr>g1x=m1{m-msl0xP82tnmUKe1Yx!dwAZMUVihnP%N z)t2qt(lEm10WMWCu&i3L&_mzCm%R6@Xn~-+oMzO>IHOdDs@fjDlzYESnZ?d1JxM9y z0A;kK8dJ}v-8nO7B%QA_Acm#OF;z{5OsKQM!Pm{V}VkdJvkbQL9mb$#X-_?R1!MllQW$S`hj_Crz7J#0or z`Iv^m*?H&j(gbvM2j?s(YjqxWOGA&3xt$z z$eW;Qb~nTv{aM_QsVFL^gJKgSAl?xXrP^>rK7>O;8)~T>kzl*2guzV-qe2q~IL|T( zgLnkEBa+M1Rqlugoh7Gz3y#Q7p<(8TJd97|h|p8l9Fg;wc>*``maD_HEFQ>N%H^;w z!EumnxE`md7ECM=)eiU@e@e|}VRfRv@kd$9|Eo#&HzbkCm{4GPnC)e{zkL+I3TTm1ZG2$UJFa|C@%333}DZCWqctkzpC5K>yL zcRWth*tHtrPePoT4A2jWCZg37nhT}4GZ z<`n)@3M9Ex_)#dDZML6Xa5k-n+p|ZU=GbV(-R$Jln$S8}wIY_U!PSQxt|Y8;uDf2? zMFaklP-Sh2!txPR+x>{4X5*Vvvh`K1?;zYHck;UyN@kmw-?BhRIWd0*RXZ~=Q>|)w z??Q^4wi7)#L3Hxqrmxc%lJJ*SLV9lx%~bns{T3zVpAmytN%@3@oY@%ixCKH=hV+y> z#gJr48Oe=VG`F;A!(Z5VqNktq7Y+`p8L1Zddeut>l&tU5pu76aGxd{BGn9IKnNN%y zF)rerTP{_~6E0-wmcrl+oX z*P9?4**M?F~5A0$LkB^;QL3K+6q7-axjGH7PqG?b#L@rj2{!N~uS? z@G{Z!F3MW|EtBYZ3%Z3?_j=S9CRf!9(*!*vJCc1BPZ7a8h+qP)_CQ8v@_jDKE$ncl{y?X_qmC{AO%~mwRMZcBGYI|Kzu#Z;WBZasng)`TCmM>;k-etqj z9&Nabp_eMu1%4~X|5@YFLS0NwT#OB|X8}*C zyG0%J$mwZ0(q-KJo~0`h_b7Zj0|y?pfwgmhfi*dh;vR)RSXyX>2dw!lJV-8!Q7oGr z>0%UXX;|+>Z?jgog#uW4AZrH#Sf_X@fHg&Q33*Y`S z&37V&zW65T-y1yjU&liW!X`>Q7$6D?JsxFEJtqNOJy3fll(hzG z_Y#n(K&||mxVHmK>aJU~szEAphx5vW9%v3H5@nR^NZB%^m zn0qT@^-6xYe0cNO5Hj4c>(VO*Hm-3lfe<2GHQ96>_b@({n@$t%zl1vz(D{QT>~NV% z(>>f=4@ue!aMogVe*y1T(O=PEHS$UO&np9d_$( zb;un+?F?5NyOsV@bEI;5U_>-7VghXOQMjaZ>Gcz^Xj|NPe#Z2kA4b$*IkDH<0X!s? zz_3jrUsicrpf-e37r~gg6CcTZijSXh$#e&iB)%x$b%v8ZlVplVorl7N;!796u@b^t-9r$b&%*|s8)pIeOvm*n#1eQhrFVOW4q3=havD#c&(D>vNS(hs24^WoytZ! z{eUU^qKB|>(J_AZ1hAS(%t^h?Q!p>EWo5Q_&thldr)eNBiS2m&CKc6vZ!v-iM9#cp zHv&jx>bXmm@kfy<6}t+2hz`2-L61V7gFRApx~*tL(CsuTs|DQ_7_) zfN#7r+4(dZDt4?dV3?$euRY5K)*jtqV9n^xv~vXN@MI!3~Yc&@;o`XvbH0>0~YwLFo`vug-OX}ajC#&ICXKUK)Z68n}m@&T@_}bg@XSC zW48kf1y>_)_)gc!yhm6V$ET5Z{3mY7|7Dp#NQeJX%LGFffuU~^>fkcL)EV=G&}kOi zIR*znk0wwUW7a$zd?Vtuio29iiv*8oSx;cU7r3~&#Pm0vUrTsHLa+3-gd3o&buD3n zfJCh&$ge#~Nrteb9>0y&MM!KOv3pHI53ndtGW1F+nn>lG=CPW&hStFyjl+epO0$7C zLo%N*u+83ZZTY4WemzkoA~HLoJX$}x3}}6Xr1Qu7+6*ne zK5OmTbJngE(l_KMe>YG$IzUA;2_RcqOf@3@DS@WhN5mT8JnL(CCJk3pC~!5iUjrGx zL~TKvDA)V(1jJJfhCdLHsKFq=o**Wp*$r(dM3n%xAe88VFmLTzP7O62<~@AVn~6dX z-}DyM2JLfQGGYQtH86r0q#78%OQ3IPV8lb^`LbS~0xDlJK*f-9$>0zb?bu@G(}BpL zV4xP^qdCVC3U5JvBx$c-Y1+&G%VK7YU4D^ek!&!}WChGr>tg2Kz_jqD^kU`>3FAvF zW)4HS?kr{^y^hgh=2J5+W>yh3b1{=)8!unTz=6FcAPHbGb1BH(X9FN+@Wu;CZW`?( zlEfF~k_jh$Cdm|!I$z8b270E&OyS8&8PvjJ<~yM~Y%%k1@QD^P>8WdrnNO*^`{80E zx1NUs*je`WpQ+Xz1AF^*h;1xveo{4{L(JhV!nNW$2k;d)Bpz8k0$I0Vr^jm8`>}n` zp51UcQ*+$eyk_-LSmcDH+_31G=a=fy!sR-=$Z072wgHQ!V~s7FHf&f27d$maYt@F! zmO9rt?8q|QBUB$}SyI_{U|1ckm*KX_=J*zWZa51048M`g7o))_EIg9xg3kdYL>o2Wf* zYtN3_A8bX_qPCh{UKuAjILQ@l6YsTLT1`#Yg;X?M)ZVdywMXq4STkyWN?&3x!I(=Z zWpb(Cf>A4Reui$ePL3U2$6Ew@h-VAULToe+_`%m^_b#(^FJg&oYX&~52d@=cRvZbRD{8>Ro)0qHkY+&vDVPH-Eq}cv)o~4CWIK-N7 zkwd-8mkKeZM|=~!P%lgt?6&kIf(4gnV8IPGuyz(OuqF$pNht+SCc+g9^=c&A`1zU%i_in zn-kf^jU!s355rZC+&-f43vC~{7u=){Y#;d;GJ$U&nL>dD+C=gX&_xzs^zPOI{9<|f zecHQgF~%6aF|ZdFNX2#E`61W`PpK~W$x|L{5=vS`lK8<=I!01$=9}ZAt~y}a&*MPs z#_6qi_^8@kzX!^|J<|^S<0nRW6aDCp;x&Zet5s{w5`?BOmIc>%xD>_-mCwHjn z79A|Q**S8wuOEzP&{R1ch5_6}4S>VN=5%lh4g?I~5nG6k^+~wFkIufaCeUQaEgytd z^)48#>y5D1A^J8}uR7NmVKhOtb?k6#acpF?kvjrCtW;{))kC#NW>5RsL+#pxG(}Krr^5ck%7W!dG$J~Nd7*jl;kj6`5in%EU#E* z2YY!9I8y{yBz_j~Q)=;G+ma9_iER*|*uknxmb)kNhtKA5RSaW#BW> z_CI3an^wfE0fGWNg%Vf zV*f)#YZZ^mcXGekoh<5&yIvrdpi>)mlyvsLc6}$KBxMJ5;`m3#1?Ao<$>mFuUo11JzfSy~x;-^W|KPAvq-(d3@ zC~MvA_D2E|wZTSyox>@n%zR(I0z(+f>5Ee4Jy1&q2Nmsr(kfrv0^_{`PFrb~j+#KD zSGsWY@RV^uOmIVjE#+XaTnxrA7_1n>`vAsgP9DZfbsD1)q)=X{h>RZsIG;axI4{$2 zW^+nmt?iO$p8|OAoIJb@TI0-DSZlP#4*{HSm^_@1*J(}CNg=&R8z3mR0$4wP@~~d6 zW6edV!h4Crn|}*n{*rEB?wx^9lVqNOIhXWS%!L*(W&53-z&tvLfdZ3ntNDF`7Qv!? z$MOH6qKP|>FNXD7eQPPE?**65J?xAYnqV$eot)dhzaJf0%}d)?X1mVHqpSHY2~#B| ztPuYr5G=HKt=Vy@l;MX7NR%>^Uss9Urjb2UFR_iF+YHU8w+sJ+Zmg!oYGYU?<0vQbU5w zxZdZR4aSc(ZpH<%Of`spnZSeWgXltYp8!g=VtEMeY<76a22W1xb8#~n1jFFDS#sqT zG21u_?l9m6e(<&ABvJ6mK*6?UTOR?58e8(~+6?`ZSo&FN!5GBW^f8!c))9^22%`&|ii$`SQ{;{2riu_-2m)uK#5M@woAXT)k}|}|7bPH^ijhZR z87aR;pK_8o#h-*iNIFZ*lTdTkt_4acJHxV_;?4kocoEOdiD0X#guvkhx@I2;mxu+N z2D4c!ufRyO6vd8Y<> z$l#ZIuv{B!zyuV_elYzY{bQrwIKFzLTW2@01*Emw4#J0udSMQfY4r{mS^q@@jGBY; z>tI1sIbETI?3>^HwqTrL&vXrvN|ry~@zHjDXonUKyM2(S4lMRVC79+gqR>h&9B|2m z)6Q*xRR>=RLqoN(Y7+}r+1U;pnZPc%m&j(%TXuf&ac21n-)Dhxm$^k1NmE0j#>H%xTjM2&yMB3{Cawt zu1NI!RKSpjb;4X9K-A z%+itxJbVp`ld%TL63Clb*L+A2L5(IIM}tUJvtB4yuvDW`Xq24tuv4vJ)D#{YpbBdT z!5A$%uoK9wA1XIoXFCK?*{QZe-PJ$knZT6h}NQ@jvkGgmP~}sAA5aJ~|G!ez1K8rbpp@6`J=x z1$eTPyr0G=I>}2}Ys%0~-L5^0h(n}7(~|v?1_Dj# z$0YvQ&)%xOdygWRz}egBJf2b#IoC_euAk5+rJy5j!M4E?Td-eu$)V%uALeeK#YRIU zQ1aZ_eE}2xiacb5AFH^H0XZ24a579FF^0><313??XXJ_8gsm_PZNh#Kdf$Of*b5q9 z((p~#Q(+R)?(1*x0b)(zXBZ0pMMOc!LIsN_;Dx~oaiQX1Sd}(u$-TX>;kqg`6EZ(ltVcCr#ryJa9XKDd>I-ApG+{HRO4!vwX7z5!_ttWzl*%=g-{D5LyuN&{reT^ zyS}Uav(Q#(u4xkpH7C!a`WZxPl^7#X%lk2mA0f|~QZvWJLcxECMS@kt92Ij1DltU83}j%+5< zlBO`?mf{l`arD$R6X^_opBlyqV(cO904iA*yjG;~;~zfehJr*XDHL#`=rSzv50wga zkiy38MQz(!>wtIqus0=Yysed!btj#KDk?BX(w13K^0%DwByBE`xMw$+RKLB=2qs`M zEei08$wV!+)HJRamDMEPz+Tmcl1+r@v!R8M^tM|{&$1QO1ifx4?Vz$6QuFoU#ZguW z&f#B~83<;b_-#_PY{S5gtjiEkC-tXo5y0We1bfH^)_zW(fi=??Bxd-y)dIhjBnGVU zXc-)4Kyq0$Rc!;Vi>B%pAV;LBs&EOJs;i-1yQV6(ElgE5xyW8R6JAG}s-{J9lG_+6 zjJge{0cXz35Tn7NT7c8%>I7h15jpa_k71jR_m8}3p<+!58C2mszH$auVz)%xD^ZWH z$(6I{DJW+tT+C6z<14Ys`2lE@MOeOuPo$jbDMC4W3}G+?w5utX_4hk@IEAi99yYT{ z8X5Fl=`VsB>shQ~Jw_&Q(@&`vi18jErV2TfR_oSK&igtBL1v=Dp71^l&#s84=J;Cz zEKs3xZs|k_xt?@AwQxE>e*?y1D4U~jMm_6B-< zhH2pDN^8Umf97`V0XJOP4>dr3g`9P~U*aDvj1tS{QVwc7CTkF$?*|-OiyVDs9uVyW zM(hi;$Pm%pU#@Y19r&mBrP;fh69weT)dnsdzK#&vg4;|tqE6Of}Np?A$iY+F*K5t%P_5D!s1FZqddkM9h`;L_?$EjYrRGQlR-K2=rQvE^#p3-pw#?L3JAlp6 zKJB1oOlbp!sE=9Ssd=D>m+JvE;9LQcXJ5QV;&FkuA>vGzJuazNn(HqBFR2MzZ1ejn zwV?wOcc|(6-xpnU5mVf{vd;CvHdtrC!4;4p;kO7_J4R?jZvoDk(MI0O!2*HOdm!ZEVj@B(H-fEUE1gB>0#a@dE!hgwO;$6Y`{Ve>GDLnN|S%bn;_qJ@v zQg~`bI6TEjF9KH-C1mj__Q4ELDQx_DN9|NnP5e0Q-6lyO2BZE;jmTR8AawB-{F7-!-Xv?#i2Ou*Bl5)Xh;&i?G+;|@C}hgN zm}64m54j1}TTa{1 z-YchrBgc^TN{%7&OYW7!!RD7(bYBTKv)?0YO%ITo1Pkn$>(7GQl@<;$WB7E&o0009`veIgx z&6QKjwzKC6z=K(6|BX*%q0v*wLZeyVfz8hg_Ety0?{SOUNSyiF=^j26%mPu;I8pZa zdksKvAs^knx25k=IMN8AQ8-*(DpZRV*QvTqNb7w792atHzz^b2{1QG$rUVB9*adqc z45iNJWD;j5!U2$U`cP~jKykKA*6MKBiBmi}f@fz5$&HRkvp(6g?9xn8#XAeZ1fEZIaD$+KG*A)s!{x+%dOrT0A z&|%-+b14-~cR|dxHn8^XJq)b5y=QguWy0i~7fPa+?5Wh_Z+-vDc1Oq;pfdTi~z}gwWz-DB?gBJL$Fn~3lg#pQBF%EAN zw_UXzQHMm@jtZNQ?YIc)wQoCO>%w+C3!Zs2c?mv(Pu;TZC;))%$iRYgVlsg5JBzm+ z=N%Td<9vJ~+mW7PZAaBm&U*{koW8Q38WUa<-e|E7{hN;w6%p`|MlBxci{Bdd2@&-; z0kQO;0U7nc*4P`J06BjS3k?81H=Enj11J;zDSxPu%hUWDJ%-RgvYJS^GN z>P0w{I_g%7&%;M z09h8oif5o1e50CKiE9YhOcTsF;ETT7HL$3fjqBXI3$0<#9Q1LuQm&Z^O)tX0{@3$I#uysY|OoW!uuTjDR`y%^y3EjQ}Eutkbc|= ze+u4(i|EHD_*3vcw3vSUE&M5XXRV+gE8$PU`z`zNDE+woMEY_Q{3&?%Jc)k18~zl$ z&pY(v6Y!_ty?HhLcrE-Xkj4UZP|p--cQyRL{m=yu*P7r5u0IuMQ2~D7B0zz(F8n~< zSQzu?V5fOs|6g-wA7e#zhH*f*&0=lMDv1VGmRlA1*aepFvevTfB6RVt0#A8Lo+)<~dj< zUYeP(NQ^Y6S)z;PE;uC?nrC5?p?~HjcqHbT`bj8FCmw=T;-T3^O*GKR?OE=~bp!ZV zOUP_;nLz$72kPD-WDrlr?OND;SW3u%ij1M`;K%KRG&iJ$F@d|P0s0Ho^p>ySlSmSG zJux>e#(LswT0BjQpPqP`79Z2%VOso4i+7&*=80#X_~nULp7`X6N1piOi8r43;)y4o z_~D5cp7`L22cDt+v}pGXb>o*nkY}hjEm}Q8ooUhN8S2C8%o;g2x-XYF>At+XrMp!k z1pi2Q{DsjX;nBnxk?`nYNy1|Xqea5wyNnhIkC}{-r-;W1o@wR{Vl(4LN<86Ap7T_VMFk#-WsW{+izrM;Vb)l3=`y5y=zU3=szTw@Wf@4!$BGhyLU4q1UA{S!McQK-u1(D1#-V=Hrf_msj9Ms>VP z7HC$^G|DoMpobGK9YGK0uaxxxv33Tqo_KUN@FcNw4)8N#ex+1g}8Jca2YW~ z>?gJ^1O|wgh*yX|ECT*Sys#MfGcoBKK#JH++(n!uP7?=~01py>zX~`(9K0GhM7;hj z;4R|BQs5I}Z!>TokzNL@CEjfTJ|YUOzz|Wp9QZmh<{F@i*hLhGWh;Oc#8bp!V&Y1m zj@UxviMNP%i2J?`JV2z{fT_eb;ufM|6)=}LM!ZT~axE~K_$To%;%FK;M%1}6H_+=Gl}or40I5?i9N*K8DJlg?gZ8l zFLnVh6DPk9oFZ<_0vX~r1~^Q7Mw}t~dx0$kUui3^_nMKDQyp# z{NUdxISs;a#zSSj{Hw0_i<&cn%oH^QIT^X-bF@ru`9?}ibW~Qyzv}Apqk1(C26if6 zkNpZV-2nQ+F@GFUj*H3wyJ40~a&rBJ^X)E)w4TquIg1`Qo7reN``@tJ7}oQf92k>py78-sBb{>N8hn&($@ zgE@2v!>^-UOYq#ckt6Td zVw|c|QUz_IaSr~eu~Uq>!C=rgGH_vJVEo;~x~zp; z$2j;y#TLuKKBcPknKcKIrVZ`~8!Y?S(Y9i5gM)XAH2r1XAyb>|d+ zf?|#3;?I?;l4WprF=M&N)P&_?#=%AXs>esL=P-GTIp)YbHF9B|y=9DNk0?f1p8ZOx zDp?qJ&w4G-n8dL>>vix|?Urjy zZdtBvcW_N_iD2y&hY2FTTv{T*Mlnvkt;n~WdQ+(?**kZqc3Ms`db4<6?X|imRF0 z2CzytiE-(|9nL+03zVvo;dOWEUdtt>g{`Q%*TJQ!k?0C-HAF`)GRf+l#@F}bDHr2W zgCg9Dq!~(8$+c=8$W7c9e`QL4(2Ok%^%9UCPc%|VRj zaM;uwK%w%I|H4;fLK7zbaHfrno|<#8pWwoI756f^?Q6(%?n4pFz^vtv|Nn>PO~r5P z&>UB)%E;L09GVV{tjVFd0foeeW?PROni?FM>#?7aho-YoQ=F(4Ch;Y=uN|{stbJBt z+6pAWw{l)&mY;e&nTXk<>V{nmdElyG9#~FFNy+Z zl?x2Bn}ZHAC%VhLSgGnP^GgY2E-05-x^&nd7 zB5zlIxh3)^N>yi(%?U&{mWwPNPma>)O7B;GzNPelQq@`Mssu`7E=Zx$FuU)d_E|-O zrS`B=)md#v0<}vjAJ>Wx~XR(JyT`Zds4q^`}3M{b? zC{>-sK9)diOhYLO;d)sW>7e$viUdpTb4pcbwNEEd8`Ds-)J7|29VEY|=&&RYD^;B( e|2mS~Svaqldy&Ol<1<{K7_8-E0`sQn!BmO|$TydR7yqmny}&Rc$`l^tV%TuT*h! z!S|b7tKgNKYWTUm!QNd-1%b0aM6i*3}Zv9#7JP{Co z{pKc9ge-Ua8*3(L@S656`%-(IzcHY2)?Z&KRjuZ1W8U-!P0y>B<{OkXak8#dbcyOs zg^KCAc!=K{s^+rzwYk`+shfGTuvE7eC{4rPf0 z&G~xCsw|k5g6WLa>P{IlaK~zR=Tyzg*h|iyJyo|nZ*>gPa>oRvV+Gr+E?O05F;{oN z#-5XxHRkOtLgq?nJLLl zYVn}I5!5y6rKW$Vr|M=9o(Xx~=$Um?uFmLmuRszUO7N2rm}r_(2YkV&DRm*_!(Je@ zSo8-&sTZ3kFAWGB@{jccPEE}HLMQdS!|C7~TQ zGE~5n62ARjJt#m*^n-_P<;qMRwHTZxT-zY-0>!=@Y9`8EiKgN zZL2raG#;8JV#^NM>d_vJ-`r}CCN*skT!u=Z?9rdFJ+jZS5h7BC{O7jAh9;%UG!>pa+>_0iJWMv@jI~Hk zyh*OOv0yeTo^YJ%jcOH+lVL8JrK;;0rct4W)-acyM%6Q%1p~ga=Nc<;)r`5h+A7@| zqod2Kwbi+~R-5zWvz*|}Hmkh-(n~Hu-9*h+KXo9H1cjbFtN=u23-|VL`AROay;~kw zuJZGdu1DjAf=J2WS4sZ*wO@c&tNqe7Q?M5*WN5$2`-oi-vnWiMBxuOL^TME26Y+)0 zQHgE9-&8?2r*2ksmvmQ)hR90a7SS9<8oY$z^0AbPhm^`QROw-@4f&VmR3>y2zRPC6 zcOm^?da>mHl{Zn*+`}c8t1ByxVr;f{?X9@p)3e6|LrcMDqbZ5SmBo6!929u2^!-`HD5Nf6gdXd8ELotvWTU z>bmH@R?*d+sjbc|JH?r~M!ixg%}>o4=-O6|(t=TfiLRH>^+m^c)mSmz>OPNp*%L>4 zYAYs=psf(H3f;)^uM&qmV3Xc6Ex#U#A%X#a2M_J!!_JbfCeN8m;$GI#?u3`BrdVO# z#-+5kl%y~Z6WPO(Ao7jcNLS_EA&tuE5`Qb|riex}e;(ZFeC=wfDCVjBFF=ZP6U*-> zx@cHy$lnyyr=ozl`(OfhBmR0W&A+U++QeAb>L>uwv|^(+(n`E9AqPDv8)1w+HT{8b z)Cs@APSIJ0BhV~=969)#@W5NGVVG|nmF91u+B{#YlnN!U`7pm;G3!$eq$;tTcDM@95LxnM6e$f_0p zFT}3aiVK3WH9}PJuT2pbNXJc`~urvXSh~p`IXzI&LI?LgWQT@`xno>4)Bvm7u2|dasV`DVaqV91-0A zo~0RcS||GEQ@}muv`(9lS}x?bU~oYsK9zTuwav>wvBlLYs}%KuPs z-%0Fha2Et+gZq`JpdViVxIY?#Q+(c!&Glh!&HJk9H8nB^x@@_Ug*OGqd2B8 zXJr}JUa%6bOB--;xpCK318fJ}uANWfp;8a0*B zfRF|SQ%eDR2@S}d#IB}Mf}m^~^<0SSg(>37(tw1sKiA%4E|F%CUhudFyzi=09d$jk zXx58H&8cI+)vh}$u5nh3yRwEE*Us&on(oQz#%IuW%}3oS zNr3|QN(?^Lyro-Zj=c+y$sbiFAj6-<~V z?=Il4Pvsj@quD;B4sDM{V0Pz z!xtH4pcfrR8K^&>b(8^f529Ze87tOiD9RrpR1B9tOn=yy%{t2Pq3{bHW!Tesl;Lf6 zTBg^iTQkP(CAU^FSE{#N?vj6z zvufWa1IM!OElP#eydp`OD&IEmL%QQut?xPzR&83NfUMdy+0k#MuqUnBcc}7uayh6V zY1IM=^=;Lr6Rg^F%&O6Spx(-f|7&7bvuc8%_9lnY%89S%LtLLu5f`PWKI^AQTy6TS zd~&e^BMwm#tu##O;Ex0>y!$Pc14DUoi0CwG&Z7G*ex{_a}y0z z_Q{p-qmOEYQP=G#fqFZa*Is8OsE0@#mOs@+n2Ho`2zTb}I{=jQge&N`N#xw5&rAg6dJ zxl9d-?NUJC$5`OyCoviz2ZsF{yATyq5oy`VFD4iZ|Ks^;1U*sGibihSP9)U+Ncp!w zn;31zcY; zN9a#x|5>)&d!u9w_}hXR-28k6POv_a^X1Yq_w++O8VnxDae=|XTf%oa69LZWOwSsD z<2>)U)=g*Y4eNk`DLH2)Uq!TR!Kqd;=zJ5xS6yrWV9^p$75UIBcSrWm3>x@P=1+mF zBm1Zbgvq+Es*ED87`f*_s9D*!zfD?-sl{Mk$(8A(ME}3xCxikk&66qE^|w;A3I(Ez zS**=;Tfi-5&=%`Xqb7pCQ6Cf#(=`2o^UIYPw`Njg`(_$aC8^_Q1(DeeKopVUn8&xB z>J)xCH43JoKyp&f_Yx+>eAe|5pea3xMlX$P4SS?VN-sL}NU86atw%bZJ0t<1^+@Sy zD8}*^g+~2hR~m(w_wpZvUvQ6fqH~Y*BXYdwOryq{H75q6bK+0UEFofB`L`4npA(YK zIrYV{sWD7@*UkDWV&y63F=uaC~Y3FH{Bt@Vh;*G;3~FQGG)$y%k(494MHVW+z5Cd$Py<1_=^GGXv5zd&Nx`cSXvSU*H)demP& zsJ01K2W_;06|fI^O9M-QjLn4O9wp9XRKQ#NP(U>k9`L6OXO9ZlG80Y;sE?KleiIb% zu9yM}in1x-LC9+~MP6+cuzeBno(JipJLPb>n?tzO~SZHys?o^19uirTxWDMv|A_WVaV_++t8MQlZ*g3_UU~Vln7NhrS!>W>$-lv|4RkU#(Vtir5@3|5?aw z*4e~A4ZmQEajc`oDBf8*ZzM$31+l9)-!ze%Jj}LZqPsO+!Js!SX>0Li3eP~Hp#`}i zTVa|l$@&Fq=f6SLkZ)|(qi0EJHU(~S*m`hy4Xu4E|1Fo-9`JJ330l zWl_3wuR;I_rozxuvL~?>B-|xvnaBG%@v7MqA?s}Rcg|S`{$ZU^1)V_?1G!?+ZVmfQP#jrf(I(qDd1OM3dt@K6!e_9a z822YRDbd{*h>kjBxAsq-W@au#Zjk30mb+#Y(K+i&1j;NT8;#!elr5RX2U2QUn#BT% zt|wQE3L<=ws}=C43}a87Gvt^wI-)xtg1^w`P~%lg#II%=1B#;S#>%spKMTptW;bs~ z`g>D^DeYz_wRs!ivWp01ibyKafV){SutJr$q?s}Hkvi?e#PQy#qus^ia^r)Kpg;TL z`tvpdK``Wd-vy!b>4zR8O0j??GT(U51<70rfpGqIt{P3V5MvV)*n70cp>(PI~6Dp8wT%$to|rPR()WwOZP@#ke!=227gW!)gK1`nfZ)iuwM!pgE8M@O86cd zH+J?)B?h-6T~8R)Jdc34{xF#Acf__K?M!5%^lr;a2A zP)<@s^@qWOjEOh~`=n4{Fd7UA4#*B3~j=G|3Le!h2C@ z0tW9UUNsB~da_~gC6Lv4imdvugVVjZEYnE~PHn2F{xDc(K4Tc{mqNzibaaAj3ips} zJw>k44!)XL>ji@-Mq)7Ftv?Jx@Cj{kG$NOHOTge8h*u4Rf}U&`JONoPq{yld40aiX zAll-@(3mHvqWZ(&`qm!{ABK z|Me7E^?||ZUNAVFgu%g0ePeJdvWQO;P4!EmXp3VQoMsGO!R4jgdm+dB#kWvJ^=Aif zWjqZo&=hz}z~HYFuNnpgJ=rig3k-TGvg!kaN4uN;6n5|^ zO@7Ah;76&V`orLFF`qFE_DdmS@Mv^yatim5>!(uWDlzyuVyzbpq8O?h@&^On`okau zpU@V^=TH*I2fswTY8VvsWW(USp#LK&vdV(N>uJ`_#q2y*o?&5-GlONTr9~UNdD5;) z`0d$PY8408(~}JxPYX}D`TklFYtxDbR#Wh# zX|M$_wu!1+i#V;ps^_syKO($vjzFFF0&ei;P_#_PZIQx1C@J)tvl0(yI$Zw84D3qr z+z0XeG(-9{@!WYE_RlIUtU?$SA(?s0Td}aa=G>fBrF}WE;+Ug3=EC*MrC0MqY@l)c z)CrPntC)6fR#xbFZHv(6%Q_?irtw|DlTG;(pN zClO(CB?3k|69_ZSJZ9Fx(hamD}FG4!A*_P8tzdfBC z4lnH#)^PptN@=kQ>w@E9XbYBL2f{|F;(=}v{L{LA{kkk)Nr`4l915m<8f<~PQyI9E z+C?qJ-5Js+YFB%K$AfJt1WU$_wGWQd$GRfHaVZNWDGV)3aNKzAXu|P1;;EA2ijZQ1 z{&W=_R}a77;JBB9sxVT^-*!U8h|%8cZnywC_EZt^WVru*WMRZNk|4!!k}U-YmYGXc5g~$IlcK{KatjF?^UcR__%cy_q3B;qe`z za7fRcQ#e-y}$q7#qzUAk&gE<|P!>X%rk(XBbM z@fg`KqWo0ACb+ypwt=fS>k2!cuv`@3+!lU4p)R}IgyYW=a>%#|$G7omf17Y5vq+AG zw$bw|L-Dq6Bglc57^n1KNa0F4{GHT(@;0Z6=C|QAT;oL5vvB$spMx=vW|@sZZIu@F z8f&nwGuD2N60d5kUWOBW9VL!Wu%l=^_)s97H0E9{s!q<_pf~5B9_LrL-u1^ zq!6W2@fVQba|Wor(R%eaWRrkE0v38h3R(eti)^pqY}@5}7;#|lfDTp?>qn{uEE#d} zri2ri8dV(j!KW{Ut{GHxdi?s_V7QYSop$M>18RFX4TPP#x-;LvflXCsrM1^te&)&! z4fYnTOjYB4B8Y*j>kge2OX*Q@{AiBDn^5U=tlX2*dD@ID4n-dXIFou zOu*Nu@Zs`TLmIl#zEZUKSWj2ezPVHPo;fRHv^B1|mP|seFT95|K42dDprx`bz19fwM!jU?>o5iWNRg(u*wgJ=Y-&(Dw%F7* zW^1tzCu}1&o};HqU55u*U7tsPx@xh9!Y{bRb|NkI&~faYQ-Utid|#-h;V@ad*NUwD zf~CM!S3&-gyw)~cA1`|gCQqn;iKU)ZHit&{WOg0|@t+N9k*M6~I4S8Mg(N%OyRa|`B@ zmB&7tw9)YVDji!6zZ*lqp`pQe(74dt9-5rR| z-s@g6Ne)dk@PqDA;CoVdlMc=Y3Cum25*7Fn3a70p2~sFax_2%sa4}uXNi`t{55VOo zGjjPE!R3{$=0xNzT{S^xHj{A<<-aDS{7fc;<|#}Zu(?X(VtkYajsda^oDx)D4dzD3 zR2=PYp+C3rN9mXhVJKjOJnT(I@F{_4&S1%Z>K;>D(v?Jlqcl~WriI+0w{#7X24g6roV;r(K&^XtoRx72h~R! z$NEz+{=%}68b2GY6nh0X~|l_>+rLCq zle$m$Dr60Sz2^a>?A{XV6p&Hqx%xDtp!Iou7zGYvznTk6?+{#vbZEu9Hwr3>J>aW@ zQE1_ObWTAlEAU_x)JIyK=uaW#$&8H82*wkPf>w$&3W9-bM&UIeVn+%QS&YJ?cbv!W zGL}JVDbD1kt=~QDNRGz7)|khE#}pmGMxY0GkmHnv5hyL2)ul$o2_{pcy{7PGk_mX$ z(ntzFl2w2jn6iI^T0XefH|h-2>@ zBIBdgI|@xh&fW|%rvB}tT%S>`?OpOpYq7i~9OFeZELQToCj~rGYdl@o|(we?6yx*>Pvd zaqUu)5!K%(>G3ZO&7|Iw5dmM4MZg;5qF-mK9#Z{pFfwAQ-^1XDs5DLWqup|GeC4-O zU?^4pdqNYsSABJMWx!Vl)o(qCop*7kqRnDT777zln4-L5E85HcoO?Y=ZvkMbI+thd0 zgtu%>{m8S7K-LX*!rKyt#$A`4hNK(XeiM;4Y4q-`t$pe)PdwM^K+|Y_YkV~3yfgmQ zTv&!aHPZFcr`FEc4*2Sz(Jh=`gvNX_Bf~R-;Vg~0AUm7(uAzc=q>#{7d)pTgj|-w1 zJT;}RzSBb*4kw?-AtDYshBQ#{K-Q23Oy!D2E8)p#RKTQCjq*H68Yh_3pRPh09t^+W zkcPK+jvcTtdq(chJOZPzxT0bfmguinH%k?I?p90}#|5F!(&dgc!C^tXX->=h;xkw( znWlXinN;G>{t4=+!N}E|4a5NSFD-<8BNvS%zD04b9Z7FPsbsSg??C#;Qy9x)C$2qdt*$tA%#7DDjpkVO0`_O8@Ln)r+=9`h z#%fGS%TJS>M9Z7y>yT~nA+}J+K(-8aeizvMPKNZfZmN?xyz!QrSu?Fw%n~AUnO2Ts z4O!J2tytAX&!%|cLPKmG&>Ca^!tCElBzE(OlFvVpV6lfn27aY{-i`D>&5%A(KJAef zclxMRl0H%LD(~^p!=w66Ug0Wl;gfZA`pCV?>hxiBKf&qKOkVlgZ7fBD{&eN^?FqkN zr|&mfojxr9?Y>!Sg(j2^phGK`X%sNpRS`4MbSfJTldNM&BKdz<(P5s0FGyQapkK@< zh8X5xuziU*mU^b8lX~hxmmno~;WJhcJ|cvF2!FCJ41XNhn#hozAe@U-5f+BG_u%3X zreb6bV_C`*I1+UK>v8b&h`qu86;TIj@-XpiaCPYSLZgcF!kwx-@_VoPGNle2iHMJ{4kT;X!A5UCZB=NUn}HKIa}(i7neoR;j*kdAzCGkOOISZ0 zmHF223%1g~*=nWru>Kd`4!Ra;4w04wxil5w(AH4c0Rch7MQny3cXVk1(f-VzN+@;l zg%ZREg&^LKKb_2(4ycbo3{PZ8Pk?$nBChCG8fWIzUK)e8Wfmb9j%&);)8(MKanTLc&W(`g18Y5_GYA?Q25_z1d5T>!6y; z{0x_j{^({|4H~iP8E6zKm2K!W67g}Q|5OT3gvvCOz4A6_-aN*{;00lek~v<}3JY#k z&~U&9AH>4e9$?4Q04;EP;35_l;BLs@9xX%@cKi)Q_}@k4sF3V?E~o?~V6R9Lt43M! zd(iiHDOD_C+mZn-NbU`}>O5N^oNRdfZ4mq26k@aBaU@i21LvQ*A`+b3bc!Fv69j}i zSP8b+f~|cSKa^FHIlXEOF5k}H#ZLUm+8BHaV%eG@eWIGSmweoPrZz`5y^$W^cI>)G zE&nJE;T}cHuQpqdZ=_Gqu@6Y?cxL}19Qlv>7uw)Y`G}C@A^Ou*FK{yag8hq6xB3^F zcWS9+`$flcDQd|!0i_iiyAO&z7=^oG(ke*AGST1)wrBC2f&=I^s?_9~gSXJ|GDR(x z7HFwt(ZZ5=_$*k!Or3=mAQqpAQYDHPVuf*((S>JHnX2;LqU!F#pR7voS)lXI4CzS; zZi`fKSA9q-M&hG`66oU~Q6lmk%KJCP+WNbH-Ke1tm3=7jcT%XI+wtGVa{JoilIWtpqORVmv`d z`!<3gEIYZM2i*^)XU*Q?Ya{6DN&~4F3C<20sP}TC8ko|}C8TH8!0|02L8wJ3)a9dcGSQ-&NOPY*DrN%mmAool(t2dJ=_|a7&$0~CguLqcjt_= zFyQdVZ?SQ9v1@WO)H;fC`-R9=g7d;;raYyu3Bi69f3h|bUq(gzNrv>)NPH<{c<{oI5pWa&*M*18!+gBJcaVE{$M*6K`gEf~;!!PeQgHA^ zE{S3XwrI>KeT+T^1dc;Okct{Un7tUB5BV?5E>DfxZoUFDcQG^VeGfU-kS$y8zS9WA zo{se!hT#ZNW^-r$9Ms;FLM`bPDfvtU#L*$v<8!xCEIbW9(-4?(Y;TdasVEhIM7IX0 zTJC5tBRDD(xg0CwqDiMVT_|4|B2z9?X)x;g0O)kDrG%Otp;D{hZP6Ft)=80yti$-1 zmVaFq-ox6ea5+$v0d6f=6rtVLAA%;4He1bp1L^G)9n)eI^MEVQN# zIVp3p;qtpPkR*NWZ-Rw)W=Nk1&h}D@5BZP|NCVxz1=5dmjkG}YBG_d!sRe?qSEQ&p zD)bR8R~tkMvy?AlS*}yf>&eSHHR1k7*J;qKrF|ojbE&_*(5PddY%d=?pY^xOCy3g# znzR09EFh(kK)31d!d{~duT*h!3v~`1DK`C$FEuNe&22u~3?`Cy%=!Zu(Z-(J*bEZi z574O{u4gXSaI-}elSkf5xE%~`(LmvD8wP~(WFY7*irWCX>Z?uv@&(87h;!}b$xHoh zF1Gi@O1S)aj9D%>@nk#Aztr-yDjuJ@$Z}Xb!QdP}$*xuU~AnX z9m`h`xKL@Hyv!f8%}RK?!QW+_FF{rwjzn-}q7D9rqJ^ke#L(LVjufEdGdl{cp)ML_gYPVTLq(h4Q#Cr zi5GEynN@B2yX!P=SIieJY_(iOF(sDtM#LH|fK5oGRLsLiK?G9M-so>P8=jL_kNnF@ z0M)i)W4V?Ofd|3z1DY?XSIr7l-41>N=~i8;e)Xv4T8*NUKfg?n+6fm23!?M-myD8v zmp@l>O9G-h^2L%%aVcOVpmLK`2>V8VE0}Si0z7buOt%He@(ZO3n0v74Z?9RkJa`gY z&J!(L>B&4sgmETKrRj5M1WhQetgPfj2Ox(D{js8TZVV~iv8MkV`hs$#FY=y+Q+=Q~ zO@A|1FJaZl@Q1tBP$<6*A z0BSiO>Q+d8-mOvfKI{)MH6=99I6c6r%3&!0c}v|~32&izJKfc)XP(c8fe=l9eZ{E) z)mvSx&GYg!n*dR*`MddE+~z9|T6-bEJp~&px(zX+AY`3Q(Ww>;$boI=Ghm-5y!0+RA(k%Do_ zBCPrAus?Vc-iyCkSOTaXP*kd7l`QhkdkFBbU|CS-yHF5N;lUt6HbrZJ0zdrABTs4b z4StN=7Q&m2g#IEw-$W0^?~(F2e=k{+KRbq|3+X@)5ec0EgX|uc6CEx~!v%gN@$H6}mL&woaFi z)8(Ud`CoMTpL8*BFlu=ZU0zC;Gj#Fk@-SV#K$qXA%iq)G|I#Ig?3 zF8_uuPtoP8bUBADE6Xljrs;BsE)US<<#gGNO<2l1>GBGM4whd=m#Z+dR=$!hzeblg z(Pa!>{PF?1l<2ZRmrv5=<8=93y8I1YZlK!ROPAlF%YVS7;SW&#;%F{LfvDkG`(3kk zea-&Sto@BOuGv|x)itisS+31BuE{m7#Wk+MHLkr`uDLa?wKcA>S+1=$uBkPyr8Tah zS+1Qmu9;b`6{JUH%yMn4aZRjoEv#`3tg-ahSn_Ku^);6G8cTbPCB4Q{USkQbv2VSf+(V%WctelhGnO}`lS-=|*;`|Ana4EqP@7sLJ?A?&|QzZmwkO}c>nSP1*m z^owCnTe1q+(@G`*dkSwAu%{p@0ehP86tJgR9|3zBeHO5%K|TR{8mD2{v%lQ%x9Lp_ zTf1$A5|vOCAd=&NER{dHJd!^= zIdm@3f;}gmSMcT%e-O?|!D*1|(e$@q#u7tx!~-1EO}7QlAElVTA3)+ixp5(S68O62jD@G&ZzHJ>$;U-B!Cj**w6R)2FLl zr+xaI&bioQ1WS+za-@1$Z6g-6E3F7ZAnjuo2_o)1^2h_QyF4rs&q!zi@x=Gnxpq&x z-C43cC5q4Vsrpa-x3B*CtLlG${I|b$_k#LQ&U+nU+RsVlr`lN57QrtORn!TIhRh|VZFHZEMPe<; zm(K!E>aH_M!a?}ZDX<}KDd%p5;u0!tYFkNc+{Pm6>OOC1mWg1VPW5mxgwv;~Lxbbn znO^yd8`#VjoMDmjJ$7vRLc#t)E}SHrN%a4zvnb=xa5h1z?O#LNzZ?b>!fXuin;`z= zJmNnE(VwIS8M=VTDYBD)(gCC<5W(xFfgeCz(|q0)6IjKACjFFSD++8MW9+Q4Z^GCg zBnHW;xuWbAn;_eiDowNFUxw*1Y<7s>5#JEMJ75O99191bz8eb_r#^ocH^>=*OoHh? zTx(fvDnIuKtELen;udjrbB!rNiKgcz?{mxFp+Ky zpo#%BurF2YXG#CX*6Sk(8Y^}i^skLT|Ds}PT#Z-7I39|B68|i|2dsTx{6LN)Cv^QT zl1EJ4{u#5_6P{HBTn>X`8i=!TacIaztV?B*FA=bjye>QTGNle-CZ7%)_fw{y?aw5W z6w@!IU_3AXo!mAJZhJ_>X}ho>llRm?`=NvO=pU7(kC@Z8c9SpE>hfAP(tO3beBr`d zY4W$Mb}r1YOiIApSi%`rSGIfN3&&o|Z8)71mljxdXX6d_*8RKp?k(THd;i`VdmQc* z*duHe{`Mn>y%lX8)@>bI2g^KiIi#tM^XO_y`# zG?^hN0n0PrVY+?7!W~D>sr$NV(;iD_24o>hUtpLx%LXxKiRU?nNh=nMw}3kB<8n>Y zLc)HB)}*DqC@)`nLosP^-NLf1)~mQnEm=fiKKUO|d%AE~sOM z+rA0gcN|yo>sNCH{I`m1ukxt&PN7<4r9HM=tvoGl7B|^aVGr+1dG=1JwpH1$F;G+s z<=VTf@`x46@3JSQ@@76){K{^%xVOhDRaV;B-7Xb3^Q=_f*xuhPl^?T*_^w>3vF*}M zsfIyo6-ErBp-RQQ90uDdRyVdVa^YcVyHtBO&mNU(Wg7Dl1}(7NLbX=f*xxQx+3tRI zx3X6R`^{XrQZAJrRl%jWQ!Lk3z!j`m@hM)|-d16ITd^waL;9+cZ=hEwDfb*R@xd-(ixu# zypC_;JgO&EoQziN%=u2HX-GmyY1oiW{I#?>BlT^n|_WA>Q65U$A8YYRqlB9g2 zCW*(%7b;0ygLLWs{Npr16ga(fxxvjNEa=bLl$#|&Qo6vBL(l_cM?rlB`>wuYoA;)xJV3L zj@;#eN~P&+^W}sg>ybWl%y=dV+;RMF*4FQn zwJ^^O;nFc{EcSwY{8^zenVX;8kOM%OZeII0)Y)T{b$l65bU0^PUa8|af%}6G_U>ek zPu2@I?#YhXW7qLK_SH4^Y#kF1EeEP$(4^1wV^W9COF~NPZ)jGjtF#4qwSVvo%3th* z4u7XGo|%Yue>`y(AYcrd8`7NH1N!I$#=Q43bQfNRxD$yf$!}WIkQ% zn+8`heHr}sDlh=~-zSAK$PXnM4M!U=$X}gf5E>f?KdnC}gQ)WgT3G0kAU%}Z*a{8= z+tUNw^0^VL1e(0KWe~2i1OtHe-^4Eh*0mSL&$xI%C&c|9rB()7_n)n2ISzDBmLL&n zLC*GknPJ`60k#(}juf?9InV)KKRp0mSs@a9Me3yZS~_2WK7h^i44fW<^(ip`V%JHj z48%fVMuXTUjPjqK0mQ!aHeG_Vs&mZ4u=RFX{T_s@uq$z38mv~x>Jg^qdI!vSwZ8`% z+*NMPpy>aIixN`tR8f4-KBJ+KtX1w=87ZhnKMKU1y;ZeVdE1dWGV8T=junXoJIR2ox$kIWncrfI2C{G*}9eMA!iU`Iv;y z03@{4XaIQ(QNMAH@@E3%Y!-4N%(8L!yG%2u^$DdYVW9jv-MKVcO~LhW7ud z0aRzY4-PwroHbxKpAOx>K}ZVB#G9ntn4B{LmkQ9dr0{GeZV3y}$PP9Jcast6pniMz0%R>_7|Ue z7;-Ue;TBgd8r|Y(aoHR=Mju3VbY(f?a=M$)EUHYyU8Kz6Vk3DSm)H1n6Sl$yP~gQx z<8r*g>%jro&7t^l4Fp;HdY-Z!a8d$u6QizMFt&}%#VC1+Bt*2V1EGMvcZ$eF2#B6A3sl=Qf z_>Pt~$%`gHHQNZ<9W4PK467PUV9rG;B6)URwZOWzNA6FXIvx)ij)qzwP+jHEJC4V- z?3W59hOZr&o*6=PUc=2C9XCOdNXp50LWnoz43zOO1=Ot{2Az$_G)nQqdZ@GFTnKm z@Z}Bl9=>X*8q;w}OBTFMcfh&<|Ax~F9;5i9(LrF)p?WXG9#w@KP4^E05?uV+O}ILq z|JNxZ;GVIU?kaEBQP1T0C*UPG_c7W{!*cXP4d;xerJ;%#m%da;dnzw+`-rM;O#}>QAO<7KnQAVQG<59r!}m@MKeZgCNET~NF}^zpQOg{ z_np=bmWtNfv|fB$d`sBkuvMg%hxG92@g6$^(&*(_|8C1;K3TAn6I*g~NtrVCw`Z3*cBJ%G1ecdTS4DAJeu8WZa2o)M>GuIi)f zJ>y69EMxL!|5#Da1(`$OGn|0JT322%a3c?p(aAcHu@SX@9XR=*TcseQyND;);d&@$ zB!)QDoAXXk2h)yQ(`7iSUe6rtKPV=}eW+sasHzZClO56e&9J;Oglz;lYx&*-wse1q z-HG1W{WroaZ9%SmiXndZ{x|Rc@cnP~43nIXs(Tp&>(Q{&Ysye4XL@!Hog9yr>oIvb zEXuo#oA?T?nPK@qVt80iuZoLWzl`xvv6HRHLw%7huP3WXY)<9XD@n5o2Dt_;aM4;o Jhh4b$_+LdyLtg*@ literal 0 HcmV?d00001 diff --git a/docs/build/doctrees/environment.pickle b/docs/build/doctrees/environment.pickle new file mode 100644 index 0000000000000000000000000000000000000000..7789700517593e008db80167992c708d285a6297 GIT binary patch literal 1891131 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 literal 0 HcmV?d00001 diff --git a/docs/build/doctrees/introduction.doctree b/docs/build/doctrees/introduction.doctree new file mode 100644 index 0000000000000000000000000000000000000000..03b9eecf52ce32b1795875828232a878fdf514a8 GIT binary patch literal 20215 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 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/source/_static/__pycache__/guide-callback-regex-ipdb.cpython-38.pyc b/docs/source/_static/__pycache__/guide-callback-regex-ipdb.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bbcc6e514023735bd11509f6d02c53642ae5e5c7 GIT binary patch literal 901 zcmZWnJ#P~+81~oYE``t{Bvke;ht%ATstO75F_lV9ms<|UcH0ZS_^^GHRLMlw{)co# z{1N^El2@jVtW3O4397)S_kGXr=i|pd9t<`RtnWX+zH10VKjP-@Vz7A*;-ZpBVvWjM zi%Y!PlahcXnl`LtO;RQpDJH38GPxqMC(}#x8J9hYk5Hc7Ko@k7lQ1~*zO~Bx`lMDe z^xup|hjBX_y@F`^QQ5I^s(i?`Hs{q;`AV4SR0%I)hxG!)s0Z=_#En2nEXgHWAde;( zgm}6HEZ2CBB)g(`?N9#m_a>=Ke75XI#5KOgGP@!RI3b|!9|#J)*DHaaC`TY}2ULv~ z6b2)W7HrOz_!?m#WKKL;(m4!2q0odLSPZ#0-$3Oou)3Aw(06b!Z@Ex`O`MsAM0QQ< z@+72Iedv_)fp%7h^h|N7tP5;xDOzhLK$a_7 zh?yzZ#b1I8X@o1B>8wyiPD~+gZ5R%&K)Lz805( zLYUzUW%y#p1I%j7T`j7JZn&onWV`+0ow5rue41lBfVzvVc=hgCQN+TbFin}9DY)h` zIX70z90w-3=lO<>te5uzOzpg~RcGr!U%wm$VpT|?u&p%^clh>b6tX{j0Y$BG-bRSF z4=N{i3rtLKt(gK>k+xg483UXD;7`GMdqSG^w(&N#Pr#F>_ED@`^?eL~WqH9b_yfeWaI>;89$cCquJ3TjYl}*nZ zJumW%ViV^nI>u3x;BQdip2JOOJHWNM^_Ug{gyx44G$lvd?c7NGPi{}l5RI3aQRfOAn=6wdYx1$aCJ55Mxp_!P5m)$JeylD3j9K(h2w zgWH>AnOv!w3W+;K;?5!Qfg=QEzq)-cJF)xoPjdWzKb7U04JpgH43l4h1?Wa6c#NT= zFceAa=nz8RK7S3i$azRpnmtyXVjL!!2=v-!^!owjqSgm2ukAgW5X$%~tv0D_vdEWy zF{jW#gug;>cEU#-9Kvq0%QBjGk~~eyu+PeUXfGc2!B!SY9$q$LNXnFlyd1EUhA|h3 z$kLF(HMd08qvb%X^@p|B8^$Sg>u!=BEXZ68SP*XDqxS`Xi=}@&^WV%%@a6Z`<_;Y# z$yec%Fr-hCUO%U6Y1xDK!PqUy5T5q*?3Ben?g#h{-VE^3J2!9K><>Q(`0A}yDXj-Q zSlv|Ooq*SRQ6AR5Vgfi2aUv%1rBWdD+=7qu7M?3WEwn}BqQ<}?Pgq177th!>0fN^)P~HecBT~s zv|S2y1e|r_L4T--OIY1j%mRgd2Bh>8Mr$9;@$MkYMON_In($e##C)$DyD{uW~;tC!63n*6qCeS(ZckDGb@^e|4#{-tg%$7 z)}sV?WwLvj?BmFj=q99oIKR0)zuA~3(_oX$e-3SU_~0%E-cdljfSlY%W$xx!4Ezha_%7?wUCd&4tooIrS|MSh!eDG zXT~>s7ZmmNcv7LYNut2#8l#6S6TtSRO1_;+$KHlB?7Cc59f6Q@mD8jyGcq#TG(Tu@aIQh`&1Aielv9PcJ^vE#72Zb_A#TB+@! z4*(~6ti+KEZ@@G7$|XtSJtjT)}?pGP9dmCc*i=8CB|XB4wUZx zk(yXkT4QUcT3MS66D85mc-`;6A;aut2ZEg_P4nY$qHGxFlZlFLOd;0fpyDDEP}4_Y z*(tk3pbG?f2~sSG`8hj>A(sg1%v%Txha6eV*<2t<0n9pwE}me{(W`!ig;kR<17Z@%hXTWj z-ts5j1>Rc~tK_Jv-Z_pE+Yx15tB-{;wiJa<%lcSFQfYI;OIK0jf+qQeMqyK=xnaNi z{((UUe-sULqS9fM#!>E1b$*B~GyW9s@=28Xf1B&eJT|_`3mq#zG&ZtH>}yQ(*e03E z3)`K}%FS#R#yEjN6o0r!wNSqqY{1DQi{L`?57+*?X^y^TuY2ba&eIv>a)$r<%CA$` zxN1yOsGzCUC^1&)u+T{GLZ#ivfgMNrs#7AQ*8+J_5lgX&U8#LC7I@2`T3V-$BHf5E! a5>;MrH_K&_sy#qoL!073lQ*F$Jop1nh2`h~ literal 0 HcmV?d00001 diff --git a/docs/source/_static/__pycache__/regex-example.cpython-38.pyc b/docs/source/_static/__pycache__/regex-example.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d3a313d31dd4b5c1117e79f8bc1e450c4121f89d GIT binary patch literal 619 zcmYjP!EV$r5Vf66HoM(j#EoAF5^LxYAq1)lJ)o)*yO&%-8c&xj-ZdpSX8EIph7=91$%59 zR3Yo12)e|id!+6S8DwitDlodDzh3ju>oVdD}9B#$@Vf~%hX51$ZOYGcs_8zf)D&>hW^U7?t_ilXzhXKe&eiR@Ji0Apl z!m4%%w&-l_qu2WjFD&>WCAPH&pIZ3XQKj?I3NYWfX+o?O_}NS6z+!EheQS-Sy^Jil z)-(>D{J-x0V0MS7|5?f=em+KFPuGsvvSjFn78MC9EcS?oP;&^uRuHyV?HCbQ^K;?hLBBz3GcwCWrg)= eNxVb6pYM*D^eN9aMs*sV(|VZ;r75Q`n()8fN~3B3 literal 0 HcmV?d00001 diff --git a/docs/source/_static/guide-callback-regex-ipdb.py b/docs/source/_static/guide-callback-regex-ipdb.py new file mode 100644 index 0000000..9ca9f9a --- /dev/null +++ b/docs/source/_static/guide-callback-regex-ipdb.py @@ -0,0 +1,20 @@ +import re +import json +import requests +from httpretty import httprettified, HTTPretty + + +@httprettified(verbose=True, allow_net_connect=False) +def test_basic_body(): + + def my_callback(request, url, headers): + body = {} + import ipdb;ipdb.set_trace() + return (200, headers, json.dumps(body)) + + # Match any url via the regular expression + HTTPretty.register_uri(HTTPretty.GET, re.compile(r'.*'), body=my_callback) + HTTPretty.register_uri(HTTPretty.POST, re.compile(r'.*'), body=my_callback) + + # will trigger ipdb + response = requests.post('https://test.com', data=json.dumps({'hello': 'world'})) diff --git a/docs/source/_static/logo.svg b/docs/source/_static/logo.svg new file mode 100644 index 0000000..7b31d61 --- /dev/null +++ b/docs/source/_static/logo.svg @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + diff --git a/docs/source/_static/read-timeout.py b/docs/source/_static/read-timeout.py new file mode 100644 index 0000000..59e668e --- /dev/null +++ b/docs/source/_static/read-timeout.py @@ -0,0 +1,39 @@ +import requests, time +from threading import Event + +from httpretty import httprettified +from httpretty import HTTPretty + + +@httprettified(allow_net_connect=False) +def test_read_timeout(): + event = Event() + wait_seconds = 10 + connect_timeout = 0.1 + read_timeout = 0.1 + + def my_callback(request, url, headers): + event.wait(wait_seconds) + return 200, headers, "Received" + + HTTPretty.register_uri( + HTTPretty.GET, "http://example.com", + body=my_callback + ) + + requested_at = time.time() + try: + requests.get( + "http://example.com", + timeout=(connect_timeout, read_timeout)) + except requests.exceptions.ReadTimeout: + pass + + event_set_at = time.time() + event.set() + + now = time.time() + + assert now - event_set_at < 0.2 + total_duration = now - requested_at + assert total_duration < 0.2 diff --git a/docs/source/_static/regex-example.py b/docs/source/_static/regex-example.py new file mode 100644 index 0000000..72fc3fe --- /dev/null +++ b/docs/source/_static/regex-example.py @@ -0,0 +1,14 @@ +import re +import requests +import httpretty + + +@httpretty.activate(allow_net_connect=False, verbose=True) +def test_regex(): + httpretty.register_uri(httpretty.GET, re.compile(r'.*'), status=418) + + response1 = requests.get('http://foo.com') + assert response1.status_code == 418 + + response2 = requests.get('http://test.com') + assert response2.status_code == 418 diff --git a/docs/source/_static/tmplun_dcms-ascii.cast b/docs/source/_static/tmplun_dcms-ascii.cast new file mode 100644 index 0000000..6e26bca --- /dev/null +++ b/docs/source/_static/tmplun_dcms-ascii.cast @@ -0,0 +1,235 @@ +{"version": 2, "width": 115, "height": 30, "timestamp": 1621882710, "env": {"SHELL": "/usr/local/bin/bash", "TERM": "xterm-256color"}} +[1.115441, "o", "HTTPretty $ "] +[1.648012, "o", "."] +[1.67985, "o", "v"] +[1.767955, "o", "e"] +[2.045646, "o", "nv/"] +[2.888016, "o", "b"] +[2.960179, "o", "i"] +[3.046058, "o", "n/"] +[4.703758, "o", "o"] +[5.007876, "o", "\b\u001b[K"] +[5.183768, "o", "n"] +[5.249014, "o", "o"] +[5.286233, "o", "s"] +[5.423938, "o", "e"] +[5.553841, "o", "\u0007tests"] +[6.562148, "o", " "] +[6.680246, "o", "d"] +[6.791965, "o", "o"] +[6.880409, "o", "cs/"] +[7.533022, "o", "s"] +[7.596079, "o", "ource/"] +[7.636732, "o", "o"] +[7.728134, "o", "u"] +[8.176255, "o", "\b\u001b[K"] +[8.321962, "o", "\b\u001b[K"] +[8.463491, "o", "_"] +[8.584109, "o", "s"] +[8.727909, "o", "t"] +[8.780703, "o", "atic/"] +[9.403611, "o", "\u0007"] +[10.393067, "o", "\r\n"] +[10.393402, "o", "__pycache__/ guide-callback-regex-ipdb.py logo.svg\r\nHTTPretty $ .venv/bin/nosetests docs/source/_static/"] +[10.517051, "o", "\r\n"] +[10.517371, "o", "__pycache__/ guide-callback-regex-ipdb.py logo.svg\r\nHTTPretty $ .venv/bin/nosetests docs/source/_static/"] +[11.423948, "o", "g"] +[11.532343, "o", "uide-callback-regex-ipdb.py "] +[14.504165, "o", "\r\n"] +[16.477912, "o", "#190 guide-callback-regex-ipdb.test_basic_body ... "] +[18.01153, "o", "> \u001b[0;32m/Users/gabrielfalcao/projects/personal/HTTPretty/docs/source/_static/guide-callback-regex-ipdb.py\u001b[0m(13)\u001b[0;36mmy_callback\u001b[0;34m()\u001b[0m\r\n\u001b[0;32m 12 \u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mipdb\u001b[0m\u001b[0;34m;\u001b[0m\u001b[0mipdb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_trace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\r\n\u001b[0m\u001b[0;32m---> 13 \u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m200\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mheaders\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mjson\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdumps\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbody\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\r\n\u001b[0m\u001b[0;32m 14 \u001b[0;31m\u001b[0;34m\u001b[0m\u001b[0m\r\n\u001b[0m\r\n"] +[18.014165, "o", "\u001b[?1l"] +[18.014537, "o", "\u001b[6n"] +[18.030527, "o", "\u001b[?2004h\u001b[?25l\u001b[0m\u001b[?7l\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[6D\u001b[6C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[18.071481, "o", "\u001b[?25l\u001b[?7l\u001b[6D\u001b[0;38;5;28mipdb> \u001b[0m\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\u001b[0m \b\u001b[22A\u001b[6C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[21.666012, "o", "\u001b[?25l\u001b[?7l\u001b[0ml\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[21.879456, "o", "\u001b[?25l\u001b[?7l\u001b[7D\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[0ml\u001b[7D\u001b[0m\r\r\n\u001b[J\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h\u001b[?2004l"] +[21.882208, "o", "\u001b[1;32m 8 \u001b[0m\u001b[0;32mdef\u001b[0m \u001b[0mtest_basic_body\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\r\n\u001b[1;32m 9 \u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\r\n\u001b[1;32m 10 \u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mmy_callback\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrequest\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0murl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mheaders\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\r\n\u001b[1;32m 11 \u001b[0m \u001b[0mbody\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\r\n\u001b[1;32m 12 \u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mipdb\u001b[0m\u001b[0;34m;\u001b[0m\u001b[0mipdb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_trace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\r\n\u001b[0;32m---> 13 \u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;36m200\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mheaders\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mjson\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdumps\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbody\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\r\n\u001b[0m\u001b[1;32m 14 \u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\r\n\u001b[1;32m 15 \u001b[0m \u001b[0;31m# Match any url via the regular expression\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\r\n\u001b[1;32m 16 \u001b[0m \u001b[0mHTTPrett"] +[21.882467, "o", "y\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mregister_uri\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mHTTPretty\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mGET\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mre\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcompile\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mr'.*'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbody\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mmy_callback\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\r\n\u001b[1;32m 17 \u001b[0m \u001b[0mHTTPretty\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mregister_uri\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mHTTPretty\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mPOST\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mre\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcompile\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mr'.*'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbody\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mmy_callback\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\r\n\u001b[1;32m 18 \u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\r\n\r\n"] +[21.883476, "o", "\u001b[?1l"] +[21.883604, "o", "\u001b[6n"] +[21.887032, "o", "\u001b[?2004h\u001b[?25l\u001b[0m\u001b[?7l\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[6D\u001b[6C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[21.892331, "o", "\u001b[?25l\u001b[?7l\u001b[6D\u001b[0;38;5;28mipdb> \u001b[0m\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\u001b[0m \b\u001b[9A\u001b[6C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[22.81778, "o", "\u001b[?25l\u001b[?7l\u001b[0mp\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[22.969469, "o", "\u001b[?25l\u001b[?7l\u001b[0mp\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[23.181313, "o", "\u001b[?25l\u001b[?7l\u001b[C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[23.322972, "o", "\u001b[?25l\u001b[?7l\u001b[0mr\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[23.378349, "o", "\u001b[?25l\u001b[?7l\u001b[0me\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[23.544925, "o", "\u001b[?25l\u001b[?7l\u001b[0mq\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[23.665954, "o", "\u001b[?25l\u001b[?7l\u001b[0mu\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[23.741902, "o", "\u001b[?25l\u001b[?7l\u001b[0me\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[23.879494, "o", "\u001b[?25l\u001b[?7l\u001b[0ms\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[24.000226, "o", "\u001b[?25l\u001b[?7l\u001b[0mt\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[24.365902, "o", "\u001b[?25l\u001b[?7l\u001b[16D\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[0mpp request\u001b[16D\u001b[0m\r\r\n\u001b[J\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h\u001b[?2004l"] +[24.367405, "o", "\r\n"] +[24.368531, "o", "\u001b[?1l"] +[24.368635, "o", "\u001b[6n"] +[24.371795, "o", "\u001b[?2004h\u001b[?25l\u001b[0m\u001b[?7l\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[6D\u001b[6C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[24.376988, "o", "\u001b[?25l\u001b[?7l\u001b[6D\u001b[0;38;5;28mipdb> \u001b[0m\r\r\n\r\r\n\r\r\n\r\r\n\r\r\n\u001b[0m \b\u001b[5A\u001b[6C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[27.359342, "o", "\u001b[?25l\u001b[?7l\u001b[0mpp request\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[27.82273, "o", "\u001b[?25l\u001b[?7l\u001b[0m.\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[28.255766, "o", "\u001b[?25l\u001b[?7l\u001b[0mh\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[28.313307, "o", "\u001b[?25l\u001b[?7l\u001b[0me\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[28.405472, "o", "\u001b[?25l\u001b[?7l\u001b[0ma\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[28.850422, "o", "\u001b[?25l\u001b[?7l\u001b[0md\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[28.912138, "o", "\u001b[?25l\u001b[?7l\u001b[0me\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[29.015229, "o", "\u001b[?25l\u001b[?7l\u001b[0mr\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[29.112081, "o", "\u001b[?25l\u001b[?7l\u001b[0ms\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[29.429921, "o", "\u001b[?25l\u001b[?7l\u001b[24D\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[0mpp request.headers\u001b[24D\u001b[0m\r\r\n\u001b[J\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h\u001b[?2004l"] +[29.431801, "o", "\r\n"] +[29.433016, "o", "\u001b[?1l"] +[29.433238, "o", "\u001b[6n"] +[29.436901, "o", "\u001b[?2004h\u001b[?25l\u001b[0m\u001b[?7l\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[6D\u001b[6C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[29.444544, "o", "\u001b[?25l\u001b[?7l\u001b[6D\u001b[0;38;5;28mipdb> \u001b[0m\r\r\n\r\r\n\r\r\n\u001b[0m \b\u001b[3A\u001b[6C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[30.156471, "o", "\u001b[?25l\u001b[?7l\u001b[0mpp request.headers\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[30.608228, "o", "\u001b[?25l\u001b[?7l\u001b[7D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[30.765725, "o", "\u001b[?25l\u001b[?7l\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[30.902549, "o", "\u001b[?25l\u001b[?7l\u001b[7D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[31.381908, "o", "\u001b[?25l\u001b[?7l\u001b[0mdrequest.headers\u001b[15D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[31.510943, "o", "\u001b[?25l\u001b[?7l\u001b[0mirequest.headers\u001b[15D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[31.57281, "o", "\u001b[?25l\u001b[?7l\u001b[0mcrequest.headers\u001b[15D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[31.725778, "o", "\u001b[?25l\u001b[?7l\u001b[0mtrequest.headers\u001b[15D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[31.890771, "o", "\u001b[?25l\u001b[?7l\u001b[0m(request.headers\u001b[15D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[32.215385, "o", "\u001b[?25l\u001b[?7l\u001b[15C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[32.495352, "o", "\u001b[?25l\u001b[?7l\u001b[0m)\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[32.983501, "o", "\u001b[?25l\u001b[?7l\u001b[30D\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[0mpp dict(request.headers)\u001b[30D\u001b[0m\r\r\n\u001b[J\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h\u001b[?2004l"] +[32.98525, "o", "{'Accept': '*/*',\r\n 'Accept-Encoding': 'gzip, deflate',\r\n 'Connection': 'keep-alive',\r\n 'Content-Length': '18',\r\n 'Host': 'test.com',\r\n 'User-Agent': 'python-requests/2.25.1'}\r\n"] +[32.986518, "o", "\u001b[?1l"] +[32.986746, "o", "\u001b[6n"] +[32.990263, "o", "\u001b[?2004h\u001b[?25l\u001b[0m\u001b[?7l\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[6D\u001b[6C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[32.996419, "o", "\u001b[?25l\u001b[?7l\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[35.671881, "o", "\u001b[?25l\u001b[?7l\u001b[0mp\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[35.856772, "o", "\u001b[?25l\u001b[?7l\u001b[0mp\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[37.215658, "o", "\u001b[?25l\u001b[?7l\u001b[C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[37.693648, "o", "\u001b[?25l\u001b[?7l\u001b[0mr\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[37.758114, "o", "\u001b[?25l\u001b[?7l\u001b[0me\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[38.110067, "o", "\u001b[?25l\u001b[?7l\b\u001b[0m\u001b[K\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[38.247765, "o", "\u001b[?25l\u001b[?7l\u001b[2D\u001b[0m\u001b[K\u001b[C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[38.397251, "o", "\u001b[?25l\u001b[?7l\u001b[0mh\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[38.444177, "o", "\u001b[?25l\u001b[?7l\u001b[0me\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[38.561504, "o", "\u001b[?25l\u001b[?7l\u001b[0ma\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[38.790802, "o", "\u001b[?25l\u001b[?7l\u001b[0md\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[38.926065, "o", "\u001b[?25l\u001b[?7l\u001b[0me\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[39.04009, "o", "\u001b[?25l\u001b[?7l\u001b[0mr\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[39.140742, "o", "\u001b[?25l\u001b[?7l\u001b[0ms\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[39.437672, "o", "\u001b[?25l\u001b[?7l\u001b[C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[39.886449, "o", "\u001b[?25l\u001b[?7l\u001b[17D\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[0mpp headers\u001b[16D\u001b[0m\r\r\n\u001b[J\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h\u001b[?2004l"] +[39.888255, "o", "{'connection': 'close',\r\n 'date': 'Mon, 24 May 2021 18:58:47 GMT',\r\n 'server': 'Python/HTTPretty',\r\n 'status': 200}\r\n"] +[39.890098, "o", "\u001b[?1l"] +[39.890285, "o", "\u001b[6n"] +[39.894169, "o", "\u001b[?2004h\u001b[?25l\u001b[0m\u001b[?7l\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[6D\u001b[6C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[39.898533, "o", "\u001b[?25l\u001b[?7l\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[45.717659, "o", "\u001b[?25l\u001b[?7l\u001b[0mh\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[45.733999, "o", "\u001b[?25l\u001b[?7l\u001b[0me\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[45.856076, "o", "\u001b[?25l\u001b[?7l\u001b[0ma\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[45.94174, "o", "\u001b[?25l\u001b[?7l\u001b[0md\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[46.030913, "o", "\u001b[?25l\u001b[?7l\u001b[0me\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[46.118401, "o", "\u001b[?25l\u001b[?7l\u001b[0mr\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[46.205205, "o", "\u001b[?25l\u001b[?7l\u001b[0ms\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[46.470445, "o", "\u001b[?25l\u001b[?7l\u001b[0m[\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[46.589064, "o", "\u001b[?25l\u001b[?7l\u001b[0m]\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[46.916657, "o", "\u001b[?25l\u001b[?7l\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[47.326705, "o", "\u001b[?25l\u001b[?7l\u001b[0m'']\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[47.354431, "o", "\u001b[?25l\u001b[?7l\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[47.384967, "o", "\u001b[?25l\u001b[?7l\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[47.47368, "o", "\u001b[?25l\u001b[?7l\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[48.062051, "o", "\u001b[?25l\u001b[?7l\u001b[C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[48.345923, "o", "\u001b[?25l\u001b[?7l\u001b[0mC']\u001b[2D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[48.59897, "o", "\u001b[?25l\u001b[?7l\u001b[0mo']\u001b[2D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[48.663284, "o", "\u001b[?25l\u001b[?7l\u001b[0mn']\u001b[2D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[48.750459, "o", "\u001b[?25l\u001b[?7l\u001b[0mt']\u001b[2D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[48.809164, "o", "\u001b[?25l\u001b[?7l\u001b[0me']\u001b[2D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[48.888522, "o", "\u001b[?25l\u001b[?7l\u001b[0mn']\u001b[2D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[48.949883, "o", "\u001b[?25l\u001b[?7l\u001b[0mt']\u001b[2D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[49.088369, "o", "\u001b[?25l\u001b[?7l\u001b[0m-']\u001b[2D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[49.265468, "o", "\u001b[?25l\u001b[?7l\u001b[0mT']\u001b[2D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[49.450521, "o", "\u001b[?25l\u001b[?7l\u001b[0my']\u001b[2D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[49.516735, "o", "\u001b[?25l\u001b[?7l\u001b[0mp']\u001b[2D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[49.662079, "o", "\u001b[?25l\u001b[?7l\u001b[0me']\u001b[2D\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[50.01415, "o", "\u001b[?25l\u001b[?7l\u001b[2C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[50.444668, "o", "\u001b[?25l\u001b[?7l\u001b[C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[50.506213, "o", "\u001b[?25l\u001b[?7l\u001b[0m=\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[50.566841, "o", "\u001b[?25l\u001b[?7l\u001b[C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[51.624083, "o", "\u001b[?25l\u001b[?7l\u001b[0m'\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[51.970211, "o", "\u001b[?25l\u001b[?7l\u001b[0m'\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[52.078158, "o", "\u001b[?25l\u001b[?7l\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[52.254808, "o", "\u001b[?25l\u001b[?7l\u001b[0ma'\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[52.349951, "o", "\u001b[?25l\u001b[?7l\u001b[0mp'\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[52.515528, "o", "\u001b[?25l\u001b[?7l\u001b[0mp'\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[52.629864, "o", "\u001b[?25l\u001b[?7l\u001b[0ml'\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[52.8266, "o", "\u001b[?25l\u001b[?7l\u001b[0mi'\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[52.912236, "o", "\u001b[?25l\u001b[?7l\u001b[0mc'\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[52.96185, "o", "\u001b[?25l\u001b[?7l\u001b[0ma'\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[53.099131, "o", "\u001b[?25l\u001b[?7l\u001b[0mt'\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[53.185005, "o", "\u001b[?25l\u001b[?7l\u001b[0mio'\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[53.254551, "o", "\u001b[?25l\u001b[?7l\u001b[0mn'\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[53.439432, "o", "\u001b[?25l\u001b[?7l\u001b[0m/'\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[53.67937, "o", "\u001b[?25l\u001b[?7l\u001b[0mj'\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[53.792533, "o", "\u001b[?25l\u001b[?7l\u001b[0ms'\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[53.843024, "o", "\u001b[?25l\u001b[?7l\u001b[0mo'\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[53.905637, "o", "\u001b[?25l\u001b[?7l\u001b[0mn'\b\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[54.32111, "o", "\u001b[?25l\u001b[?7l\u001b[49D\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[0mheaders['Content-Type'] = 'application/json'\u001b[50D\u001b[0m\r\r\n\u001b[J\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h\u001b[?2004l"] +[54.323453, "o", "\u001b[?1l"] +[54.323703, "o", "\u001b[6n"] +[54.32769, "o", "\u001b[?2004h\u001b[?25l\u001b[0m\u001b[?7l\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[6D\u001b[6C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[54.33208, "o", "\u001b[?25l\u001b[?7l\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[55.431101, "o", "\u001b[?25l\u001b[?7l\u001b[0mb\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[55.502203, "o", "\u001b[?25l\u001b[?7l\u001b[0mo\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[55.577597, "o", "\u001b[?25l\u001b[?7l\u001b[0md\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[55.702116, "o", "\u001b[?25l\u001b[?7l\u001b[0my\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[55.887196, "o", "\u001b[?25l\u001b[?7l\u001b[10D\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[0mbody\u001b[10D\u001b[0m\r\r\n\u001b[J\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[55.887473, "o", "\u001b[?2004l"] +[55.888628, "o", "{}\r\n"] +[55.889744, "o", "\u001b[?1l"] +[55.889857, "o", "\u001b[6n"] +[55.893146, "o", "\u001b[?2004h\u001b[?25l\u001b[0m\u001b[?7l\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[6D\u001b[6C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[55.89828, "o", "\u001b[?25l\u001b[?7l\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[56.247068, "o", "\u001b[?25l\u001b[?7l\u001b[0mb\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[56.319912, "o", "\u001b[?25l\u001b[?7l\u001b[0mo\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[56.448876, "o", "\u001b[?25l\u001b[?7l\u001b[0md\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[56.521946, "o", "\u001b[?25l\u001b[?7l\u001b[0my\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[56.870316, "o", "\u001b[?25l\u001b[?7l\u001b[0m=\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[57.286911, "o", "\u001b[?25l\u001b[?7l\b\u001b[0m\u001b[K\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[57.598176, "o", "\u001b[?25l\u001b[?7l\u001b[0m[\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[58.044934, "o", "\u001b[?25l\u001b[?7l\u001b[0m\"\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[58.398262, "o", "\u001b[?25l\u001b[?7l\u001b[0mo\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[58.568438, "o", "\u001b[?25l\u001b[?7l\u001b[0mo\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[58.814278, "o", "\u001b[?25l\u001b[?7l\b\u001b[0m\u001b[K\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[58.98533, "o", "\u001b[?25l\u001b[?7l\b\u001b[0m\u001b[K\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[59.183923, "o", "\u001b[?25l\u001b[?7l\b\u001b[0m\u001b[K\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[60.874043, "o", "\u001b[?25l\u001b[?7l\u001b[0m\"\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[61.07425, "o", "\u001b[?25l\u001b[?7l\u001b[0mf\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[61.154785, "o", "\u001b[?25l\u001b[?7l\u001b[0mo\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[61.28069, "o", "\u001b[?25l\u001b[?7l\u001b[0mo\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[61.831178, "o", "\u001b[?25l\u001b[?7l\u001b[0m\"\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[61.927243, "o", "\u001b[?25l\u001b[?7l\u001b[0m]\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[62.205321, "o", "\u001b[?25l\u001b[?7l\u001b[C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[62.288705, "o", "\u001b[?25l\u001b[?7l\u001b[0m=\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[62.381831, "o", "\u001b[?25l\u001b[?7l\u001b[C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[62.827726, "o", "\u001b[?25l\u001b[?7l\u001b[0m\"\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[62.999464, "o", "\u001b[?25l\u001b[?7l\u001b[0mb\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[63.070687, "o", "\u001b[?25l\u001b[?7l\u001b[0ma\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[63.157669, "o", "\u001b[?25l\u001b[?7l\u001b[0mr\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[63.421688, "o", "\u001b[?25l\u001b[?7l\u001b[0m\"\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[63.710915, "o", "\u001b[?25l\u001b[?7l\u001b[25D\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[0mbody[\"foo\"] = \"bar\"\u001b[25D\u001b[0m\r\r\n\u001b[J\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[63.711171, "o", "\u001b[?2004l"] +[63.713816, "o", "\u001b[?1l"] +[63.71398, "o", "\u001b[6n"] +[63.717705, "o", "\u001b[?2004h\u001b[?25l\u001b[0m\u001b[?7l\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[6D\u001b[6C\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[63.721978, "o", "\u001b[?25l\u001b[?7l\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[64.750191, "o", "\u001b[?25l\u001b[?7l\u001b[0mc\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[65.540761, "o", "\u001b[?25l\u001b[?7l\u001b[7D\u001b[0m\u001b[J\u001b[0;38;5;28mipdb> \u001b[0mc\u001b[7D\u001b[0m\r\r\n\u001b[J\u001b[?7h\u001b[0m\u001b[?12l\u001b[?25h"] +[65.541109, "o", "\u001b[?2004l"] +[65.544155, "o", "\u001b[32mpassed\u001b[0m\r\n"] +[65.54465, "o", "\r\n"] +[65.849412, "o", "Name Stmts Miss Branch BrPart Cover\r\n---------------------------------------------------------\r\n"] +[65.849701, "o", "httpretty/__init__.py 37 2 0 0 95%\r\nhttpretty/compat.py 17 2 0 0 88%\r\nhttpretty/core.py 1007 200 304 59 76%\r\nhttpretty/errors.py 16 2 6 3 77%\r\nhttpretty/http.py 28 0 4 1 97%\r\nhttpretty/utils.py 8 0 4 0 100%\r\nhttpretty/version.py 1 0 0 0 100%\r\n---------------------------------------------------------\r\nTOTAL 1114 206 318 63 77%\r\n"] +[66.339561, "o", "\u001b[30m-----------------------------------------------------------------------------\u001b[0m\r\n"] +[66.33975, "o", "1 test run in 49.067 seconds\u001b[32m (1 test passed)\u001b[0m\r\n"] +[66.340776, "o", "Error in atexit._run_exitfuncs:\r\nTraceback (most recent call last):\r\n"] +[66.340975, "o", " File \"/Users/gabrielfalcao/projects/personal/HTTPretty/.venv/lib/python3.8/site-packages/IPython/core/history.py\", line 780, in writeout_cache\r\n"] +[66.342214, "o", " self._writeout_input_cache(conn)\r\n"] +[66.342401, "o", " File \"/Users/gabrielfalcao/projects/personal/HTTPretty/.venv/lib/python3.8/site-packages/IPython/core/history.py\", line 763, in _writeout_input_cache\r\n"] +[66.343137, "o", " conn.execute(\"INSERT INTO history VALUES (?, ?, ?, ?)\",\r\nsqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 123145518436352 and this is thread id 4682546624.\r\n"] +[66.624442, "o", "HTTPretty $ "] +[67.88294, "o", "exit\r\n"] diff --git a/docs/source/acks.rst b/docs/source/acks.rst new file mode 100644 index 0000000..036b795 --- /dev/null +++ b/docs/source/acks.rst @@ -0,0 +1,21 @@ +Acknowledgements +################ + +Caveats +======= + +``forcing_headers`` + ``Content-Length`` +---------------------------------------- + +When using the ``forcing_headers`` option make sure to add the header +``Content-Length`` otherwise calls using :py:mod:`requests` will try +to load the response endlessly. + +Supported Libraries +------------------- + +Because HTTPretty works in the socket level it should work with any HTTP client libraries, although it is `battle tested `_ against: + +* `requests `_ +* `httplib2 `_ +* `urllib2 `_ diff --git a/docs/source/api.rst b/docs/source/api.rst new file mode 100644 index 0000000..71fe992 --- /dev/null +++ b/docs/source/api.rst @@ -0,0 +1,191 @@ +.. _api: + +API Reference +============= + +.. _httpretty: + +register_uri +------------ + +.. automethod:: httpretty.core.httpretty.register_uri + :noindex: + +enable +------ + +.. automethod:: httpretty.core.httpretty.enable + :noindex: + +disable +------- + +.. automethod:: httpretty.core.httpretty.disable + :noindex: + +is_enabled +---------- + +.. automethod:: httpretty.core.httpretty.is_enabled + :noindex: + +last_request +------------ + +.. autofunction:: httpretty.last_request + :noindex: + +latest_requests +--------------- + +.. autofunction:: httpretty.latest_requests + :noindex: + + +.. automodule:: httpretty + +.. _activate: + +activate +-------- + +.. autoclass:: httpretty.activate + :members: + :noindex: + + +.. _httprettified: + +httprettified +------------- + +.. autofunction:: httpretty.core.httprettified + :noindex: + + +.. _enabled: + +enabled +------- + +.. autoclass:: httpretty.enabled + :members: + :noindex: + + +.. _httprettized: + +httprettized +------------ + +.. autoclass:: httpretty.core.httprettized + :members: + :noindex: + + + +.. _HTTPrettyRequest: + +HTTPrettyRequest +---------------- + +.. autoclass:: httpretty.core.HTTPrettyRequest + :members: + :noindex: + + +.. _HTTPrettyRequestEmpty: + +HTTPrettyRequestEmpty +--------------------- + +.. autoclass:: httpretty.core.HTTPrettyRequestEmpty + :members: + :noindex: + +.. _FakeSockFile: + +FakeSockFile +------------ + +.. autoclass:: httpretty.core.FakeSockFile + :members: + :noindex: + + +.. _FakeSSLSocket: + +FakeSSLSocket +------------- + +.. autoclass:: httpretty.core.FakeSSLSocket + :members: + :noindex: + + +.. _URIInfo: + +URIInfo +------- + +.. autoclass:: httpretty.URIInfo + :members: + :noindex: + + +.. _URIMatcher: + +URIMatcher +---------- + +.. autoclass:: httpretty.URIMatcher + :members: + :noindex: + + +.. _Entry: + +Entry +----- + +.. autoclass:: httpretty.Entry + :members: + :noindex: + + +.. _api modules: + +Modules +======= + +.. _api module core: + +Core +---- + +.. automodule:: httpretty.core + :members: + +.. _api module http: + +Http +---- + +.. automodule:: httpretty.http + :members: + +.. _api module utils: + +Utils +----- + +.. automodule:: httpretty.utils + :members: + +.. _api module exceptions: + +Exceptions +---------- + +.. automodule:: httpretty.errors + :members: diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst new file mode 100644 index 0000000..c1386ca --- /dev/null +++ b/docs/source/changelog.rst @@ -0,0 +1,212 @@ +Release Notes +============= + +Release 1.1.4 +------------- + +- Bugfix: `#435 `_ Fallback to WARNING when logging.getLogger().level is None. + +Release 1.1.3 +------------- + +- Bugfix: `#430 `_ Respect socket timeout. + +Release 1.1.2 +------------- + +- Bugfix: `#426 `_ Segmentation fault when running against a large amount of tests with ``pytest --mypy``. + +Release 1.1.1 +------------- + +- Bugfix: `httpretty.disable()` injects pyopenssl into :py:mod:`urllib3` even if it originally wasn't `#417 `_ +- Bugfix: "Incompatibility with boto3 S3 put_object" `#416 `_ +- Bugfix: "Regular expression for URL -> TypeError: wrap_socket() missing 1 required" `#413 `_ +- Bugfix: "Making requests to non-stadard port throws TimeoutError "`#387 `_ + + +Release 1.1.0 +------------- + +- Feature: Display mismatched URL within ``UnmockedError`` whenever possible. `#388 `_ +- Feature: Display mismatched URL via logging. `#419 `_ +- Add new properties to :py:class:`httpretty.core.HTTPrettyRequest` (``protocol, host, url, path, method``). + +Example usage: + +.. testcode:: + + import httpretty + import requests + + @httpretty.activate(verbose=True, allow_net_connect=False) + def test_mismatches(): + requests.get('http://sql-server.local') + requests.get('https://redis.local') + + +Release 1.0.5 +------------- + +- Bugfix: Support `socket.socketpair() `_ . `#402 `_ +- Bugfix: Prevent exceptions from re-applying monkey patches. `#406 `_ + +Release 1.0.4 +------------- + +- Python 3.8 and 3.9 support. `#407 `_ + +Release 1.0.3 +------------- + +- Fix compatibility with urllib3>=1.26. `#410 `_ + +Release 1.0.0 +------------- + +- Drop Python 2 support. +- Fix usage with redis and improve overall real-socket passthrough. `#271 `_. +- Fix TypeError: wrap_socket() missing 1 required positional argument: 'sock' (`#393 `_) +- Merge pull request `#364 `_ +- Merge pull request `#371 `_ +- Merge pull request `#379 `_ +- Merge pull request `#386 `_ +- Merge pull request `#302 `_ +- Merge pull request `#373 `_ +- Merge pull request `#383 `_ +- Merge pull request `#385 `_ +- Merge pull request `#389 `_ +- Merge pull request `#391 `_ +- Fix simple typo: neighter -> neither. +- Updated documentation for register_uri concerning using ports. +- Clarify relation between ``enabled`` and ``httprettized`` in API docs. +- Align signature with builtin socket. + +Release 0.9.4 +------------- + +Improvements: + +- Official Python 3.6 support +- Normalized coding style to comform with PEP8 (partially) +- Add more API reference coverage in docstrings of members such as :py:class:`httpretty.core.Entry` +- Continuous Integration building python 2.7 and 3.6 +- Migrate from `pip `_ to `pipenv `_ + + +Release 0.8.4 +------------- + +Improvements: + +- Refactored ``core.py`` and increased its unit test coverage to 80%. + HTTPretty is slightly more robust now. + +Bug fixes: + +- POST requests being called twice + `#100 `__ + +Release 0.6.5 +------------- + +Applied pull requests: + +- continue on EAGAIN socket errors: + `#102 `__ by + `kouk `__. +- Fix ``fake_gethostbyname`` for requests 2.0: + `#101 `__ by + `mgood `__ +- Add a way to match the querystrings: + `#98 `__ by + `ametaireau `__ +- Use common string case for URIInfo hostname comparison: + `#95 `__ by + `mikewaters `__ +- Expose httpretty.reset() to public API: + `#91 `__ by + `imankulov `__ +- Don't duplicate http ports number: + `#89 `__ by + `mardiros `__ +- Adding parsed\_body parameter to simplify checks: + `#88 `__ by + `toumorokoshi `__ +- Use the real socket if it's not HTTP: + `#87 `__ by + `mardiros `__ + +Release 0.6.2 +------------- + +- Fixing bug of lack of trailing slashes + `#73 `__ +- Applied pull requests + `#71 `__ and + `#72 `__ by + @andresriancho +- Keyword arg coercion fix by @dupuy +- @papaeye fixed content-length calculation. + +Release 0.6.1 +------------- + +- New API, no more camel case and everything is available through a + simple import: + +.. code:: python + + import httpretty + + @httpretty.activate + def test_function(): + # httpretty.register_uri(...) + # make request... + pass + +- Re-organized module into submodules + +Release 0.5.14 +-------------- + +- Delegate calls to other methods on socket + +- `Normalized + header `__ + strings + +- Callbacks are `more intelligent + now `__ + +- Normalize urls matching for url quoting + +Release 0.5.12 +-------------- + +- HTTPretty doesn't hang when using other application protocols under a + @httprettified decorated test. + +Release 0.5.11 +-------------- + +- Ability to know whether HTTPretty is or not enabled through + ``httpretty.is_enabled()`` + +Release 0.5.10 +-------------- + +- Support to multiple methods per registered URL. Thanks @hughsaunders + +Release 0.5.9 +------------- + +- Fixed python 3 support. Thanks @spulec + +Release 0.5.8 +------------- + +- Support to `register regular expressions to match + urls <#matching-regular-expressions>`__ +- `Body callback <#dynamic-responses-through-callbacks>`__ suppport +- Python 3 support diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..1b47afb --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- + +import sys +import sphinx_rtd_theme +try: + from pathlib2 import Path +except ImportError: + from pathlib import Path + +project_path = Path(__file__).absolute().parent.joinpath('../..') + +sys.path.insert(0, project_path.as_posix()) + +from httpretty.version import version # noqa + + +project = 'HTTPretty' +copyright = '2011-2021, Gabriel Falcao' +author = 'Gabriel Falcao' + +# The short X.Y version +version = version +# The full version, including alpha/beta/rc tags +release = version + + +extensions = [ + 'sphinx.ext.napoleon', + 'sphinx.ext.autodoc', + 'sphinx.ext.doctest', + 'sphinx.ext.intersphinx', + 'sphinx.ext.coverage', + 'sphinx.ext.ifconfig', + 'sphinx.ext.viewcode', + 'sphinx.ext.githubpages', + 'sphinx.ext.autosummary', + 'sphinx.ext.autosummary', + 'sphinxcontrib.asciinema', +] + +templates_path = ['_templates'] + +source_suffix = '.rst' +master_doc = 'index' +language = None +exclude_patterns = [] +pygments_style = 'friendly' +html_theme = "sphinx_rtd_theme" +html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] +# html_theme_options = {} +html_static_path = ['_static'] + +htmlhelp_basename = 'HTTPrettydoc' + +latex_elements = {} + +latex_documents = [ + (master_doc, 'HTTPretty.tex', 'HTTPretty Documentation', + 'Gabriel Falcao', 'manual'), +] + +man_pages = [ + (master_doc, 'httpretty', 'HTTPretty Documentation', + [author], 1) +] + + +texinfo_documents = [ + (master_doc, 'HTTPretty', 'HTTPretty Documentation', + author, 'HTTPretty', 'One line description of project.', + 'Miscellaneous'), +] + + +epub_title = project +epub_author = author +epub_publisher = author +epub_copyright = copyright + +epub_exclude_files = ['search.html'] +intersphinx_mapping = { + 'python': ('https://docs.python.org/3', None), + + 'httplib2': ('https://httplib2.readthedocs.io/en/latest/', None), + 'requests': ('https://requests.readthedocs.io/en/master/', None), + 'urllib3': ('https://urllib3.readthedocs.io/en/latest/', None), +} diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst new file mode 100644 index 0000000..99d390b --- /dev/null +++ b/docs/source/contributing.rst @@ -0,0 +1,71 @@ +Hacking on HTTPretty +==================== + +install development dependencies +-------------------------------- + + +.. note:: HTTPretty uses `GNU Make + `_ as default build + tool. + + +.. code:: bash + + make dependencies + + +next steps +---------- + +1. run the tests with make: + +.. code:: bash + + make tests + +2. hack at will +3. commit, push etc +4. send a pull request + + +License +======= + +:: + + + Copyright (C) <2011-2021> Gabriel Falcão + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + +Main contributors +================= + +HTTPretty has received `many contributions `_ +but some folks made remarkable contributions and deserve extra credit: + +- Andrew Gross ~> `@andrewgross `_ +- Hugh Saunders ~> `@hughsaunders `_ +- James Rowe ~> `@JNRowe `_ +- Matt Luongo ~> `@mhluongo `_ +- Steve Pulec ~> `@spulec `_ diff --git a/docs/source/guides.rst b/docs/source/guides.rst new file mode 100644 index 0000000..6349240 --- /dev/null +++ b/docs/source/guides.rst @@ -0,0 +1,119 @@ +.. _guides: + + +Guides +###### + +A series of guides to using HTTPretty for various interesting +purposes. + + +.. _matching_urls_via_regular_expressions: + +Matching URLs via regular expressions +===================================== + +You can pass a compiled regular expression via :py:func:`re.compile`, +for example for intercepting all requests to a specific host. + +**Example:** + + +.. literalinclude:: _static/regex-example.py + :emphasize-lines: 8,10,13 + + +Response Callbacks +================== + + + +You can use the `body` parameter of +:py:meth:`~httpretty.core.httpretty.register_uri` in useful, practical +ways because it accepts a :py:func:`callable` as value. + +As matter of example, this is analogous to `defining routes in Flask +`_ when combined with :ref:`matching urls via regular expressions ` + +This analogy breaks down, though, because HTTPretty does not provide +tools to make it easy to handle cookies, parse querystrings etc. + +So far this has been a deliberate decision to keep HTTPretty operating +mostly at the TCP socket level. + +Nothing prevents you from being creative with callbacks though, and as +you will see in the examples below, the request parameter is an +instance of :py:class:`~httpretty.core.HTTPrettyRequest` which has +everything you need to create elaborate fake APIs. + + +Defining callbacks +------------------ + +The body parameter callback must: + +- Accept 3 arguments: + + - `request` - :py:class:`~httpretty.core.HTTPrettyRequest` + - `uri` - :py:class:`str` + - `headers` - :py:class:`dict` with default response headers (including the ones from the parameters ``adding_headers`` and ``forcing_headers`` of :py:meth:`~httpretty.core.httpretty.register_uri` + +- Return 3 a tuple (or list) with 3 values + + - :py:class:`int` - HTTP Status Code + - :py:class:`dict` - Response Headers + - :py:class:`st` - Response Body + +.. important:: + The **Content-Length** should match the byte length of the body. + + Changing **Content-Length** it in your handler can cause your HTTP + client to misbehave, be very intentional when modifying it in our + callback. + + The suggested way to manipulate headers is by modifying the + response headers passed as argument and returning them in the tuple + at the end. + + .. code:: python + + from typing import Tuple + from httpretty.core import HTTPrettyRequest + + def my_callback( + request: HTTPrettyRequest, + url: str, + headers: dict + + ) -> Tuple[int, dict, str]: + + headers['Content-Type'] = 'text/plain' + return (200, headers, "the body") + + HTTPretty.register_uri(HTTPretty.GET, "https://test.com", body=my_callback) + + +Debug requests interactively with ipdb +-------------------------------------- + +The library `ipdb `_ comes in handy to +introspect the request interactively with auto-complete via IPython. + +.. literalinclude:: _static/guide-callback-regex-ipdb.py + :emphasize-lines: 12,16,17 + +.. asciinema:: 415981 + :preload: 1 + + +Emulating timeouts +------------------ + +In the bug report `#430 +`_ the contributor `@mariojonke +`_ provided a neat example of how to +emulate read timeout errors by "waiting" inside of a body callback. + + +.. literalinclude:: _static/read-timeout.py + :emphasize-lines: 11-13,21,28 diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..c2a30a6 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,80 @@ +.. HTTPretty documentation master file, created by + sphinx-quickstart on Sun Dec 13 07:25:00 2015. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +HTTPretty's - HTTP Client Mocking for Python +============================================ + +.. image:: https://github.com/gabrielfalcao/HTTPretty/raw/master/docs/source/_static/logo.svg?sanitize=true + +HTTP Client mocking tool for Python created by `Gabriel Falcão `_ . It provides a full fake TCP socket module. Inspired by `FakeWeb `_ + +Looking for the `Github Repository `_ ? + +**Python Support:** + +- **3.6** +- **3.7** +- **3.8** +- **3.9** + +.. image:: https://img.shields.io/pypi/dm/HTTPretty + :target: https://pypi.org/project/HTTPretty + +.. image:: https://img.shields.io/codecov/c/github/gabrielfalcao/HTTPretty + :target: https://codecov.io/gh/gabrielfalcao/HTTPretty + +.. image:: https://img.shields.io/github/workflow/status/gabrielfalcao/HTTPretty/HTTPretty%20Tests?label=Python%203.6%20-%203.9 + :target: https://github.com/gabrielfalcao/HTTPretty/actions + +.. image:: https://img.shields.io/readthedocs/httpretty + :target: https://httpretty.readthedocs.io/ + +.. image:: https://img.shields.io/github/license/gabrielfalcao/HTTPretty?label=Github%20License + :target: https://github.com/gabrielfalcao/HTTPretty/blob/master/COPYING + +.. image:: https://img.shields.io/pypi/v/HTTPretty + :target: https://pypi.org/project/HTTPretty + +.. image:: https://img.shields.io/pypi/l/HTTPretty?label=PyPi%20License + :target: https://pypi.org/project/HTTPretty + +.. image:: https://img.shields.io/pypi/format/HTTPretty + :target: https://pypi.org/project/HTTPretty + +.. image:: https://img.shields.io/pypi/status/HTTPretty + :target: https://pypi.org/project/HTTPretty + +.. image:: https://img.shields.io/pypi/pyversions/HTTPretty + :target: https://pypi.org/project/HTTPretty + +.. image:: https://img.shields.io/pypi/implementation/HTTPretty + :target: https://pypi.org/project/HTTPretty + +.. image:: https://img.shields.io/snyk/vulnerabilities/github/gabrielfalcao/HTTPretty + :target: https://github.com/gabrielfalcao/HTTPretty/network/alerts + +.. image:: https://img.shields.io/github/v/tag/gabrielfalcao/HTTPretty + :target: https://github.com/gabrielfalcao/HTTPretty/releases + +.. |Join the chat at https://gitter.im/gabrielfalcao/HTTPretty| image:: https://badges.gitter.im/gabrielfalcao/HTTPretty.svg + :target: https://gitter.im/gabrielfalcao/HTTPretty?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge + + +.. toctree:: + :maxdepth: 2 + + introduction + guides + acks + api + contributing + changelog + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst new file mode 100644 index 0000000..a5339d2 --- /dev/null +++ b/docs/source/introduction.rst @@ -0,0 +1,182 @@ +.. _introduction: + +`Github `_ + + +What is HTTPretty ? +################### + +.. highlight:: python + +Once upon a time a python developer wanted to use a RESTful api, +everything was fine but until the day he needed to test the code that +hits the RESTful API: what if the API server is down? What if its +content has changed ? + +Don't worry, HTTPretty is here for you: + +:: + + import logging + import requests + import httpretty + + from sure import expect + + logging.getLogger('httpretty.core').setLevel(logging.DEBUG) + + @httpretty.activate(allow_net_connect=False) + def test_yipit_api_returning_deals(): + httpretty.register_uri(httpretty.GET, "http://api.yipit.com/v1/deals/", + body='[{"title": "Test Deal"}]', + content_type="application/json") + + response = requests.get('http://api.yipit.com/v1/deals/') + + expect(response.json()).to.equal([{"title": "Test Deal"}]) + + +A more technical description +============================ + +HTTPretty is a python library that swaps the modules :py:mod:`socket` +and :py:mod:`ssl` with fake implementations that intercept HTTP +requests at the level of a TCP connection. + +It is inspired on Ruby's `FakeWeb `_. + +If you come from the Ruby programming language this would probably sound familiar :smiley: + +Installing +========== + +Installing httpretty is as easy as: + +.. highlight:: bash + +:: + + pip install httpretty + + +Demo +#### + +expecting a simple response body +================================ + + +.. code:: python + + import requests + import httpretty + + def test_one(): + httpretty.enable(verbose=True, allow_net_connect=False) # enable HTTPretty so that it will monkey patch the socket module + httpretty.register_uri(httpretty.GET, "http://yipit.com/", + body="Find the best daily deals") + + response = requests.get('http://yipit.com') + + assert response.text == "Find the best daily deals" + + httpretty.disable() # disable afterwards, so that you will have no problems in code that uses that socket module + httpretty.reset() # reset HTTPretty state (clean up registered urls and request history) + + +making assertions in a callback that generates the response body +================================================================ + +.. code:: python + + import requests + import json + import httpretty + + @httpretty.activate + def test_with_callback_response(): + def request_callback(request, uri, response_headers): + content_type = request.headers.get('Content-Type') + assert request.body == '{"nothing": "here"}', 'unexpected body: {}'.format(request.body) + assert content_type == 'application/json', 'expected application/json but received Content-Type: {}'.format(content_type) + return [200, response_headers, json.dumps({"hello": "world"})] + + httpretty.register_uri( + httpretty.POST, "https://httpretty.example.com/api", + body=request_callback) + + response = requests.post('https://httpretty.example.com/api', headers={'Content-Type': 'application/json'}, data='{"nothing": "here"}') + + expect(response.json()).to.equal({"hello": "world"}) + + +Link headers +============ + + + Tests link headers by using the `adding_headers` parameter. + + + .. code:: python + + import requests + from sure import expect + import httpretty + + + @httpretty.activate + def test_link_response(): + first_url = "http://foo-api.com/data" + second_url = "http://foo-api.com/data?page=2" + link_str = "<%s>; rel='next'" % second_url + + httpretty.register_uri( + httpretty.GET, + first_url, + body='{"success": true}', + status=200, + content_type="text/json", + adding_headers={"Link": link_str}, + ) + httpretty.register_uri( + httpretty.GET, + second_url, + body='{"success": false}', + status=500, + content_type="text/json", + ) + # Performs a request to `first_url` followed by some testing + response = requests.get(first_url) + expect(response.json()).to.equal({"success": True}) + expect(response.status_code).to.equal(200) + next_url = response.links["next"]["url"] + expect(next_url).to.equal(second_url) + + # Follow the next URL and perform some testing. + response2 = requests.get(next_url) + expect(response2.json()).to.equal({"success": False}) + expect(response2.status_code).to.equal(500) + + +Motivation +########## + +When building systems that access external resources such as RESTful +webservices, XMLRPC or even simple HTTP requests, we stumble in the +problem: + + *"I'm gonna need to mock all those requests"* + +It can be a bit of a hassle to use something like +:py:class:`mock.Mock` to stub the requests, this can work well for +low-level unit tests but when writing functional or integration tests +we should be able to allow the http calls to go through the TCP socket +module. + +HTTPretty `monkey patches +`_ Python's +:py:mod:`socket` core module with a fake version of the module. + +Because HTTPretty implements a fake the modules :py:mod:`socket` and +:py:mod:`ssl` you can use write tests to code against any HTTP library +that use those modules. diff --git a/httpretty.egg-info/PKG-INFO b/httpretty.egg-info/PKG-INFO new file mode 100644 index 0000000..df3fece --- /dev/null +++ b/httpretty.egg-info/PKG-INFO @@ -0,0 +1,190 @@ +Metadata-Version: 1.2 +Name: httpretty +Version: 1.1.4 +Summary: HTTP client mock for Python +Home-page: https://httpretty.readthedocs.io/en/latest/ +Author: Gabriel Falcao +Author-email: gabriel@nacaolivre.org +License: MIT +Project-URL: Documentation, https://httpretty.readthedocs.io/en/latest/ +Project-URL: Source Code, https://github.com/gabrielfalcao/httpretty +Project-URL: Issue Tracker, https://github.com/gabrielfalcao/httpretty/issues +Project-URL: Continuous Integration, https://github.com/gabrielfalcao/HTTPretty/actions/workflows/pyenv.yml?query=branch%3Amaster+event%3Apush +Project-URL: Test Coverage, https://codecov.io/gh/gabrielfalcao/httpretty +Description: HTTPretty 1.1.4 + =============== + + .. image:: https://github.com/gabrielfalcao/HTTPretty/raw/master/docs/source/_static/logo.svg?sanitize=true + + HTTP Client mocking tool for Python created by `Gabriel Falcão `_ . It provides a full fake TCP socket module. Inspired by `FakeWeb `_ + + + - `Github Repository `_ + - `Documentation `_ + - `PyPI Package `_ + + + **Python Support:** + + - **3.6** + - **3.7** + - **3.8** + - **3.9** + + .. image:: https://img.shields.io/pypi/dm/HTTPretty + :target: https://pypi.org/project/HTTPretty + + .. image:: https://img.shields.io/codecov/c/github/gabrielfalcao/HTTPretty + :target: https://codecov.io/gh/gabrielfalcao/HTTPretty + + .. image:: https://img.shields.io/github/workflow/status/gabrielfalcao/HTTPretty/HTTPretty%20Tests?label=Python%203.6%20-%203.9 + :target: https://github.com/gabrielfalcao/HTTPretty/actions + + .. image:: https://img.shields.io/readthedocs/httpretty + :target: https://httpretty.readthedocs.io/ + + .. image:: https://img.shields.io/github/license/gabrielfalcao/HTTPretty?label=Github%20License + :target: https://github.com/gabrielfalcao/HTTPretty/blob/master/COPYING + + .. image:: https://img.shields.io/pypi/v/HTTPretty + :target: https://pypi.org/project/HTTPretty + + .. image:: https://img.shields.io/pypi/l/HTTPretty?label=PyPi%20License + :target: https://pypi.org/project/HTTPretty + + .. image:: https://img.shields.io/pypi/format/HTTPretty + :target: https://pypi.org/project/HTTPretty + + .. image:: https://img.shields.io/pypi/status/HTTPretty + :target: https://pypi.org/project/HTTPretty + + .. image:: https://img.shields.io/pypi/pyversions/HTTPretty + :target: https://pypi.org/project/HTTPretty + + .. image:: https://img.shields.io/pypi/implementation/HTTPretty + :target: https://pypi.org/project/HTTPretty + + .. image:: https://img.shields.io/snyk/vulnerabilities/github/gabrielfalcao/HTTPretty + :target: https://github.com/gabrielfalcao/HTTPretty/network/alerts + + .. image:: https://img.shields.io/github/v/tag/gabrielfalcao/HTTPretty + :target: https://github.com/gabrielfalcao/HTTPretty/releases + + .. |Join the chat at https://gitter.im/gabrielfalcao/HTTPretty| image:: https://badges.gitter.im/gabrielfalcao/HTTPretty.svg + :target: https://gitter.im/gabrielfalcao/HTTPretty?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge + + Install + ------- + + .. code:: bash + + pip install httpretty + + + + Common Use Cases + ================ + + - Test-driven development of API integrations + - Fake responses of external APIs + - Record and playback HTTP requests + + + Simple Example + -------------- + + .. code:: python + + import sure + import httpretty + import requests + + + @httpretty.activate(verbose=True, allow_net_connect=False) + def test_httpbin(): + httpretty.register_uri( + httpretty.GET, + "https://httpbin.org/ip", + body='{"origin": "127.0.0.1"}' + ) + + response = requests.get('https://httpbin.org/ip') + response.json().should.equal({'origin': '127.0.0.1'}) + + httpretty.latest_requests().should.have.length_of(1) + httpretty.last_request().should.equal(httpretty.latest_requests()[0]) + httpretty.last_request().body.should.equal('{"origin": "127.0.0.1"}') + + + checking multiple responses + --------------------------- + + .. code:: python + + @httpretty.activate(verbose=True, allow_net_connect=False) + def test_post_bodies(): + url = 'http://httpbin.org/post' + httpretty.register_uri(httpretty.POST, url, status=200) + httpretty.register_uri(httpretty.POST, url, status=400) + requests.post(url, data={'foo': 'bar'}) + requests.post(url, data={'zoo': 'zoo'}) + assert 'foo=bar' in httpretty.latest_requests()[0].body + assert 'zoo=bar' in httpretty.latest_requests()[1].body + + + License + ======= + + :: + + + Copyright (C) <2011-2021> Gabriel Falcão + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + Main contributors + ================= + + HTTPretty has received `many contributions `_ + but some folks made remarkable contributions and deserve extra credit: + + - Andrew Gross ~> `@andrewgross `_ + - Hugh Saunders ~> `@hughsaunders `_ + - James Rowe ~> `@JNRowe `_ + - Matt Luongo ~> `@mhluongo `_ + - Steve Pulec ~> `@spulec `_ + - Miro Hrončok ~> `@hroncok `_ + Mario Jonke ~> `@mariojonke `_ + +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP +Classifier: Topic :: Software Development :: Testing +Requires-Python: >=3 diff --git a/httpretty.egg-info/SOURCES.txt b/httpretty.egg-info/SOURCES.txt new file mode 100644 index 0000000..9f47a71 --- /dev/null +++ b/httpretty.egg-info/SOURCES.txt @@ -0,0 +1,82 @@ +COPYING +MANIFEST.in +Makefile +README.rst +development.txt +requirements.txt +setup.cfg +setup.py +tox.ini +docs/make.bat +docs/build/doctrees/acks.doctree +docs/build/doctrees/api.doctree +docs/build/doctrees/changelog.doctree +docs/build/doctrees/contributing.doctree +docs/build/doctrees/environment.pickle +docs/build/doctrees/guides.doctree +docs/build/doctrees/index.doctree +docs/build/doctrees/introduction.doctree +docs/source/acks.rst +docs/source/api.rst +docs/source/changelog.rst +docs/source/conf.py +docs/source/contributing.rst +docs/source/guides.rst +docs/source/index.rst +docs/source/introduction.rst +docs/source/_static/guide-callback-regex-ipdb.py +docs/source/_static/logo.svg +docs/source/_static/read-timeout.py +docs/source/_static/regex-example.py +docs/source/_static/tmplun_dcms-ascii.cast +docs/source/_static/__pycache__/guide-callback-regex-ipdb.cpython-38.pyc +docs/source/_static/__pycache__/read-timeout.cpython-38-pytest-6.2.4.pyc +docs/source/_static/__pycache__/read-timeout.cpython-38.pyc +docs/source/_static/__pycache__/regex-example.cpython-38.pyc +httpretty/__init__.py +httpretty/compat.py +httpretty/core.py +httpretty/errors.py +httpretty/http.py +httpretty/utils.py +httpretty/version.py +httpretty.egg-info/PKG-INFO +httpretty.egg-info/SOURCES.txt +httpretty.egg-info/dependency_links.txt +httpretty.egg-info/not-zip-safe +httpretty.egg-info/top_level.txt +tests/__init__.py +tests/compat.py +tests/bugfixes/nosetests/__init__.py +tests/bugfixes/nosetests/test_242_ssl_bad_handshake.py +tests/bugfixes/nosetests/test_387_regex_port.py +tests/bugfixes/nosetests/test_388_unmocked_error_with_url.py +tests/bugfixes/nosetests/test_413_regex.py +tests/bugfixes/nosetests/test_414_httpx.py +tests/bugfixes/nosetests/test_416_boto3.py +tests/bugfixes/nosetests/test_417_openssl.py +tests/bugfixes/nosetests/test_425_latest_requests.py +tests/bugfixes/nosetests/test_430_respect_timeout.py +tests/bugfixes/nosetests/test_eventlet.py +tests/bugfixes/nosetests/test_redis.py +tests/bugfixes/nosetests/test_tornado_bind_unused_port.py +tests/bugfixes/pytest/test_426_mypy_segfault.py +tests/functional/__init__.py +tests/functional/base.py +tests/functional/test_bypass.py +tests/functional/test_debug.py +tests/functional/test_decorator.py +tests/functional/test_fakesocket.py +tests/functional/test_httplib2.py +tests/functional/test_passthrough.py +tests/functional/test_requests.py +tests/functional/test_urllib2.py +tests/functional/testserver.py +tests/functional/fixtures/playback-1.json +tests/pyopenssl/__init__.py +tests/pyopenssl/test_mock.py +tests/unit/__init__.py +tests/unit/test_core.py +tests/unit/test_http.py +tests/unit/test_httpretty.py +tests/unit/test_main.py \ No newline at end of file diff --git a/httpretty.egg-info/dependency_links.txt b/httpretty.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/httpretty.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/httpretty.egg-info/not-zip-safe b/httpretty.egg-info/not-zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/httpretty.egg-info/not-zip-safe @@ -0,0 +1 @@ + diff --git a/httpretty.egg-info/top_level.txt b/httpretty.egg-info/top_level.txt new file mode 100644 index 0000000..b0284b1 --- /dev/null +++ b/httpretty.egg-info/top_level.txt @@ -0,0 +1 @@ +httpretty diff --git a/httpretty/__init__.py b/httpretty/__init__.py new file mode 100644 index 0000000..5e7d01f --- /dev/null +++ b/httpretty/__init__.py @@ -0,0 +1,94 @@ +# #!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# flake8: noqa + + +from . import core + +from .core import httpretty, httprettified, EmptyRequestHeaders +from .core import set_default_thread_timeout, get_default_thread_timeout +from .errors import HTTPrettyError, UnmockedError +from .version import version + +__version__ = version + +# aliases +EmptyRequestHeaders = core.EmptyRequestHeaders +Entry = core.Entry +HTTPrettyRequestEmpty = core.HTTPrettyRequestEmpty +URIInfo = core.URIInfo +URIMatcher = core.URIMatcher +httprettified = core.httprettified +httprettized = core.httprettized +httpretty = core.httpretty + +HTTPretty = httpretty +activate = httprettified + +enabled = httprettized + +enable = httpretty.enable +register_uri = httpretty.register_uri +disable = httpretty.disable +is_enabled = httpretty.is_enabled +reset = httpretty.reset +Response = httpretty.Response + +GET = httpretty.GET +"""Match requests of GET method""" +PUT = httpretty.PUT +"""Match requests of PUT method""" +POST = httpretty.POST +"""Match requests of POST method""" +DELETE = httpretty.DELETE +"""Match requests of DELETE method""" +HEAD = httpretty.HEAD +"""Match requests of HEAD method""" +PATCH = httpretty.PATCH +"""Match requests of OPTIONS method""" +OPTIONS = httpretty.OPTIONS +"""Match requests of OPTIONS method""" +CONNECT = httpretty.CONNECT +"""Match requests of CONNECT method""" + + +def last_request(): + """ + :returns: the last :py:class:`~httpretty.core.HTTPrettyRequest` + """ + return httpretty.last_request + + +def latest_requests(): + """returns the history of made requests""" + return httpretty.latest_requests + + +def has_request(): + """ + :returns: bool - whether any request has been made + """ + return not isinstance(httpretty.last_request.headers, EmptyRequestHeaders) diff --git a/httpretty/compat.py b/httpretty/compat.py new file mode 100644 index 0000000..a8f551c --- /dev/null +++ b/httpretty/compat.py @@ -0,0 +1,60 @@ +# #!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +import io +import types +from urllib.parse import urlsplit +from urllib.parse import urlunsplit +from urllib.parse import parse_qs +from urllib.parse import quote +from urllib.parse import quote_plus +from urllib.parse import unquote +from urllib.parse import urlencode +from http.server import BaseHTTPRequestHandler + +unquote_utf8 = unquote + + +def encode_obj(in_obj): + return in_obj + + +class BaseClass(object): + def __repr__(self): + return self.__str__() + + +__all__ = [ + 'BaseClass', + 'BaseHTTPRequestHandler', + 'quote', + 'quote_plus', + 'urlencode', + 'urlunsplit', + 'urlsplit', + 'parse_qs', +] diff --git a/httpretty/core.py b/httpretty/core.py new file mode 100644 index 0000000..19715e0 --- /dev/null +++ b/httpretty/core.py @@ -0,0 +1,2082 @@ +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +import io +import time +import codecs +import contextlib +import functools +import hashlib +import inspect +import logging +import itertools +import json +import types +import re +import socket +import tempfile +import threading +import traceback +import warnings + +from functools import partial +from typing import Callable + +from .compat import ( + BaseClass, + BaseHTTPRequestHandler, + quote, + quote_plus, + urlencode, + encode_obj, + urlunsplit, + urlsplit, + parse_qs, + unquote_utf8, +) +from .http import ( + STATUSES, + HttpBaseClass, + parse_requestline, + last_requestline, +) + +from .utils import ( + utf8, + decode_utf8, +) + +from .errors import HTTPrettyError, UnmockedError + +from datetime import datetime +from datetime import timedelta +from errno import EAGAIN + +class __internals__: + thread_timeout = 0.1 # https://github.com/gabrielfalcao/HTTPretty/issues/430 + temp_files = [] + threads = [] + + @classmethod + def cleanup_sockets(cls): + cls.cleanup_temp_files() + cls.cleanup_threads() + + @classmethod + def cleanup_threads(cls): + for t in cls.threads: + t.join(cls.thread_timeout) + if t.is_alive(): + raise socket.timeout(cls.thread_timeout) + + @classmethod + def create_thread(cls, *args, **kwargs): + return threading.Thread(*args, **kwargs) + + @classmethod + def cleanup_temp_files(cls): + for fd in cls.temp_files[:]: + try: + fd.close() + except Exception as e: + logger.debug('error closing file {}: {}'.format(fd, e)) + cls.temp_files.remove(fd) + + @classmethod + def create_temp_file(cls): + fd = tempfile.TemporaryFile() + cls.temp_files.append(fd) + return fd + +def set_default_thread_timeout(timeout): + """sets the default thread timeout for HTTPretty threads + + :param timeout: int + """ + __internals__.thread_timeout = timeout + +def get_default_thread_timeout(): + """sets the default thread timeout for HTTPretty threads + + :returns: int + """ + + return __internals__.thread_timeout + + +SOCKET_GLOBAL_DEFAULT_TIMEOUT = socket._GLOBAL_DEFAULT_TIMEOUT +old_socket = socket.socket +old_socketpair = getattr(socket, 'socketpair', None) +old_SocketType = socket.SocketType +old_create_connection = socket.create_connection +old_gethostbyname = socket.gethostbyname +old_gethostname = socket.gethostname +old_getaddrinfo = socket.getaddrinfo +old_socksocket = None +old_ssl_wrap_socket = None +old_sslwrap_simple = None +old_sslsocket = None +old_sslcontext_wrap_socket = None +old_sslcontext = None + +MULTILINE_ANY_REGEX = re.compile(r'.*', re.M) +hostname_re = re.compile(r'\^?(?:https?://)?[^:/]*[:/]?') + + +logger = logging.getLogger(__name__) + +try: # pragma: no cover + import socks + old_socksocket = socks.socksocket +except ImportError: + socks = None + +try: # pragma: no cover + import ssl + old_sslcontext_class = ssl.SSLContext + old_sslcontext = ssl.create_default_context() + old_ssl_wrap_socket = old_sslcontext.wrap_socket + try: + old_sslcontext_wrap_socket = ssl.SSLContext.wrap_socket + except AttributeError: + pass + old_sslsocket = ssl.SSLSocket +except ImportError: # pragma: no cover + ssl = None + +try: + import _ssl +except ImportError: + _ssl = None +# used to handle error caused by ndg-httpsclient +pyopenssl_overrides_inject = [] +pyopenssl_overrides_extract = [] +try: + from requests.packages.urllib3.contrib.pyopenssl import inject_into_urllib3, extract_from_urllib3 + pyopenssl_overrides_extract.append(extract_from_urllib) + pyopenssl_overrides_inject.append(inject_from_urllib) +except Exception: + pass + + + +try: + from urllib3.contrib.pyopenssl import extract_from_urllib3, inject_into_urllib3 + pyopenssl_overrides_extract.append(extract_from_urllib) + pyopenssl_overrides_inject.append(inject_from_urllib) +except Exception: + pass + + +try: + import requests.packages.urllib3.connection as requests_urllib3_connection + old_requests_ssl_wrap_socket = requests_urllib3_connection.ssl_wrap_socket +except ImportError: + requests_urllib3_connection = None + old_requests_ssl_wrap_socket = None + +try: + import eventlet + import eventlet.green +except ImportError: + eventlet = None + +DEFAULT_HTTP_PORTS = frozenset([80]) +POTENTIAL_HTTP_PORTS = set(DEFAULT_HTTP_PORTS) +DEFAULT_HTTPS_PORTS = frozenset([443]) +POTENTIAL_HTTPS_PORTS = set(DEFAULT_HTTPS_PORTS) + + + +def FALLBACK_FUNCTION(x): + return x + + +class HTTPrettyRequest(BaseHTTPRequestHandler, BaseClass): + r"""Represents a HTTP request. It takes a valid multi-line, + ``\r\n`` separated string with HTTP headers and parse them out using + the internal `parse_request` method. + + It also replaces the `rfile` and `wfile` attributes with :py:class:`io.BytesIO` + instances so that we guarantee that it won't make any I/O, neither + for writing nor reading. + + It has some convenience attributes: + + ``headers`` -> a mimetype object that can be cast into a dictionary, + contains all the request headers + + ``protocol`` -> the protocol of this host, inferred from the port + of the underlying fake TCP socket. + + ``host`` -> the hostname of this request. + + ``url`` -> the full url of this request. + + ``path`` -> the path of the request. + + ``method`` -> the HTTP method used in this request. + + ``querystring`` -> a dictionary containing lists with the + attributes. Please notice that if you need a single value from a + query string you will need to get it manually like: + + ``body`` -> the request body as a string. + + ``parsed_body`` -> the request body parsed by ``parse_request_body``. + + .. testcode:: + + >>> request.querystring + {'name': ['Gabriel Falcao']} + >>> print request.querystring['name'][0] + + """ + def __init__(self, headers, body='', sock=None, path_encoding = 'iso-8859-1'): + # first of all, lets make sure that if headers or body are + # unicode strings, it must be converted into a utf-8 encoded + # byte string + self.created_at = time.time() + self.raw_headers = utf8(headers.strip()) + self._body = utf8(body) + self.connection = sock + # Now let's concatenate the headers with the body, and create + # `rfile` based on it + self.rfile = io.BytesIO(b'\r\n\r\n'.join([self.raw_headers, self.body])) + + # Creating `wfile` as an empty BytesIO, just to avoid any + # real I/O calls + self.wfile = io.BytesIO() + + # parsing the request line preemptively + self.raw_requestline = self.rfile.readline() + + # initiating the error attributes with None + self.error_code = None + self.error_message = None + + # Parse the request based on the attributes above + if not self.parse_request(): + return + + # Now 2 convenient attributes for the HTTPretty API: + + # - `path` + # - `querystring` holds a dictionary with the parsed query string + # - `parsed_body` a string + try: + self.path = self.path.encode(path_encoding) + except UnicodeDecodeError: + pass + + self.path = decode_utf8(self.path) + + qstring = self.path.split("?", 1)[-1] + self.querystring = self.parse_querystring(qstring) + + # And the body will be attempted to be parsed as + # `application/json` or `application/x-www-form-urlencoded` + """a dictionary containing parsed request body or None if + HTTPrettyRequest doesn't know how to parse it. It currently + supports parsing body data that was sent under the + ``content`-type` headers values: ``application/json`` or + ``application/x-www-form-urlencoded`` + """ + self.parsed_body = self.parse_request_body(self._body) + + @property + def method(self): + """the HTTP method used in this request""" + return self.command + + @property + def protocol(self): + """the protocol used in this request""" + proto = '' + if not self.connection: + return '' + elif self.connection.is_http: + proto = 'http' + + if self.connection.is_secure: + proto = 'https' + + return proto + + @property + def body(self): + return self._body + + @body.setter + def body(self, value): + self._body = utf8(value) + + # And the body will be attempted to be parsed as + # `application/json` or `application/x-www-form-urlencoded` + self.parsed_body = self.parse_request_body(self._body) + + def __nonzero__(self): + return bool(self.body) or bool(self.raw_headers) + + @property + def url(self): + """the full url of this recorded request""" + return "{}://{}{}".format(self.protocol, self.host, self.path) + + @property + def host(self): + return self.headers.get('Host') or '' + + def __str__(self): + tmpl = '' + return tmpl.format( + self.method, + self.url, + dict(self.headers), + len(self.body), + ) + + def parse_querystring(self, qs): + """parses an UTF-8 encoded query string into a dict of string lists + + :param qs: a querystring + :returns: a dict of lists + + """ + expanded = unquote_utf8(qs) + parsed = parse_qs(expanded) + result = {} + for k in parsed: + result[k] = list(map(decode_utf8, parsed[k])) + + return result + + def parse_request_body(self, body): + """Attempt to parse the post based on the content-type passed. + Return the regular body if not + + :param body: string + :returns: a python object such as dict or list in case the deserialization suceeded. Else returns the given param ``body`` + """ + + PARSING_FUNCTIONS = { + 'application/json': json.loads, + 'text/json': json.loads, + 'application/x-www-form-urlencoded': self.parse_querystring, + } + + content_type = self.headers.get('content-type', '') + + do_parse = PARSING_FUNCTIONS.get(content_type, FALLBACK_FUNCTION) + try: + body = decode_utf8(body) + return do_parse(body) + except Exception: + return body + + +class EmptyRequestHeaders(dict): + """A dict subclass used as internal representation of empty request + headers + """ + + +class HTTPrettyRequestEmpty(object): + """Represents an empty :py:class:`~httpretty.core.HTTPrettyRequest` + where all its properties are somehow empty or ``None`` + """ + + method = None + url = None + body = '' + headers = EmptyRequestHeaders() + + + +class FakeSockFile(object): + """Fake socket file descriptor. Under the hood all data is written in + a temporary file, giving it a real file descriptor number. + + """ + def __init__(self): + self.file = None + self._fileno = None + self.__closed__ = None + self.reset() + + def reset(self): + if self.file: + try: + self.file.close() + except Exception as e: + logger.debug('error closing file {}: {}'.format(self.file, e)) + self.file = None + + self.file = __internals__.create_temp_file() + self._fileno = self.file.fileno() + self.__closed__ = False + + def getvalue(self): + if hasattr(self.file, 'getvalue'): + value = self.file.getvalue() + else: + value = self.file.read() + self.file.seek(0) + return value + + def close(self): + if self.__closed__: + return + self.__closed__ = True + self.flush() + + def flush(self): + try: + super().flush() + except Exception as e: + logger.debug('error closing file {}: {}'.format(self, e)) + + try: + self.file.flush() + except Exception as e: + logger.debug('error closing file {}: {}'.format(self.file, e)) + + + + def fileno(self): + return self._fileno + + def __getattr__(self, name): + try: + return getattr(self.file, name) + except AttributeError: + return super().__getattribute__(name) + + def __del__(self): + try: + self.close() + except (ValueError, AttributeError): + pass + + # Adding the line below as a potential fix of github issue #426 + # that seems to be a compatible the solution of #413 + self.file.close() + + + +class FakeSSLSocket(object): + """Shorthand for :py:class:`~httpretty.core.fakesock` + """ + def __init__(self, sock, *args, **kw): + self._httpretty_sock = sock + + def __getattr__(self, attr): + return getattr(self._httpretty_sock, attr) + + +class FakeAddressTuple(object): + def __init__(self, fakesocket): + self.fakesocket = fakesocket + + def __getitem__(self, *args, **kw): + raise AssertionError('socket {} is not connected'.format(self.fakesocket.truesock)) + + +def fake_socketpair(*args, **kw): + with restored_libs(): + return old_socketpair(*args, **kw) + +class fakesock(object): + """ + fake :py:mod:`socket` + """ + class socket(object): + """drop-in replacement for :py:class:`socket.socket` + """ + _entry = None + _read_buf = None + + debuglevel = 0 + _sent_data = [] + is_secure = False + def __init__( + self, + family=socket.AF_INET, + type=socket.SOCK_STREAM, + proto=0, + fileno=None + ): + self.socket_family = family + self.socket_type = type + self.socket_proto = proto + if httpretty.allow_net_connect: + self.truesock = self.create_socket() + else: + self.truesock = None + + self._address = FakeAddressTuple(self) + self.__truesock_is_connected__ = False + self.fd = FakeSockFile() + self.fd.socket = fileno or self + self.timeout = socket._GLOBAL_DEFAULT_TIMEOUT + self._sock = fileno or self + self.is_http = False + self._bufsize = 32 * 1024 + + def __repr__(self): + return '{self.__class__.__module__}.{self.__class__.__name__}("{self.host}")'.format(**locals()) + + @property + def host(self): + return ":".join(map(str, self._address)) + + def create_socket(self, address=None): + return old_socket(self.socket_family, self.socket_type, self.socket_proto) + + def getpeercert(self, *a, **kw): + now = datetime.now() + shift = now + timedelta(days=30 * 12) + return { + 'notAfter': shift.strftime('%b %d %H:%M:%S GMT'), + 'subjectAltName': ( + ('DNS', '*.%s' % self._host), + ('DNS', self._host), + ('DNS', '*'), + ), + 'subject': ( + ( + ('organizationName', '*.%s' % self._host), + ), + ( + ('organizationalUnitName', + 'Domain Control Validated'), + ), + ( + ('commonName', '*.%s' % self._host), + ), + ), + } + + def ssl(self, sock, *args, **kw): + return sock + + def setsockopt(self, level, optname, value): + if httpretty.allow_net_connect and not self.truesock: + self.truesock = self.create_socket() + elif not self.truesock: + logger.debug('setsockopt(%s, %s, %s) failed', level, optname, value) + return + + return self.truesock.setsockopt(level, optname, value) + + def connect(self, address): + try: + self._address = (self._host, self._port) = address + except ValueError: + # We get here when the address is just a string pointing to a + # unix socket path/file + # + # See issue #206 + self.is_http = False + else: + ports_to_check = ( + POTENTIAL_HTTP_PORTS.union(POTENTIAL_HTTPS_PORTS)) + self.is_http = self._port in ports_to_check + self.is_secure = self._port in POTENTIAL_HTTPS_PORTS + + if not self.is_http: + self.connect_truesock(address=address) + elif self.truesock and not self.real_socket_is_connected(): + # TODO: remove nested if + matcher = httpretty.match_http_address(self._host, self._port) + if matcher is None: + self.connect_truesock(address=address) + + def bind(self, address): + self._address = (self._host, self._port) = address + if self.truesock: + self.bind_truesock(address) + + def bind_truesock(self, address): + if httpretty.allow_net_connect and not self.truesock: + self.truesock = self.create_socket() + elif not self.truesock: + raise UnmockedError('Failed to socket.bind() because because a real socket was never created.', address=address) + + return self.truesock.bind(address) + + def connect_truesock(self, request=None, address=None): + address = address or self._address + + if self.__truesock_is_connected__: + return self.truesock + + if request: + logger.warning('real call to socket.connect() for {request}'.format(**locals())) + elif address: + logger.warning('real call to socket.connect() for {address}'.format(**locals())) + else: + logger.warning('real call to socket.connect()') + + if httpretty.allow_net_connect and not self.truesock: + self.truesock = self.create_socket(address) + elif not self.truesock: + raise UnmockedError('Failed to socket.connect() because because a real socket was never created.', request=request, address=address) + + undo_patch_socket() + try: + hostname = self._address[0] + port = 80 + if len(self._address) == 2: + port = self._address[1] + if port == 443 and old_sslsocket: + self.truesock = old_ssl_wrap_socket(self.truesock, server_hostname=hostname) + + sock = self.truesock + + sock.connect(self._address) + self.__truesock_is_connected__ = True + self.truesock = sock + finally: + apply_patch_socket() + + return self.truesock + + def real_socket_is_connected(self): + return self.__truesock_is_connected__ + + def fileno(self): + if self.truesock: + return self.truesock.fileno() + return self.fd.fileno() + + def close(self): + if self.truesock: + self.truesock.close() + self.truesock = None + self.__truesock_is_connected__ = False + + def makefile(self, mode='r', bufsize=-1): + """Returns this fake socket's own tempfile buffer. + + If there is an entry associated with the socket, the file + descriptor gets filled in with the entry data before being + returned. + """ + self._mode = mode + self._bufsize = bufsize + + if self._entry: + t = __internals__.create_thread( + target=self._entry.fill_filekind, args=(self.fd,) + ) + + # execute body callback and send http response in a + # thread, wait for thread to finish within the timeout + # set via socket.settimeout() + t.start() + if self.timeout == SOCKET_GLOBAL_DEFAULT_TIMEOUT: + timeout = get_default_thread_timeout() + else: + timeout = self.timeout + + # fake socket timeout error by checking if the thread + # finished in time. + t.join(timeout) + if t.is_alive(): + # For more info check issue https://github.com/gabrielfalcao/HTTPretty/issues/430 + raise socket.timeout(timeout) + + return self.fd + + def real_sendall(self, data, *args, **kw): + """Sends data to the remote server. This method is called + when HTTPretty identifies that someone is trying to send + non-http data. + + The received bytes are written in this socket's tempfile + buffer so that HTTPretty can return it accordingly when + necessary. + """ + request = kw.pop('request', None) + if request: + bytecount = len(data) + logger.warning('{self}.real_sendall({bytecount} bytes) to {request.url} via {request.method} at {request.created_at}'.format(**locals())) + + if httpretty.allow_net_connect and not self.truesock: + + self.connect_truesock(request=request) + elif not self.truesock: + raise UnmockedError(request=request) + + if not self.is_http: + self.truesock.setblocking(1) + return self.truesock.sendall(data, *args, **kw) + + sock = self.connect_truesock(request=request) + + sock.setblocking(1) + sock.sendall(data, *args, **kw) + + should_continue = True + while should_continue: + try: + received = sock.recv(self._bufsize) + self.fd.write(received) + should_continue = bool(received.strip()) + + except socket.error as e: + if e.errno == EAGAIN: + continue + break + + self.fd.seek(0) + + def sendall(self, data, *args, **kw): + # if self.__truesock_is_connected__: + # return self.truesock.sendall(data, *args, **kw) + + self._sent_data.append(data) + self.fd = FakeSockFile() + self.fd.socket = self + if isinstance(data, str): + data = data.encode('utf-8') + elif not isinstance(data, bytes): + logger.debug('cannot sendall({data!r})') + data = bytes(data) + + try: + requestline, _ = data.split(b'\r\n', 1) + method, path, version = parse_requestline( + decode_utf8(requestline)) + is_parsing_headers = True + except ValueError: + path = '' + is_parsing_headers = False + + if self._entry is None: + # If the previous request wasn't mocked, don't + # mock the subsequent sending of data + return self.real_sendall(data, *args, **kw) + else: + method = self._entry.method + path = self._entry.info.path + + self.fd.seek(0) + + if not is_parsing_headers: + if len(self._sent_data) > 1: + headers = utf8(last_requestline(self._sent_data)) + meta = self._entry.request.headers + body = utf8(self._sent_data[-1]) + if meta.get('transfer-encoding', '') == 'chunked': + if not body.isdigit() and (body != b'\r\n') and (body != b'0\r\n\r\n'): + self._entry.request.body += body + else: + self._entry.request.body += body + + httpretty.historify_request(headers, body, sock=self) + return + + if path[:2] == '//': + path = '//' + path + # path might come with + s = urlsplit(path) + POTENTIAL_HTTP_PORTS.add(int(s.port or 80)) + parts = list(map(utf8, data.split(b'\r\n\r\n', 1))) + if len(parts) == 2: + headers, body = parts + else: + headers = '' + body = data + + request = httpretty.historify_request(headers, body, sock=self) + + info = URIInfo( + hostname=self._host, + port=self._port, + path=s.path, + query=s.query, + last_request=request + ) + + matcher, entries = httpretty.match_uriinfo(info) + + if not entries: + logger.debug('no entries matching {}'.format(request)) + self._entry = None + self._read_buf = None + self.real_sendall(data, request=request) + return + + self._entry = matcher.get_next_entry(method, info, request) + + def forward_and_trace(self, function_name, *a, **kw): + if not self.truesock: + raise UnmockedError('Failed to socket.{}() because because a real socket was never created.'.format(function_name)) + + callback = getattr(self.truesock, function_name) + return callback(*a, **kw) + + def settimeout(self, new_timeout): + self.timeout = new_timeout + if not self.is_http: + if self.truesock: + self.truesock.settimeout(new_timeout) + + def send(self, data, *args, **kwargs): + self.sendall(data, *args, **kwargs) + return len(data) + + def sendto(self, *args, **kwargs): + return self.forward_and_trace('sendto', *args, **kwargs) + + def recvfrom_into(self, *args, **kwargs): + return self.forward_and_trace('recvfrom_into', *args, **kwargs) + + def recv_into(self, *args, **kwargs): + return self.forward_and_trace('recv_into', *args, **kwargs) + + def recvfrom(self, *args, **kwargs): + return self.forward_and_trace('recvfrom', *args, **kwargs) + + def recv(self, buffersize=0, *args, **kwargs): + if not self._read_buf: + self._read_buf = io.BytesIO() + + if self._entry: + self._entry.fill_filekind(self._read_buf) + + if not self._read_buf: + raise UnmockedError('socket cannot recv(): {!r}'.format(self)) + + return self._read_buf.read(buffersize) + + def __getattr__(self, name): + if name in ('getsockopt', 'selected_alpn_protocol') and not self.truesock: + self.truesock = self.create_socket() + elif httpretty.allow_net_connect and not self.truesock: + # can't call self.connect_truesock() here because we + # don't know if user wants to execute server of client + # calls (or can they?) + self.truesock = self.create_socket() + elif not self.truesock: + # Special case for + # `hasattr(sock, "version")` call added in urllib3>=1.26. + if name == 'version': + raise AttributeError( + "HTTPretty synthesized this error to fix urllib3 compatibility " + "(see issue https://github.com/gabrielfalcao/HTTPretty/issues/409). " + "Please open an issue if this error causes further unexpected issues." + ) + + raise UnmockedError('Failed to socket.{} because because a real socket does not exist'.format(name)) + + return getattr(self.truesock, name) + +def with_socket_is_secure(sock, kw): + sock.is_secure = True + sock.kwargs = kw + for k, v in kw.items(): + setattr(sock, k, v) + return sock + +def fake_wrap_socket(orig_wrap_socket_fn, *args, **kw): + """drop-in replacement for py:func:`ssl.wrap_socket` + """ + if 'sock' in kw: + sock = kw['sock'] + else: + sock = args[0] + + server_hostname = kw.get('server_hostname') + if server_hostname is not None: + matcher = httpretty.match_https_hostname(server_hostname) + if matcher is None: + logger.debug('no requests registered for hostname: "{}"'.format(server_hostname)) + return with_socket_is_secure(sock, kw) + + return with_socket_is_secure(sock, kw) + + +def create_fake_connection( + address, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + source_address=None): + """drop-in replacement for :py:func:`socket.create_connection`""" + s = fakesock.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP) + if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT: + s.settimeout(timeout) + + if isinstance(source_address, tuple) and len(source_address) == 2: + source_address[1] = int(source_address[1]) + + if source_address: + s.bind(source_address) + s.connect(address) + return s + + +def fake_gethostbyname(host): + """drop-in replacement for :py:func:`socket.gethostbyname`""" + return '127.0.0.1' + + +def fake_gethostname(): + """drop-in replacement for :py:func:`socket.gethostname`""" + return 'localhost' + + +def fake_getaddrinfo( + host, port, family=None, socktype=None, proto=None, flags=None): + """drop-in replacement for :py:func:`socket.getaddrinfo`""" + return [(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP, + '', (host, port)), + (socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_TCP, + '', (host, port))] + + +class Entry(BaseClass): + """Created by :py:meth:`~httpretty.core.httpretty.register_uri` and + stored in memory as internal representation of a HTTP + request/response definition. + + Args: + method (str): One of ``httpretty.GET``, ``httpretty.PUT``, ``httpretty.POST``, ``httpretty.DELETE``, ``httpretty.HEAD``, ``httpretty.PATCH``, ``httpretty.OPTIONS``, ``httpretty.CONNECT``. + uri (str|re.Pattern): The URL to match + adding_headers (dict): Extra headers to be added to the response + forcing_headers (dict): Overwrite response headers. + status (int): The status code for the response, defaults to ``200``. + streaming (bool): Whether should stream the response into chunks via generator. + headers: Headers to inject in the faked response. + + Returns: + httpretty.Entry: containing the request-matching metadata. + + + .. warning:: When using the ``forcing_headers`` option make sure to add the header ``Content-Length`` to match at most the total body length, otherwise some HTTP clients can hang indefinitely. + """ + def __init__(self, method, uri, body, + adding_headers=None, + forcing_headers=None, + status=200, + streaming=False, + **headers): + + self.method = method + self.uri = uri + self.info = None + self.request = None + + self.body_is_callable = False + if hasattr(body, "__call__"): + self.callable_body = body + self.body = None + self.body_is_callable = True + elif isinstance(body, str): + self.body = utf8(body) + else: + self.body = body + + self.streaming = streaming + if not streaming and not self.body_is_callable: + self.body_length = len(self.body or '') + else: + self.body_length = 0 + + self.adding_headers = adding_headers or {} + self.forcing_headers = forcing_headers or {} + self.status = int(status) + + for k, v in headers.items(): + name = "-".join(k.split("_")).title() + self.adding_headers[name] = v + + self.validate() + + def validate(self): + """validates the body size with the value of the ``Content-Length`` + header + """ + content_length_keys = 'Content-Length', 'content-length' + for key in content_length_keys: + got = self.adding_headers.get( + key, self.forcing_headers.get(key, None)) + + if got is None: + continue + + igot = None + try: + igot = int(got) + except (ValueError, TypeError): + warnings.warn( + 'HTTPretty got to register the Content-Length header ' + 'with "%r" which is not a number' % got) + return + + if igot and igot > self.body_length: + raise HTTPrettyError( + 'HTTPretty got inconsistent parameters. The header ' + 'Content-Length you registered expects size "%d" but ' + 'the body you registered for that has actually length ' + '"%d".' % ( + igot, self.body_length, + ) + ) + + def __str__(self): + return r''.format( + self.method, + self.uri, + self.status + ) + + def normalize_headers(self, headers): + """Normalize keys in header names so that ``COntent-tyPe`` becomes ``content-type`` + + :param headers: dict + + :returns: dict + """ + new = {} + for k in headers: + new_k = '-'.join([s.lower() for s in k.split('-')]) + new[new_k] = headers[k] + + return new + + def fill_filekind(self, fk): + """writes HTTP Response data to a file descriptor + + :parm fk: a file-like object + + .. warning:: **side-effect:** this method moves the cursor of the given file object to zero + """ + now = datetime.utcnow() + + headers = { + 'status': self.status, + 'date': now.strftime('%a, %d %b %Y %H:%M:%S GMT'), + 'server': 'Python/HTTPretty', + 'connection': 'close', + } + + if self.forcing_headers: + headers = self.forcing_headers + + if self.adding_headers: + headers.update( + self.normalize_headers( + self.adding_headers)) + + headers = self.normalize_headers(headers) + status = headers.get('status', self.status) + if self.body_is_callable: + status, headers, self.body = self.callable_body(self.request, self.info.full_url(), headers) + headers = self.normalize_headers(headers) + # TODO: document this behavior: + if 'content-length' not in headers: + headers.update({ + 'content-length': len(self.body) + }) + + string_list = [ + 'HTTP/1.1 %d %s' % (status, STATUSES[status]), + ] + + if 'date' in headers: + string_list.append('date: %s' % headers.pop('date')) + + if not self.forcing_headers: + content_type = headers.pop('content-type', + 'text/plain; charset=utf-8') + + content_length = headers.pop('content-length', + self.body_length) + + string_list.append('content-type: %s' % content_type) + if not self.streaming: + string_list.append('content-length: %s' % content_length) + + server = headers.pop('server', None) + if server: + string_list.append('server: %s' % server) + + for k, v in headers.items(): + string_list.append( + '{}: {}'.format(k, v), + ) + + for item in string_list: + fk.write(utf8(item) + b'\n') + + fk.write(b'\r\n') + + if self.streaming: + self.body, body = itertools.tee(self.body) + for chunk in body: + fk.write(utf8(chunk)) + else: + fk.write(utf8(self.body)) + + fk.seek(0) + + +def url_fix(s, charset=None): + """escapes special characters + """ + if charset: + warnings.warn("{}.url_fix() charset argument is deprecated".format(__name__), DeprecationWarning) + + scheme, netloc, path, querystring, fragment = urlsplit(s) + path = quote(path, b'/%') + querystring = quote_plus(querystring, b':&=') + return urlunsplit((scheme, netloc, path, querystring, fragment)) + + +class URIInfo(BaseClass): + """Internal representation of `URIs `_ + + .. tip:: all arguments are optional + + :param username: + :param password: + :param hostname: + :param port: + :param path: + :param query: + :param fragment: + :param scheme: + :param last_request: + """ + default_str_attrs = ( + 'username', + 'password', + 'hostname', + 'port', + 'path', + ) + + def __init__(self, + username='', + password='', + hostname='', + port=80, + path='/', + query='', + fragment='', + scheme='', + last_request=None): + + self.username = username or '' + self.password = password or '' + self.hostname = hostname or '' + + if port: + port = int(port) + + elif scheme == 'https': + port = 443 + + self.port = port or 80 + self.path = path or '' + if query: + query_items = sorted(parse_qs(query).items()) + self.query = urlencode( + encode_obj(query_items), + doseq=True, + ) + else: + self.query = '' + if scheme: + self.scheme = scheme + elif self.port in POTENTIAL_HTTPS_PORTS: + self.scheme = 'https' + else: + self.scheme = 'http' + self.fragment = fragment or '' + self.last_request = last_request + + def to_str(self, attrs): + fmt = ", ".join(['%s="%s"' % (k, getattr(self, k, '')) for k in attrs]) + return r'' % fmt + + def __str__(self): + return self.to_str(self.default_str_attrs) + + def str_with_query(self): + attrs = self.default_str_attrs + ('query',) + return self.to_str(attrs) + + def __hash__(self): + return int(hashlib.sha1(bytes(self, 'ascii')).hexdigest(), 16) + + def __eq__(self, other): + self_tuple = ( + self.port, + decode_utf8(self.hostname.lower()), + url_fix(decode_utf8(self.path)), + ) + other_tuple = ( + other.port, + decode_utf8(other.hostname.lower()), + url_fix(decode_utf8(other.path)), + ) + return self_tuple == other_tuple + + def full_url(self, use_querystring=True): + """ + :param use_querystring: bool + :returns: a string with the full url with the format ``{scheme}://{credentials}{domain}{path}{query}`` + """ + credentials = "" + if self.password: + credentials = "{}:{}@".format( + self.username, self.password) + + query = "" + if use_querystring and self.query: + query = "?{}".format(decode_utf8(self.query)) + + result = "{scheme}://{credentials}{domain}{path}{query}".format( + scheme=self.scheme, + credentials=credentials, + domain=self.get_full_domain(), + path=decode_utf8(self.path), + query=query + ) + return result + + def get_full_domain(self): + """ + :returns: a string in the form ``{domain}:{port}`` or just the domain if the port is 80 or 443 + """ + hostname = decode_utf8(self.hostname) + # Port 80/443 should not be appended to the url + if self.port not in DEFAULT_HTTP_PORTS | DEFAULT_HTTPS_PORTS: + return ":".join([hostname, str(self.port)]) + + return hostname + + @classmethod + def from_uri(cls, uri, entry): + """ + :param uri: string + :param entry: an instance of :py:class:`~httpretty.core.Entry` + """ + result = urlsplit(uri) + if result.scheme == 'https': + POTENTIAL_HTTPS_PORTS.add(int(result.port or 443)) + else: + POTENTIAL_HTTP_PORTS.add(int(result.port or 80)) + return cls(result.username, + result.password, + result.hostname, + result.port, + result.path, + result.query, + result.fragment, + result.scheme, + entry) + + +class URIMatcher(object): + regex = None + info = None + + def __init__(self, uri, entries, match_querystring=False, priority=0): + self._match_querystring = match_querystring + # CPython, Jython + regex_types = ('SRE_Pattern', 'org.python.modules.sre.PatternObject', + 'Pattern') + is_regex = type(uri).__name__ in regex_types + if is_regex: + self.regex = uri + result = urlsplit(uri.pattern) + if result.scheme == 'https': + POTENTIAL_HTTPS_PORTS.add(int(result.port or 443)) + else: + POTENTIAL_HTTP_PORTS.add(int(result.port or 80)) + else: + self.info = URIInfo.from_uri(uri, entries) + + self.entries = entries + self.priority = priority + self.uri = uri + # hash of current_entry pointers, per method. + self.current_entries = {} + + def matches(self, info): + if self.info: + # Query string is not considered when comparing info objects, compare separately + return self.info == info and (not self._match_querystring or self.info.query == info.query) + else: + return self.regex.search(info.full_url( + use_querystring=self._match_querystring)) + + def __str__(self): + wrap = 'URLMatcher({})' + if self.info: + if self._match_querystring: + return wrap.format(str(self.info.str_with_query())) + else: + return wrap.format(str(self.info)) + else: + return wrap.format(self.regex.pattern) + + def get_next_entry(self, method, info, request): + """Cycle through available responses, but only once. + Any subsequent requests will receive the last response""" + + if method not in self.current_entries: + self.current_entries[method] = 0 + + # restrict selection to entries that match the requested + # method + entries_for_method = [e for e in self.entries if e.method == method] + + if self.current_entries[method] >= len(entries_for_method): + self.current_entries[method] = -1 + + if not self.entries or not entries_for_method: + raise ValueError('I have no entries for method %s: %s' + % (method, self)) + + entry = entries_for_method[self.current_entries[method]] + if self.current_entries[method] != -1: + self.current_entries[method] += 1 + + # Create a copy of the original entry to make it thread-safe + body = entry.callable_body if entry.body_is_callable else entry.body + new_entry = Entry(entry.method, entry.uri, body, + status=entry.status, + streaming=entry.streaming, + adding_headers=entry.adding_headers, + forcing_headers=entry.forcing_headers) + + # Attach more info to the entry + # So the callback can be more clever about what to do + # This does also fix the case where the callback + # would be handed a compiled regex as uri instead of the + # real uri + new_entry.info = info + new_entry.request = request + return new_entry + + def __hash__(self): + return hash(str(self)) + + def __eq__(self, other): + return str(self) == str(other) + + +class httpretty(HttpBaseClass): + """manages HTTPretty's internal request/response registry and request matching. + """ + _entries = {} + latest_requests = [] + + last_request = HTTPrettyRequestEmpty() + _is_enabled = False + allow_net_connect = True + + @classmethod + def match_uriinfo(cls, info): + """ + :param info: an :py:class:`~httpretty.core.URIInfo` + :returns: a 2-item tuple: (:py:class:`~httpretty.core.URLMatcher`, :py:class:`~httpretty.core.URIInfo`) or ``(None, [])`` + """ + items = sorted( + cls._entries.items(), + key=lambda matcher_entries: matcher_entries[0].priority, + reverse=True, + ) + for matcher, value in items: + if matcher.matches(info): + return (matcher, info) + + return (None, []) + + @classmethod + def match_https_hostname(cls, hostname): + """ + :param hostname: a string + :returns: an :py:class:`~httpretty.core.URLMatcher` or ``None`` + """ + items = sorted( + cls._entries.items(), + key=lambda matcher_entries: matcher_entries[0].priority, + reverse=True, + ) + for matcher, value in items: + if matcher.info is None: + pattern_with_port = "https://{0}:".format(hostname) + pattern_without_port = "https://{0}/".format(hostname) + hostname_pattern = ( + hostname_re + .match(matcher.regex.pattern) + .group(0) + ) + for pattern in [pattern_with_port, pattern_without_port]: + if re.match(hostname_pattern, pattern): + return matcher + + elif matcher.info.hostname == hostname: + return matcher + return None + + @classmethod + def match_http_address(cls, hostname, port): + """ + :param hostname: a string + :param port: an integer + :returns: an :py:class:`~httpretty.core.URLMatcher` or ``None`` + """ + items = sorted( + cls._entries.items(), + key=lambda matcher_entries: matcher_entries[0].priority, + reverse=True, + ) + for matcher, value in items: + if matcher.info is None: + if port in POTENTIAL_HTTPS_PORTS: + scheme = 'https://' + else: + scheme = 'http://' + + pattern_without_port = "{0}{1}/".format(scheme, hostname) + pattern_with_port = "{0}{1}:{2}/".format(scheme, hostname, port) + hostname_pattern = ( + hostname_re + .match(matcher.regex.pattern) + .group(0) + ) + for pattern in [pattern_with_port, pattern_without_port]: + if re.match(hostname_pattern, pattern): + return matcher + + elif matcher.info.hostname == hostname \ + and matcher.info.port == port: + return matcher + + return None + + @classmethod + @contextlib.contextmanager + def record(cls, filename, indentation=4, encoding='utf-8', verbose=False, allow_net_connect=True, pool_manager_params=None): + """ + .. testcode:: + + import io + import json + import requests + import httpretty + + with httpretty.record('/tmp/ip.json'): + data = requests.get('https://httpbin.org/ip').json() + + with io.open('/tmp/ip.json') as fd: + assert data == json.load(fd) + + :param filename: a string + :param indentation: an integer, defaults to **4** + :param encoding: a string, defaults to **"utf-8"** + + :returns: a `context-manager `_ + """ + try: + import urllib3 + except ImportError: + msg = ( + 'HTTPretty requires urllib3 installed ' + 'for recording actual requests.' + ) + raise RuntimeError(msg) + + http = urllib3.PoolManager(**pool_manager_params or {}) + + cls.enable(allow_net_connect, verbose=verbose) + calls = [] + + def record_request(request, uri, headers): + cls.disable() + + kw = {} + kw.setdefault('body', request.body) + kw.setdefault('headers', dict(request.headers)) + response = http.request(request.method, uri, **kw) + calls.append({ + 'request': { + 'uri': uri, + 'method': request.method, + 'headers': dict(request.headers), + 'body': decode_utf8(request.body), + 'querystring': request.querystring + }, + 'response': { + 'status': response.status, + 'body': decode_utf8(response.data), + # urllib3 1.10 had a bug if you just did: + # dict(response.headers) + # which would cause all the values to become lists + # with the header name as the first item and the + # true value as the second item. Workaround that + 'headers': dict(response.headers.items()) + } + }) + cls.enable(allow_net_connect, verbose=verbose) + return response.status, response.headers, response.data + + for method in cls.METHODS: + cls.register_uri(method, MULTILINE_ANY_REGEX, body=record_request) + + yield + cls.disable() + with codecs.open(filename, 'w', encoding) as f: + f.write(json.dumps(calls, indent=indentation)) + + @classmethod + @contextlib.contextmanager + def playback(cls, filename, allow_net_connect=True, verbose=False): + """ + .. testcode:: + + import io + import json + import requests + import httpretty + + with httpretty.record('/tmp/ip.json'): + data = requests.get('https://httpbin.org/ip').json() + + with io.open('/tmp/ip.json') as fd: + assert data == json.load(fd) + + :param filename: a string + :returns: a `context-manager `_ + """ + cls.enable(allow_net_connect, verbose=verbose) + + data = json.loads(open(filename).read()) + for item in data: + uri = item['request']['uri'] + method = item['request']['method'] + body = item['response']['body'] + headers = item['response']['headers'] + cls.register_uri(method, uri, body=body, forcing_headers=headers) + + yield + cls.disable() + + @classmethod + def reset(cls): + """resets the internal state of HTTPretty, unregistering all URLs + """ + POTENTIAL_HTTP_PORTS.intersection_update(DEFAULT_HTTP_PORTS) + POTENTIAL_HTTPS_PORTS.intersection_update(DEFAULT_HTTPS_PORTS) + cls._entries.clear() + cls.latest_requests = [] + cls.last_request = HTTPrettyRequestEmpty() + __internals__.cleanup_sockets() + + @classmethod + def historify_request(cls, headers, body='', sock=None): + """appends request to a list for later retrieval + + .. testcode:: + + import httpretty + + httpretty.register_uri(httpretty.GET, 'https://httpbin.org/ip', body='') + with httpretty.enabled(): + requests.get('https://httpbin.org/ip') + + assert httpretty.latest_requests[-1].url == 'https://httpbin.org/ip' + """ + request = HTTPrettyRequest(headers, body, sock=sock) + cls.last_request = request + + if request not in cls.latest_requests: + cls.latest_requests.append(request) + else: + cls.latest_requests[-1] = request + + logger.info("captured: {}".format(request)) + return request + + @classmethod + def register_uri(cls, method, uri, body='{"message": "HTTPretty :)"}', + adding_headers=None, + forcing_headers=None, + status=200, + responses=None, + match_querystring=False, + priority=0, + **headers): + """ + .. testcode:: + + import httpretty + + + def request_callback(request, uri, response_headers): + content_type = request.headers.get('Content-Type') + assert request.body == '{"nothing": "here"}', 'unexpected body: {}'.format(request.body) + assert content_type == 'application/json', 'expected application/json but received Content-Type: {}'.format(content_type) + return [200, response_headers, json.dumps({"hello": "world"})] + + httpretty.register_uri( + HTTPretty.POST, "https://httpretty.example.com/api", + body=request_callback) + + + with httpretty.enabled(): + requests.post('https://httpretty.example.com/api', data='{"nothing": "here"}', headers={'Content-Type': 'application/json'}) + + assert httpretty.latest_requests[-1].url == 'https://httpbin.org/ip' + + :param method: one of ``httpretty.GET``, ``httpretty.PUT``, ``httpretty.POST``, ``httpretty.DELETE``, ``httpretty.HEAD``, ``httpretty.PATCH``, ``httpretty.OPTIONS``, ``httpretty.CONNECT`` + :param uri: a string or regex pattern (e.g.: **"https://httpbin.org/ip"**) + :param body: a string, defaults to ``{"message": "HTTPretty :)"}`` + :param adding_headers: dict - headers to be added to the response + :param forcing_headers: dict - headers to be forcefully set in the response + :param status: an integer, defaults to **200** + :param responses: a list of entries, ideally each created with :py:meth:`~httpretty.core.httpretty.Response` + :param priority: an integer, useful for setting higher priority over previously registered urls. defaults to zero + :param match_querystring: bool - whether to take the querystring into account when matching an URL + :param headers: headers to be added to the response + + .. warning:: When using a port in the request, add a trailing slash if no path is provided otherwise Httpretty will not catch the request. Ex: ``httpretty.register_uri(httpretty.GET, 'http://fakeuri.com:8080/', body='{"hello":"world"}')`` + """ + uri_is_string = isinstance(uri, str) + + if uri_is_string and re.search(r'^\w+://[^/]+[.]\w{2,}(:[0-9]+)?$', uri): + uri += '/' + + if isinstance(responses, list) and len(responses) > 0: + for response in responses: + response.uri = uri + response.method = method + entries_for_this_uri = responses + else: + headers['body'] = body + headers['adding_headers'] = adding_headers + headers['forcing_headers'] = forcing_headers + headers['status'] = status + + entries_for_this_uri = [ + cls.Response(method=method, uri=uri, **headers), + ] + + matcher = URIMatcher(uri, entries_for_this_uri, + match_querystring, priority) + if matcher in cls._entries: + matcher.entries.extend(cls._entries[matcher]) + del cls._entries[matcher] + + cls._entries[matcher] = entries_for_this_uri + + def __str__(self): + return '' % len(self._entries) + + @classmethod + def Response( + cls, body, + method=None, + uri=None, + adding_headers=None, + forcing_headers=None, + status=200, + streaming=False, + **kw): + """Shortcut to create an :py:class:`~httpretty.core.Entry` that takes + the body as first positional argument. + + .. seealso:: the parameters of this function match those of + the :py:class:`~httpretty.core.Entry` constructor. + + Args: + body (str): The body to return as response.. + method (str): One of ``httpretty.GET``, ``httpretty.PUT``, ``httpretty.POST``, ``httpretty.DELETE``, ``httpretty.HEAD``, ``httpretty.PATCH``, ``httpretty.OPTIONS``, ``httpretty.CONNECT``. + uri (str|re.Pattern): The URL to match + adding_headers (dict): Extra headers to be added to the response + forcing_headers (dict): Overwrite **any** response headers, even "Content-Length". + status (int): The status code for the response, defaults to ``200``. + streaming (bool): Whether should stream the response into chunks via generator. + kwargs: Keyword-arguments are forwarded to :py:class:`~httpretty.core.Entry` + + Returns: + httpretty.Entry: containing the request-matching metadata. + """ + kw['body'] = body + kw['adding_headers'] = adding_headers + kw['forcing_headers'] = forcing_headers + kw['status'] = int(status) + kw['streaming'] = streaming + return Entry(method, uri, **kw) + + @classmethod + def disable(cls): + """Disables HTTPretty entirely, putting the original :py:mod:`socket` + module back in its place. + + + .. code:: + + import re, json + import httpretty + + httpretty.enable() + # request passes through fake socket + response = requests.get('https://httpbin.org') + + httpretty.disable() + # request uses real python socket module + response = requests.get('https://httpbin.org') + + .. note:: This method does not call :py:meth:`httpretty.core.reset` automatically. + """ + undo_patch_socket() + cls._is_enabled = False + + + @classmethod + def is_enabled(cls): + """Check if HTTPretty is enabled + + :returns: bool + + .. testcode:: + + import httpretty + + httpretty.enable() + assert httpretty.is_enabled() == True + + httpretty.disable() + assert httpretty.is_enabled() == False + """ + return cls._is_enabled + + @classmethod + def enable(cls, allow_net_connect=True, verbose=False): + """Enables HTTPretty. + + :param allow_net_connect: boolean to determine if unmatched requests are forwarded to a real network connection OR throw :py:class:`httpretty.errors.UnmockedError`. + :param verbose: boolean to set HTTPretty's logging level to DEBUG + + .. testcode:: + + import re, json + import httpretty + + httpretty.enable(allow_net_connect=True, verbose=True) + + httpretty.register_uri( + httpretty.GET, + re.compile(r'http://.*'), + body=json.dumps({'man': 'in', 'the': 'middle'}) + ) + + response = requests.get('https://foo.bar/foo/bar') + + response.json().should.equal({ + "man": "in", + "the": "middle", + }) + + .. warning:: after calling this method the original :py:mod:`socket` is replaced with :py:class:`httpretty.core.fakesock`. Make sure to call :py:meth:`~httpretty.disable` after done with your tests or use the :py:class:`httpretty.enabled` as decorator or `context-manager `_ + """ + httpretty.allow_net_connect = allow_net_connect + apply_patch_socket() + cls._is_enabled = True + if verbose: + logger.setLevel(logging.DEBUG) + else: + logger.setLevel(logging.getLogger().level or logging.WARNING) + + +def apply_patch_socket(): + # Some versions of python internally shadowed the + # SocketType variable incorrectly https://bugs.python.org/issue20386 + bad_socket_shadow = (socket.socket != socket.SocketType) + + new_wrap = None + socket.socket = fakesock.socket + socket.socketpair = fake_socketpair + socket._socketobject = fakesock.socket + if not bad_socket_shadow: + socket.SocketType = fakesock.socket + + socket.create_connection = create_fake_connection + socket.gethostname = fake_gethostname + socket.gethostbyname = fake_gethostbyname + socket.getaddrinfo = fake_getaddrinfo + + socket.__dict__['socket'] = fakesock.socket + socket.__dict__['socketpair'] = fake_socketpair + socket.__dict__['_socketobject'] = fakesock.socket + if not bad_socket_shadow: + socket.__dict__['SocketType'] = fakesock.socket + + socket.__dict__['create_connection'] = create_fake_connection + socket.__dict__['gethostname'] = fake_gethostname + socket.__dict__['gethostbyname'] = fake_gethostbyname + socket.__dict__['getaddrinfo'] = fake_getaddrinfo + + + # Take out the pyopenssl version - use the default implementation + for extract_from_urllib3 in pyopenssl_overrides_extract: + extract_into_urllib3() + + if requests_urllib3_connection is not None: + urllib3_wrap = partial(fake_wrap_socket, old_requests_ssl_wrap_socket) + requests_urllib3_connection.ssl_wrap_socket = urllib3_wrap + requests_urllib3_connection.__dict__['ssl_wrap_socket'] = urllib3_wrap + + if eventlet: + eventlet.green.ssl.GreenSSLContext = old_sslcontext_class + eventlet.green.ssl.__dict__['GreenSSLContext'] = old_sslcontext_class + eventlet.green.ssl.SSLContext = old_sslcontext_class + eventlet.green.ssl.__dict__['SSLContext'] = old_sslcontext_class + + if socks: + socks.socksocket = fakesock.socket + socks.__dict__['socksocket'] = fakesock.socket + + if ssl: + new_wrap = partial(fake_wrap_socket, old_ssl_wrap_socket) + ssl.wrap_socket = new_wrap + ssl.SSLSocket = FakeSSLSocket + ssl.SSLContext = old_sslcontext_class + try: + ssl.SSLContext.wrap_socket = partial(fake_wrap_socket, old_ssl_wrap_socket) + except AttributeError: + pass + + ssl.__dict__['wrap_socket'] = new_wrap + ssl.__dict__['SSLSocket'] = FakeSSLSocket + ssl.__dict__['SSLContext'] = old_sslcontext_class + + +def undo_patch_socket(): + socket.socket = old_socket + socket.socketpair = old_socketpair + socket.SocketType = old_SocketType + socket._socketobject = old_socket + + socket.create_connection = old_create_connection + socket.gethostname = old_gethostname + socket.gethostbyname = old_gethostbyname + socket.getaddrinfo = old_getaddrinfo + + socket.__dict__['socket'] = old_socket + socket.__dict__['socketpair'] = old_socketpair + socket.__dict__['_socketobject'] = old_socket + socket.__dict__['SocketType'] = old_SocketType + + socket.__dict__['create_connection'] = old_create_connection + socket.__dict__['gethostname'] = old_gethostname + socket.__dict__['gethostbyname'] = old_gethostbyname + socket.__dict__['getaddrinfo'] = old_getaddrinfo + + if socks: + socks.socksocket = old_socksocket + socks.__dict__['socksocket'] = old_socksocket + + if ssl: + ssl.wrap_socket = old_ssl_wrap_socket + ssl.SSLSocket = old_sslsocket + try: + ssl.SSLContext.wrap_socket = old_sslcontext_wrap_socket + except AttributeError: + pass + ssl.__dict__['wrap_socket'] = old_ssl_wrap_socket + ssl.__dict__['SSLSocket'] = old_sslsocket + + if requests_urllib3_connection is not None: + requests_urllib3_connection.ssl_wrap_socket = \ + old_requests_ssl_wrap_socket + requests_urllib3_connection.__dict__['ssl_wrap_socket'] = \ + old_requests_ssl_wrap_socket + + + # Put the pyopenssl version back in place + for inject_from_urllib3 in pyopenssl_overrides_inject: + inject_into_urllib3() + + +@contextlib.contextmanager +def restored_libs(): + undo_patch_socket() + yield + apply_patch_socket() + + +class httprettized(object): + """`context-manager `_ for enabling HTTPretty. + + .. tip:: Also available under the alias :py:func:`httpretty.enabled` + + .. testcode:: + + import json + import httpretty + + httpretty.register_uri(httpretty.GET, 'https://httpbin.org/ip', body=json.dumps({'origin': '42.42.42.42'})) + with httpretty.enabled(): + response = requests.get('https://httpbin.org/ip') + + assert httpretty.latest_requests[-1].url == 'https://httpbin.org/ip' + assert response.json() == {'origin': '42.42.42.42'} + """ + def __init__(self, allow_net_connect=True, verbose=False): + self.allow_net_connect = allow_net_connect + self.verbose = verbose + + def __enter__(self): + httpretty.reset() + httpretty.enable(allow_net_connect=self.allow_net_connect, verbose=self.verbose) + + def __exit__(self, exc_type, exc_value, db): + httpretty.disable() + httpretty.reset() + + +def httprettified(test=None, allow_net_connect=True, verbose=False): + """decorator for test functions + + .. tip:: Also available under the alias :py:func:`httpretty.activate` + + :param test: a callable + + + example usage with `nosetests `_ + + .. testcode:: + + import sure + from httpretty import httprettified + + @httprettified + def test_using_nosetests(): + httpretty.register_uri( + httpretty.GET, + 'https://httpbin.org/ip' + ) + + response = requests.get('https://httpbin.org/ip') + + response.json().should.equal({ + "message": "HTTPretty :)" + }) + + example usage with `unittest module `_ + + .. testcode:: + + import unittest + from sure import expect + from httpretty import httprettified + + @httprettified + class TestWithPyUnit(unittest.TestCase): + def test_httpbin(self): + httpretty.register_uri(httpretty.GET, 'https://httpbin.org/ip') + response = requests.get('https://httpbin.org/ip') + expect(response.json()).to.equal({ + "message": "HTTPretty :)" + }) + + """ + def decorate_unittest_TestCase_setUp(klass): + + # Prefer addCleanup (added in python 2.7), but fall back + # to using tearDown if it isn't available + use_addCleanup = hasattr(klass, 'addCleanup') + + original_setUp = (klass.setUp + if hasattr(klass, 'setUp') + else None) + + def new_setUp(self): + httpretty.reset() + httpretty.enable(allow_net_connect, verbose=verbose) + if use_addCleanup: + self.addCleanup(httpretty.disable) + if original_setUp: + original_setUp(self) + klass.setUp = new_setUp + + if not use_addCleanup: + original_tearDown = (klass.setUp + if hasattr(klass, 'tearDown') + else None) + + def new_tearDown(self): + httpretty.disable() + httpretty.reset() + if original_tearDown: + original_tearDown(self) + klass.tearDown = new_tearDown + + return klass + + def decorate_test_methods(klass): + for attr in dir(klass): + if not attr.startswith('test_'): + continue + + attr_value = getattr(klass, attr) + if not hasattr(attr_value, "__call__"): + continue + + setattr(klass, attr, decorate_callable(attr_value)) + return klass + + def is_unittest_TestCase(klass): + try: + import unittest + return issubclass(klass, unittest.TestCase) + except ImportError: + return False + + def decorate_class(klass): + if is_unittest_TestCase(klass): + return decorate_unittest_TestCase_setUp(klass) + return decorate_test_methods(klass) + + def decorate_callable(test): + @functools.wraps(test) + def wrapper(*args, **kw): + with httprettized(allow_net_connect): + return test(*args, **kw) + return wrapper + + if isinstance(test, type): + return decorate_class(test) + elif callable(test): + return decorate_callable(test) + return decorate_callable diff --git a/httpretty/errors.py b/httpretty/errors.py new file mode 100644 index 0000000..149c6c6 --- /dev/null +++ b/httpretty/errors.py @@ -0,0 +1,48 @@ +# #!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +from __future__ import unicode_literals +import json + +class HTTPrettyError(Exception): + pass + + +class UnmockedError(HTTPrettyError): + def __init__(self, message='Failed to handle network request', request=None, address=None): + hint = 'Tip: You could try setting (allow_net_connect=True) to allow unregistered requests through a real TCP connection in addition to (verbose=True) to debug the issue.' + if request: + headers = json.dumps(dict(request.headers), indent=2) + message = '{message}.\n\nIntercepted unknown {request.method} request {request.url}\n\nWith headers {headers}'.format(**locals()) + + if isinstance(address, (tuple, list)): + address = ":".join(map(str, address)) + + if address: + hint = 'address: {address} | {hint}'.format(**locals()) + + self.request = request + super(UnmockedError, self).__init__('{message}\n\n{hint}'.format(**locals())) diff --git a/httpretty/http.py b/httpretty/http.py new file mode 100644 index 0000000..87ceca9 --- /dev/null +++ b/httpretty/http.py @@ -0,0 +1,153 @@ +# #!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +from __future__ import unicode_literals + +import re +from .compat import BaseClass +from .utils import decode_utf8 + + +STATUSES = { + 100: "Continue", + 101: "Switching Protocols", + 102: "Processing", + 200: "OK", + 201: "Created", + 202: "Accepted", + 203: "Non-Authoritative Information", + 204: "No Content", + 205: "Reset Content", + 206: "Partial Content", + 207: "Multi-Status", + 208: "Already Reported", + 226: "IM Used", + 300: "Multiple Choices", + 301: "Moved Permanently", + 302: "Found", + 303: "See Other", + 304: "Not Modified", + 305: "Use Proxy", + 306: "Switch Proxy", + 307: "Temporary Redirect", + 308: "Permanent Redirect", + 400: "Bad Request", + 401: "Unauthorized", + 402: "Payment Required", + 403: "Forbidden", + 404: "Not Found", + 405: "Method Not Allowed", + 406: "Not Acceptable", + 407: "Proxy Authentication Required", + 408: "Request a Timeout", + 409: "Conflict", + 410: "Gone", + 411: "Length Required", + 412: "Precondition Failed", + 413: "Request Entity Too Large", + 414: "Request-URI Too Long", + 415: "Unsupported Media Type", + 416: "Requested Range Not Satisfiable", + 417: "Expectation Failed", + 418: "I'm a teapot", + 420: "Enhance Your Calm", + 422: "Unprocessable Entity", + 423: "Locked", + 424: "Failed Dependency", + 425: "Unordered Collection", + 426: "Upgrade Required", + 428: "Precondition Required", + 429: "Too Many Requests", + 431: "Request Header Fields Too Large", + 444: "No Response", + 449: "Retry With", + 450: "Blocked by Windows Parental Controls", + 451: "Unavailable For Legal Reasons", + 494: "Request Header Too Large", + 495: "Cert Error", + 496: "No Cert", + 497: "HTTP to HTTPS", + 499: "Client Closed Request", + 500: "Internal Server Error", + 501: "Not Implemented", + 502: "Bad Gateway", + 503: "Service Unavailable", + 504: "Gateway Timeout", + 505: "HTTP Version Not Supported", + 506: "Variant Also Negotiates", + 507: "Insufficient Storage", + 508: "Loop Detected", + 509: "Bandwidth Limit Exceeded", + 510: "Not Extended", + 511: "Network Authentication Required", + 598: "Network read timeout error", + 599: "Network connect timeout error", +} + + +class HttpBaseClass(BaseClass): + GET = 'GET' + PUT = 'PUT' + POST = 'POST' + DELETE = 'DELETE' + HEAD = 'HEAD' + PATCH = 'PATCH' + OPTIONS = 'OPTIONS' + CONNECT = 'CONNECT' + METHODS = (GET, PUT, POST, DELETE, HEAD, PATCH, OPTIONS, CONNECT) + + +def parse_requestline(s): + """ + http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5 + + >>> parse_requestline('GET / HTTP/1.0') + ('GET', '/', '1.0') + >>> parse_requestline('post /testurl htTP/1.1') + ('POST', '/testurl', '1.1') + >>> parse_requestline('Im not a RequestLine') + Traceback (most recent call last): + ... + ValueError: Not a Request-Line + """ + methods = '|'.join(HttpBaseClass.METHODS) + m = re.match(r'(' + methods + r')\s+(.*)\s+HTTP/(1.[0|1])', s, re.I) + if m: + return m.group(1).upper(), m.group(2), m.group(3) + else: + raise ValueError('Not a Request-Line') + + +def last_requestline(sent_data): + """ + Find the last line in sent_data that can be parsed with parse_requestline + """ + for line in reversed(sent_data): + try: + parse_requestline(decode_utf8(line)) + except ValueError: + pass + else: + return line diff --git a/httpretty/utils.py b/httpretty/utils.py new file mode 100644 index 0000000..5c6fe20 --- /dev/null +++ b/httpretty/utils.py @@ -0,0 +1,37 @@ +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + + +def utf8(s): + if isinstance(s, str): + s = s.encode('utf-8') + + return bytes(s) + + +def decode_utf8(s): + if isinstance(s, bytes): + s = s.decode("utf-8") + + return str(s) diff --git a/httpretty/version.py b/httpretty/version.py new file mode 100644 index 0000000..67c2416 --- /dev/null +++ b/httpretty/version.py @@ -0,0 +1 @@ +version = '1.1.4' diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ + diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..2b9b0cb --- /dev/null +++ b/setup.cfg @@ -0,0 +1,18 @@ +[nosetests] +verbosity = 2 +rednose = 1 +with-coverage = 1 +cover-inclusive = 1 +cover-package = httpretty +cover-branches = 1 +nocapture = 1 +nologcapture = 1 +stop = 1 +with-id = 1 +cover-xml = 1 +cover-xml-file = coverage.xml + +[egg_info] +tag_build = +tag_date = 0 + diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..879decd --- /dev/null +++ b/setup.py @@ -0,0 +1,83 @@ +# #!/usr/bin/env python +# -*- coding: utf-8 -*- + +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +import io +import os +from setuptools import setup, find_packages + + +def read_version(): + ctx = {} + exec(local_file('httpretty', 'version.py'), ctx) + return ctx['version'] + + +local_file = lambda *f: \ + io.open( + os.path.join(os.path.dirname(__file__), *f), encoding='utf-8').read() + + +install_requires = [] +tests_requires = ['nose', 'sure', 'coverage', 'mock;python_version<"3.3"', + 'rednose'] + + +setup( + name='httpretty', + version=read_version(), + description='HTTP client mock for Python', + long_description=local_file('README.rst'), + author='Gabriel Falcao', + author_email='gabriel@nacaolivre.org', + url='https://httpretty.readthedocs.io/en/latest/', + zip_safe=False, + packages=find_packages(exclude=['*tests*']), + tests_require=local_file('development.txt').splitlines(), + install_requires=install_requires, + license='MIT', + test_suite='nose.collector', + project_urls={ + "Documentation": "https://httpretty.readthedocs.io/en/latest/", + "Source Code": "https://github.com/gabrielfalcao/httpretty", + "Issue Tracker": "https://github.com/gabrielfalcao/httpretty/issues", + "Continuous Integration": "https://github.com/gabrielfalcao/HTTPretty/actions/workflows/pyenv.yml?query=branch%3Amaster+event%3Apush", + "Test Coverage": "https://codecov.io/gh/gabrielfalcao/httpretty", + }, + python_requires='>=3', + classifiers=[ + 'Development Status :: 5 - Production/Stable', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: MIT License', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Software Development :: Testing' + ], +) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..9047465 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +import sure diff --git a/tests/bugfixes/nosetests/__init__.py b/tests/bugfixes/nosetests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/bugfixes/nosetests/test_242_ssl_bad_handshake.py b/tests/bugfixes/nosetests/test_242_ssl_bad_handshake.py new file mode 100644 index 0000000..0653b41 --- /dev/null +++ b/tests/bugfixes/nosetests/test_242_ssl_bad_handshake.py @@ -0,0 +1,25 @@ +import httpretty +import requests + + +@httpretty.activate +def test_test_ssl_bad_handshake(): + # Reproduces https://github.com/gabrielfalcao/HTTPretty/issues/242 + + url_http = 'http://httpbin.org/status/200' + url_https = 'https://github.com/gabrielfalcao/HTTPretty' + + httpretty.register_uri(httpretty.GET, url_http, body='insecure') + httpretty.register_uri(httpretty.GET, url_https, body='encrypted') + + requests.get(url_http).text.should.equal('insecure') + requests.get(url_https).text.should.equal('encrypted') + + httpretty.latest_requests().should.have.length_of(2) + insecure_request, secure_request = httpretty.latest_requests()[:2] + + insecure_request.protocol.should.be.equal('http') + secure_request.protocol.should.be.equal('https') + + insecure_request.url.should.be.equal(url_http) + secure_request.url.should.be.equal(url_https) diff --git a/tests/bugfixes/nosetests/test_387_regex_port.py b/tests/bugfixes/nosetests/test_387_regex_port.py new file mode 100644 index 0000000..c3f90cd --- /dev/null +++ b/tests/bugfixes/nosetests/test_387_regex_port.py @@ -0,0 +1,26 @@ +# based on the snippet from https://github.com/gabrielfalcao/HTTPretty/issues/387 + +import httpretty +import requests +from sure import expect + +@httpretty.activate(allow_net_connect=False, verbose=True) +def test_match_with_port_no_slashes(): + "Reproduce #387 registering host:port without trailing slash" + httpretty.register_uri(httpretty.GET, 'http://fakeuri.com:8080', body='{"hello":"world"}') + req = requests.get('http://fakeuri.com:8080', timeout=1) + expect(req.status_code).to.equal(200) + expect(req.json()).to.equal({"hello": "world"}) + + +@httpretty.activate(allow_net_connect=False, verbose=True) +def test_match_with_port_trailing_slash(): + "Reproduce #387 registering host:port with trailing slash" + httpretty.register_uri(httpretty.GET, 'https://fakeuri.com:443/', body='{"hello":"world"}') + req = requests.get('https://fakeuri.com:443', timeout=1) + expect(req.status_code).to.equal(200) + expect(req.json()).to.equal({"hello": "world"}) + + req = requests.get('https://fakeuri.com:443/', timeout=1) + expect(req.status_code).to.equal(200) + expect(req.json()).to.equal({"hello": "world"}) diff --git a/tests/bugfixes/nosetests/test_388_unmocked_error_with_url.py b/tests/bugfixes/nosetests/test_388_unmocked_error_with_url.py new file mode 100644 index 0000000..ff8b756 --- /dev/null +++ b/tests/bugfixes/nosetests/test_388_unmocked_error_with_url.py @@ -0,0 +1,56 @@ +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +import requests +import httpretty +from httpretty.errors import UnmockedError + +from unittest import skip +from sure import expect + + +def http(): + sess = requests.Session() + adapter = requests.adapters.HTTPAdapter(pool_connections=1, pool_maxsize=1) + sess.mount('http://', adapter) + sess.mount('https://', adapter) + return sess + +@httpretty.activate(allow_net_connect=False) +def test_https_forwarding(): + "#388 UnmockedError is raised with details about the mismatched request" + httpretty.register_uri(httpretty.GET, 'http://google.com/', body="Not Google") + httpretty.register_uri(httpretty.GET, 'https://google.com/', body="Not Google") + response1 = http().get('http://google.com/') + response2 = http().get('https://google.com/') + + http().get.when.called_with("https://github.com/gabrielfalcao/HTTPretty").should.have.raised(UnmockedError, 'https://github.com/gabrielfalcao/HTTPretty') + + response1.text.should.equal(response2.text) + try: + http().get("https://github.com/gabrielfalcao/HTTPretty") + except UnmockedError as exc: + expect(exc).to.have.property('request') + expect(exc.request).to.have.property('host').being.equal('github.com') + expect(exc.request).to.have.property('protocol').being.equal('https') + expect(exc.request).to.have.property('url').being.equal('https://github.com/gabrielfalcao/HTTPretty') diff --git a/tests/bugfixes/nosetests/test_413_regex.py b/tests/bugfixes/nosetests/test_413_regex.py new file mode 100644 index 0000000..2131f7f --- /dev/null +++ b/tests/bugfixes/nosetests/test_413_regex.py @@ -0,0 +1,39 @@ +# File based on the snippet provided in https://github.com/gabrielfalcao/HTTPretty/issues/413#issue-787264551 +import requests +import httpretty +import re + + +def mock_body(request, url, response_headers): + return [200, response_headers, "Mocked " + url] + + +@httpretty.activate(verbose=True, allow_net_connect=False) +def test_works_with_regex_path(): + "Issue #413 regex with path" + patmatchpat = re.compile("/file-one") + + httpretty.register_uri(httpretty.GET, patmatchpat, body=mock_body) + + response = requests.get("https://example.com/file-one.html") + response.status_code.should.equal(200) + response.text.should.equal("Mocked https://example.com/file-one.html") + + response = requests.get("https://github.com/file-one.json") + response.status_code.should.equal(200) + response.text.should.equal("Mocked https://github.com/file-one.json") + +@httpretty.activate(verbose=True, allow_net_connect=False) +def test_works_with_regex_dotall(): + "Issue #413 regex with .*" + patmatchpat = re.compile(".*/file-two.*") + + httpretty.register_uri(httpretty.GET, patmatchpat, body=mock_body) + + response = requests.get("https://example.com/file-two.html") + response.status_code.should.equal(200) + response.text.should.equal("Mocked https://example.com/file-two.html") + + response = requests.get("https://github.com/file-two.json") + response.status_code.should.equal(200) + response.text.should.equal("Mocked https://github.com/file-two.json") diff --git a/tests/bugfixes/nosetests/test_414_httpx.py b/tests/bugfixes/nosetests/test_414_httpx.py new file mode 100644 index 0000000..889b871 --- /dev/null +++ b/tests/bugfixes/nosetests/test_414_httpx.py @@ -0,0 +1,13 @@ +import httpretty +import httpx +from sure import expect + +@httpretty.activate(verbose=True, allow_net_connect=False) +def test_httpx(): + "#414 httpx support" + httpretty.register_uri(httpretty.GET, "https://blog.falcao.it/", + body="Posts") + + response = httpx.get('https://blog.falcao.it') + + expect(response.text).to.equal("Posts") diff --git a/tests/bugfixes/nosetests/test_416_boto3.py b/tests/bugfixes/nosetests/test_416_boto3.py new file mode 100644 index 0000000..8db807b --- /dev/null +++ b/tests/bugfixes/nosetests/test_416_boto3.py @@ -0,0 +1,33 @@ +import httpretty +import boto3 +from botocore.exceptions import ClientError + +from sure import expect + + +@httpretty.activate(allow_net_connect=False, verbose=True) +def test_boto3(): + "#416 boto3 issue" + httpretty.register_uri( + httpretty.PUT, + "https://foo-bucket.s3.amazonaws.com/foo-object", + body=""" + + AccessDenied + Access Denied + foo + foo + """, + status=403 + ) + + session = boto3.Session(aws_access_key_id="foo", aws_secret_access_key="foo") + s3_client = session.client('s3') + + put_object = expect(s3_client.put_object).when.called_with( + Bucket="foo-bucket", + Key="foo-object", + Body=b"foo" + ) + + put_object.should.have.raised(ClientError, 'Access Denied') diff --git a/tests/bugfixes/nosetests/test_417_openssl.py b/tests/bugfixes/nosetests/test_417_openssl.py new file mode 100644 index 0000000..750a3fc --- /dev/null +++ b/tests/bugfixes/nosetests/test_417_openssl.py @@ -0,0 +1,33 @@ +# This test is based on @ento's example snippet: +# https://gist.github.com/ento/e1e33d7d67e406bf03fe61f018404c21 + +# Original Issue: +# https://github.com/gabrielfalcao/HTTPretty/issues/417 +import httpretty +import requests +import urllib3 +from sure import expect +from unittest import skipIf +try: + from urllib3.contrib.pyopenssl import extract_from_urllib3 +except Exception: + extract_from_urllib3 = None + + +@skipIf(extract_from_urllib3 is None, + "urllib3.contrib.pyopenssl.extract_from_urllib3 does not exist") +def test_enable_disable_httpretty_extract(): + "#417 urllib3.contrib.pyopenssl enable -> disable extract" + expect(urllib3.util.IS_PYOPENSSL).to.be.false + httpretty.enable() + httpretty.disable() + extract_from_urllib3() + expect(urllib3.util.IS_PYOPENSSL).to.be.false + +def test_enable_disable_httpretty(): + "#417 urllib3.contrib.pyopenssl enable -> disable extract" + expect(urllib3.util.IS_PYOPENSSL).to.be.false + httpretty.enable() + httpretty.disable() + extract_from_urllib3() + expect(urllib3.util.IS_PYOPENSSL).to.be.false diff --git a/tests/bugfixes/nosetests/test_425_latest_requests.py b/tests/bugfixes/nosetests/test_425_latest_requests.py new file mode 100644 index 0000000..72578c8 --- /dev/null +++ b/tests/bugfixes/nosetests/test_425_latest_requests.py @@ -0,0 +1,29 @@ +import requests +import httpretty +from httpretty.errors import UnmockedError + +from unittest import skip +from sure import expect + + +@httpretty.activate(allow_net_connect=True) +def test_latest_requests(): + "#425 - httpretty.latest_requests() can be called multiple times" + httpretty.register_uri(httpretty.GET, 'http://google.com/', body="Not Google") + httpretty.register_uri(httpretty.GET, 'https://google.com/', body="Not Google") + + requests.get('http://google.com/') + httpretty.latest_requests()[-1].url.should.equal('http://google.com/') + requests.get('https://google.com/') + httpretty.latest_requests()[-1].url.should.equal('https://google.com/') + + httpretty.latest_requests().should.have.length_of(2) + httpretty.latest_requests()[-1].url.should.equal('https://google.com/') + + requests.get('https://google.com/') + httpretty.latest_requests().should.have.length_of(3) + httpretty.latest_requests()[-1].url.should.equal('https://google.com/') + + requests.get('http://google.com/') + httpretty.latest_requests().should.have.length_of(4) + httpretty.latest_requests()[-1].url.should.equal('http://google.com/') diff --git a/tests/bugfixes/nosetests/test_430_respect_timeout.py b/tests/bugfixes/nosetests/test_430_respect_timeout.py new file mode 100644 index 0000000..f21a546 --- /dev/null +++ b/tests/bugfixes/nosetests/test_430_respect_timeout.py @@ -0,0 +1,54 @@ +# This test is based on @mariojonke snippet: +# https://github.com/gabrielfalcao/HTTPretty/issues/430 +import time +from requests import Session +from requests.adapters import HTTPAdapter +from requests.exceptions import ReadTimeout + +from threading import Event + +from httpretty import httprettified +from httpretty import HTTPretty + + +def http(max_connections=1): + session = Session() + adapter = HTTPAdapter( + pool_connections=max_connections, + pool_maxsize=max_connections + ) + session.mount('http://', adapter) + session.mount('https://', adapter) + return session + + + +@httprettified(verbose=True, allow_net_connect=False) +def test_read_timeout(): + "#430 httpretty should respect read timeout" + event = Event() + uri = "http://example.com" + + # Given that I register a uri with a callback body that delays 10 seconds + wait_seconds = 10 + + def my_callback(request, url, headers): + event.wait(wait_seconds) + return 200, headers, "Received" + + HTTPretty.register_uri(HTTPretty.GET, uri, body=my_callback) + + # And I use a thread pool with 1 TCP connection max + max_connections = 1 + request = http(max_connections) + started_at = time.time() + # When I make an HTTP request with a read timeout of 0.1 and an indefinite connect timeout + when_called = request.get.when.called_with(uri, timeout=(None, 0.1)) + + # Then the request should have raised a connection timeout + when_called.should.have.raised(ReadTimeout) + + # And the total execution time should be less than 0.2 seconds + event.set() + total_time = time.time() - started_at + total_time.should.be.lower_than(0.2) diff --git a/tests/bugfixes/nosetests/test_eventlet.py b/tests/bugfixes/nosetests/test_eventlet.py new file mode 100644 index 0000000..25a58a9 --- /dev/null +++ b/tests/bugfixes/nosetests/test_eventlet.py @@ -0,0 +1,11 @@ +import httpretty +import requests +import eventlet +eventlet.monkey_patch(all=False, socket=True) + + +@httpretty.activate +def test_something(): + + httpretty.register_uri(httpretty.GET, 'https://example.com', body='foo') + requests.get('https://example.com').text.should.equal('foo') diff --git a/tests/bugfixes/nosetests/test_redis.py b/tests/bugfixes/nosetests/test_redis.py new file mode 100644 index 0000000..e7328a4 --- /dev/null +++ b/tests/bugfixes/nosetests/test_redis.py @@ -0,0 +1,52 @@ +import os +import requests +import httpretty + +try: + from redis import Redis +except ImportError: + Redis = None + +from unittest import skipUnless + + +def redis_available(): + if Redis is None: + return False + + params = dict( + host=os.getenv('REDIS_HOST') or '127.0.0.1', + port=int(os.getenv('REDIS_PORT') or 6379) + ) + conn = Redis(**params) + try: + conn.keys('*') + conn.close() + return True + except Exception: + return False + + +@skipUnless(redis_available(), reason='no redis server available for test') +@httpretty.activate() +def test_work_in_parallel_to_redis(): + "HTTPretty should passthrough redis connections" + + redis = Redis() + + keys = redis.keys('*') + for key in keys: + redis.delete(key) + + redis.append('item1', 'value1') + redis.append('item2', 'value2') + + sorted(redis.keys('*')).should.equal([b'item1', b'item2']) + + httpretty.register_uri( + httpretty.GET, + "http://redis.io", + body="salvatore") + + response = requests.get('http://redis.io') + response.text.should.equal('salvatore') diff --git a/tests/bugfixes/nosetests/test_tornado_bind_unused_port.py b/tests/bugfixes/nosetests/test_tornado_bind_unused_port.py new file mode 100644 index 0000000..82cb2b9 --- /dev/null +++ b/tests/bugfixes/nosetests/test_tornado_bind_unused_port.py @@ -0,0 +1,18 @@ +import httpretty +from unittest import skip +from tornado.testing import bind_unused_port + + +@skip('') +@httpretty.activate(allow_net_connect=True) +def test_passthrough_binding_socket(): + # issue #247 + + result = bind_unused_port() + result.should.be.a(tuple) + result.should.have.length_of(2) + + socket, port = result + + port.should.be.an(int) + socket.close() diff --git a/tests/bugfixes/pytest/test_426_mypy_segfault.py b/tests/bugfixes/pytest/test_426_mypy_segfault.py new file mode 100644 index 0000000..3a60601 --- /dev/null +++ b/tests/bugfixes/pytest/test_426_mypy_segfault.py @@ -0,0 +1,81 @@ +import time +import requests +import json +import unittest +import re +import httpretty + + +class GenerateTests(type): + def __init__(cls, name, bases, attrs): + if name in ('GenerateTestMeta',): return + + count = getattr(cls, '__generate_count__', attrs.get('__generate_count__')) + if not isinstance(count, int): + raise SyntaxError(f'Metaclass requires def `__generate_count__ = NUMBER_OF_TESTS` to be set to an integer') + + generate_method = getattr(cls, '__generate_method__', attrs.get('__generate_method__')) + if not callable(generate_method): + raise SyntaxError(f'Metaclass requires def `__generate_method__(test_name):` to be implemented') + + + for x in range(count): + test_name = "test_{}".format(x) + def test_func(self, *args, **kwargs): + run_test = generate_method(test_name) + run_test(self, *args, **kwargs) + + test_func.__name__ = test_name + attrs[test_name] = test_func + setattr(cls, test_name, test_func) + + +class TestBug426MypySegfaultWithCallbackAndPayload(unittest.TestCase, metaclass=GenerateTests): + __generate_count__ = 1000 + + def __generate_method__(test_name): + @httpretty.httprettified(allow_net_connect=False) + def test_func(self): + httpretty.register_uri(httpretty.GET, 'http://github.com', body=self.json_response_callback({"kind": "insecure"})) + httpretty.register_uri(httpretty.GET, 'https://github.com', body=self.json_response_callback({"kind": "secure"})) + httpretty.register_uri(httpretty.POST, re.compile('github.com/.*'), body=self.json_response_callback({"kind": "regex"}) ) + + response = requests.post( + 'https://github.com/foo', + headers={ + "Content-Type": "application/json" + }, + data=json.dumps({test_name: time.time()})) + + assert response.status_code == 200 + + try: + response = requests.get('https://gitlab.com') + assert response.status_code == 200 + except Exception: + pass + + return test_func + + def json_response_callback(self, data): + + payload = dict(data) + payload.update({ + "time": time.time() + }) + + def request_callback(request, path, headers): + return [200, headers, json.dumps(payload)] + + return request_callback + + +class TestBug426MypySegfaultWithEmptyMethod(unittest.TestCase, metaclass=GenerateTests): + __generate_count__ = 10000 + + def __generate_method__(test_name): + @httpretty.httprettified(allow_net_connect=False) + def test_func(self): + pass + + return test_func diff --git a/tests/compat.py b/tests/compat.py new file mode 100644 index 0000000..8a6c903 --- /dev/null +++ b/tests/compat.py @@ -0,0 +1,4 @@ +try: + from unittest.mock import Mock, patch, call, MagicMock +except ImportError: + from mock import Mock, patch, call, MagicMock diff --git a/tests/functional/__init__.py b/tests/functional/__init__.py new file mode 100644 index 0000000..1b809ba --- /dev/null +++ b/tests/functional/__init__.py @@ -0,0 +1,28 @@ +# #!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +import warnings +warnings.simplefilter('ignore') diff --git a/tests/functional/base.py b/tests/functional/base.py new file mode 100644 index 0000000..7d2ecee --- /dev/null +++ b/tests/functional/base.py @@ -0,0 +1,118 @@ +# #!/usr/bin/env python +# -*- coding: utf-8 -*- + +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +from __future__ import unicode_literals + +import os +import json +import socket +import threading + +import tornado.ioloop +import tornado.web +from functools import wraps + +from os.path import abspath, dirname, join +from httpretty.core import POTENTIAL_HTTP_PORTS, old_socket + + +def get_free_tcp_port(): + """returns a TCP port that can be used for listen in the host. + """ + tcp = old_socket(socket.AF_INET, socket.SOCK_STREAM) + tcp.bind(('', 0)) + host, port = tcp.getsockname() + tcp.close() + return port + + +LOCAL_FILE = lambda *path: join(abspath(dirname(__file__)), *path) +FIXTURE_FILE = lambda name: LOCAL_FILE('fixtures', name) + + +class JSONEchoHandler(tornado.web.RequestHandler): + def get(self, matched): + payload = dict([(x, self.get_argument(x)) for x in self.request.arguments]) + self.write(json.dumps({matched or 'index': payload}, indent=4)) + + def post(self, matched): + payload = dict(self.request.arguments) + self.write(json.dumps({ + matched or 'index': payload, + 'req_body': self.request.body.decode('utf-8'), + 'req_headers': dict(self.request.headers.items()), + }, indent=4)) + + +class JSONEchoServer(threading.Thread): + def __init__(self, lock, port, *args, **kw): + self.lock = lock + self.port = int(port) + self._stop = threading.Event() + super(JSONEchoServer, self).__init__(*args, **kw) + self.daemon = True + + def stop(self): + self._stop.set() + + def stopped(self): + return self._stop.isSet() + + def setup_application(self): + return tornado.web.Application([ + (r"/(.*)", JSONEchoHandler), + ]) + + def run(self): + loop = tornado.ioloop.IOLoop() + + application = self.setup_application() + application.listen(self.port) + self.lock.release() + loop.start() + + +def use_tornado_server(callback): + lock = threading.Lock() + lock.acquire() + + @wraps(callback) + def func(*args, **kw): + port = os.getenv('TEST_PORT', get_free_tcp_port()) + POTENTIAL_HTTP_PORTS.add(port) + kw['port'] = port + server = JSONEchoServer(lock, port) + server.start() + try: + lock.acquire() + callback(*args, **kw) + finally: + lock.release() + server.stop() + if port in POTENTIAL_HTTP_PORTS: + POTENTIAL_HTTP_PORTS.remove(port) + return func diff --git a/tests/functional/fixtures/playback-1.json b/tests/functional/fixtures/playback-1.json new file mode 100644 index 0000000..1eef307 --- /dev/null +++ b/tests/functional/fixtures/playback-1.json @@ -0,0 +1,58 @@ +[ + { + "request": { + "body": "", + "headers": { + "host": "localhost:8888", + "accept-encoding": "gzip, deflate, compress", + "content-length": "0", + "accept": "*/*", + "user-agent": "python-requests/1.1.0 CPython/2.7.5 Darwin/12.5.0" + }, + "querystring": { + "age": [ + "25" + ], + "name": [ + "Gabriel" + ] + }, + "uri": "http://localhost:8888/foobar?name=Gabriel&age=25", + "method": "GET" + }, + "response": { + "status": 200, + "body": "{\n \"foobar\": {\n \"age\": \"25\", \n \"name\": \"Gabriel\"\n }\n}", + "headers": { + "content-length": "73", + "etag": "\"6fdccaba6542114e7d1098d22a01623dc2aa5761\"", + "content-type": "text/html; charset=UTF-8", + "server": "TornadoServer/2.4" + } + } + }, + { + "request": { + "body": "{\"test\": \"123\"}", + "headers": { + "host": "localhost:8888", + "accept-encoding": "gzip, deflate, compress", + "content-length": "15", + "accept": "*/*", + "user-agent": "python-requests/1.1.0 CPython/2.7.5 Darwin/12.5.0" + }, + "querystring": {}, + "uri": "http://localhost:8888/foobar", + "method": "POST" + }, + "response": { + "status": 200, + "body": "{\n \"foobar\": {}\n}", + "headers": { + "content-length": "20", + "content-type": "text/html; charset=UTF-8", + "server": "TornadoServer/2.4" + } + } + } +] \ No newline at end of file diff --git a/tests/functional/test_bypass.py b/tests/functional/test_bypass.py new file mode 100644 index 0000000..e85dfac --- /dev/null +++ b/tests/functional/test_bypass.py @@ -0,0 +1,212 @@ +# #!/usr/bin/env python +# -*- coding: utf-8 -*- + +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +from __future__ import unicode_literals +import time +import requests +try: + import urllib.request as urllib2 +except ImportError: + import urllib2 + +from .testserver import TornadoServer, TCPServer, TCPClient +from .base import get_free_tcp_port +from sure import expect, that_with_context + +import functools + +import httpretty +from httpretty import core, HTTPretty + + +def start_http_server(context): + if httpretty.httpretty._is_enabled: + allow_net_connect = httpretty.httpretty.allow_net_connect + else: + allow_net_connect = True + httpretty.disable() + context.http_port = get_free_tcp_port() + context.server = TornadoServer(context.http_port) + context.server.start() + ready = False + timeout = 2 + started_at = time.time() + while not ready: + httpretty.disable() + time.sleep(.1) + try: + requests.get('http://localhost:{}/'.format(context.http_port)) + ready = True + except Exception: + if time.time() - started_at >= timeout: + break + + httpretty.enable(allow_net_connect=allow_net_connect) + + +def stop_http_server(context): + context.server.stop() + httpretty.enable() + + +def start_tcp_server(context): + context.tcp_port = get_free_tcp_port() + context.server = TCPServer(context.tcp_port) + context.server.start() + context.client = TCPClient(context.tcp_port) + httpretty.enable() + + +def stop_tcp_server(context): + context.server.stop() + context.client.close() + httpretty.enable() + + +@httpretty.activate +@that_with_context(start_http_server, stop_http_server) +def test_httpretty_bypasses_when_disabled(context): + "httpretty should bypass all requests by disabling it" + + httpretty.register_uri( + httpretty.GET, "http://localhost:{}/go-for-bubbles/".format(context.http_port), + body="glub glub") + + httpretty.disable() + + fd = urllib2.urlopen('http://localhost:{}/go-for-bubbles/'.format(context.http_port)) + got1 = fd.read() + fd.close() + + expect(got1).to.equal( + b'. o O 0 O o . o O 0 O o . o O 0 O o . o O 0 O o . o O 0 O o .') + + fd = urllib2.urlopen('http://localhost:{}/come-again/'.format(context.http_port)) + got2 = fd.read() + fd.close() + + expect(got2).to.equal(b'<- HELLO WORLD ->') + + httpretty.enable() + + fd = urllib2.urlopen('http://localhost:{}/go-for-bubbles/'.format(context.http_port)) + got3 = fd.read() + fd.close() + + expect(got3).to.equal(b'glub glub') + core.POTENTIAL_HTTP_PORTS.remove(context.http_port) + + +@httpretty.activate(verbose=True) +@that_with_context(start_http_server, stop_http_server) +def test_httpretty_bypasses_a_unregistered_request(context): + "httpretty should bypass a unregistered request by disabling it" + + httpretty.register_uri( + httpretty.GET, "http://localhost:{}/go-for-bubbles/".format(context.http_port), + body="glub glub") + + fd = urllib2.urlopen('http://localhost:{}/go-for-bubbles/'.format(context.http_port)) + got1 = fd.read() + fd.close() + + expect(got1).to.equal(b'glub glub') + + fd = urllib2.urlopen('http://localhost:{}/come-again/'.format(context.http_port)) + got2 = fd.read() + fd.close() + + expect(got2).to.equal(b'<- HELLO WORLD ->') + core.POTENTIAL_HTTP_PORTS.remove(context.http_port) + + +@httpretty.activate(verbose=True) +@that_with_context(start_tcp_server, stop_tcp_server) +def test_using_httpretty_with_other_tcp_protocols(context): + "httpretty should work even when testing code that also use other TCP-based protocols" + + httpretty.register_uri( + httpretty.GET, "http://falcao.it/foo/", + body="BAR") + + fd = urllib2.urlopen('http://falcao.it/foo/') + got1 = fd.read() + fd.close() + + expect(got1).to.equal(b'BAR') + + expect(context.client.send("foobar")).to.equal(b"RECEIVED: foobar") + + +@httpretty.activate(allow_net_connect=False) +@that_with_context(start_http_server, stop_http_server) +def test_disallow_net_connect_1(context, verbose=True): + """ + When allow_net_connect = False, a request that otherwise + would have worked results in UnmockedError. + """ + httpretty.register_uri(httpretty.GET, "http://falcao.it/foo/", + body="BAR") + + def foo(): + fd = None + try: + fd = urllib2.urlopen('http://localhost:{}/go-for-bubbles/'.format(context.http_port)) + finally: + if fd: + fd.close() + + foo.should.throw(httpretty.UnmockedError) + + +@httpretty.activate(allow_net_connect=False) +def test_disallow_net_connect_2(): + """ + When allow_net_connect = False, a request that would have + failed results in UnmockedError. + """ + + def foo(): + fd = None + try: + fd = urllib2.urlopen('http://example.com/nonsense') + finally: + if fd: + fd.close() + + foo.should.throw(httpretty.UnmockedError) + + +@httpretty.activate(allow_net_connect=False) +def test_disallow_net_connect_3(): + "When allow_net_connect = False, mocked requests still work correctly." + + httpretty.register_uri(httpretty.GET, "http://falcao.it/foo/", + body="BAR") + fd = urllib2.urlopen('http://falcao.it/foo/') + got1 = fd.read() + fd.close() + expect(got1).to.equal(b'BAR') diff --git a/tests/functional/test_debug.py b/tests/functional/test_debug.py new file mode 100644 index 0000000..86bf09e --- /dev/null +++ b/tests/functional/test_debug.py @@ -0,0 +1,91 @@ +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +import socket +from unittest import skip +from sure import scenario, expect +from httpretty import httprettified + + +def create_socket(context): + context.sock = socket.socket( + socket.AF_INET, + socket.SOCK_STREAM, + socket.IPPROTO_TCP, + ) + context.sock.is_http = True + + +@skip('not currently supported') +@httprettified +@scenario(create_socket) +def test_httpretty_debugs_socket_send(context): + "HTTPretty should forward_and_trace socket.send" + + expect(context.sock.send).when.called_with(b'data').to.throw( + "not connected" + ) + + +@skip('not currently supported') +@httprettified +@scenario(create_socket) +def test_httpretty_debugs_socket_sendto(context): + "HTTPretty should forward_and_trace socket.sendto" + + expect(context.sock.sendto).when.called.to.throw( + "not connected" + ) + + +@skip('not currently supported') +@httprettified +@scenario(create_socket) +def test_httpretty_debugs_socket_recvfrom(context): + "HTTPretty should forward_and_trace socket.recvfrom" + + expect(context.sock.recvfrom).when.called.to.throw( + "not connected" + ) + + +@skip('not currently supported') +@httprettified +@scenario(create_socket) +def test_httpretty_debugs_socket_recv_into(context): + "HTTPretty should forward_and_trace socket.recv_into" + buf = bytearray() + expect(context.sock.recv_into).when.called_with(buf).to.throw( + "not connected" + ) + + +@skip('not currently supported') +@httprettified +@scenario(create_socket) +def test_httpretty_debugs_socket_recvfrom_into(context): + "HTTPretty should forward_and_trace socket.recvfrom_into" + + expect(context.sock.recvfrom_into).when.called.to.throw( + "not connected" + ) diff --git a/tests/functional/test_decorator.py b/tests/functional/test_decorator.py new file mode 100644 index 0000000..d1f156a --- /dev/null +++ b/tests/functional/test_decorator.py @@ -0,0 +1,116 @@ +# coding: utf-8 +from unittest import TestCase +from sure import expect +from httpretty import httprettified, HTTPretty + +try: + import urllib.request as urllib2 +except ImportError: + import urllib2 + + +@httprettified +def test_decor(): + HTTPretty.register_uri( + HTTPretty.GET, "http://localhost/", + body="glub glub") + + fd = urllib2.urlopen('http://localhost/') + got1 = fd.read() + fd.close() + + expect(got1).to.equal(b'glub glub') + + +@httprettified +class DecoratedNonUnitTest(object): + + def test_fail(self): + raise AssertionError('Tests in this class should not ' + 'be executed by the test runner.') + + def test_decorated(self): + HTTPretty.register_uri( + HTTPretty.GET, "http://localhost/", + body="glub glub") + + fd = urllib2.urlopen('http://localhost/') + got1 = fd.read() + fd.close() + + expect(got1).to.equal(b'glub glub') + + +class NonUnitTestTest(TestCase): + """ + Checks that the test methods in DecoratedNonUnitTest were decorated. + """ + + def test_decorated(self): + DecoratedNonUnitTest().test_decorated() + + +@httprettified +class ClassDecorator(TestCase): + + def test_decorated(self): + HTTPretty.register_uri( + HTTPretty.GET, "http://localhost/", + body="glub glub") + + fd = urllib2.urlopen('http://localhost/') + got1 = fd.read() + fd.close() + + expect(got1).to.equal(b'glub glub') + + def test_decorated2(self): + HTTPretty.register_uri( + HTTPretty.GET, "http://localhost/", + body="buble buble") + + fd = urllib2.urlopen('http://localhost/') + got1 = fd.read() + fd.close() + + expect(got1).to.equal(b'buble buble') + + +@httprettified +class ClassDecoratorWithSetUp(TestCase): + + def setUp(self): + HTTPretty.register_uri( + HTTPretty.GET, "http://localhost/", + responses=[ + HTTPretty.Response("glub glub"), + HTTPretty.Response("buble buble"), + ]) + + def test_decorated(self): + + fd = urllib2.urlopen('http://localhost/') + got1 = fd.read() + fd.close() + + expect(got1).to.equal(b'glub glub') + + fd = urllib2.urlopen('http://localhost/') + got2 = fd.read() + fd.close() + + expect(got2).to.equal(b'buble buble') + + def test_decorated2(self): + + fd = urllib2.urlopen('http://localhost/') + got1 = fd.read() + fd.close() + + expect(got1).to.equal(b'glub glub') + + fd = urllib2.urlopen('http://localhost/') + got2 = fd.read() + fd.close() + + expect(got2).to.equal(b'buble buble') diff --git a/tests/functional/test_fakesocket.py b/tests/functional/test_fakesocket.py new file mode 100644 index 0000000..39d914b --- /dev/null +++ b/tests/functional/test_fakesocket.py @@ -0,0 +1,75 @@ +# #!/usr/bin/env python +# -*- coding: utf-8 -*- + +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +import functools +import socket + +import mock + + +class FakeSocket(socket.socket): + """ + Just an editable socket factory + It allows mock to patch readonly functions + """ + connect = sendall = lambda *args, **kw: None + + +fake_socket_interupter_flag = {} + + +def recv(flag, size): + """ + Two pass recv implementation + + This implementation will for the first time send something that is smaller than + the asked size passed in argument. + Any further call will just raise RuntimeError + """ + if 'was_here' in flag: + raise RuntimeError('Already sent everything') + else: + flag['was_here'] = None + return 'a' * (size - 1) + + +recv = functools.partial(recv, fake_socket_interupter_flag) + + +@mock.patch('httpretty.old_socket', new=FakeSocket) +def _test_shorten_response(): + u"HTTPretty shouldn't try to read from server when communication is over" + from sure import expect + import httpretty + + fakesocket = httpretty.fakesock.socket(socket.AF_INET, + socket.SOCK_STREAM) + with mock.patch.object(fakesocket.truesock, 'recv', recv): + fakesocket.connect(('localhost', 80)) + fakesocket._true_sendall('WHATEVER') + expect(fakesocket.fd.read()).to.equal( + 'a' * (httpretty.socket_buffer_size - 1)) diff --git a/tests/functional/test_httplib2.py b/tests/functional/test_httplib2.py new file mode 100644 index 0000000..c913d8a --- /dev/null +++ b/tests/functional/test_httplib2.py @@ -0,0 +1,306 @@ +# #!/usr/bin/env python +# -*- coding: utf-8 -*- + +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +from __future__ import unicode_literals + +import re +import httplib2 +from freezegun import freeze_time +from sure import expect, within, miliseconds +from httpretty import HTTPretty, httprettified +from httpretty.core import decode_utf8 + + +@httprettified +@within(two=miliseconds) +def test_httpretty_should_mock_a_simple_get_with_httplib2_read(now): + "HTTPretty should mock a simple GET with httplib2.context.http" + + HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/", + body="Find the best daily deals") + + _, got = httplib2.Http().request('http://yipit.com', 'GET') + expect(got).to.equal(b'Find the best daily deals') + + expect(HTTPretty.last_request.method).to.equal('GET') + expect(HTTPretty.last_request.path).to.equal('/') + + +@httprettified +@within(two=miliseconds) +def test_httpretty_provides_easy_access_to_querystrings(now): + "HTTPretty should provide an easy access to the querystring" + + HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/", + body="Find the best daily deals") + + httplib2.Http().request('http://yipit.com?foo=bar&foo=baz&chuck=norris', 'GET') + expect(HTTPretty.last_request.querystring).to.equal({ + 'foo': ['bar', 'baz'], + 'chuck': ['norris'], + }) + + +@httprettified +@freeze_time("2013-10-04 04:20:00") +def test_httpretty_should_mock_headers_httplib2(): + "HTTPretty should mock basic headers with httplib2" + + HTTPretty.register_uri(HTTPretty.GET, "http://github.com/", + body="this is supposed to be the response", + status=201) + + headers, _ = httplib2.Http().request('http://github.com', 'GET') + expect(headers['status']).to.equal('201') + expect(dict(headers)).to.equal({ + 'content-type': 'text/plain; charset=utf-8', + 'connection': 'close', + 'content-length': '35', + 'status': '201', + 'server': 'Python/HTTPretty', + 'date': 'Fri, 04 Oct 2013 04:20:00 GMT', + }) + + +@httprettified +@freeze_time("2013-10-04 04:20:00") +def test_httpretty_should_allow_adding_and_overwritting_httplib2(): + "HTTPretty should allow adding and overwritting headers with httplib2" + + HTTPretty.register_uri(HTTPretty.GET, "http://github.com/foo", + body="this is supposed to be the response", + adding_headers={ + 'Server': 'Apache', + 'Content-Length': '27', + 'Content-Type': 'application/json', + }) + + headers, _ = httplib2.Http().request('http://github.com/foo', 'GET') + + expect(dict(headers)).to.equal({ + 'content-type': 'application/json', + 'content-location': 'http://github.com/foo', + 'connection': 'close', + 'content-length': '27', + 'status': '200', + 'server': 'Apache', + 'date': 'Fri, 04 Oct 2013 04:20:00 GMT', + }) + + +@httprettified +@within(two=miliseconds) +def test_httpretty_should_allow_forcing_headers_httplib2(now): + "HTTPretty should allow forcing headers with httplib2" + + HTTPretty.register_uri(HTTPretty.GET, "http://github.com/foo", + body="this is supposed to be the response", + forcing_headers={ + 'Content-Type': 'application/xml', + }) + + headers, _ = httplib2.Http().request('http://github.com/foo', 'GET') + + expect(dict(headers)).to.equal({ + 'content-location': 'http://github.com/foo', # httplib2 FORCES + # content-location + # even if the + # server does not + # provide it + 'content-type': 'application/xml', + 'status': '200', # httplib2 also ALWAYS put status on headers + }) + + +@httprettified +@freeze_time("2013-10-04 04:20:00") +def test_httpretty_should_allow_adding_and_overwritting_by_kwargs_u2(): + "HTTPretty should allow adding and overwritting headers by keyword args " \ + "with httplib2" + + HTTPretty.register_uri(HTTPretty.GET, "http://github.com/foo", + body="this is supposed to be the response", + server='Apache', + content_length='27', + content_type='application/json') + + headers, _ = httplib2.Http().request('http://github.com/foo', 'GET') + + expect(dict(headers)).to.equal({ + 'content-type': 'application/json', + 'content-location': 'http://github.com/foo', # httplib2 FORCES + # content-location + # even if the + # server does not + # provide it + 'connection': 'close', + 'content-length': '27', + 'status': '200', + 'server': 'Apache', + 'date': 'Fri, 04 Oct 2013 04:20:00 GMT', + }) + + +@httprettified +@within(two=miliseconds) +def test_rotating_responses_with_httplib2(now): + "HTTPretty should support rotating responses with httplib2" + + HTTPretty.register_uri( + HTTPretty.GET, "https://api.yahoo.com/test", + responses=[ + HTTPretty.Response(body="first response", status=201), + HTTPretty.Response(body='second and last response', status=202), + ]) + + headers1, body1 = httplib2.Http().request( + 'https://api.yahoo.com/test', 'GET') + + expect(headers1['status']).to.equal('201') + expect(body1).to.equal(b'first response') + + headers2, body2 = httplib2.Http().request( + 'https://api.yahoo.com/test', 'GET') + + expect(headers2['status']).to.equal('202') + expect(body2).to.equal(b'second and last response') + + headers3, body3 = httplib2.Http().request( + 'https://api.yahoo.com/test', 'GET') + + expect(headers3['status']).to.equal('202') + expect(body3).to.equal(b'second and last response') + + +@httprettified +@within(two=miliseconds) +def test_can_inspect_last_request(now): + "HTTPretty.last_request is a mimetools.Message request from last match" + + HTTPretty.register_uri(HTTPretty.POST, "http://api.github.com/", + body='{"repositories": ["HTTPretty", "lettuce"]}') + + headers, body = httplib2.Http().request( + 'http://api.github.com', 'POST', + body='{"username": "gabrielfalcao"}', + headers={ + 'content-type': 'text/json', + }, + ) + + expect(HTTPretty.last_request.method).to.equal('POST') + expect(HTTPretty.last_request.body).to.equal( + b'{"username": "gabrielfalcao"}', + ) + expect(HTTPretty.last_request.headers['content-type']).to.equal( + 'text/json', + ) + expect(body).to.equal(b'{"repositories": ["HTTPretty", "lettuce"]}') + + +@httprettified +@within(two=miliseconds) +def test_can_inspect_last_request_with_ssl(now): + "HTTPretty.last_request is recorded even when mocking 'https' (SSL)" + + HTTPretty.register_uri(HTTPretty.POST, "https://secure.github.com/", + body='{"repositories": ["HTTPretty", "lettuce"]}') + + headers, body = httplib2.Http().request( + 'https://secure.github.com', 'POST', + body='{"username": "gabrielfalcao"}', + headers={ + 'content-type': 'text/json', + }, + ) + + expect(HTTPretty.last_request.method).to.equal('POST') + expect(HTTPretty.last_request.body).to.equal( + b'{"username": "gabrielfalcao"}', + ) + expect(HTTPretty.last_request.headers['content-type']).to.equal( + 'text/json', + ) + expect(body).to.equal(b'{"repositories": ["HTTPretty", "lettuce"]}') + + +@httprettified +@within(two=miliseconds) +def test_httpretty_ignores_querystrings_from_registered_uri(now): + "Registering URIs with query string cause them to be ignored" + + HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/?id=123", + body="Find the best daily deals") + + _, got = httplib2.Http().request('http://yipit.com/?id=123', 'GET') + + expect(got).to.equal(b'Find the best daily deals') + expect(HTTPretty.last_request.method).to.equal('GET') + expect(HTTPretty.last_request.path).to.equal('/?id=123') + + +@httprettified +@within(two=miliseconds) +def test_callback_response(now): + ("HTTPretty should call a callback function to be set as the body with" + " httplib2") + + def request_callback(request, uri, headers): + return [200, headers, "The {} response from {}".format(decode_utf8(request.method), uri)] + + HTTPretty.register_uri( + HTTPretty.GET, "https://api.yahoo.com/test", + body=request_callback) + + headers1, body1 = httplib2.Http().request( + 'https://api.yahoo.com/test', 'GET') + + expect(body1).to.equal(b"The GET response from https://api.yahoo.com/test") + + HTTPretty.register_uri( + HTTPretty.POST, "https://api.yahoo.com/test_post", + body=request_callback) + + headers2, body2 = httplib2.Http().request( + 'https://api.yahoo.com/test_post', 'POST') + + expect(body2).to.equal(b"The POST response from https://api.yahoo.com/test_post") + + +@httprettified +def test_httpretty_should_allow_registering_regexes(): + "HTTPretty should allow registering regexes with httplib2" + + HTTPretty.register_uri( + HTTPretty.GET, + 'http://api.yipit.com/v1/deal;brand=gap', + body="Found brand", + ) + + response, body = httplib2.Http().request('http://api.yipit.com/v1/deal;brand=gap', 'GET') + expect(body).to.equal(b'Found brand') + expect(HTTPretty.last_request.method).to.equal('GET') + expect(HTTPretty.last_request.path).to.equal('/v1/deal;brand=gap') diff --git a/tests/functional/test_passthrough.py b/tests/functional/test_passthrough.py new file mode 100644 index 0000000..47c9e79 --- /dev/null +++ b/tests/functional/test_passthrough.py @@ -0,0 +1,78 @@ +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +import requests +import httpretty + +from sure import expect + + +def http(): + sess = requests.Session() + adapter = requests.adapters.HTTPAdapter(pool_connections=1, pool_maxsize=1) + sess.mount('http://', adapter) + sess.mount('https://', adapter) + return sess + + +def test_http_passthrough(): + url = 'http://httpbin.org/status/200' + response1 = http().get(url) + + response1 = http().get(url) + + httpretty.enable(allow_net_connect=False, verbose=True) + httpretty.register_uri(httpretty.GET, 'http://google.com/', body="Not Google") + httpretty.register_uri(httpretty.GET, url, body="mocked") + + response2 = http().get('http://google.com/') + expect(response2.content).to.equal(b'Not Google') + + response3 = http().get(url) + response3.content.should.equal(b"mocked") + + httpretty.disable() + + response4 = http().get(url) + (response4.content).should.equal(response1.content) + + +def test_https_passthrough(): + url = 'https://httpbin.org/status/200' + + response1 = http().get(url) + + httpretty.enable(allow_net_connect=False, verbose=True) + httpretty.register_uri(httpretty.GET, 'https://google.com/', body="Not Google") + httpretty.register_uri(httpretty.GET, url, body="mocked") + + response2 = http().get('https://google.com/') + expect(response2.content).to.equal(b'Not Google') + + response3 = http().get(url) + (response3.text).should.equal('mocked') + + httpretty.disable() + + response4 = http().get(url) + (response4.content).should.equal(response1.content) diff --git a/tests/functional/test_requests.py b/tests/functional/test_requests.py new file mode 100644 index 0000000..752428b --- /dev/null +++ b/tests/functional/test_requests.py @@ -0,0 +1,949 @@ +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +import os +import re +import json +import requests +import signal +import httpretty + +from freezegun import freeze_time +from contextlib import contextmanager +from sure import within, miliseconds, expect +from tornado import version as tornado_version +from httpretty import HTTPretty, httprettified +from httpretty.core import decode_utf8 + +from tests.functional.base import FIXTURE_FILE, use_tornado_server + +from tests.compat import Mock + + +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() + + +next = advance_iterator + +server_url = lambda path, port: "http://localhost:{}/{}".format(port, path.lstrip('/')) + + +@httprettified +@within(two=miliseconds) +def test_httpretty_should_mock_a_simple_get_with_requests_read(now): + "HTTPretty should mock a simple GET with requests.get" + + HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/", + body="Find the best daily deals") + + response = requests.get('http://yipit.com') + expect(response.text).to.equal('Find the best daily deals') + expect(HTTPretty.last_request.method).to.equal('GET') + expect(HTTPretty.last_request.path).to.equal('/') + + +@httprettified +@within(two=miliseconds) +def test_hostname_case_insensitive(now): + "HTTPretty should match the hostname case insensitive" + + HTTPretty.register_uri(HTTPretty.GET, "http://yipit/", + body="Find the best daily deals") + + response = requests.get('http://YIPIT') + expect(response.text).to.equal('Find the best daily deals') + expect(HTTPretty.last_request.method).to.equal('GET') + expect(HTTPretty.last_request.path).to.equal('/') + + +@httprettified +@within(two=miliseconds) +def test_httpretty_provides_easy_access_to_querystrings(now): + "HTTPretty should provide an easy access to the querystring" + + HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/", + body="Find the best daily deals") + + requests.get('http://yipit.com/?foo=bar&foo=baz&chuck=norris') + expect(HTTPretty.last_request.querystring).to.equal({ + 'foo': ['bar', 'baz'], + 'chuck': ['norris'], + }) + + +@httprettified +@freeze_time("2013-10-04 04:20:00") +def test_httpretty_should_mock_headers_requests(): + "HTTPretty should mock basic headers with requests" + + HTTPretty.register_uri(HTTPretty.GET, "http://github.com/", + body="this is supposed to be the response", + status=201) + + response = requests.get('http://github.com') + expect(response.status_code).to.equal(201) + + expect(dict(response.headers)).to.equal({ + 'content-type': 'text/plain; charset=utf-8', + 'connection': 'close', + 'content-length': '35', + 'status': '201', + 'server': 'Python/HTTPretty', + 'date': 'Fri, 04 Oct 2013 04:20:00 GMT', + }) + + +@httprettified +@freeze_time("2013-10-04 04:20:00") +def test_httpretty_should_allow_adding_and_overwritting_requests(): + "HTTPretty should allow adding and overwritting headers with requests" + + HTTPretty.register_uri(HTTPretty.GET, "http://github.com/foo", + body="this is supposed to be the response", + adding_headers={ + 'Server': 'Apache', + 'Content-Length': '27', + 'Content-Type': 'application/json', + }) + + response = requests.get('http://github.com/foo') + + expect(dict(response.headers)).to.equal({ + 'content-type': 'application/json', + 'connection': 'close', + 'content-length': '27', + 'status': '200', + 'server': 'Apache', + 'date': 'Fri, 04 Oct 2013 04:20:00 GMT', + }) + + +@httprettified +@within(two=miliseconds) +def test_httpretty_should_allow_forcing_headers_requests(now): + "HTTPretty should allow forcing headers with requests" + + HTTPretty.register_uri(HTTPretty.GET, "http://github.com/foo", + body="", + forcing_headers={ + 'Content-Type': 'application/xml', + 'Content-Length': '19', + }) + + response = requests.get('http://github.com/foo') + + expect(dict(response.headers)).to.equal({ + 'content-type': 'application/xml', + 'content-length': '19', + }) + + +@httprettified +@freeze_time("2013-10-04 04:20:00") +def test_httpretty_should_allow_adding_and_overwritting_by_kwargs_u2(): + "HTTPretty should allow adding and overwritting headers by keyword args " \ + "with requests" + + HTTPretty.register_uri(HTTPretty.GET, "http://github.com/foo", + body="this is supposed to be the response", + server='Apache', + content_length='27', + content_type='application/json') + + response = requests.get('http://github.com/foo') + + expect(dict(response.headers)).to.equal({ + 'content-type': 'application/json', + 'connection': 'close', + 'content-length': '27', + 'status': '200', + 'server': 'Apache', + 'date': 'Fri, 04 Oct 2013 04:20:00 GMT', + }) + + +@httprettified +@within(two=miliseconds) +def test_rotating_responses_with_requests(now): + "HTTPretty should support rotating responses with requests" + + HTTPretty.register_uri( + HTTPretty.GET, "https://api.yahoo.com/test", + responses=[ + HTTPretty.Response(body=b"first response", status=201), + HTTPretty.Response(body=b'second and last response', status=202), + ]) + + response1 = requests.get( + 'https://api.yahoo.com/test') + + expect(response1.status_code).to.equal(201) + expect(response1.text).to.equal('first response') + + response2 = requests.get( + 'https://api.yahoo.com/test') + + expect(response2.status_code).to.equal(202) + expect(response2.text).to.equal('second and last response') + + response3 = requests.get( + 'https://api.yahoo.com/test') + + expect(response3.status_code).to.equal(202) + expect(response3.text).to.equal('second and last response') + + +@httprettified +@within(two=miliseconds) +def test_can_inspect_last_request(now): + "HTTPretty.last_request is a mimetools.Message request from last match" + + HTTPretty.register_uri(HTTPretty.POST, "http://api.github.com/", + body='{"repositories": ["HTTPretty", "lettuce"]}') + + response = requests.post( + 'http://api.github.com', + '{"username": "gabrielfalcao"}', + headers={ + 'content-type': 'text/json', + }, + ) + + expect(HTTPretty.last_request.method).to.equal('POST') + expect(HTTPretty.last_request.body).to.equal( + b'{"username": "gabrielfalcao"}', + ) + expect(HTTPretty.last_request.headers['content-type']).to.equal( + 'text/json', + ) + expect(response.json()).to.equal({"repositories": ["HTTPretty", "lettuce"]}) + + +@httprettified +@within(two=miliseconds) +def test_can_inspect_last_request_with_ssl(now): + "HTTPretty.last_request is recorded even when mocking 'https' (SSL)" + + HTTPretty.register_uri(HTTPretty.POST, "https://secure.github.com/", + body='{"repositories": ["HTTPretty", "lettuce"]}') + + response = requests.post( + 'https://secure.github.com', + '{"username": "gabrielfalcao"}', + headers={ + 'content-type': 'text/json', + }, + ) + + expect(HTTPretty.last_request.method).to.equal('POST') + expect(HTTPretty.last_request.body).to.equal( + b'{"username": "gabrielfalcao"}', + ) + expect(HTTPretty.last_request.headers['content-type']).to.equal( + 'text/json', + ) + expect(response.json()).to.equal({"repositories": ["HTTPretty", "lettuce"]}) + + +@httprettified +@within(two=miliseconds) +def test_httpretty_ignores_querystrings_from_registered_uri(now): + "HTTPretty should ignore querystrings from the registered uri (requests library)" + + HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/?id=123", + body=b"Find the best daily deals") + + response = requests.get('http://yipit.com/', params={'id': 123}) + expect(response.text).to.equal('Find the best daily deals') + expect(HTTPretty.last_request.method).to.equal('GET') + expect(HTTPretty.last_request.path).to.equal('/?id=123') + + +@httprettified +@within(five=miliseconds) +def test_streaming_responses(now): + """ + Mock a streaming HTTP response, like those returned by the Twitter streaming + API. + """ + + @contextmanager + def in_time(time, message): + """ + A context manager that uses signals to force a time limit in tests + (unlike the `@within` decorator, which only complains afterward), or + raise an AssertionError. + """ + def handler(signum, frame): + raise AssertionError(message) + signal.signal(signal.SIGALRM, handler) + signal.setitimer(signal.ITIMER_REAL, time) + yield + signal.setitimer(signal.ITIMER_REAL, 0) + + # XXX this obviously isn't a fully functional twitter streaming client! + twitter_response_lines = [ + b'{"text":"If \\"for the boobs\\" requests to follow me one more time I\'m calling the police. http://t.co/a0mDEAD8"}\r\n', + b'\r\n', + b'{"text":"RT @onedirection: Thanks for all your # FollowMe1D requests Directioners! We\u2019ll be following 10 people throughout the day starting NOW. G ..."}\r\n' + ] + + TWITTER_STREAMING_URL = "https://stream.twitter.com/1/statuses/filter.json" + + HTTPretty.register_uri(HTTPretty.POST, TWITTER_STREAMING_URL, + body=(l for l in twitter_response_lines), + streaming=True) + + # taken from the requests docs + + # test iterating by line + # Http://docs.python-requests.org/en/latest/user/advanced/# streaming-requests + response = requests.post(TWITTER_STREAMING_URL, data={'track': 'requests'}, + auth=('username', 'password'), stream=True) + + line_iter = response.iter_lines() + with in_time(0.01, 'Iterating by line is taking forever!'): + for i in range(len(twitter_response_lines)): + expect(next(line_iter).strip()).to.equal( + twitter_response_lines[i].strip()) + + HTTPretty.register_uri(HTTPretty.POST, TWITTER_STREAMING_URL, + body=(l for l in twitter_response_lines), + streaming=True) + # test iterating by line after a second request + response = requests.post( + TWITTER_STREAMING_URL, + data={ + 'track': 'requests' + }, + auth=('username', 'password'), + stream=True, + ) + + line_iter = response.iter_lines() + with in_time(0.01, 'Iterating by line is taking forever the second time ' + 'around!'): + for i in range(len(twitter_response_lines)): + expect(next(line_iter).strip()).to.equal( + twitter_response_lines[i].strip()) + + HTTPretty.register_uri(HTTPretty.POST, TWITTER_STREAMING_URL, + body=(l for l in twitter_response_lines), + streaming=True) + # test iterating by char + response = requests.post( + TWITTER_STREAMING_URL, + data={ + 'track': 'requests' + }, + auth=('username', 'password'), + stream=True + ) + + twitter_expected_response_body = b''.join(twitter_response_lines) + with in_time(0.02, 'Iterating by char is taking forever!'): + twitter_body = b''.join(c for c in response.iter_content(chunk_size=1)) + + expect(twitter_body).to.equal(twitter_expected_response_body) + + # test iterating by chunks larger than the stream + HTTPretty.register_uri(HTTPretty.POST, TWITTER_STREAMING_URL, + body=(l for l in twitter_response_lines), + streaming=True) + response = requests.post(TWITTER_STREAMING_URL, data={'track': 'requests'}, + auth=('username', 'password'), stream=True) + + with in_time(0.02, 'Iterating by large chunks is taking forever!'): + twitter_body = b''.join(c for c in + response.iter_content(chunk_size=1024)) + + expect(twitter_body).to.equal(twitter_expected_response_body) + + +@httprettified +def test_multiline(): + url = 'https://httpbin.org/post' + data = b'content=Im\r\na multiline\r\n\r\nsentence\r\n' + headers = { + 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', + 'Accept': 'text/plain', + } + HTTPretty.register_uri( + HTTPretty.POST, + url, + ) + response = requests.post(url, data=data, headers=headers) + + expect(response.status_code).to.equal(200) + expect(HTTPretty.last_request.method).to.equal('POST') + expect(HTTPretty.last_request.url).to.equal('https://httpbin.org/post') + expect(HTTPretty.last_request.protocol).to.equal('https') + expect(HTTPretty.last_request.path).to.equal('/post') + expect(HTTPretty.last_request.body).to.equal(data) + expect(HTTPretty.last_request.headers['content-length']).to.equal('37') + expect(HTTPretty.last_request.headers['content-type']).to.equal('application/x-www-form-urlencoded; charset=utf-8') + expect(len(HTTPretty.latest_requests)).to.equal(2) + + +@httprettified +def test_octet_stream(): + url = 'https://httpbin.org/post' + data = b"\xf5\x00\x00\x00" # utf-8 with invalid start byte + headers = { + 'Content-Type': 'application/octet-stream', + } + HTTPretty.register_uri( + HTTPretty.POST, + url, + ) + response = requests.post(url, data=data, headers=headers) + + expect(response.status_code).to.equal(200) + expect(HTTPretty.last_request.method).to.equal('POST') + expect(HTTPretty.last_request.url).to.equal('https://httpbin.org/post') + expect(HTTPretty.last_request.protocol).to.equal('https') + expect(HTTPretty.last_request.path).to.equal('/post') + expect(HTTPretty.last_request.body).to.equal(data) + expect(HTTPretty.last_request.headers['content-length']).to.equal('4') + expect(HTTPretty.last_request.headers['content-type']).to.equal('application/octet-stream') + expect(len(HTTPretty.latest_requests)).to.equal(2) + + +@httprettified +def test_multipart(): + url = 'https://httpbin.org/post' + data = b'--xXXxXXyYYzzz\r\nContent-Disposition: form-data; name="content"\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Length: 68\r\n\r\nAction: comment\nText: Comment with attach\nAttachment: x1.txt, x2.txt\r\n--xXXxXXyYYzzz\r\nContent-Disposition: form-data; name="attachment_2"; filename="x.txt"\r\nContent-Type: text/plain\r\nContent-Length: 4\r\n\r\nbye\n\r\n--xXXxXXyYYzzz\r\nContent-Disposition: form-data; name="attachment_1"; filename="x.txt"\r\nContent-Type: text/plain\r\nContent-Length: 4\r\n\r\nbye\n\r\n--xXXxXXyYYzzz--\r\n' + headers = {'Content-Length': '495', 'Content-Type': 'multipart/form-data; boundary=xXXxXXyYYzzz', 'Accept': 'text/plain'} + HTTPretty.register_uri( + HTTPretty.POST, + url, + ) + response = requests.post(url, data=data, headers=headers) + expect(response.status_code).to.equal(200) + expect(HTTPretty.last_request.method).to.equal('POST') + expect(HTTPretty.last_request.url).to.equal('https://httpbin.org/post') + expect(HTTPretty.last_request.protocol).to.equal('https') + expect(HTTPretty.last_request.path).to.equal('/post') + expect(HTTPretty.last_request.body).to.equal(data) + expect(HTTPretty.last_request.headers['content-length']).to.equal('495') + expect(HTTPretty.last_request.headers['content-type']).to.equal('multipart/form-data; boundary=xXXxXXyYYzzz') + expect(len(HTTPretty.latest_requests)).to.equal(2) + + +@httprettified +@within(two=miliseconds) +def test_callback_response(now): + ("HTTPretty should call a callback function and set its return value as the body of the response" + " requests") + + def request_callback(request, uri, headers): + return [200, headers, "The {} response from {}".format(decode_utf8(request.method), uri)] + + HTTPretty.register_uri( + HTTPretty.GET, "https://api.yahoo.com/test", + body=request_callback) + + response = requests.get('https://api.yahoo.com/test') + + expect(response.text).to.equal("The GET response from https://api.yahoo.com/test") + + HTTPretty.register_uri( + HTTPretty.POST, "https://api.yahoo.com/test_post", + body=request_callback) + + response = requests.post( + "https://api.yahoo.com/test_post", + {"username": "gabrielfalcao"} + ) + + expect(response.text).to.equal("The POST response from https://api.yahoo.com/test_post") + + +@httprettified +@within(two=miliseconds) +def test_callback_body_remains_callable_for_any_subsequent_requests(now): + ("HTTPretty should call a callback function more than one" + " requests") + + def request_callback(request, uri, headers): + return [200, headers, "The {} response from {}".format(decode_utf8(request.method), uri)] + + HTTPretty.register_uri( + HTTPretty.GET, "https://api.yahoo.com/test", + body=request_callback) + + response = requests.get('https://api.yahoo.com/test') + expect(response.text).to.equal("The GET response from https://api.yahoo.com/test") + + response = requests.get('https://api.yahoo.com/test') + expect(response.text).to.equal("The GET response from https://api.yahoo.com/test") + + +@httprettified +@within(two=miliseconds) +def test_callback_setting_headers_and_status_response(now): + ("HTTPretty should call a callback function and uses it retur tuple as status code, headers and body" + " requests") + + def request_callback(request, uri, headers): + headers.update({'a': 'b'}) + return [418, headers, "The {} response from {}".format(decode_utf8(request.method), uri)] + + HTTPretty.register_uri( + HTTPretty.GET, "https://api.yahoo.com/test", + body=request_callback) + + response = requests.get('https://api.yahoo.com/test') + expect(response.text).to.equal("The GET response from https://api.yahoo.com/test") + expect(response.headers).to.have.key('a').being.equal("b") + expect(response.status_code).to.equal(418) + + HTTPretty.register_uri( + HTTPretty.POST, "https://api.yahoo.com/test_post", + body=request_callback) + + response = requests.post( + "https://api.yahoo.com/test_post", + {"username": "gabrielfalcao"} + ) + + expect(response.text).to.equal("The POST response from https://api.yahoo.com/test_post") + expect(response.headers).to.have.key('a').being.equal("b") + expect(response.status_code).to.equal(418) + + +@httprettified +def test_httpretty_should_respect_matcher_priority(): + HTTPretty.register_uri( + HTTPretty.GET, + re.compile(r".*"), + body='high priority', + priority=5, + ) + HTTPretty.register_uri( + HTTPretty.GET, + re.compile(r".+"), + body='low priority', + priority=0, + ) + response = requests.get('http://api.yipit.com/v1/') + expect(response.text).to.equal('high priority') + + +@httprettified +@within(two=miliseconds) +def test_callback_setting_content_length_on_head(now): + ("HTTPretty should call a callback function, use it's return tuple as status code, headers and body" + " requests and respect the content-length header when responding to HEAD") + + def request_callback(request, uri, headers): + headers.update({'content-length': 12345}) + return [200, headers, ""] + + HTTPretty.register_uri( + HTTPretty.HEAD, "https://api.yahoo.com/test", + body=request_callback) + + response = requests.head('https://api.yahoo.com/test') + expect(response.headers).to.have.key('content-length').being.equal("12345") + expect(response.status_code).to.equal(200) + + +@httprettified +def test_httpretty_should_allow_registering_regexes_and_give_a_proper_match_to_the_callback(): + "HTTPretty should allow registering regexes with requests and giva a proper match to the callback" + + HTTPretty.register_uri( + HTTPretty.GET, + re.compile(r"https://api.yipit.com/v1/deal;brand=(?P\w+)"), + body=lambda method, uri, headers: [200, headers, uri] + ) + + response = requests.get('https://api.yipit.com/v1/deal;brand=gap?first_name=chuck&last_name=norris') + + expect(response.text).to.equal('https://api.yipit.com/v1/deal;brand=gap?first_name=chuck&last_name=norris') + expect(HTTPretty.last_request.method).to.equal('GET') + expect(HTTPretty.last_request.path).to.equal('/v1/deal;brand=gap?first_name=chuck&last_name=norris') + + +@httprettified +def test_httpretty_should_allow_registering_regexes(): + "HTTPretty should allow registering regexes with requests" + + HTTPretty.register_uri( + HTTPretty.GET, + re.compile(r"https://api.yipit.com/v1/deal;brand=(?P\w+)"), + body="Found brand", + ) + + response = requests.get('https://api.yipit.com/v1/deal;brand=gap?first_name=chuck&last_name=norris' + ) + expect(response.text).to.equal('Found brand') + expect(HTTPretty.last_request.method).to.equal('GET') + expect(HTTPretty.last_request.path).to.equal('/v1/deal;brand=gap?first_name=chuck&last_name=norris') + + +@httprettified +def test_httpretty_provides_easy_access_to_querystrings_with_regexes(): + "HTTPretty should match regexes even if they have a different querystring" + + HTTPretty.register_uri( + HTTPretty.GET, + re.compile(r"https://api.yipit.com/v1/(?P\w+)/$"), + body="Find the best daily deals" + ) + + response = requests.get('https://api.yipit.com/v1/deals/?foo=bar&foo=baz&chuck=norris') + expect(response.text).to.equal("Find the best daily deals") + expect(HTTPretty.last_request.querystring).to.equal({ + 'foo': ['bar', 'baz'], + 'chuck': ['norris'], + }) + + +@httprettified(verbose=True) +def test_httpretty_allows_to_chose_if_querystring_should_be_matched(): + "HTTPretty should provide a way to not match regexes that have a different querystring" + + HTTPretty.register_uri( + HTTPretty.GET, + "http://localhost:9090", + ) + HTTPretty.register_uri( + HTTPretty.GET, + re.compile(r"http://localhost:9090/what/?$"), + body="Nudge, nudge, wink, wink. Know what I mean?", + match_querystring=True + ) + HTTPretty.register_uri( + HTTPretty.GET, + re.compile(r"http://localhost:9090/what.*[?]?.*"), + body="Different", + match_querystring=False + ) + response = requests.get('http://localhost:9090/what/') + expect(response.text).to.equal('Nudge, nudge, wink, wink. Know what I mean?') + + response = requests.get('http://localhost:9090/what/', params={'flying': 'coconuts'}) + expect(response.text).to.not_be.equal('Nudge, nudge, wink, wink. Know what I mean?') + + +@httprettified +def test_httpretty_should_allow_multiple_methods_for_the_same_uri(): + "HTTPretty should allow registering multiple methods for the same uri" + + url = 'http://test.com/test' + methods = ['GET', 'POST', 'PUT', 'OPTIONS'] + for method in methods: + HTTPretty.register_uri( + getattr(HTTPretty, method), + url, + method + ) + + for method in methods: + request_action = getattr(requests, method.lower()) + expect(request_action(url).text).to.equal(method) + + +@httprettified +def test_httpretty_should_allow_registering_regexes_with_streaming_responses(): + "HTTPretty should allow registering regexes with streaming responses" + + os.environ['DEBUG'] = 'true' + + def my_callback(request, url, headers): + request.body.should.equal(b'hithere') + return 200, headers, "Received" + + HTTPretty.register_uri( + HTTPretty.POST, + re.compile(r"https://api.yipit.com/v1/deal;brand=(?P\w+)"), + body=my_callback, + ) + + def gen(): + yield b'hi' + yield b'there' + + response = requests.post( + 'https://api.yipit.com/v1/deal;brand=gap?first_name=chuck&last_name=norris', + data=gen(), + ) + expect(response.content).to.equal(b"Received") + expect(HTTPretty.last_request.method).to.equal('POST') + expect(HTTPretty.last_request.path).to.equal('/v1/deal;brand=gap?first_name=chuck&last_name=norris') + + +@httprettified +def test_httpretty_should_allow_multiple_responses_with_multiple_methods(): + "HTTPretty should allow multiple responses when binding multiple methods to the same uri" + + url = 'http://test.com/list' + + # add get responses + HTTPretty.register_uri( + HTTPretty.GET, url, + responses=[ + HTTPretty.Response(body='a'), + HTTPretty.Response(body='b'), + ] + ) + + # add post responses + HTTPretty.register_uri( + HTTPretty.POST, url, + responses=[ + HTTPretty.Response(body='c'), + HTTPretty.Response(body='d'), + ] + ) + + expect(requests.get(url).text).to.equal('a') + expect(requests.post(url).text).to.equal('c') + + expect(requests.get(url).text).to.equal('b') + expect(requests.get(url).text).to.equal('b') + expect(requests.get(url).text).to.equal('b') + + expect(requests.post(url).text).to.equal('d') + expect(requests.post(url).text).to.equal('d') + expect(requests.post(url).text).to.equal('d') + + +@httprettified +def test_httpretty_should_normalize_url_patching(): + "HTTPretty should normalize all url patching" + + HTTPretty.register_uri( + HTTPretty.GET, + "http://yipit.com/foo(bar)", + body="Find the best daily deals") + + response = requests.get('http://yipit.com/foo%28bar%29') + expect(response.text).to.equal('Find the best daily deals') + + +@httprettified +def test_lack_of_trailing_slash(): + ("HTTPretty should automatically append a slash to given urls") + url = 'http://www.youtube.com' + HTTPretty.register_uri(HTTPretty.GET, url, body='') + response = requests.get(url) + response.status_code.should.equal(200) + + +@httprettified +def test_unicode_querystrings(): + ("Querystrings should accept unicode characters") + HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/login", + body="Find the best daily deals") + requests.get('http://yipit.com/login?user=Gabriel+Falcão') + expect(HTTPretty.last_request.querystring['user'][0]).should.be.equal('Gabriel Falcão') + + +@use_tornado_server +def test_recording_calls(port): + ("HTTPretty should be able to record calls") + # Given a destination path: + destination = FIXTURE_FILE("recording-1.json") + + # When I record some calls + with HTTPretty.record(destination): + requests.get(server_url("/foobar?name=Gabriel&age=25", port)) + requests.post(server_url("/foobar", port), + data=json.dumps({'test': '123'}), + headers={"Test": "foobar"}) + + # Then the destination path should exist + os.path.exists(destination).should.be.true + + # And the contents should be json + raw = open(destination).read() + json.loads.when.called_with(raw).should_not.throw(ValueError) + + # And the contents should be expected + data = json.loads(raw) + data.should.be.a(list) + data.should.have.length_of(2) + + # And the responses should have the expected keys + response = data[0] + response.should.have.key("request").being.length_of(5) + response.should.have.key("response").being.length_of(3) + + response['request'].should.have.key("method").being.equal("GET") + response['request'].should.have.key("headers").being.a(dict) + response['request'].should.have.key("querystring").being.equal({ + "age": [ + "25" + ], + "name": [ + "Gabriel" + ] + }) + response['response'].should.have.key("status").being.equal(200) + response['response'].should.have.key("body").being.an(str) + response['response'].should.have.key("headers").being.a(dict) + # older urllib3 had a bug where header keys were lower-cased: + # https://github.com/shazow/urllib3/issues/236 + # cope with that + if 'server' in response['response']["headers"]: + response['response']["headers"]["Server"] = response['response']["headers"].pop("server") + response['response']["headers"].should.have.key("Server").being.equal("TornadoServer/" + tornado_version) + + # And When I playback the previously recorded calls + with HTTPretty.playback(destination): + # And make the expected requests + response1 = requests.get(server_url("/foobar?name=Gabriel&age=25", port)) + response2 = requests.post( + server_url("/foobar", port), + data=json.dumps({'test': '123'}), + headers={"Test": "foobar"}, + ) + + # Then the responses should be the expected + response1.json().should.equal({"foobar": {"age": "25", "name": "Gabriel"}}) + response2.json()["foobar"].should.equal({}) + response2.json()["req_body"].should.equal(json.dumps({"test": "123"})) + response2.json()["req_headers"].should.have.key("Test") + response2.json()["req_headers"]["Test"].should.equal("foobar") + + +@httprettified +def test_py26_callback_response(): + ("HTTPretty should call a callback function *once* and set its return value" + " as the body of the response requests") + + def _request_callback(request, uri, headers): + return [200, headers, "The {} response from {}".format(decode_utf8(request.method), uri)] + + request_callback = Mock() + request_callback.side_effect = _request_callback + + HTTPretty.register_uri( + HTTPretty.POST, "https://api.yahoo.com/test_post", + body=request_callback) + + requests.post( + "https://api.yahoo.com/test_post", + {"username": "gabrielfalcao"} + ) + os.environ['STOP'] = 'true' + expect(request_callback.call_count).equal(1) + + +@httprettified +def test_httpretty_should_work_with_non_standard_ports(): + "HTTPretty should work with a non-standard port number" + + HTTPretty.register_uri( + HTTPretty.GET, + re.compile(r"https://api.yipit.com:1234/v1/deal;brand=(?P\w+)"), + body=lambda method, uri, headers: [200, headers, uri] + ) + HTTPretty.register_uri( + HTTPretty.POST, + "https://asdf.com:666/meow", + body=lambda method, uri, headers: [200, headers, uri] + ) + + response = requests.get('https://api.yipit.com:1234/v1/deal;brand=gap?first_name=chuck&last_name=norris') + + expect(response.text).to.equal('https://api.yipit.com:1234/v1/deal;brand=gap?first_name=chuck&last_name=norris') + expect(HTTPretty.last_request.method).to.equal('GET') + expect(HTTPretty.last_request.path).to.equal('/v1/deal;brand=gap?first_name=chuck&last_name=norris') + + response = requests.post('https://asdf.com:666/meow') + + expect(response.text).to.equal('https://asdf.com:666/meow') + expect(HTTPretty.last_request.method).to.equal('POST') + expect(HTTPretty.last_request.path).to.equal('/meow') + + +@httprettified +def test_httpretty_reset_by_switching_protocols_for_same_port(): + "HTTPretty should reset protocol/port associations" + + HTTPretty.register_uri( + HTTPretty.GET, + "http://api.yipit.com:1234/v1/deal", + body=lambda method, uri, headers: [200, headers, uri] + ) + + response = requests.get('http://api.yipit.com:1234/v1/deal') + + expect(response.text).to.equal('http://api.yipit.com:1234/v1/deal') + expect(HTTPretty.last_request.method).to.equal('GET') + expect(HTTPretty.last_request.path).to.equal('/v1/deal') + + HTTPretty.reset() + + HTTPretty.register_uri( + HTTPretty.GET, + "https://api.yipit.com:1234/v1/deal", + body=lambda method, uri, headers: [200, headers, uri] + ) + + response = requests.get('https://api.yipit.com:1234/v1/deal') + + expect(response.text).to.equal('https://api.yipit.com:1234/v1/deal') + expect(HTTPretty.last_request.method).to.equal('GET') + expect(HTTPretty.last_request.path).to.equal('/v1/deal') + + +@httprettified +def test_httpretty_should_allow_registering_regexes_with_port_and_give_a_proper_match_to_the_callback(): + "HTTPretty should allow registering regexes with requests and giva a proper match to the callback" + + HTTPretty.register_uri( + HTTPretty.GET, + re.compile(r"https://api.yipit.com:1234/v1/deal;brand=(?P\w+)"), + body=lambda method, uri, headers: [200, headers, uri] + ) + + response = requests.get('https://api.yipit.com:1234/v1/deal;brand=gap?first_name=chuck&last_name=norris') + + expect(response.text).to.equal('https://api.yipit.com:1234/v1/deal;brand=gap?first_name=chuck&last_name=norris') + expect(HTTPretty.last_request.method).to.equal('GET') + expect(HTTPretty.last_request.path).to.equal('/v1/deal;brand=gap?first_name=chuck&last_name=norris') + + +@httprettified +def test_httpretty_should_handle_paths_starting_with_two_slashes(): + "HTTPretty should handle URLs with paths starting with //" + + HTTPretty.register_uri( + HTTPretty.GET, "http://example.com//foo", + body="Find the best foo" + ) + + response = requests.get('http://example.com//foo') + expect(response.text).to.equal('Find the best foo') + expect(HTTPretty.last_request.method).to.equal('GET') + expect(HTTPretty.last_request.path).to.equal('//foo') diff --git a/tests/functional/test_urllib2.py b/tests/functional/test_urllib2.py new file mode 100644 index 0000000..9c8ff39 --- /dev/null +++ b/tests/functional/test_urllib2.py @@ -0,0 +1,341 @@ +# #!/usr/bin/env python +# -*- coding: utf-8 -*- + +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +from __future__ import unicode_literals + +import re +try: + from urllib.request import urlopen + import urllib.request as urllib2 +except ImportError: + import urllib2 + urlopen = urllib2.urlopen + +from freezegun import freeze_time +from sure import within, miliseconds +from httpretty import HTTPretty, httprettified +from httpretty.core import decode_utf8 + + +@httprettified +@within(two=miliseconds) +def test_httpretty_should_mock_a_simple_get_with_urllib2_read(): + "HTTPretty should mock a simple GET with urllib2.read()" + + HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/", + body="Find the best daily deals") + + fd = urlopen('http://yipit.com') + got = fd.read() + fd.close() + + got.should.equal(b'Find the best daily deals') + + +@httprettified +@within(two=miliseconds) +def test_httpretty_provides_easy_access_to_querystrings(now): + "HTTPretty should provide an easy access to the querystring" + + HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/", + body="Find the best daily deals") + + fd = urllib2.urlopen('http://yipit.com/?foo=bar&foo=baz&chuck=norris') + fd.read() + fd.close() + + HTTPretty.last_request.querystring.should.equal({ + 'foo': ['bar', 'baz'], + 'chuck': ['norris'], + }) + + +@httprettified +@freeze_time("2013-10-04 04:20:00") +def test_httpretty_should_mock_headers_urllib2(): + "HTTPretty should mock basic headers with urllib2" + + HTTPretty.register_uri(HTTPretty.GET, "http://github.com/", + body="this is supposed to be the response", + status=201) + + request = urlopen('http://github.com') + + headers = dict(request.headers) + request.close() + + request.code.should.equal(201) + headers.should.equal({ + 'content-type': 'text/plain; charset=utf-8', + 'connection': 'close', + 'content-length': '35', + 'status': '201', + 'server': 'Python/HTTPretty', + 'date': 'Fri, 04 Oct 2013 04:20:00 GMT', + }) + + +@httprettified +@freeze_time("2013-10-04 04:20:00") +def test_httpretty_should_allow_adding_and_overwritting_urllib2(): + "HTTPretty should allow adding and overwritting headers with urllib2" + + HTTPretty.register_uri(HTTPretty.GET, "http://github.com/", + body="this is supposed to be the response", + adding_headers={ + 'Server': 'Apache', + 'Content-Length': '27', + 'Content-Type': 'application/json', + }) + + request = urlopen('http://github.com') + headers = dict(request.headers) + request.close() + + request.code.should.equal(200) + headers.should.equal({ + 'content-type': 'application/json', + 'connection': 'close', + 'content-length': '27', + 'status': '200', + 'server': 'Apache', + 'date': 'Fri, 04 Oct 2013 04:20:00 GMT', + }) + + +@httprettified +@within(two=miliseconds) +def test_httpretty_should_allow_forcing_headers_urllib2(): + "HTTPretty should allow forcing headers with urllib2" + + HTTPretty.register_uri(HTTPretty.GET, "http://github.com/", + body="this is supposed to be the response", + forcing_headers={ + 'Content-Type': 'application/xml', + 'Content-Length': '35a', + }) + + request = urlopen('http://github.com') + headers = dict(request.headers) + request.close() + + headers.should.equal({ + 'content-type': 'application/xml', + 'content-length': '35a', + }) + + +@httprettified +@freeze_time("2013-10-04 04:20:00") +def test_httpretty_should_allow_adding_and_overwritting_by_kwargs_u2(): + ("HTTPretty should allow adding and overwritting headers by " + "keyword args with urllib2") + + body = "this is supposed to be the response, indeed" + HTTPretty.register_uri(HTTPretty.GET, "http://github.com/", + body=body, + server='Apache', + content_length=len(body), + content_type='application/json') + + request = urlopen('http://github.com') + headers = dict(request.headers) + request.close() + + request.code.should.equal(200) + headers.should.equal({ + 'content-type': 'application/json', + 'connection': 'close', + 'content-length': str(len(body)), + 'status': '200', + 'server': 'Apache', + 'date': 'Fri, 04 Oct 2013 04:20:00 GMT', + }) + + +@httprettified +@within(two=miliseconds) +def test_httpretty_should_support_a_list_of_successive_responses_urllib2(now): + ("HTTPretty should support adding a list of successive " + "responses with urllib2") + + HTTPretty.register_uri( + HTTPretty.GET, "https://api.yahoo.com/test", + responses=[ + HTTPretty.Response(body="first response", status=201), + HTTPretty.Response(body='second and last response', status=202), + ]) + + request1 = urlopen('https://api.yahoo.com/test') + body1 = request1.read() + request1.close() + + request1.code.should.equal(201) + body1.should.equal(b'first response') + + request2 = urlopen('https://api.yahoo.com/test') + body2 = request2.read() + request2.close() + request2.code.should.equal(202) + body2.should.equal(b'second and last response') + + request3 = urlopen('https://api.yahoo.com/test') + body3 = request3.read() + request3.close() + request3.code.should.equal(202) + body3.should.equal(b'second and last response') + + +@httprettified +@within(two=miliseconds) +def test_can_inspect_last_request(now): + "HTTPretty.last_request is a mimetools.Message request from last match" + + HTTPretty.register_uri(HTTPretty.POST, "http://api.github.com/", + body='{"repositories": ["HTTPretty", "lettuce"]}') + + request = urllib2.Request( + 'http://api.github.com', + b'{"username": "gabrielfalcao"}', + { + 'content-type': 'text/json', + }, + ) + fd = urlopen(request) + got = fd.read() + fd.close() + + HTTPretty.last_request.method.should.equal('POST') + HTTPretty.last_request.body.should.equal( + b'{"username": "gabrielfalcao"}', + ) + HTTPretty.last_request.headers['content-type'].should.equal( + 'text/json', + ) + got.should.equal(b'{"repositories": ["HTTPretty", "lettuce"]}') + + +@httprettified +@within(two=miliseconds) +def test_can_inspect_last_request_with_ssl(now): + "HTTPretty.last_request is recorded even when mocking 'https' (SSL)" + + HTTPretty.register_uri(HTTPretty.POST, "https://secure.github.com/", + body='{"repositories": ["HTTPretty", "lettuce"]}') + + request = urllib2.Request( + 'https://secure.github.com', + b'{"username": "gabrielfalcao"}', + { + 'content-type': 'text/json', + }, + ) + fd = urlopen(request) + got = fd.read() + fd.close() + + HTTPretty.last_request.method.should.equal('POST') + HTTPretty.last_request.body.should.equal( + b'{"username": "gabrielfalcao"}', + ) + HTTPretty.last_request.headers['content-type'].should.equal( + 'text/json', + ) + got.should.equal(b'{"repositories": ["HTTPretty", "lettuce"]}') + + +@httprettified +@within(two=miliseconds) +def test_httpretty_ignores_querystrings_from_registered_uri(): + "HTTPretty should mock a simple GET with urllib2.read()" + + HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/?id=123", + body="Find the best daily deals") + + fd = urlopen('http://yipit.com/?id=123') + got = fd.read() + fd.close() + + got.should.equal(b'Find the best daily deals') + HTTPretty.last_request.method.should.equal('GET') + HTTPretty.last_request.path.should.equal('/?id=123') + + +@httprettified +@within(two=miliseconds) +def test_callback_response(now): + ("HTTPretty should call a callback function to be set as the body with" + " urllib2") + + def request_callback(request, uri, headers): + return [200, headers, "The {} response from {}".format(decode_utf8(request.method), uri)] + + HTTPretty.register_uri( + HTTPretty.GET, "https://api.yahoo.com/test", + body=request_callback) + + fd = urllib2.urlopen('https://api.yahoo.com/test') + got = fd.read() + fd.close() + + got.should.equal(b"The GET response from https://api.yahoo.com/test") + + HTTPretty.register_uri( + HTTPretty.POST, "https://api.yahoo.com/test_post", + body=request_callback) + + request = urllib2.Request( + "https://api.yahoo.com/test_post", + b'{"username": "gabrielfalcao"}', + { + 'content-type': 'text/json', + }, + ) + fd = urllib2.urlopen(request) + got = fd.read() + fd.close() + + got.should.equal(b"The POST response from https://api.yahoo.com/test_post") + + +@httprettified +def test_httpretty_should_allow_registering_regexes(): + "HTTPretty should allow registering regexes with urllib2" + + HTTPretty.register_uri( + HTTPretty.GET, + re.compile(r"https://api.yipit.com/v1/deal;brand=(?P\w+)"), + body="Found brand", + ) + + request = urllib2.Request( + "https://api.yipit.com/v1/deal;brand=GAP", + ) + fd = urllib2.urlopen(request) + got = fd.read() + fd.close() + + got.should.equal(b"Found brand") diff --git a/tests/functional/testserver.py b/tests/functional/testserver.py new file mode 100644 index 0000000..623dd88 --- /dev/null +++ b/tests/functional/testserver.py @@ -0,0 +1,162 @@ +# #!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +from __future__ import unicode_literals + +import os +import time +import socket + +from tornado.web import Application +from tornado.web import RequestHandler +from tornado.httpserver import HTTPServer +from tornado.ioloop import IOLoop +from httpretty import HTTPretty +from httpretty.core import old_socket as true_socket +from multiprocessing import Process + + +def utf8(s): + if isinstance(s, str): + s = s.encode('utf-8') + + return bytes(s) + + +class BubblesHandler(RequestHandler): + def get(self): + self.write(". o O 0 O o . o O 0 O o . o O 0 O o . o O 0 O o . o O 0 O o .") + + +class ComeHandler(RequestHandler): + def get(self): + self.write("<- HELLO WORLD ->") + + +def subprocess_server_tornado(app, port, data={}): + from httpretty import HTTPretty + HTTPretty.disable() + + http = HTTPServer(app) + HTTPretty.disable() + + http.listen(int(port)) + IOLoop.instance().start() + + +class TornadoServer(object): + is_running = False + + def __init__(self, port): + self.port = int(port) + self.process = None + + @classmethod + def get_handlers(cls): + return Application([ + (r"/go-for-bubbles/?", BubblesHandler), + (r"/come-again/?", ComeHandler), + ]) + + def start(self): + + app = self.get_handlers() + + data = {} + args = (app, self.port, data) + HTTPretty.disable() + self.process = Process(target=subprocess_server_tornado, args=args) + self.process.start() + time.sleep(1) + + def stop(self): + try: + os.kill(self.process.pid, 9) + except OSError: + self.process.terminate() + finally: + self.is_running = False + + +def subprocess_server_tcp(port): + from httpretty import HTTPretty + HTTPretty.disable() + import socket + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.bind(('localhost', port)) + s.listen(True) + conn, addr = s.accept() + + while True: + data = conn.recv(1024) + conn.send(b"RECEIVED: " + bytes(data)) + + conn.close() + + +class TCPServer(object): + def __init__(self, port): + self.port = int(port) + + def start(self): + HTTPretty.disable() + + + args = [self.port] + self.process = Process(target=subprocess_server_tcp, args=args) + self.process.start() + time.sleep(1) + + def stop(self): + try: + os.kill(self.process.pid, 9) + except OSError: + self.process.terminate() + finally: + self.is_running = False + + +class TCPClient(object): + def __init__(self, port): + self.port = int(port) + self.sock = true_socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock.connect(('localhost', self.port)) + + def send(self, data): + if isinstance(data, str): + data = data.encode('utf-8') + + self.sock.sendall(data) + return self.sock.recv(len(data) + 11) + + def close(self): + try: + self.sock.close() + except socket.error: + pass # already closed + + def __del__(self): + self.close() diff --git a/tests/pyopenssl/__init__.py b/tests/pyopenssl/__init__.py new file mode 100644 index 0000000..1b809ba --- /dev/null +++ b/tests/pyopenssl/__init__.py @@ -0,0 +1,28 @@ +# #!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +import warnings +warnings.simplefilter('ignore') diff --git a/tests/pyopenssl/test_mock.py b/tests/pyopenssl/test_mock.py new file mode 100644 index 0000000..f98b102 --- /dev/null +++ b/tests/pyopenssl/test_mock.py @@ -0,0 +1,45 @@ +# #!/usr/bin/env python +# -*- coding: utf-8 -*- + +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +from __future__ import unicode_literals + +import requests + +from httpretty import HTTPretty, httprettified +from sure import expect + + +@httprettified +def test_httpretty_overrides_when_pyopenssl_installed(): + ('HTTPretty should remove PyOpenSSLs urllib3 mock if it is installed') + # And HTTPretty works successfully + HTTPretty.register_uri(HTTPretty.GET, "https://yipit.com/", + body="Find the best daily deals") + + response = requests.get('https://yipit.com') + expect(response.text).to.equal('Find the best daily deals') + expect(HTTPretty.last_request.method).to.equal('GET') + expect(HTTPretty.last_request.path).to.equal('/') diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 0000000..a9eab2a --- /dev/null +++ b/tests/unit/__init__.py @@ -0,0 +1,25 @@ +# #!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. diff --git a/tests/unit/test_core.py b/tests/unit/test_core.py new file mode 100644 index 0000000..80c4a86 --- /dev/null +++ b/tests/unit/test_core.py @@ -0,0 +1,668 @@ +import io +import json +import errno + +from freezegun import freeze_time +from sure import expect + +from httpretty.core import HTTPrettyRequest, FakeSSLSocket, fakesock, httpretty +from httpretty.core import URIMatcher, URIInfo + +from tests.compat import Mock, patch, call + + +class SocketErrorStub(Exception): + def __init__(self, errno): + self.errno = errno + + +def test_request_stubs_internals(): + ("HTTPrettyRequest is a BaseHTTPRequestHandler that replaces " + "real socket file descriptors with in-memory ones") + + # Given a valid HTTP request header string + headers = "\r\n".join([ + 'POST /somewhere/?name=foo&age=bar HTTP/1.1', + 'accept-encoding: identity', + 'host: github.com', + 'content-type: application/json', + 'connection: close', + 'user-agent: Python-urllib/2.7', + ]) + + # When I create a HTTPrettyRequest with an empty body + request = HTTPrettyRequest(headers, body='') + + # Then it should have parsed the headers + dict(request.headers).should.equal({ + 'accept-encoding': 'identity', + 'connection': 'close', + 'content-type': 'application/json', + 'host': 'github.com', + 'user-agent': 'Python-urllib/2.7' + }) + + # And the `rfile` should be a io.BytesIO + type_as_str = io.BytesIO.__module__ + '.' + io.BytesIO.__name__ + + request.should.have.property('rfile').being.a(type_as_str) + + # And the `wfile` should be a io.BytesIO + request.should.have.property('wfile').being.a(type_as_str) + + # And the `method` should be available + request.should.have.property('method').being.equal('POST') + + +def test_request_parse_querystring(): + ("HTTPrettyRequest#parse_querystring should parse unicode data") + + # Given a request string containing a unicode encoded querystring + + headers = "\r\n".join([ + 'POST /create?name=Gabriel+Falcão HTTP/1.1', + 'Content-Type: multipart/form-data', + ]) + + # When I create a HTTPrettyRequest with an empty body + request = HTTPrettyRequest(headers, body='') + + # Then it should have a parsed querystring + request.querystring.should.equal({'name': ['Gabriel Falcão']}) + + +def test_request_parse_body_when_it_is_application_json(): + ("HTTPrettyRequest#parse_request_body recognizes the " + "content-type `application/json` and parses it") + + # Given a request string containing a unicode encoded querystring + headers = "\r\n".join([ + 'POST /create HTTP/1.1', + 'Content-Type: application/json', + ]) + # And a valid json body + body = json.dumps({'name': 'Gabriel Falcão'}) + + # When I create a HTTPrettyRequest with that data + request = HTTPrettyRequest(headers, body) + + # Then it should have a parsed body + request.parsed_body.should.equal({'name': 'Gabriel Falcão'}) + + +def test_request_parse_body_when_it_is_text_json(): + ("HTTPrettyRequest#parse_request_body recognizes the " + "content-type `text/json` and parses it") + + # Given a request string containing a unicode encoded querystring + headers = "\r\n".join([ + 'POST /create HTTP/1.1', + 'Content-Type: text/json', + ]) + # And a valid json body + body = json.dumps({'name': 'Gabriel Falcão'}) + + # When I create a HTTPrettyRequest with that data + request = HTTPrettyRequest(headers, body) + + # Then it should have a parsed body + request.parsed_body.should.equal({'name': 'Gabriel Falcão'}) + + +def test_request_parse_body_when_it_is_urlencoded(): + ("HTTPrettyRequest#parse_request_body recognizes the " + "content-type `application/x-www-form-urlencoded` and parses it") + + # Given a request string containing a unicode encoded querystring + headers = "\r\n".join([ + 'POST /create HTTP/1.1', + 'Content-Type: application/x-www-form-urlencoded', + ]) + # And a valid urlencoded body + body = "name=Gabriel+Falcão&age=25&projects=httpretty&projects=sure&projects=lettuce" + + # When I create a HTTPrettyRequest with that data + request = HTTPrettyRequest(headers, body) + + # Then it should have a parsed body + request.parsed_body.should.equal({ + 'name': ['Gabriel Falcão'], + 'age': ["25"], + 'projects': ["httpretty", "sure", "lettuce"] + }) + + +def test_request_parse_body_when_unrecognized(): + ("HTTPrettyRequest#parse_request_body returns the value as " + "is if the Content-Type is not recognized") + + # Given a request string containing a unicode encoded querystring + headers = "\r\n".join([ + 'POST /create HTTP/1.1', + 'Content-Type: whatever', + ]) + # And a valid urlencoded body + body = "foobar:\nlalala" + + # When I create a HTTPrettyRequest with that data + request = HTTPrettyRequest(headers, body) + + # Then it should have a parsed body + request.parsed_body.should.equal("foobar:\nlalala") + + +def test_request_string_representation(): + ("HTTPrettyRequest should have a forward_and_trace-friendly " + "string representation") + + # Given a request string containing a unicode encoded querystring + headers = "\r\n".join([ + 'POST /create HTTP/1.1', + 'Content-Type: JPEG-baby', + 'Host: blog.falcao.it' + ]) + # And a valid urlencoded body + body = "foobar:\nlalala" + + # When I create a HTTPrettyRequest with that data + request = HTTPrettyRequest(headers, body, sock=Mock(is_https=True)) + + # Then its string representation should show the headers and the body + str(request).should.equal('') + + +def test_fake_ssl_socket_proxies_its_ow_socket(): + ("FakeSSLSocket is a simpel wrapper around its own socket, " + "which was designed to be a HTTPretty fake socket") + + # Given a sentinel mock object + socket = Mock() + + # And a FakeSSLSocket wrapping it + ssl = FakeSSLSocket(socket) + + # When I make a method call + ssl.send("FOO") + + # Then it should bypass any method calls to its own socket + socket.send.assert_called_once_with("FOO") + + +@freeze_time("2013-10-04 04:20:00") +def test_fakesock_socket_getpeercert(): + ("fakesock.socket#getpeercert should return a hardcoded fake certificate") + # Given a fake socket instance + socket = fakesock.socket() + + # And that it's bound to some host + socket._host = 'somewhere.com' + + # When I retrieve the peer certificate + certificate = socket.getpeercert() + + # Then it should return a hardcoded value + certificate.should.equal({ + u'notAfter': 'Sep 29 04:20:00 GMT', + u'subject': ( + ((u'organizationName', u'*.somewhere.com'),), + ((u'organizationalUnitName', u'Domain Control Validated'),), + ((u'commonName', u'*.somewhere.com'),)), + u'subjectAltName': ( + (u'DNS', u'*.somewhere.com'), + (u'DNS', u'somewhere.com'), + (u'DNS', u'*') + ) + }) + + +def test_fakesock_socket_ssl(): + ("fakesock.socket#ssl should take a socket instance and return itself") + # Given a fake socket instance + socket = fakesock.socket() + + # And a stubbed socket sentinel + sentinel = Mock() + + # When I call `ssl` on that mock + result = socket.ssl(sentinel) + + # Then it should have returned its first argument + result.should.equal(sentinel) + + +@patch('httpretty.core.old_socket') +@patch('httpretty.core.POTENTIAL_HTTP_PORTS') +def test_fakesock_socket_connect_fallback(POTENTIAL_HTTP_PORTS, old_socket): + ("fakesock.socket#connect should open a real connection if the " + "given port is not a potential http port") + # Background: the potential http ports are 80 and 443 + POTENTIAL_HTTP_PORTS.__contains__.side_effect = lambda other: int(other) in (80, 443) + + # Given a fake socket instance + socket = fakesock.socket() + + # When it is connected to a remote server in a port that isn't 80 nor 443 + socket.connect(('somewhere.com', 42)) + + # Then it should have open a real connection in the background + old_socket.return_value.connect.assert_called_once_with(('somewhere.com', 42)) + + +@patch('httpretty.core.old_socket') +def test_fakesock_socket_close(old_socket): + ("fakesock.socket#close should close the actual socket in case " + "it's not http and __truesock_is_connected__ is True") + # Given a fake socket instance that is synthetically open + socket = fakesock.socket() + socket.__truesock_is_connected__ = True + + # When I close it + socket.close() + + # Then its real socket should have been closed + old_socket.return_value.close.assert_called_once_with() + socket.__truesock_is_connected__.should.be.false + + +@patch('httpretty.core.old_socket') +def test_fakesock_socket_makefile(old_socket): + ("fakesock.socket#makefile should set the mode, " + "bufsize and return its mocked file descriptor") + + # Given a fake socket that has a mocked Entry associated with it + socket = fakesock.socket() + socket._entry = Mock() + + # When I call makefile() + fd = socket.makefile(mode='rw', bufsize=512) + + # Then it should have returned the socket's own filedescriptor + expect(fd).to.equal(socket.fd) + # And the mode should have been set in the socket instance + socket._mode.should.equal('rw') + # And the bufsize should have been set in the socket instance + socket._bufsize.should.equal(512) + + # And the entry should have been filled with that filedescriptor + socket._entry.fill_filekind.assert_called_once_with(fd) + + +@patch('httpretty.core.old_socket') +def test_fakesock_socket_real_sendall(old_socket): + ("fakesock.socket#real_sendall calls truesock#connect and bails " + "out when not http") + # Background: the real socket will stop returning bytes after the + # first call + real_socket = old_socket.return_value + real_socket.recv.side_effect = [b'response from server', b""] + + # Given a fake socket + socket = fakesock.socket() + socket._address = ('1.2.3.4', 42) + + # When I call real_sendall with data, some args and kwargs + socket.real_sendall(b"SOMEDATA", b'some extra args...', foo=b'bar') + + # Then it should have called sendall in the real socket + real_socket.sendall.assert_called_once_with(b"SOMEDATA", b'some extra args...', foo=b'bar') + + # # And setblocking was never called + # real_socket.setblocking.called.should.be.false + + # And recv was never called + real_socket.recv.called.should.be.false + + # And the buffer is empty + socket.fd.read().should.equal(b'') + + # And connect was never called + real_socket.connect.called.should.be.false + + +@patch('httpretty.core.old_socket') +def test_fakesock_socket_real_sendall_when_http(old_socket): + ("fakesock.socket#real_sendall sends data and buffers " + "the response in the file descriptor") + # Background: the real socket will stop returning bytes after the + # first call + real_socket = old_socket.return_value + real_socket.recv.side_effect = [b'response from server', b""] + + # Given a fake socket + socket = fakesock.socket() + socket._address = ('1.2.3.4', 42) + socket.is_http = True + + # When I call real_sendall with data, some args and kwargs + socket.real_sendall(b"SOMEDATA", b'some extra args...', foo=b'bar') + + # Then it should have called sendall in the real socket + real_socket.sendall.assert_called_once_with(b"SOMEDATA", b'some extra args...', foo=b'bar') + + # And the socket was set to blocking + real_socket.setblocking.assert_called_once_with(1) + + # And recv was called with the bufsize + real_socket.recv.assert_has_calls([ + call(socket._bufsize) + ]) + + # And the buffer should contain the data from the server + socket.fd.read().should.equal(b"response from server") + + # And connect was called + real_socket.connect.called.should.be.true + + +@patch('httpretty.core.old_socket') +@patch('httpretty.core.socket') +def test_fakesock_socket_real_sendall_continue_eagain_when_http(socket, old_socket): + ("fakesock.socket#real_sendall should continue if the socket error was EAGAIN") + socket.error = SocketErrorStub + # Background: the real socket will stop returning bytes after the + # first call + real_socket = old_socket.return_value + real_socket.recv.side_effect = [SocketErrorStub(errno.EAGAIN), b'after error', b""] + + # Given a fake socket + socket = fakesock.socket() + socket._address = ('1.2.3.4', 42) + socket.is_http = True + + # When I call real_sendall with data, some args and kwargs + socket.real_sendall(b"SOMEDATA", b'some extra args...', foo=b'bar') + + # Then it should have called sendall in the real socket + real_socket.sendall.assert_called_once_with(b"SOMEDATA", b'some extra args...', foo=b'bar') + + # And the socket was set to blocking + real_socket.setblocking.assert_called_once_with(1) + + # And recv was called with the bufsize + real_socket.recv.assert_has_calls([ + call(socket._bufsize) + ]) + + # And the buffer should contain the data from the server + socket.fd.read().should.equal(b"after error") + + # And connect was called + real_socket.connect.called.should.be.true + + +@patch('httpretty.core.old_socket') +@patch('httpretty.core.socket') +def test_fakesock_socket_real_sendall_socket_error_when_http(socket, old_socket): + ("fakesock.socket#real_sendall should continue if the socket error was EAGAIN") + socket.error = SocketErrorStub + # Background: the real socket will stop returning bytes after the + # first call + real_socket = old_socket.return_value + real_socket.recv.side_effect = [SocketErrorStub(42), b'after error', ""] + + # Given a fake socket + socket = fakesock.socket() + socket._address = ('1.2.3.4', 42) + socket.is_http = True + + # When I call real_sendall with data, some args and kwargs + socket.real_sendall(b"SOMEDATA", b'some extra args...', foo=b'bar') + + # Then it should have called sendall in the real socket + real_socket.sendall.assert_called_once_with(b"SOMEDATA", b'some extra args...', foo=b'bar') + + # And the socket was set to blocking + real_socket.setblocking.assert_called_once_with(1) + + # And recv was called with the bufsize + real_socket.recv.assert_called_once_with(socket._bufsize) + + # And the buffer should contain the data from the server + socket.fd.read().should.equal(b"") + + # And connect was called + real_socket.connect.called.should.be.true + + +@patch('httpretty.core.old_socket') +@patch('httpretty.core.POTENTIAL_HTTP_PORTS') +def test_fakesock_socket_real_sendall_when_sending_data(POTENTIAL_HTTP_PORTS, old_socket): + ("fakesock.socket#real_sendall should connect before sending data") + # Background: the real socket will stop returning bytes after the + # first call + real_socket = old_socket.return_value + real_socket.recv.side_effect = [b'response from foobar :)', b""] + + # And the potential http port is 4000 + POTENTIAL_HTTP_PORTS.__contains__.side_effect = lambda other: int(other) == 4000 + POTENTIAL_HTTP_PORTS.union.side_effect = lambda other: POTENTIAL_HTTP_PORTS + + # Given a fake socket + socket = fakesock.socket() + + # When I call connect to a server in a port that is considered HTTP + socket.connect(('foobar.com', 4000)) + + # And send some data + socket.real_sendall(b"SOMEDATA") + + # Then connect should have been called + real_socket.connect.assert_called_once_with(('foobar.com', 4000)) + + # And the socket was set to blocking + real_socket.setblocking.assert_called_once_with(1) + + # And recv was called with the bufsize + real_socket.recv.assert_has_calls([ + call(socket._bufsize) + ]) + + # And the buffer should contain the data from the server + socket.fd.read().should.equal(b"response from foobar :)") + + +@patch('httpretty.core.old_socket') +@patch('httpretty.core.httpretty') +@patch('httpretty.core.POTENTIAL_HTTP_PORTS') +def test_fakesock_socket_sendall_with_valid_requestline(POTENTIAL_HTTP_PORTS, httpretty, old_socket): + ("fakesock.socket#sendall should create an entry if it's given a valid request line") + matcher = Mock(name='matcher') + info = Mock(name='info') + httpretty.match_uriinfo.return_value = (matcher, info) + httpretty.register_uri(httpretty.GET, 'http://foo.com/foobar') + + # Background: + # using a subclass of socket that mocks out real_sendall + class MySocket(fakesock.socket): + def real_sendall(self, data, *args, **kw): + raise AssertionError('should never call this...') + + # Given an instance of that socket + socket = MySocket() + + # And that is is considered http + socket.connect(('foo.com', 80)) + + # When I try to send data + socket.sendall(b"GET /foobar HTTP/1.1\r\nContent-Type: application/json\r\n\r\n") + + +@patch('httpretty.core.old_socket') +@patch('httpretty.core.httpretty') +@patch('httpretty.core.POTENTIAL_HTTP_PORTS') +def test_fakesock_socket_sendall_with_valid_requestline_2(POTENTIAL_HTTP_PORTS, httpretty, old_socket): + ("fakesock.socket#sendall should create an entry if it's given a valid request line") + matcher = Mock(name='matcher') + info = Mock(name='info') + httpretty.match_uriinfo.return_value = (matcher, info) + httpretty.register_uri(httpretty.GET, 'http://foo.com/foobar') + + # Background: + # using a subclass of socket that mocks out real_sendall + class MySocket(fakesock.socket): + def real_sendall(self, data, *args, **kw): + raise AssertionError('should never call this...') + + # Given an instance of that socket + socket = MySocket() + + # And that is is considered http + socket.connect(('foo.com', 80)) + + # When I try to send data + socket.sendall(b"GET /foobar HTTP/1.1\r\nContent-Type: application/json\r\n\r\n") + + +@patch('httpretty.core.old_socket') +def test_fakesock_socket_sendall_with_body_data_no_entry(old_socket): + ("fakesock.socket#sendall should call real_sendall when not parsing headers and there is no entry") + # Background: + # Using a subclass of socket that mocks out real_sendall + + class MySocket(fakesock.socket): + def real_sendall(self, data): + data.should.equal(b'BLABLABLABLA') + return 'cool' + + # Given an instance of that socket + socket = MySocket() + socket._entry = None + + # And that is is considered http + socket.connect(('foo.com', 80)) + + # When I try to send data + result = socket.sendall(b"BLABLABLABLA") + + # Then the result should be the return value from real_sendall + result.should.equal('cool') + + +@patch('httpretty.core.old_socket') +@patch('httpretty.core.POTENTIAL_HTTP_PORTS') +def test_fakesock_socket_sendall_with_body_data_with_entry(POTENTIAL_HTTP_PORTS, old_socket): + ("fakesock.socket#sendall should call real_sendall when there is no entry") + # Background: + # Using a subclass of socket that mocks out real_sendall + data_sent = [] + + class MySocket(fakesock.socket): + def real_sendall(self, data): + data_sent.append(data) + + # Given an instance of that socket + socket = MySocket() + + # And that is is considered http + socket.connect(('foo.com', 80)) + + # When I try to send data + socket.sendall(b"BLABLABLABLA") + + # Then it should have called real_sendall + data_sent.should.equal([b'BLABLABLABLA']) + + +@patch('httpretty.core.httpretty.match_uriinfo') +@patch('httpretty.core.old_socket') +@patch('httpretty.core.POTENTIAL_HTTP_PORTS') +def test_fakesock_socket_sendall_with_body_data_with_chunked_entry(POTENTIAL_HTTP_PORTS, old_socket, match_uriinfo): + ("fakesock.socket#sendall should call real_sendall when not ") + # Background: + # Using a subclass of socket that mocks out real_sendall + + class MySocket(fakesock.socket): + def real_sendall(self, data): + raise AssertionError('should have never been called') + + matcher = Mock(name='matcher') + info = Mock(name='info') + httpretty.match_uriinfo.return_value = (matcher, info) + + # Using a mocked entry + entry = Mock() + entry.method = 'GET' + entry.info.path = '/foo' + + entry.request.headers = { + 'transfer-encoding': 'chunked', + } + entry.request.body = b'' + + # Given an instance of that socket + socket = MySocket() + socket._entry = entry + + # And that is is considered http + socket.connect(('foo.com', 80)) + + # When I try to send data + socket.sendall(b"BLABLABLABLA") + + # Then the entry should have that body + httpretty.last_request.body.should.equal(b'BLABLABLABLA') + + +def test_fakesock_socket_sendall_with_path_starting_with_two_slashes(): + ("fakesock.socket#sendall handles paths starting with // well") + + httpretty.register_uri(httpretty.GET, 'http://example.com//foo') + + class MySocket(fakesock.socket): + def real_sendall(self, data, *args, **kw): + raise AssertionError('should never call this...') + + # Given an instance of that socket + socket = MySocket() + + # And that is is considered http + socket.connect(('example.com', 80)) + + # When I try to send data + socket.sendall(b"GET //foo HTTP/1.1\r\nContent-Type: application/json\r\n\r\n") + + +def test_URIMatcher_respects_querystring(): + ("URIMatcher response querystring") + matcher = URIMatcher('http://www.foo.com/?query=true', None) + info = URIInfo.from_uri('http://www.foo.com/', None) + assert matcher.matches(info) + + matcher = URIMatcher('http://www.foo.com/?query=true', None, match_querystring=True) + info = URIInfo.from_uri('http://www.foo.com/', None) + assert not matcher.matches(info) + + matcher = URIMatcher('http://www.foo.com/?query=true', None, match_querystring=True) + info = URIInfo.from_uri('http://www.foo.com/?query=true', None) + assert matcher.matches(info) + + matcher = URIMatcher('http://www.foo.com/?query=true&unquery=false', None, match_querystring=True) + info = URIInfo.from_uri('http://www.foo.com/?unquery=false&query=true', None) + assert matcher.matches(info) + + matcher = URIMatcher('http://www.foo.com/?unquery=false&query=true', None, match_querystring=True) + info = URIInfo.from_uri('http://www.foo.com/?query=true&unquery=false', None) + assert matcher.matches(info) + + +def test_URIMatcher_equality_respects_querystring(): + ("URIMatcher equality check should check querystring") + matcher_a = URIMatcher('http://www.foo.com/?query=true', None) + matcher_b = URIMatcher('http://www.foo.com/?query=false', None) + assert matcher_a == matcher_b + + matcher_a = URIMatcher('http://www.foo.com/?query=true', None) + matcher_b = URIMatcher('http://www.foo.com/', None) + assert matcher_a == matcher_b + + matcher_a = URIMatcher('http://www.foo.com/?query=true', None, match_querystring=True) + matcher_b = URIMatcher('http://www.foo.com/?query=false', None, match_querystring=True) + assert not matcher_a == matcher_b + + matcher_a = URIMatcher('http://www.foo.com/?query=true', None, match_querystring=True) + matcher_b = URIMatcher('http://www.foo.com/', None, match_querystring=True) + assert not matcher_a == matcher_b + + matcher_a = URIMatcher('http://www.foo.com/?query=true&unquery=false', None, match_querystring=True) + matcher_b = URIMatcher('http://www.foo.com/?unquery=false&query=true', None, match_querystring=True) + assert matcher_a == matcher_b diff --git a/tests/unit/test_http.py b/tests/unit/test_http.py new file mode 100644 index 0000000..7ea5fe1 --- /dev/null +++ b/tests/unit/test_http.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +from httpretty.http import parse_requestline + + +def test_parse_request_line_connect(): + ("parse_requestline should parse the CONNECT method appropriately") + + # Given a valid request line string that has the CONNECT method + line = "CONNECT / HTTP/1.1" + + # When I parse it + result = parse_requestline(line) + + # Then it should return a tuple + result.should.equal(("CONNECT", "/", "1.1")) diff --git a/tests/unit/test_httpretty.py b/tests/unit/test_httpretty.py new file mode 100644 index 0000000..017b290 --- /dev/null +++ b/tests/unit/test_httpretty.py @@ -0,0 +1,429 @@ +# #!/usr/bin/env python +# -*- coding: utf-8 -*- + +# +# Copyright (C) <2011-2021> Gabriel Falcão +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +from __future__ import unicode_literals +import re +import json +from sure import expect +import httpretty +from httpretty import HTTPretty +from httpretty import HTTPrettyError +from httpretty import core +from httpretty.core import URIInfo, BaseClass, Entry, FakeSockFile, HTTPrettyRequest +from httpretty.http import STATUSES + +from tests.compat import MagicMock, patch + + +TEST_HEADER = """ +GET /test/test.html HTTP/1.1 +Host: www.host1.com:80 +Content-Type: %(content_type)s +""" + + +def test_httpretty_should_raise_proper_exception_on_inconsistent_length(): + ("HTTPretty should raise proper exception on inconsistent Content-Length / " + "registered response body") + + HTTPretty.register_uri.when.called_with( + HTTPretty.GET, + "http://github.com/gabrielfalcao", + body="that's me!", + adding_headers={ + 'Content-Length': '999' + } + ).should.have.raised( + HTTPrettyError, + 'HTTPretty got inconsistent parameters. The header Content-Length you registered expects size "999" ' + 'but the body you registered for that has actually length "10".' + ) + + +def test_does_not_have_last_request_by_default(): + 'HTTPretty.last_request is a dummy object by default' + HTTPretty.reset() + + expect(HTTPretty.last_request.headers).to.be.empty + expect(HTTPretty.last_request.body).to.be.empty + + +def test_status_codes(): + "HTTPretty supports N status codes" + + expect(STATUSES).to.equal({ + 100: "Continue", + 101: "Switching Protocols", + 102: "Processing", + 200: "OK", + 201: "Created", + 202: "Accepted", + 203: "Non-Authoritative Information", + 204: "No Content", + 205: "Reset Content", + 206: "Partial Content", + 207: "Multi-Status", + 208: "Already Reported", + 226: "IM Used", + 300: "Multiple Choices", + 301: "Moved Permanently", + 302: "Found", + 303: "See Other", + 304: "Not Modified", + 305: "Use Proxy", + 306: "Switch Proxy", + 307: "Temporary Redirect", + 308: "Permanent Redirect", + 400: "Bad Request", + 401: "Unauthorized", + 402: "Payment Required", + 403: "Forbidden", + 404: "Not Found", + 405: "Method Not Allowed", + 406: "Not Acceptable", + 407: "Proxy Authentication Required", + 408: "Request a Timeout", + 409: "Conflict", + 410: "Gone", + 411: "Length Required", + 412: "Precondition Failed", + 413: "Request Entity Too Large", + 414: "Request-URI Too Long", + 415: "Unsupported Media Type", + 416: "Requested Range Not Satisfiable", + 417: "Expectation Failed", + 418: "I'm a teapot", + 420: "Enhance Your Calm", + 422: "Unprocessable Entity", + 423: "Locked", + 424: "Failed Dependency", + 425: "Unordered Collection", + 426: "Upgrade Required", + 428: "Precondition Required", + 429: "Too Many Requests", + 431: "Request Header Fields Too Large", + 444: "No Response", + 449: "Retry With", + 450: "Blocked by Windows Parental Controls", + 451: "Unavailable For Legal Reasons", + 494: "Request Header Too Large", + 495: "Cert Error", + 496: "No Cert", + 497: "HTTP to HTTPS", + 499: "Client Closed Request", + 500: "Internal Server Error", + 501: "Not Implemented", + 502: "Bad Gateway", + 503: "Service Unavailable", + 504: "Gateway Timeout", + 505: "HTTP Version Not Supported", + 506: "Variant Also Negotiates", + 507: "Insufficient Storage", + 508: "Loop Detected", + 509: "Bandwidth Limit Exceeded", + 510: "Not Extended", + 511: "Network Authentication Required", + 598: "Network read timeout error", + 599: "Network connect timeout error", + }) + + +def test_uri_info_full_url(): + uri_info = URIInfo( + username='johhny', + password='password', + hostname=b'google.com', + port=80, + path=b'/', + query=b'foo=bar&baz=test', + fragment='', + scheme='', + ) + + expect(uri_info.full_url()).to.equal( + "http://johhny:password@google.com/?baz=test&foo=bar" + ) + + expect(uri_info.full_url(use_querystring=False)).to.equal( + "http://johhny:password@google.com/" + ) + + +def test_uri_info_eq_ignores_case(): + """Test that URIInfo.__eq__ method ignores case for + hostname matching. + """ + uri_info_uppercase = URIInfo( + username='johhny', + password='password', + hostname=b'GOOGLE.COM', + port=80, + path=b'/', + query=b'foo=bar&baz=test', + fragment='', + scheme='', + ) + uri_info_lowercase = URIInfo( + username='johhny', + password='password', + hostname=b'google.com', + port=80, + path=b'/', + query=b'foo=bar&baz=test', + fragment='', + scheme='', + ) + expect(uri_info_uppercase).to.equal(uri_info_lowercase) + + +def test_global_boolean_enabled(): + HTTPretty.disable() + expect(HTTPretty.is_enabled()).to.be.falsy + HTTPretty.enable() + expect(HTTPretty.is_enabled()).to.be.truthy + HTTPretty.disable() + expect(HTTPretty.is_enabled()).to.be.falsy + + +def test_py3kobject_implements_valid__repr__based_on__str__(): + class MyObject(BaseClass): + def __str__(self): + return 'hi' + + myobj = MyObject() + expect(repr(myobj)).to.be.equal('hi') + + +def test_Entry_class_normalizes_headers(): + entry = Entry(HTTPretty.GET, 'http://example.com', 'example', + host='example.com', cache_control='no-cache', x_forward_for='proxy') + + entry.adding_headers.should.equal({ + 'Host': 'example.com', + 'Cache-Control': 'no-cache', + 'X-Forward-For': 'proxy' + }) + + +def test_Entry_class_counts_multibyte_characters_in_bytes(): + entry = Entry(HTTPretty.GET, 'http://example.com', 'こんにちは') + buf = FakeSockFile() + entry.fill_filekind(buf) + response = buf.read() + expect(b'content-length: 15\n').to.be.within(response) + + +def test_Entry_class_counts_dynamic(): + result = (200, {}, 'こんにちは'.encode('utf-8')) + entry = Entry(HTTPretty.GET, 'http://example.com', lambda *args: result) + entry.info = URIInfo.from_uri('http://example.com', entry) + buf = FakeSockFile() + entry.fill_filekind(buf) + response = buf.getvalue() + expect(b'content-length: 15\n').to.be.within(response) + + +def test_fake_socket_passes_through_setblocking(): + import socket + HTTPretty.enable() + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.truesock = MagicMock() + expect(s.setblocking).called_with(0).should_not.throw(AttributeError) + s.truesock.setblocking.assert_called_with(0) + + +def test_fake_socket_passes_through_fileno(): + import socket + with httpretty.enabled(): + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.truesock = MagicMock() + expect(s.fileno).called_with().should_not.throw(AttributeError) + s.truesock.fileno.assert_called_with() + + +def test_fake_socket_passes_through_getsockopt(): + import socket + HTTPretty.enable() + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.truesock = MagicMock() + expect(s.getsockopt).called_with(socket.SOL_SOCKET, 1).should_not.throw(AttributeError) + s.truesock.getsockopt.assert_called_with(socket.SOL_SOCKET, 1) + + +def test_fake_socket_passes_through_bind(): + import socket + HTTPretty.enable() + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.truesock = MagicMock() + expect(s.bind).called_with(('127.0.0.1', 1000)).should_not.throw(AttributeError) + s.truesock.bind.assert_called_with(('127.0.0.1', 1000)) + + +def test_fake_socket_passes_through_connect_ex(): + import socket + HTTPretty.enable() + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.truesock = MagicMock() + expect(s.connect_ex).called_with().should_not.throw(AttributeError) + s.truesock.connect_ex.assert_called_with() + + +def test_fake_socket_passes_through_listen(): + import socket + HTTPretty.enable() + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.truesock = MagicMock() + expect(s.listen).called_with().should_not.throw(AttributeError) + s.truesock.listen.assert_called_with() + + +def test_fake_socket_passes_through_getpeername(): + import socket + HTTPretty.enable() + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.truesock = MagicMock() + expect(s.getpeername).called_with().should_not.throw(AttributeError) + s.truesock.getpeername.assert_called_with() + + +def test_fake_socket_passes_through_getsockname(): + import socket + HTTPretty.enable() + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.truesock = MagicMock() + expect(s.getsockname).called_with().should_not.throw(AttributeError) + s.truesock.getsockname.assert_called_with() + + +def test_fake_socket_passes_through_gettimeout(): + import socket + HTTPretty.enable() + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.truesock = MagicMock() + expect(s.gettimeout).called_with().should_not.throw(AttributeError) + s.truesock.gettimeout.assert_called_with() + + +def test_fake_socket_passes_through_shutdown(): + import socket + HTTPretty.enable() + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.truesock = MagicMock() + expect(s.shutdown).called_with(socket.SHUT_RD).should_not.throw(AttributeError) + s.truesock.shutdown.assert_called_with(socket.SHUT_RD) + + +def test_unix_socket(): + import socket + HTTPretty.enable() + + # Create a UDS socket + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + server_address = './not-exist-socket' + try: + sock.connect(server_address) + except socket.error: + # We expect this, since the server_address does not exist + pass + + +def test_HTTPrettyRequest_json_body(): + """ A content-type of application/json should parse a valid json body """ + header = TEST_HEADER % {'content_type': 'application/json'} + test_dict = {'hello': 'world'} + request = HTTPrettyRequest(header, json.dumps(test_dict)) + expect(request.parsed_body).to.equal(test_dict) + + +def test_HTTPrettyRequest_invalid_json_body(): + """ A content-type of application/json with an invalid json body should return the content unaltered """ + header = TEST_HEADER % {'content_type': 'application/json'} + invalid_json = u"{'hello', 'world','thisstringdoesntstops}" + request = HTTPrettyRequest(header, invalid_json) + expect(request.parsed_body).to.equal(invalid_json) + + +def test_HTTPrettyRequest_queryparam(): + """ A content-type of x-www-form-urlencoded with a valid queryparam body should return parsed content """ + header = TEST_HEADER % {'content_type': 'application/x-www-form-urlencoded'} + valid_queryparam = u"hello=world&this=isavalidquerystring" + valid_results = {'hello': ['world'], 'this': ['isavalidquerystring']} + request = HTTPrettyRequest(header, valid_queryparam) + expect(request.parsed_body).to.equal(valid_results) + + +def test_HTTPrettyRequest_arbitrarypost(): + """ A non-handled content type request's post body should return the content unaltered """ + header = TEST_HEADER % {'content_type': 'thisis/notarealcontenttype'} + gibberish_body = "1234567890!@#$%^&*()" + request = HTTPrettyRequest(header, gibberish_body) + expect(request.parsed_body).to.equal(gibberish_body) + + +def test_socktype_bad_python_version_regression(): + """ Some versions of python accidentally internally shadowed the SockType + variable, so it was no longer the socket object but and int Enum representing + the socket type e.g. AF_INET. Make sure we don't patch SockType in these cases + https://bugs.python.org/issue20386 + """ + import socket + someObject = object() + with patch('socket.SocketType', someObject): + HTTPretty.enable() + expect(socket.SocketType).to.equal(someObject) + HTTPretty.disable() + + +def test_socktype_good_python_version(): + import socket + with patch('socket.SocketType', socket.socket): + HTTPretty.enable() + expect(socket.SocketType).to.equal(socket.socket) + HTTPretty.disable() + + +def test_httpretty_should_allow_registering_regex_hostnames(): + "HTTPretty should allow registering regexes with requests" + + HTTPretty.register_uri( + HTTPretty.GET, + re.compile(r'^http://\w+\.foo\.com/baz$'), + body="yay", + ) + + assert HTTPretty.match_http_address('www.foo.com', 80) + + +def test_httpretty_should_allow_registering_regex_hostnames_ssl(): + "HTTPretty should allow registering regexes with requests (ssl version)" + + HTTPretty.register_uri( + HTTPretty.GET, + re.compile(r'^https://\w+\.foo\.com/baz$'), + body="yay", + ) + + assert HTTPretty.match_https_hostname('www.foo.com') diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py new file mode 100644 index 0000000..35a7b7d --- /dev/null +++ b/tests/unit/test_main.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +import httpretty +from httpretty.core import HTTPrettyRequest + +try: + from unittest.mock import patch +except ImportError: + from mock import patch + + +@patch('httpretty.httpretty') +def test_last_request(original): + ("httpretty.last_request() should return httpretty.core.last_request") + + httpretty.last_request().should.equal(original.last_request) + + +@patch('httpretty.httpretty') +def test_latest_requests(original): + ("httpretty.latest_requests() should return httpretty.core.latest_requests") + + httpretty.latest_requests().should.equal(original.latest_requests) + + +def test_has_request(): + ("httpretty.has_request() correctly detects " + "whether or not a request has been made") + httpretty.reset() + httpretty.has_request().should.be.false + with patch('httpretty.httpretty.last_request', return_value=HTTPrettyRequest('')): + httpretty.has_request().should.be.true diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..def2c55 --- /dev/null +++ b/tox.ini @@ -0,0 +1,7 @@ +[tox] +envlist = py27, py36, py37 + +[testenv] +deps = pipenv + +commands = make test