Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-responses for 
openSUSE:Factory checked in at 2021-03-11 20:07:18
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-responses (Old)
 and      /work/SRC/openSUSE:Factory/.python-responses.new.2401 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-responses"

Thu Mar 11 20:07:18 2021 rev:14 rq:877834 version:0.12.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-responses/python-responses.changes        
2020-06-10 00:34:37.032786815 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-responses.new.2401/python-responses.changes  
    2021-03-11 20:07:58.908243931 +0100
@@ -1,0 +2,18 @@
+Mon Mar  8 22:40:48 UTC 2021 - Dirk M??ller <[email protected]>
+
+- update to 0.12.1:
+  * `responses.urlencoded_params_matcher` and `responses.json_params_matcher` 
now
+    accept None to match empty requests.
+  * Fixed imports to work with new `urllib3` versions.
+  * `request.params` now allows parameters to have multiple values for the 
same key.
+  * Improved ConnectionError messages.
+  - Remove support for Python 3.4.
+  - Added the `match` parameter to `add()`.
+  - Added `responses.urlencoded_params_matcher()` and 
`responses.json_params_matcher()`.
+  - Add a requirements pin to urllib3. This helps prevent broken install 
states where
+    cookie usage fails.
+  - Added `assert_call_count` to improve ergonomics around ensuring a mock was 
called.
+  - Fix incorrect handling of paths with query strings.
+  - Add Python 3.9 support to CI matrix.
+
+-------------------------------------------------------------------

Old:
----
  responses-0.10.14.tar.gz

New:
----
  responses-0.12.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-responses.spec ++++++
--- /var/tmp/diff_new_pack.FGyog9/_old  2021-03-11 20:07:59.992245690 +0100
+++ /var/tmp/diff_new_pack.FGyog9/_new  2021-03-11 20:07:59.996245696 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-responses
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-responses
-Version:        0.10.14
+Version:        0.12.1
 Release:        0
 Summary:        A utility library for mocking out the `requests` Python library
 License:        Apache-2.0

++++++ responses-0.10.14.tar.gz -> responses-0.12.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.10.14/CHANGES 
new/responses-0.12.1/CHANGES
--- old/responses-0.10.14/CHANGES       2020-04-20 04:26:10.000000000 +0200
+++ new/responses-0.12.1/CHANGES        2020-11-12 07:51:13.000000000 +0100
@@ -1,3 +1,41 @@
+0.12.1
+------
+
+* `responses.urlencoded_params_matcher` and `responses.json_params_matcher` now
+  accept None to match empty requests.
+* Fixed imports to work with new `urllib3` versions.
+* `request.params` now allows parameters to have multiple values for the same 
key.
+* Improved ConnectionError messages.
+
+0.12.0
+------
+
+- Remove support for Python 3.4.
+
+0.11.0
+------
+
+- Added the `match` parameter to `add()`.
+- Added `responses.urlencoded_params_matcher()` and 
`responses.json_params_matcher()`.
+
+0.10.16
+-------
+
+- Add a requirements pin to urllib3. This helps prevent broken install states 
where
+  cookie usage fails.
+
+0.10.15
+-------
+
+- Added `assert_call_count` to improve ergonomics around ensuring a mock was 
called.
+- Fix incorrect handling of paths with query strings.
+- Add Python 3.9 support to CI matrix.
+
+0.10.14
+-------
+
+- Retag of 0.10.13
+
 0.10.13
 -------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.10.14/PKG-INFO 
new/responses-0.12.1/PKG-INFO
--- old/responses-0.10.14/PKG-INFO      2020-04-20 04:26:47.000000000 +0200
+++ new/responses-0.12.1/PKG-INFO       2020-11-12 07:51:53.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: responses
-Version: 0.10.14
+Version: 0.12.1
 Summary: A utility library for mocking out the `requests` Python library.
 Home-page: https://github.com/getsentry/responses
 Author: David Cramer
@@ -17,7 +17,7 @@
         .. image:: https://img.shields.io/pypi/pyversions/responses.svg
             :target: https://pypi.org/project/responses/
         
-        A utility library for mocking out the `requests` Python library.
+        A utility library for mocking out the ``requests`` Python library.
         
         ..  note::
         
@@ -132,6 +132,40 @@
         stream (``bool``)
             Disabled by default. Indicates the response should use the 
streaming API.
         
