Hello community, here is the log from the commit of package python-mocket for openSUSE:Factory checked in at 2020-10-29 09:48:24 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-mocket (Old) and /work/SRC/openSUSE:Factory/.python-mocket.new.3463 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-mocket" Thu Oct 29 09:48:24 2020 rev:6 rq:842363 version:3.9.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-mocket/python-mocket.changes 2020-08-12 10:36:44.508298543 +0200 +++ /work/SRC/openSUSE:Factory/.python-mocket.new.3463/python-mocket.changes 2020-10-29 09:48:32.480179445 +0100 @@ -1,0 +2,19 @@ +Sun Oct 11 07:03:02 UTC 2020 - Sebastian Wagner <sebix+novell....@sebix.at> + +- Update to version 3.9.1: + - Multiple HTTP writes (#125) + - Fix for #111. + +------------------------------------------------------------------- +Sat Sep 26 07:39:57 UTC 2020 - Sebastian Wagner <sebix+novell....@sebix.at> + +- Update to version 3.9.0: + - MockHTTP uses `http-parser` as parser + Fix for second sendall used for delivering request's body. +- Update to version 3.8.9: + - Small refactor for HTTPretty plugin + Now the import line can be written as from mocket.plugins.httpretty import httpretty, httprettified. +- Update to version 3.8.8: + - Small fix applied to `setup.py` + +------------------------------------------------------------------- Old: ---- mocket-3.8.7.tar.gz New: ---- mocket-3.9.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-mocket.spec ++++++ --- /var/tmp/diff_new_pack.1r90CA/_old 2020-10-29 09:48:33.980180725 +0100 +++ /var/tmp/diff_new_pack.1r90CA/_new 2020-10-29 09:48:33.984180729 +0100 @@ -26,7 +26,7 @@ %bcond_with test %endif Name: python-mocket%{psuffix} -Version: 3.8.7 +Version: 3.9.1 Release: 0 Summary: Python socket mock framework License: BSD-3-Clause @@ -36,6 +36,7 @@ BuildRequires: fdupes BuildRequires: python-rpm-macros Requires: python-decorator +Requires: python-http-parser >= 0.9.0 Requires: python-python-magic Requires: python-six Requires: python-urllib3 @@ -50,6 +51,7 @@ BuildRequires: %{python_module cryptography} BuildRequires: %{python_module decorator} BuildRequires: %{python_module gevent} +BuildRequires: %{python_module http-parser >= 0.9.0} BuildRequires: %{python_module mock} BuildRequires: %{python_module pook} BuildRequires: %{python_module pyOpenSSL} ++++++ mocket-3.8.7.tar.gz -> mocket-3.9.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.8.7/PKG-INFO new/mocket-3.9.1/PKG-INFO --- old/mocket-3.8.7/PKG-INFO 2020-07-27 19:01:18.508651700 +0200 +++ new/mocket-3.9.1/PKG-INFO 2020-10-09 20:32:55.048277000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: mocket -Version: 3.8.7 +Version: 3.9.1 Summary: Socket Mock Framework - for all kinds of socket animals, web-clients included - with gevent/asyncio/SSL support Home-page: https://github.com/mindflayer/python-mocket Author: Giorgio Salluzzo @@ -28,6 +28,9 @@ ------------------------- for all kinds of socket *animals*, web-clients included - with gevent/asyncio/SSL support + ...and then MicroPython's *urequest* (*mocket >= 3.9.1*) + + Versioning ========== Starting from *3.7.0*, Mocket major version will follow the same numbering pattern as Python's and therefore indicate the most recent Python version that is supported. @@ -82,8 +85,8 @@ ============ When opening an **Issue**, please add few lines of code as failing test, or -better- open its relative **Pull request** adding this test to our test suite. - Quick example of its HTTP mock - ============================== + Example of how to mock an HTTP[S] call + ====================================== Let's create a new virtualenv with all we need:: $ virtualenv example @@ -148,6 +151,30 @@ $ py.test example.py + Example of how to record real socket traffic + ============================================ + + You probably know what *VCRpy* is capable of, that's the `mocket`'s way of achieving it: + + .. code-block:: python + + @mocketize(truesocket_recording_dir=tempfile.mkdtemp()) + def test_truesendall_with_recording_https(): + url = 'https://httpbin.org/ip' + + requests.get(url, headers={"Accept": "application/json"}) + resp = requests.get(url, headers={"Accept": "application/json"}) + assert resp.status_code == 200 + + dump_filename = os.path.join( + Mocket.get_truesocket_recording_dir(), + Mocket.get_namespace() + '.json', + ) + with io.open(dump_filename) as f: + response = json.load(f) + + assert len(response['httpbin.org']['443'].keys()) == 1 + HTTPretty compatibility layer ============================= Mocket HTTP mock can work as *HTTPretty* replacement for many different use cases. Two main features are missing: @@ -168,15 +195,15 @@ import async_timeout from unittest import TestCase - from mocket.plugins.httpretty import HTTPretty, httprettified + from mocket.plugins.httpretty import httpretty, httprettified class AioHttpEntryTestCase(TestCase): @httprettified def test_https_session(self): url = 'https://httpbin.org/ip' - HTTPretty.register_uri( - HTTPretty.GET, + httpretty.register_uri( + httpretty.GET, url, body=json.dumps(dict(origin='127.0.0.1')), ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.8.7/README.rst new/mocket-3.9.1/README.rst --- old/mocket-3.8.7/README.rst 2020-07-27 18:58:39.000000000 +0200 +++ new/mocket-3.9.1/README.rst 2020-10-09 20:32:23.000000000 +0200 @@ -20,6 +20,9 @@ ------------------------- for all kinds of socket *animals*, web-clients included - with gevent/asyncio/SSL support +...and then MicroPython's *urequest* (*mocket >= 3.9.1*) + + Versioning ========== Starting from *3.7.0*, Mocket major version will follow the same numbering pattern as Python's and therefore indicate the most recent Python version that is supported. @@ -74,8 +77,8 @@ ============ When opening an **Issue**, please add few lines of code as failing test, or -better- open its relative **Pull request** adding this test to our test suite. -Quick example of its HTTP mock -============================== +Example of how to mock an HTTP[S] call +====================================== Let's create a new virtualenv with all we need:: $ virtualenv example @@ -140,6 +143,30 @@ $ py.test example.py +Example of how to record real socket traffic +============================================ + +You probably know what *VCRpy* is capable of, that's the `mocket`'s way of achieving it: + +.. code-block:: python + + @mocketize(truesocket_recording_dir=tempfile.mkdtemp()) + def test_truesendall_with_recording_https(): + url = 'https://httpbin.org/ip' + + requests.get(url, headers={"Accept": "application/json"}) + resp = requests.get(url, headers={"Accept": "application/json"}) + assert resp.status_code == 200 + + dump_filename = os.path.join( + Mocket.get_truesocket_recording_dir(), + Mocket.get_namespace() + '.json', + ) + with io.open(dump_filename) as f: + response = json.load(f) + + assert len(response['httpbin.org']['443'].keys()) == 1 + HTTPretty compatibility layer ============================= Mocket HTTP mock can work as *HTTPretty* replacement for many different use cases. Two main features are missing: @@ -160,15 +187,15 @@ import async_timeout from unittest import TestCase - from mocket.plugins.httpretty import HTTPretty, httprettified + from mocket.plugins.httpretty import httpretty, httprettified class AioHttpEntryTestCase(TestCase): @httprettified def test_https_session(self): url = 'https://httpbin.org/ip' - HTTPretty.register_uri( - HTTPretty.GET, + httpretty.register_uri( + httpretty.GET, url, body=json.dumps(dict(origin='127.0.0.1')), ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.8.7/mocket/__init__.py new/mocket-3.9.1/mocket/__init__.py --- old/mocket-3.8.7/mocket/__init__.py 2020-07-27 18:44:00.000000000 +0200 +++ new/mocket-3.9.1/mocket/__init__.py 2020-10-09 20:32:23.000000000 +0200 @@ -1,10 +1,10 @@ try: # Py2 - from mocket import mocketize, Mocket, MocketEntry, Mocketizer + from mocket import Mocket, MocketEntry, Mocketizer, mocketize except ImportError: # Py3 - from mocket.mocket import mocketize, Mocket, MocketEntry, Mocketizer + from mocket.mocket import Mocket, MocketEntry, Mocketizer, mocketize __all__ = ("mocketize", "Mocket", "MocketEntry", "Mocketizer") -__version__ = "3.8.7" +__version__ = "3.9.1" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.8.7/mocket/mocket.py new/mocket-3.9.1/mocket/mocket.py --- old/mocket-3.8.7/mocket/mocket.py 2020-06-18 08:04:42.000000000 +0200 +++ new/mocket-3.9.1/mocket/mocket.py 2020-10-09 20:32:23.000000000 +0200 @@ -38,7 +38,7 @@ hasher = xxh32 or hashlib.md5 try: # pragma: no cover - from urllib3.contrib.pyopenssl import inject_into_urllib3, extract_from_urllib3 + from urllib3.contrib.pyopenssl import extract_from_urllib3, inject_into_urllib3 pyopenssl_override = True except ImportError: @@ -386,7 +386,7 @@ else: req = Mocket.last_request() if hasattr(req, "add_data"): - req.add_data(decode_from_bytes(data)) + req.add_data(data) self._entry = entry return len(data) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.8.7/mocket/mockhttp.py new/mocket-3.9.1/mocket/mockhttp.py --- old/mocket-3.8.7/mocket/mockhttp.py 2020-07-27 18:30:19.000000000 +0200 +++ new/mocket-3.9.1/mocket/mockhttp.py 2020-10-09 20:32:23.000000000 +0200 @@ -2,7 +2,6 @@ import re import time -from io import BytesIO from .compat import ( BaseHTTPRequestHandler, @@ -16,6 +15,11 @@ from .mocket import Mocket, MocketEntry try: + from http_parser.parser import HttpParser +except ImportError: + from http_parser.pyparser import HttpParser + +try: import magic except ImportError: magic = None @@ -25,20 +29,31 @@ CRLF = "\r\n" -class Request(BaseHTTPRequestHandler): +class Request: + parser = None + _body = None + def __init__(self, data): - _, self.body = decode_from_bytes(data).split("\r\n\r\n", 1) - self.rfile = BytesIO(encode_to_bytes(data)) - self.raw_requestline = self.rfile.readline() - self.error_code = self.error_message = None - self.parse_request() - self.method = self.command + self.parser = HttpParser() + self.parser.execute(data, len(data)) + + self.method = self.parser.get_method() + self.path = self.parser.get_path() + self.headers = self.parser.get_headers() self.querystring = parse_qs( - unquote_utf8(urlsplit(self.path).query), keep_blank_values=True + unquote_utf8(self.parser.get_query_string()), keep_blank_values=True ) + if self.querystring: + self.path += "?{}".format(self.parser.get_query_string()) def add_data(self, data): - self.body += data + self.parser.execute(data, len(data)) + + @property + def body(self): + if self._body is None: + self._body = decode_from_bytes(self.parser.recv_body()) + return self._body def __str__(self): return "{} - {} - {}".format(self.method, self.path, self.headers) @@ -68,12 +83,15 @@ self.data = self.get_protocol_data() + self.body - def get_protocol_data(self): + def get_protocol_data(self, str_format_fun_name="capitalize"): status_line = "HTTP/1.1 {status_code} {status}".format( status_code=self.status, status=STATUS[self.status] ) header_lines = CRLF.join( - ["{0}: {1}".format(k.capitalize(), v) for k, v in self.headers.items()] + ( + "{0}: {1}".format(getattr(k, str_format_fun_name)(), v) + for k, v in self.headers.items() + ) ) return "{0}\r\n{1}\r\n\r\n".format(status_line, header_lines).encode("utf-8") @@ -91,8 +109,18 @@ self.headers["Content-Type"] = do_the_magic(self.magic, self.body) def set_extra_headers(self, headers): + r""" + >>> r = Response(body="<html />") + >>> len(r.headers.keys()) + 6 + >>> r.set_extra_headers({"foo-bar": "Foobar"}) + >>> len(r.headers.keys()) + 7 + >>> encode_to_bytes(r.headers.get("Foo-Bar")) == encode_to_bytes("Foobar") + True + """ for k, v in headers.items(): - self.headers["-".join([token.capitalize() for token in k.split("-")])] = v + self.headers["-".join((token.capitalize() for token in k.split("-")))] = v class Entry(MocketEntry): @@ -129,10 +157,12 @@ self._match_querystring = match_querystring def collect(self, data): - self._sent_data += data decoded_data = decode_from_bytes(data) - if not decoded_data.startswith(Entry.METHODS) and decoded_data.endswith(CRLF): + if not decoded_data.startswith(Entry.METHODS): Mocket.remove_last_request() + self._sent_data += data + else: + self._sent_data = data super(Entry, self).collect(self._sent_data) def can_handle(self, data): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.8.7/mocket/plugins/httpretty/__init__.py new/mocket-3.9.1/mocket/plugins/httpretty/__init__.py --- old/mocket-3.8.7/mocket/plugins/httpretty/__init__.py 2020-06-18 08:04:42.000000000 +0200 +++ new/mocket-3.9.1/mocket/plugins/httpretty/__init__.py 2020-10-09 20:32:23.000000000 +0200 @@ -1,9 +1,9 @@ from sys import version_info from mocket import Mocket, mocketize -from mocket.compat import byte_type, encode_to_bytes, text_type -from mocket.mockhttp import CRLF, STATUS +from mocket.compat import byte_type, text_type from mocket.mockhttp import Entry as MocketHttpEntry +from mocket.mockhttp import Request as MocketHttpRequest from mocket.mockhttp import Response as MocketHttpResponse @@ -11,17 +11,21 @@ return {k.lower().replace("_", "-"): v for k, v in headers.items()} +class Request(MocketHttpRequest): + @property + def body(self): + if self._body is None: + self._body = self.parser.recv_body() + return self._body + + class Response(MocketHttpResponse): - def get_protocol_data(self): - status_line = "HTTP/1.1 {status_code} {status}".format( - status_code=self.status, status=STATUS[self.status] - ) + def get_protocol_data(self, str_format_fun_name="lower"): if "server" in self.headers and self.headers["server"] == "Python/Mocket": self.headers["server"] = "Python/HTTPretty" - header_lines = CRLF.join( - ["{0}: {1}".format(k.lower(), v) for k, v in self.headers.items()] + return super(Response, self).get_protocol_data( + str_format_fun_name=str_format_fun_name ) - return "{0}\r\n{1}\r\n\r\n".format(status_line, header_lines).encode("utf-8") def set_base_headers(self): super(Response, self).set_base_headers() @@ -34,6 +38,7 @@ class Entry(MocketHttpEntry): + request_cls = Request response_cls = Response @@ -43,6 +48,7 @@ major, minor = version_info[:2] if major == 3 and minor >= 5: from mocket.async_mocket import get_async_mocketize + async_httprettified = get_async_mocketize() enable = Mocket.enable @@ -108,7 +114,6 @@ def __getattr__(self, name): if name == "last_request": last_request = getattr(Mocket, "last_request")() - last_request.body = encode_to_bytes(last_request.body) return last_request elif name == "latest_requests": return getattr(Mocket, "_requests") @@ -118,7 +123,7 @@ HTTPretty = MocketHTTPretty() HTTPretty.register_uri = register_uri - +httpretty = HTTPretty __all__ = ( "HTTPretty", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.8.7/mocket.egg-info/PKG-INFO new/mocket-3.9.1/mocket.egg-info/PKG-INFO --- old/mocket-3.8.7/mocket.egg-info/PKG-INFO 2020-07-27 19:01:18.000000000 +0200 +++ new/mocket-3.9.1/mocket.egg-info/PKG-INFO 2020-10-09 20:32:54.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: mocket -Version: 3.8.7 +Version: 3.9.1 Summary: Socket Mock Framework - for all kinds of socket animals, web-clients included - with gevent/asyncio/SSL support Home-page: https://github.com/mindflayer/python-mocket Author: Giorgio Salluzzo @@ -28,6 +28,9 @@ ------------------------- for all kinds of socket *animals*, web-clients included - with gevent/asyncio/SSL support + ...and then MicroPython's *urequest* (*mocket >= 3.9.1*) + + Versioning ========== Starting from *3.7.0*, Mocket major version will follow the same numbering pattern as Python's and therefore indicate the most recent Python version that is supported. @@ -82,8 +85,8 @@ ============ When opening an **Issue**, please add few lines of code as failing test, or -better- open its relative **Pull request** adding this test to our test suite. - Quick example of its HTTP mock - ============================== + Example of how to mock an HTTP[S] call + ====================================== Let's create a new virtualenv with all we need:: $ virtualenv example @@ -148,6 +151,30 @@ $ py.test example.py + Example of how to record real socket traffic + ============================================ + + You probably know what *VCRpy* is capable of, that's the `mocket`'s way of achieving it: + + .. code-block:: python + + @mocketize(truesocket_recording_dir=tempfile.mkdtemp()) + def test_truesendall_with_recording_https(): + url = 'https://httpbin.org/ip' + + requests.get(url, headers={"Accept": "application/json"}) + resp = requests.get(url, headers={"Accept": "application/json"}) + assert resp.status_code == 200 + + dump_filename = os.path.join( + Mocket.get_truesocket_recording_dir(), + Mocket.get_namespace() + '.json', + ) + with io.open(dump_filename) as f: + response = json.load(f) + + assert len(response['httpbin.org']['443'].keys()) == 1 + HTTPretty compatibility layer ============================= Mocket HTTP mock can work as *HTTPretty* replacement for many different use cases. Two main features are missing: @@ -168,15 +195,15 @@ import async_timeout from unittest import TestCase - from mocket.plugins.httpretty import HTTPretty, httprettified + from mocket.plugins.httpretty import httpretty, httprettified class AioHttpEntryTestCase(TestCase): @httprettified def test_https_session(self): url = 'https://httpbin.org/ip' - HTTPretty.register_uri( - HTTPretty.GET, + httpretty.register_uri( + httpretty.GET, url, body=json.dumps(dict(origin='127.0.0.1')), ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.8.7/mocket.egg-info/SOURCES.txt new/mocket-3.9.1/mocket.egg-info/SOURCES.txt --- old/mocket-3.8.7/mocket.egg-info/SOURCES.txt 2020-07-27 19:01:18.000000000 +0200 +++ new/mocket-3.9.1/mocket.egg-info/SOURCES.txt 2020-10-09 20:32:54.000000000 +0200 @@ -2,7 +2,6 @@ MANIFEST.in README.rst requirements.txt -setup.cfg setup.py mocket/__init__.py mocket/async_mocket.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.8.7/mocket.egg-info/requires.txt new/mocket-3.9.1/mocket.egg-info/requires.txt --- old/mocket-3.8.7/mocket.egg-info/requires.txt 2020-07-27 19:01:18.000000000 +0200 +++ new/mocket-3.9.1/mocket.egg-info/requires.txt 2020-10-09 20:32:54.000000000 +0200 @@ -1,4 +1,5 @@ decorator==4.4.2 +http-parser==0.9.0 python-magic==0.4.18 six==1.15.0 urllib3==1.25.10 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.8.7/requirements.txt new/mocket-3.9.1/requirements.txt --- old/mocket-3.8.7/requirements.txt 2020-07-27 19:01:14.000000000 +0200 +++ new/mocket-3.9.1/requirements.txt 2020-10-09 20:32:50.000000000 +0200 @@ -1,5 +1,6 @@ -i https://pypi.python.org/simple decorator==4.4.2 +http-parser==0.9.0 python-magic==0.4.18 six==1.15.0 urllib3==1.25.10 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.8.7/setup.cfg new/mocket-3.9.1/setup.cfg --- old/mocket-3.8.7/setup.cfg 2020-07-27 19:01:18.508651700 +0200 +++ new/mocket-3.9.1/setup.cfg 2020-10-09 20:32:55.048277000 +0200 @@ -1,7 +1,3 @@ -[tool:pytest] -python_files = test*.py -addopts = --doctest-glob="mock*.py" --cov=mocket --cov-report=term-missing -v -x - [egg_info] tag_build = tag_date = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.8.7/setup.py new/mocket-3.9.1/setup.py --- old/mocket-3.8.7/setup.py 2020-07-27 16:57:54.000000000 +0200 +++ new/mocket-3.9.1/setup.py 2020-10-09 19:05:44.000000000 +0200 @@ -40,7 +40,7 @@ long_description_content_type="text/x-rst", packages=find_packages(exclude=exclude_packages), install_requires=install_requires, - setup_requires=["pipenv"], + setup_requires=[], extras_require={ "speedups": [ 'xxhash;platform_python_implementation=="CPython"', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.8.7/tests/main/test_http.py new/mocket-3.9.1/tests/main/test_http.py --- old/mocket-3.8.7/tests/main/test_http.py 2020-02-20 11:00:16.000000000 +0100 +++ new/mocket-3.9.1/tests/main/test_http.py 2020-10-09 20:32:23.000000000 +0200 @@ -4,6 +4,7 @@ import io import json import os +import socket import tempfile import time from unittest import TestCase @@ -190,6 +191,20 @@ self.assertEqual(len(Mocket._requests), 3) @mocketize + def test_mockhttp_entry_collect_duplicates(self): + Entry.single_register( + Entry.POST, "http://testme.org/", status=200, match_querystring=False + ) + requests.post( + "http://testme.org/?foo=bar", + data="{'foo': 'bar'}", + headers={"content-type": "application/json"}, + ) + requests.post("http://testme.org/") + self.assertEqual(len(Mocket._requests), 2) + self.assertEqual(Mocket.last_request().path, "/") + + @mocketize def test_multipart(self): url = "http://httpbin.org/post" data = '--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' @@ -307,3 +322,38 @@ files = {"content": file_obj} r = requests.post(url, files=files, data={}, verify=False) self.assertEqual(r.status_code, 201) + + @mocketize + def test_sockets(self): + """ + https://github.com/mindflayer/python-mocket/issues/111 + https://gist.github.com/amotl/015ef6b336db55128798d7f1a9a67dea + """ + + # Define HTTP conversation. + url = "http://127.0.0.1/api/data" + Entry.single_register(Entry.POST, url) + + # Define HTTP url segments and data. + host = "127.0.0.1" + port = 80 + method = "POST" + path = "/api/data" + data = json.dumps({"hello": "world"}) + + # Invoke HTTP request. + address = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM)[0] + sock = socket.socket(address[0], address[1], address[2]) + + sock.connect(address[-1]) + sock.write("%s %s HTTP/1.0\r\n" % (method, path)) + sock.write("Host: %s\r\n" % host) + sock.write("Content-Type: application/json\r\n") + sock.write("Content-Length: %d\r\n" % len(data)) + sock.write("Connection: close\r\n\r\n") + sock.write(data) + sock.close() + + # Proof that worked. + print(Mocket.last_request().__dict__) + assert Mocket.last_request().body == '{"hello": "world"}' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mocket-3.8.7/tests/main/test_httpretty.py new/mocket-3.9.1/tests/main/test_httpretty.py --- old/mocket-3.8.7/tests/main/test_httpretty.py 2020-02-26 14:27:52.000000000 +0100 +++ new/mocket-3.9.1/tests/main/test_httpretty.py 2020-10-09 19:05:44.000000000 +0200 @@ -29,98 +29,108 @@ import requests from sure import expect -from mocket.plugins.httpretty import HTTPretty, httprettified +from mocket.plugins.httpretty import HTTPretty, httprettified, httpretty @httprettified def test_httpretty_should_mock_a_simple_get_with_requests_read(): """HTTPretty should mock a simple GET with requests.get""" - HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/", - body="Find the best daily deals") + 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('/') + 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 def test_httpretty_provides_easy_access_to_querystrings(): """HTTPretty should provide an easy access to the querystring""" - HTTPretty.register_uri(HTTPretty.GET, "http://yipit.com/", - body="Find the best daily deals") + 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'], - }) + requests.get("http://yipit.com/?foo=bar&foo=baz&chuck=norris") + expect(HTTPretty.last_request.querystring).to.equal( + {"foo": ["bar", "baz"], "chuck": ["norris"],} + ) @httprettified 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) + HTTPretty.register_uri( + HTTPretty.GET, + "http://github.com/", + body="this is supposed to be the response", + status=201, + ) - response = requests.get('http://github.com') + 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': response.headers['date'], - }) + expect(dict(response.headers)).to.equal( + { + "content-type": "text/plain; charset=utf-8", + "connection": "close", + "content-length": "35", + "status": "201", + "server": "Python/HTTPretty", + "date": response.headers["date"], + } + ) @httprettified 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': response.headers['date'], - }) + 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": response.headers["date"], + } + ) @httprettified def test_httpretty_should_allow_forcing_headers_requests(): """HTTPretty should allow forcing headers with requests""" - HTTPretty.register_uri(HTTPretty.GET, "http://github.com/foo", - body="<root><baz /</root>", - 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', - }) + HTTPretty.register_uri( + HTTPretty.GET, + "http://github.com/foo", + body="<root><baz /</root>", + 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 @@ -128,22 +138,27 @@ """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': response.headers['date'], - }) + 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": response.headers["date"], + } + ) @httprettified @@ -151,53 +166,49 @@ """HTTPretty should support rotating responses with requests""" HTTPretty.register_uri( - HTTPretty.GET, "https://api.yahoo.com/test", + 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), - ]) + HTTPretty.Response(body=b"second and last response", status=202), + ], + ) - response1 = requests.get( - 'https://api.yahoo.com/test') + response1 = requests.get("https://api.yahoo.com/test") expect(response1.status_code).to.equal(201) - expect(response1.text).to.equal('first response') + expect(response1.text).to.equal("first response") - response2 = requests.get( - 'https://api.yahoo.com/test') + response2 = requests.get("https://api.yahoo.com/test") expect(response2.status_code).to.equal(202) - expect(response2.text).to.equal('second and last response') + expect(response2.text).to.equal("second and last response") - response3 = requests.get( - 'https://api.yahoo.com/test') + response3 = requests.get("https://api.yahoo.com/test") expect(response3.status_code).to.equal(202) - expect(response3.text).to.equal('second and last response') + expect(response3.text).to.equal("second and last response") @httprettified def test_can_inspect_last_request(): """HTTPretty.last_request is a mimetools.Message request from last match""" - HTTPretty.register_uri(HTTPretty.POST, "http://api.github.com/", - body='{"repositories": ["HTTPretty", "lettuce"]}') + HTTPretty.register_uri( + HTTPretty.POST, + "http://api.github.com/", + body='{"repositories": ["HTTPretty", "lettuce"]}', + ) response = requests.post( - 'http://api.github.com', + "http://api.github.com", '{"username": "gabrielfalcao"}', - headers={ - 'content-type': 'text/json', - }, + 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(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"]}) @@ -205,24 +216,21 @@ def test_can_inspect_last_request_with_ssl(): """HTTPretty.last_request is recorded even when mocking 'https' (SSL)""" - HTTPretty.register_uri(HTTPretty.POST, "https://secure.github.com/", - body='{"repositories": ["HTTPretty", "lettuce"]}') + HTTPretty.register_uri( + HTTPretty.POST, + "https://secure.github.com/", + body='{"repositories": ["HTTPretty", "lettuce"]}', + ) response = requests.post( - 'https://secure.github.com', + "https://secure.github.com", '{"username": "gabrielfalcao"}', - headers={ - 'content-type': 'text/json', - }, + 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(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"]}) @@ -230,54 +238,61 @@ def test_httpretty_ignores_querystrings_from_registered_uri(): """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") + 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') + 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 def test_multiline(): - url = 'http://httpbin.org/post' - data = b'content=Im\r\na multiline\r\n\r\nsentence\r\n' + url = "http://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', + "Content-Type": "application/x-www-form-urlencoded; charset=utf-8", + "Accept": "text/plain", } HTTPretty.register_uri( - HTTPretty.POST, - url, + 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.path).to.equal('/post') + expect(HTTPretty.last_request.method).to.equal("POST") + 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(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(1) @httprettified def test_multipart(): - url = 'http://httpbin.org/post' + url = "http://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'} + headers = { + "Content-Length": "495", + "Content-Type": "multipart/form-data; boundary=xXXxXXyYYzzz", + "Accept": "text/plain", + } HTTPretty.register_uri( - HTTPretty.POST, - url, + 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.path).to.equal('/post') + expect(HTTPretty.last_request.method).to.equal("POST") + 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(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(1) @@ -285,14 +300,10 @@ 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'] + url = "http://test.com/test" + methods = ["GET", "POST", "PUT", "OPTIONS"] for method in methods: - HTTPretty.register_uri( - getattr(HTTPretty, method), - url, - method - ) + HTTPretty.register_uri(getattr(HTTPretty, method), url, method) for method in methods: request_action = getattr(requests, method.lower()) @@ -303,39 +314,39 @@ 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' + url = "http://test.com/list" - #add get responses - HTTPretty.register_uri(HTTPretty.GET, url, - responses=[HTTPretty.Response(body='a'), - HTTPretty.Response(body='b') - ] + # 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') - ] + # 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("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') + 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_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='') + url = "http://www.youtube.com" + HTTPretty.register_uri(HTTPretty.GET, url, body="") response = requests.get(url) expect(response.status_code).should.equal(200) @@ -343,8 +354,10 @@ @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') - + 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" + )