Repository: getsentry/responses

Issue:
Add capability for matching non json request bodies
At work I use responses for mocking api responses for the applications I develop. One of the APIs my application is interacting with does not take input in json format.

A call to this api looks like this

'''Curl api.company.com/v1/id --data '12345' '''

I would like to create a matcher for non json in the body.

I am pretty new to open source and only have some bug fixes and documentation fixes so I would like to contribute this feature back to responses. I think I can code this up from looking at the source. But would responses accept this feature?

Discussion:

Patch:
diff --git a/responses/matchers.py b/responses/matchers.py
index c9f7a63..79148e8 100644
--- a/responses/matchers.py
+++ b/responses/matchers.py
@@ -31,6 +31,21 @@ def _filter_dict_recursively(
     return filtered_dict
 
 
+def body_matcher(params: str, *, allow_blank: bool = False) -> Callable[..., Any]:
+    def match(request: PreparedRequest) -> Tuple[bool, str]:
+        reason = ""
+        if isinstance(request.body, bytes):
+            request_body = request.body.decode("utf-8")
+        else:
+            request_body = request.body
+        valid = True if request_body == params else False
+        if not valid:
+            reason = f"request.body doesn't match {params} doesn't match {request_body}"
+        return valid, reason
+
+    return match
+
+
 def urlencoded_params_matcher(
     params: Optional[Mapping[str, str]], *, allow_blank: bool = False
 ) -> Callable[..., Any]:


Test patch:
diff --git a/responses/tests/test_matchers.py b/responses/tests/test_matchers.py
index 67d8e83..2775fff 100644
--- a/responses/tests/test_matchers.py
+++ b/responses/tests/test_matchers.py
@@ -14,6 +14,40 @@ from responses.tests.test_responses import assert_reset
 from responses.tests.test_responses import assert_response
 
 
+def test_body_match_get():
+    @responses.activate
+    def run():
+        url = "http://example.com"
+        responses.add(
+            responses.GET,
+            url,
+            body=b"test",
+            match=[matchers.body_matcher("123456")],
+        )
+        resp = requests.get("http://example.com", data="123456")
+        assert_response(resp, "test")
+
+    run()
+    assert_reset()
+
+
+def test_body_match_post():
+    @responses.activate
+    def run():
+        url = "http://example.com"
+        responses.add(
+            responses.POST,
+            url,
+            body=b"test",
+            match=[matchers.body_matcher("123456")],
+        )
+        resp = requests.post("http://example.com", data="123456")
+        assert_response(resp, "test")
+
+    run()
+    assert_reset()
+
+
 def test_query_string_matcher():
     @responses.activate
     def run():