+        match (``list``)
+            A list of callbacks to match requests based on request body 
contents.
+        
+        
+        Matching Request Parameters
+        ---------------------------
+        
+        When adding responses for endpoints that are sent request data you can 
add
+        matchers to ensure your code is sending the right parameters and 
provide
+        different responses based on the request body contents. Responses 
provides
+        matchers for JSON and URLencoded request bodies and you can supply 
your own for
+        other formats.
+        
+        .. code-block:: python
+        
+            import responses
+            import requests
+        
+            @responses.activate
+            def test_calc_api():
+                responses.add(
+                    responses.POST,
+                    url='http://calc.com/sum',
+                    body=4,
+                    match=[
+                        responses.urlencoded_params_matcher({"left": 1, 
"right": 3})
+                    ]
+                )
+                requests.post("http://calc.com/sum";, data={"left": 1, "right": 
3})
+        
+        Matching JSON encoded data can be done with 
``responses.json_params_matcher()``.
+        If your application uses other encodings you can build your own 
matcher that
+        returns ``True`` or ``False`` if the request parameters match. Your 
matcher can
+        expect a ``request_body`` parameter to be provided by responses.
         
         Dynamic Responses
         -----------------
@@ -177,7 +211,7 @@
                     '728d329e-0e86-11e4-a748-0c84dc037c13'
                 )
         
-        You can also pass a compiled regex to `add_callback` to match multiple 
urls:
+        You can also pass a compiled regex to ``add_callback`` to match 
multiple urls:
         
         ..  code-block:: python
         
@@ -322,6 +356,28 @@
                              body='{}', status=200,
                              content_type='application/json')
         
+        assert_call_count
+        -----------------
+        
+        Assert that the request was called exactly n times.
+        
+        .. code-block:: python
+        
+            import responses
+            import requests
+        
+            @responses.activate
+            def test_assert_call_count():
+                responses.add(responses.GET, "http://example.com";)
+        
+                requests.get("http://example.com";)
+                assert responses.assert_call_count("http://example.com";, 1) is 
True
+        
+                requests.get("http://example.com";)
+                with pytest.raises(AssertionError) as excinfo:
+                    responses.assert_call_count("http://example.com";, 1)
+                assert "Expected URL 'http://example.com' to be called 1 
times. Called 2 times." in str(excinfo.value)
+        
         
         Multiple Responses
         ------------------
@@ -374,10 +430,10 @@
                 assert resp.callback_processed is True
         
         
-        Passing thru real requests
-        --------------------------
+        Passing through real requests
+        -----------------------------
         
-        In some cases you may wish to allow for certain requests to pass thru 
responses
+        In some cases you may wish to allow for certain requests to pass 
through responses
         and hit a real server. This can be done with the ``add_passthru`` 
methods:
         
         .. code-block:: python
@@ -406,7 +462,7 @@
         registered responses which can be accessed via 
``responses.mock._matches``.
         
         The ``replace`` function allows a previously registered ``response`` 
to be
-        changed. The method signature is identical to ``add``. ``response``s 
are
+        changed. The method signature is identical to ``add``. ``response`` s 
are
         identified using ``method`` and ``url``. Only the first matched 
``response`` is
         replaced.
         
@@ -476,12 +532,12 @@
 Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 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: Topic :: Software Development
-Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
+Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
 Description-Content-Type: text/x-rst
 Provides-Extra: tests
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.10.14/README.rst 
new/responses-0.12.1/README.rst
--- old/responses-0.10.14/README.rst    2020-04-20 04:26:10.000000000 +0200
+++ new/responses-0.12.1/README.rst     2020-11-12 07:51:13.000000000 +0100
@@ -10,7 +10,7 @@
 .. image:: https://img.shields.io/pypi/pyversions/responses.svg
     :target: https://pypi.org/project/responses/
 
-A utility library for mocking out the `requests` Python library.
+A utility library for mocking out the ``requests`` Python library.
 
 ..  note::
 
@@ -125,6 +125,40 @@
 stream (``bool``)
     Disabled by default. Indicates the response should use the streaming API.
 
