Fix ordering issue with a user-defined Responses-activation (#4896)

This commit is contained in:
Bert Blommers 2022-02-28 21:57:41 -01:00 committed by GitHub
parent 8bbfe9c151
commit 206590acf5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 71 additions and 5 deletions

View File

@ -100,7 +100,8 @@ def not_implemented_callback(request):
# - Same request, executed again, will be matched on the subsequent match, which happens to be the catch-all, not-yet-implemented, callback
# Fix: Always return the first match
def _find_first_match_legacy(self, request):
matches = [match for match in self._matches if match.matches(request)]
all_possibles = self._matches + responses._default_mock._matches
matches = [match for match in all_possibles if match.matches(request)]
# Look for implemented callbacks first
implemented_matches = [
@ -120,7 +121,8 @@ def _find_first_match_legacy(self, request):
def _find_first_match(self, request):
matches = []
match_failed_reasons = []
for match in self._matches:
all_possibles = self._matches + responses._default_mock._matches
for match in all_possibles:
match_result, reason = match.matches(request)
if match_result:
matches.append(match)

View File

@ -1,9 +1,9 @@
# This will only exist in responses >= 0.17
from responses import registries
import responses
from .custom_responses_mock import CallbackResponse, not_implemented_callback
class CustomRegistry(registries.FirstMatchRegistry):
class CustomRegistry(responses.registries.FirstMatchRegistry):
"""
Custom Registry that returns requests in an order that makes sense for Moto:
- Implemented callbacks take precedence over non-implemented-callbacks
@ -11,9 +11,10 @@ class CustomRegistry(registries.FirstMatchRegistry):
"""
def find(self, request):
all_possibles = responses._default_mock._registry.registered + self.registered
found = []
match_failed_reasons = []
for response in self.registered:
for response in all_possibles:
match_result, reason = response.matches(request)
if match_result:
found.append(response)

View File

@ -0,0 +1,63 @@
"""
Ensure that the responses module plays nice with our mocks
"""
import boto3
import requests
import responses
from moto import mock_s3, settings
from unittest import SkipTest, TestCase
class TestResponsesModule(TestCase):
def setUp(self):
if settings.TEST_SERVER_MODE:
raise SkipTest("No point in testing responses-decorator in ServerMode")
@mock_s3
@responses.activate
def test_moto_first(self):
"""
Verify we can activate a user-defined `responses` on top of our Moto mocks
"""
self.moto_responses_compatibility()
@responses.activate
@mock_s3
def test_moto_second(self):
"""
Verify we can load Moto after activating a `responses`-mock
"""
self.moto_responses_compatibility()
def moto_responses_compatibility(self):
responses.add(
responses.GET, url="http://127.0.0.1/lkdsfjlkdsa", json={"a": "4"},
)
s3 = boto3.client("s3")
s3.create_bucket(Bucket="mybucket")
s3.put_object(Bucket="mybucket", Key="name", Body="value")
s3.get_object(Bucket="mybucket", Key="name")["Body"].read()
with requests.get("http://127.0.0.1/lkdsfjlkdsa",) as r:
assert r.json() == {"a": "4"}
@responses.activate
def test_moto_as_late_as_possible(self):
"""
Verify we can load moto after registering a response
"""
responses.add(
responses.GET, url="http://127.0.0.1/lkdsfjlkdsa", json={"a": "4"},
)
with mock_s3():
s3 = boto3.client("s3")
s3.create_bucket(Bucket="mybucket")
s3.put_object(Bucket="mybucket", Key="name", Body="value")
# This mock exists within Moto
with requests.get("http://127.0.0.1/lkdsfjlkdsa",) as r:
assert r.json() == {"a": "4"}
# And outside of Moto
with requests.get("http://127.0.0.1/lkdsfjlkdsa",) as r:
assert r.json() == {"a": "4"}