+match (``list``)
+    A list of callbacks to match requests based on request body contents.
+
+
+Matching Request Parameters
+---------------------------
+
+When adding responses for endpoints that are sent request data you can add
+matchers to ensure your code is sending the right parameters and provide
+different responses based on the request body contents. Responses provides
+matchers for JSON and URLencoded request bodies and you can supply your own for
+other formats.
+
+.. code-block:: python
+
+    import responses
+    import requests
+
+    @responses.activate
+    def test_calc_api():
+        responses.add(
+            responses.POST,
+            url='http://calc.com/sum',
+            body=4,
+            match=[
+                responses.urlencoded_params_matcher({"left": 1, "right": 3})
+            ]
+        )
+        requests.post("http://calc.com/sum";, data={"left": 1, "right": 3})
+
+Matching JSON encoded data can be done with 
``responses.json_params_matcher()``.
+If your application uses other encodings you can build your own matcher that
+returns ``True`` or ``False`` if the request parameters match. Your matcher can
+expect a ``request_body`` parameter to be provided by responses.
 
 Dynamic Responses
 -----------------
@@ -170,7 +204,7 @@
             '728d329e-0e86-11e4-a748-0c84dc037c13'
         )
 
-You can also pass a compiled regex to `add_callback` to match multiple urls:
+You can also pass a compiled regex to ``add_callback`` to match multiple urls:
 
 ..  code-block:: python
 
@@ -315,6 +349,28 @@
                      body='{}', status=200,
                      content_type='application/json')
 
+assert_call_count
+-----------------
+
+Assert that the request was called exactly n times.
+
+.. code-block:: python
+
+    import responses
+    import requests
+
+    @responses.activate
+    def test_assert_call_count():
+        responses.add(responses.GET, "http://example.com";)
+
+        requests.get("http://example.com";)
+        assert responses.assert_call_count("http://example.com";, 1) is True
+
+        requests.get("http://example.com";)
+        with pytest.raises(AssertionError) as excinfo:
+            responses.assert_call_count("http://example.com";, 1)
+        assert "Expected URL 'http://example.com' to be called 1 times. Called 
2 times." in str(excinfo.value)
+
 
 Multiple Responses
 ------------------
@@ -367,10 +423,10 @@
         assert resp.callback_processed is True
 
 
-Passing thru real requests
---------------------------
+Passing through real requests
+-----------------------------
 
-In some cases you may wish to allow for certain requests to pass thru responses
+In some cases you may wish to allow for certain requests to pass through 
responses
 and hit a real server. This can be done with the ``add_passthru`` methods:
 
 .. code-block:: python
@@ -399,7 +455,7 @@
 registered responses which can be accessed via ``responses.mock._matches``.
 
 The ``replace`` function allows a previously registered ``response`` to be
-changed. The method signature is identical to ``add``. ``response``s are
+changed. The method signature is identical to ``add``. ``response`` s are
 identified using ``method`` and ``url``. Only the first matched ``response`` is
 replaced.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.10.14/responses.egg-info/PKG-INFO 
new/responses-0.12.1/responses.egg-info/PKG-INFO
--- old/responses-0.10.14/responses.egg-info/PKG-INFO   2020-04-20 
04:26:47.000000000 +0200
+++ new/responses-0.12.1/responses.egg-info/PKG-INFO    2020-11-12 
07:51:53.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: responses
-Version: 0.10.14
+Version: 0.12.1
 Summary: A utility library for mocking out the `requests` Python library.
 Home-page: https://github.com/getsentry/responses
 Author: David Cramer
@@ -17,7 +17,7 @@
         .. image:: https://img.shields.io/pypi/pyversions/responses.svg
             :target: https://pypi.org/project/responses/
         
-        A utility library for mocking out the `requests` Python library.
+        A utility library for mocking out the ``requests`` Python library.
         
         ..  note::
         
@@ -132,6 +132,40 @@
         stream (``bool``)
             Disabled by default. Indicates the response should use the 
streaming API.
         
+        match (``list``)
+            A list of callbacks to match requests based on request body 
contents.
+        
+        
+        Matching Request Parameters
+        ---------------------------
+        
+        When adding responses for endpoints that are sent request data you can 
add
+        matchers to ensure your code is sending the right parameters and 
provide
+        different responses based on the request body contents. Responses 
provides
+        matchers for JSON and URLencoded request bodies and you can supply 
your own for
+        other formats.
+        
+        .. code-block:: python
+        
+            import responses
+            import requests
+        
+            @responses.activate
+            def test_calc_api():
+                responses.add(
+                    responses.POST,
+                    url='http://calc.com/sum',
+                    body=4,
+                    match=[
+                        responses.urlencoded_params_matcher({"left": 1, 
"right": 3})
+                    ]
+                )
+                requests.post("http://calc.com/sum";, data={"left": 1, "right": 
3})
+        
+        Matching JSON encoded data can be done with 
``responses.json_params_matcher()``.
+        If your application uses other encodings you can build your own 
matcher that
+        returns ``True`` or ``False`` if the request parameters match. Your 
matcher can
+        expect a ``request_body`` parameter to be provided by responses.
         
         Dynamic Responses
         -----------------
@@ -177,7 +211,7 @@
                     '728d329e-0e86-11e4-a748-0c84dc037c13'
                 )
         
-        You can also pass a compiled regex to `add_callback` to match multiple 
urls:
+        You can also pass a compiled regex to ``add_callback`` to match 
multiple urls:
         
         ..  code-block:: python
         
@@ -322,6 +356,28 @@
                              body='{}', status=200,
                              content_type='application/json')
         
+        assert_call_count
+        -----------------
+        
+        Assert that the request was called exactly n times.
+        
+        .. code-block:: python
+        
+            import responses
+            import requests
+        
+            @responses.activate
+            def test_assert_call_count():
+                responses.add(responses.GET, "http://example.com";)
+        
+                requests.get("http://example.com";)
+                assert responses.assert_call_count("http://example.com";, 1) is 
True
+        
+                requests.get("http://example.com";)
+                with pytest.raises(AssertionError) as excinfo:
+                    responses.assert_call_count("http://example.com";, 1)
+                assert "Expected URL 'http://example.com' to be called 1 
times. Called 2 times." in str(excinfo.value)
+        
         
         Multiple Responses
         ------------------
@@ -374,10 +430,10 @@
                 assert resp.callback_processed is True
         
         
-        Passing thru real requests
-        --------------------------
+        Passing through real requests
+        -----------------------------
         
-        In some cases you may wish to allow for certain requests to pass thru 
responses
+        In some cases you may wish to allow for certain requests to pass 
through responses
         and hit a real server. This can be done with the ``add_passthru`` 
methods:
         
         .. code-block:: python
@@ -406,7 +462,7 @@
         registered responses which can be accessed via 
``responses.mock._matches``.
         
         The ``replace`` function allows a previously registered ``response`` 
to be
-        changed. The method signature is identical to ``add``. ``response``s 
are
+        changed. The method signature is identical to ``add``. ``response`` s 
are
         identified using ``method`` and ``url``. Only the first matched 
``response`` is
         replaced.
         
@@ -476,12 +532,12 @@
 Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 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: Topic :: Software Development
-Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
+Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
 Description-Content-Type: text/x-rst
 Provides-Extra: tests
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.10.14/responses.egg-info/requires.txt 
new/responses-0.12.1/responses.egg-info/requires.txt
--- old/responses-0.10.14/responses.egg-info/requires.txt       2020-04-20 
04:26:47.000000000 +0200
+++ new/responses-0.12.1/responses.egg-info/requires.txt        2020-11-12 
07:51:53.000000000 +0100
@@ -1,4 +1,5 @@
 requests>=2.0
+urllib3>=1.25.10
 six
 
 [:python_version < "3.3"]
@@ -8,7 +9,7 @@
 cookies
 
 [tests]
-coverage<5.0.0,>=3.7.1
+coverage<6.0.0,>=3.7.1
 pytest-cov
 pytest-localserver
 flake8
@@ -17,4 +18,4 @@
 pytest<5.0,>=4.6
 
 [tests:python_version >= "3.5"]
-pytest
+pytest>=4.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.10.14/responses.py 
new/responses-0.12.1/responses.py
--- old/responses-0.10.14/responses.py  2020-04-20 04:26:10.000000000 +0200
+++ new/responses-0.12.1/responses.py   2020-11-12 07:51:13.000000000 +0100
@@ -5,6 +5,8 @@
 import json as json_module
 import logging
 import re
+from itertools import groupby
+
 import six
 
 from collections import namedtuple
@@ -26,7 +28,7 @@
 try:
     from requests.packages.urllib3.connection import HTTPHeaderDict
 except ImportError:
-    from urllib3.connection import HTTPHeaderDict
+    from urllib3.response import HTTPHeaderDict
 
 if six.PY2:
     from urlparse import urlparse, parse_qsl, urlsplit, urlunsplit
@@ -53,6 +55,11 @@
     # Python 3.7
     Pattern = re.Pattern
 
+try:
+    from json.decoder import JSONDecodeError
+except ImportError:
+    JSONDecodeError = ValueError
+
 UNSET = object()
 
 Call = namedtuple("Call", ["request", "response"])
@@ -229,17 +236,45 @@
 _unspecified = object()
 
 
+def urlencoded_params_matcher(params):
+    def match(request_body):
+        return (
+            params is None
+            if request_body is None
+            else sorted(params.items()) == sorted(parse_qsl(request_body))
+        )
+
+    return match
+
+
+def json_params_matcher(params):
+    def match(request_body):
+        try:
+            if isinstance(request_body, bytes):
+                request_body = request_body.decode("utf-8")
+            return (
+                params is None
+                if request_body is None
+                else params == json_module.loads(request_body)
+            )
+        except JSONDecodeError:
+            return False
+
+    return match
+
+
 class BaseResponse(object):
     content_type = None
     headers = None
 
     stream = False
 
-    def __init__(self, method, url, match_querystring=_unspecified):
+    def __init__(self, method, url, match_querystring=_unspecified, match=[]):
         self.method = method
         # ensure the url has a default path set if the url is a string
         self.url = _ensure_url_default_path(url)
         self.match_querystring = 
self._should_match_querystring(match_querystring)
+        self.match = match
         self.call_count = 0
 
     def __eq__(self, other):
@@ -302,6 +337,13 @@
         else:
             return False
 
+    def _body_matches(self, match, request_body):
+        for matcher in match:
+            if not matcher(request_body):
+                return False
+
+        return True
+
     def get_headers(self):
         headers = HTTPHeaderDict()  # Duplicate headers are legal
         if self.content_type is not None:
@@ -315,12 +357,15 @@
 
     def matches(self, request):
         if request.method != self.method:
-            return False
+            return False, "Method does not match"
 
         if not self._url_matches(self.url, request.url, 
self.match_querystring):
-            return False
+            return False, "URL does not match"
 
-        return True
+        if not self._body_matches(self.match, request.body):
+            return False, "Parameters do not match"
+
+        return True, ""
 
 
 class Response(BaseResponse):
@@ -608,21 +653,33 @@
     def _find_match(self, request):
         found = None
         found_match = None
+        match_failed_reasons = []
         for i, match in enumerate(self._matches):
-            if match.matches(request):
+            match_result, reason = match.matches(request)
+            if match_result:
                 if found is None:
                     found = i
                     found_match = match
                 else:
                     # Multiple matches found.  Remove & return the first match.
-                    return self._matches.pop(found)
+                    return self._matches.pop(found), match_failed_reasons
+            else:
+                match_failed_reasons.append(reason)
+        return found_match, match_failed_reasons
 
-        return found_match
+    def _parse_request_params(self, url):
+        params = {}
+        for key, val in groupby(parse_qsl(urlparse(url).query), lambda kv: 
kv[0]):
+            values = list(map(lambda x: x[1], val))
+            if len(values) == 1:
+                values = values[0]
+            params[key] = values
+        return params
 
     def _on_request(self, adapter, request, **kwargs):
-        match = self._find_match(request)
+        match, match_failed_reasons = self._find_match(request)
         resp_callback = self.response_callback
-        request.params = dict(parse_qsl(request.path_url.replace("/?", "")))
+        request.params = self._parse_request_params(request.path_url)
 
         if match is None:
             if any(
@@ -643,8 +700,10 @@
                 "- %s %s\n\n"
                 "Available matches:\n" % (request.method, request.url)
             )
-            for m in self._matches:
-                error_msg += "- {} {}\n".format(m.method, m.url)
+            for i, m in enumerate(self._matches):
+                error_msg += "- {} {} {}\n".format(
+                    m.method, m.url, match_failed_reasons[i]
+                )
 
             response = ConnectionError(error_msg)
             response.request = request
@@ -692,6 +751,23 @@
                 )
             )
 
+    def assert_call_count(self, url, count):
+        call_count = len(
+            [
+                1
+                for call in self.calls
+                if call.request.url == _ensure_url_default_path(url)
+            ]
+        )
+        if call_count == count:
+            return True
+        else:
+            raise AssertionError(
+                "Expected URL '{0}' to be called {1} times. Called {2} 
times.".format(
+                    url, count, call_count
+                )
+            )
+
 
 # expose default mock namespace
 mock = _default_mock = RequestsMock(assert_all_requests_are_fired=False)
@@ -705,6 +781,7 @@
     "add_callback",
     "add_passthru",
     "assert_all_requests_are_fired",
+    "assert_call_count",
     "calls",
     "DELETE",
     "GET",
@@ -728,6 +805,7 @@
 add_callback = _default_mock.add_callback
 add_passthru = _default_mock.add_passthru
 assert_all_requests_are_fired = _default_mock.assert_all_requests_are_fired
+assert_call_count = _default_mock.assert_call_count
 calls = _default_mock.calls
 DELETE = _default_mock.DELETE
 GET = _default_mock.GET
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.10.14/setup.py 
new/responses-0.12.1/setup.py
--- old/responses-0.10.14/setup.py      2020-04-20 04:26:10.000000000 +0200
+++ new/responses-0.12.1/setup.py       2020-11-12 07:51:13.000000000 +0100
@@ -23,13 +23,14 @@
     "cookies; python_version < '3.4'",
     "mock; python_version < '3.3'",
     "requests>=2.0",
+    "urllib3>=1.25.10",
     "six",
 ]
 
 tests_require = [
     "pytest>=4.6,<5.0; python_version < '3.5'",
-    "pytest; python_version >= '3.5'",
-    "coverage >= 3.7.1, < 5.0.0",
+    "pytest>=4.6; python_version >= '3.5'",
+    "coverage >= 3.7.1, < 6.0.0",
     "pytest-cov",
     "pytest-localserver",
     "flake8",
@@ -54,7 +55,7 @@
 
 setup(
     name="responses",
-    version="0.10.14",
+    version="0.12.1",
     author="David Cramer",
     description=("A utility library for mocking out the `requests` Python 
library."),
     url="https://github.com/getsentry/responses";,
@@ -63,7 +64,7 @@
     long_description_content_type="text/x-rst",
     py_modules=["responses"],
     zip_safe=False,
-    python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
+    python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*",
     install_requires=install_requires,
     extras_require=extras_require,
     tests_require=tests_require,
@@ -78,11 +79,11 @@
         "Programming Language :: Python :: 2",
         "Programming Language :: Python :: 2.7",
         "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.4",
         "Programming Language :: Python :: 3.5",
         "Programming Language :: Python :: 3.6",
         "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: 3.8",
+        "Programming Language :: Python :: 3.9",
         "Topic :: Software Development",
     ],
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.10.14/test_responses.py 
new/responses-0.12.1/test_responses.py
--- old/responses-0.10.14/test_responses.py     2020-04-20 04:26:10.000000000 
+0200
+++ new/responses-0.12.1/test_responses.py      2020-11-12 07:51:13.000000000 
+0100
@@ -396,9 +396,9 @@
     @responses.activate
     def run():
         url = "http://example.com/";
-        responses.add(responses.GET, url, body="test", status=418)
+        responses.add(responses.GET, url, body="test", status=419)
         resp = requests.get(url)
-        assert resp.status_code == 418
+        assert resp.status_code == 419
         assert resp.reason is None
 
     run()
@@ -1122,23 +1122,180 @@
         assert v == expected[k]
 
 
-def test_request_param():
[email protected](
+    "url",
+    (
+        "http://example.com";,
+        "http://example.com/some/path";,
+        "http://example.com/other/path/";,
+    ),
+)
+def test_request_param(url):
     @responses.activate
     def run():
         params = {"hello": "world", "example": "params"}
         responses.add(
             method=responses.GET,
-            url="http://example.com?hello=world";,
+            url="{0}?hello=world".format(url),
             body="test",
             match_querystring=False,
         )
-        resp = requests.get("http://example.com";, params=params)
+        resp = requests.get(url, params=params)
         assert_response(resp, "test")
         assert resp.request.params == params
 
-        resp = requests.get("http://example.com";)
+        resp = requests.get(url)
         assert_response(resp, "test")
         assert resp.request.params == {}
 
     run()
     assert_reset()
+
+
+def test_request_param_with_multiple_values_for_the_same_key():
+    @responses.activate
+    def run():
+        url = "http://example.com";
+        params = {"key1": ["one", "two"], "key2": "three"}
+        responses.add(
+            method=responses.GET,
+            url=url,
+            body="test",
+        )
+        resp = requests.get(url, params=params)
+        assert_response(resp, "test")
+        assert resp.request.params == params
+
+    run()
+    assert_reset()
+
+
[email protected](
+    "url", ("http://example.com";, "http://example.com?hello=world";)
+)
+def test_assert_call_count(url):
+    @responses.activate
+    def run():
+        responses.add(responses.GET, url)
+        responses.add(responses.GET, "http://example1.com";)
+
+        assert responses.assert_call_count(url, 0) is True
+
+        with pytest.raises(AssertionError) as excinfo:
+            responses.assert_call_count(url, 2)
+        assert "Expected URL '{0}' to be called 2 times. Called 0 
times.".format(
+            url
+        ) in str(excinfo.value)
+
+        requests.get(url)
+        assert responses.assert_call_count(url, 1) is True
+
+        requests.get("http://example1.com";)
+        assert responses.assert_call_count(url, 1) is True
+
+        requests.get(url)
+        with pytest.raises(AssertionError) as excinfo:
+            responses.assert_call_count(url, 3)
+        assert "Expected URL '{0}' to be called 3 times. Called 2 
times.".format(
+            url
+        ) in str(excinfo.value)
+
+    run()
+    assert_reset()
+
+
+def test_request_matches_post_params():
+    @responses.activate
+    def run():
+        responses.add(
+            method=responses.POST,
+            url="http://example.com/";,
+            body="one",
+            match=[
+                responses.json_params_matcher(
+                    {"page": {"name": "first", "type": "json"}}
+                )
+            ],
+        )
+        responses.add(
+            method=responses.POST,
+            url="http://example.com/";,
+            body="two",
+            match=[
+                responses.urlencoded_params_matcher(
+                    {"page": "second", "type": "urlencoded"}
+                )
+            ],
+        )
+
+        resp = requests.request(
+            "POST",
+            "http://example.com/";,
+            headers={"Content-Type": "x-www-form-urlencoded"},
+            data={"page": "second", "type": "urlencoded"},
+        )
+        assert_response(resp, "two")
+
+        resp = requests.request(
+            "POST",
+            "http://example.com/";,
+            headers={"Content-Type": "application/json"},
+            json={"page": {"name": "first", "type": "json"}},
+        )
+        assert_response(resp, "one")
+
+    run()
+    assert_reset()
+
+
+def test_request_matches_empty_body():
+    @responses.activate
+    def run():
+        responses.add(
+            method=responses.POST,
+            url="http://example.com/";,
+            body="one",
+            match=[responses.json_params_matcher(None)],
+        )
+
+        responses.add(
+            method=responses.POST,
+            url="http://example.com/";,
+            body="two",
+            match=[responses.urlencoded_params_matcher(None)],
+        )
+
+        resp = requests.request("POST", "http://example.com/";)
+        assert_response(resp, "one")
+
+        resp = requests.request(
+            "POST",
+            "http://example.com/";,
+            headers={"Content-Type": "x-www-form-urlencoded"},
+        )
+        assert_response(resp, "two")
+
+    run()
+    assert_reset()
+
+
+def test_fail_request_error():
+    @responses.activate
+    def run():
+        responses.add("POST", "http://example1.com";)
+        responses.add("GET", "http://example.com";)
+        responses.add(
+            "POST",
+            "http://example.com";,
+            match=[responses.urlencoded_params_matcher({"foo": "bar"})],
+        )
+
+        with pytest.raises(ConnectionError) as excinfo:
+            requests.post("http://example.com";, data={"id": "bad"})
+        msg = str(excinfo.value)
+        assert "- POST http://example1.com/ URL does not match" in msg
+        assert "- GET http://example.com/ Method does not match" in msg
+        assert "- POST http://example.com/ Parameters do not match" in msg
+
+    run()
+    assert_reset()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/responses-0.10.14/tox.ini 
new/responses-0.12.1/tox.ini
--- old/responses-0.10.14/tox.ini       2020-04-20 04:26:10.000000000 +0200
+++ new/responses-0.12.1/tox.ini        2020-11-12 07:51:13.000000000 +0100
@@ -1,5 +1,5 @@
 [tox]
-envlist = py27,py34,py35,py36,py37,py38
+envlist = py27,py35,py36,py37,py38,py39
 
 [testenv]
 extras = tests

Reply via email to