Repository: getsentry/responses

Issue:
Passthrough Responses should appear in CallList
<!--
Please provide some context on what problem you are trying to solve and how this feature is going to help.
-->

Currently, Passthrough responses do not appear in the `CallList` after termination of the test. A successful match does also not increase the call count of a `PassthroughResponse`.

Discussion:
codecov[bot]: # [Codecov](https://app.codecov.io/gh/getsentry/responses/compare/409?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getsentry) Report
> Merging [#409](https://app.codecov.io/gh/getsentry/responses/compare/409?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getsentry) (e753cba) into [master](https://codecov.io/gh/getsentry/responses/commit/3100f2d38fc2574ac9c2a0a81c6bdbd6bc5463ea?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getsentry) (3100f2d) will **increase** coverage by `0.00%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/getsentry/responses/pull/409/graphs/tree.svg?width=650&height=150&src=pr&token=x2tAGR7rxE&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getsentry)](https://app.codecov.io/gh/getsentry/responses/compare/409?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getsentry)

```diff
@@           Coverage Diff           @@
##           master     #409   +/-   ##
=======================================
  Coverage   97.32%   97.32%           
=======================================
  Files           4        4           
  Lines        1568     1572    +4     
=======================================
+ Hits         1526     1530    +4     
  Misses         42       42           
```


| [Impacted Files](https://app.codecov.io/gh/getsentry/responses/compare/409?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getsentry) | Coverage Δ | |
|---|---|---|
| [responses/\_\_init\_\_.py](https://app.codecov.io/gh/getsentry/responses/compare/409/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getsentry#diff-cmVzcG9uc2VzL19faW5pdF9fLnB5) | `97.37% <100.00%> (+<0.01%)` | :arrow_up: |
| [responses/test\_responses.py](https://app.codecov.io/gh/getsentry/responses/compare/409/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getsentry#diff-cmVzcG9uc2VzL3Rlc3RfcmVzcG9uc2VzLnB5) | `99.05% <100.00%> (+<0.01%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://app.codecov.io/gh/getsentry/responses/compare/409?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getsentry).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getsentry)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://app.codecov.io/gh/getsentry/responses/compare/409?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getsentry). Last update [3100f2d...e753cba](https://app.codecov.io/gh/getsentry/responses/compare/409?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getsentry). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=getsentry).

carloshorn: I encountered a problem when `passthrough_response.stream = False`, but the request is sent as stream.

Patch:
diff --git a/responses/__init__.py b/responses/__init__.py
index 130f8c0..43474ff 100644
--- a/responses/__init__.py
+++ b/responses/__init__.py
@@ -760,18 +760,22 @@ class RequestsMock(object):
 
         if match.passthrough:
             logger.info("request.passthrough-response", extra={"url": request.url})
-            return _real_send(adapter, request, **kwargs)
-
-        try:
-            response = adapter.build_response(request, match.get_response(request))
-        except BaseException as response:
-            match.call_count += 1
-            self._calls.add(request, response)
-            response = resp_callback(response) if resp_callback else response
-            raise
+            response = _real_send(adapter, request, **kwargs)
+        else:
+            try:
+                response = adapter.build_response(request, match.get_response(request))
+            except BaseException as response:
+                match.call_count += 1
+                self._calls.add(request, response)
+                response = resp_callback(response) if resp_callback else response
+                raise
 
         if not match.stream:
-            response.content  # NOQA
+            content = response.content
+            if kwargs.get("stream"):
+                response.raw = BufferIO(content)
+            else:
+                response.close()
 
         response = resp_callback(response) if resp_callback else response
         match.call_count += 1


Test patch:
diff --git a/responses/test_responses.py b/responses/test_responses.py
index 16b5503..f9cc629 100644
--- a/responses/test_responses.py
+++ b/responses/test_responses.py
@@ -1296,6 +1296,24 @@ def test_passthrough_response(httpserver):
         resp = requests.get(httpserver.url)
         assert_response(resp, "OK")
 
+        assert len(responses.calls) == 3
+        responses.assert_call_count(httpserver.url, 1)
+
+    run()
+    assert_reset()
+
+
+def test_passthrough_response_stream(httpserver):
+    httpserver.serve_content("OK", headers={"Content-Type": "text/plain"})
+
+    @responses.activate
+    def run():
+        responses.add(PassthroughResponse(responses.GET, httpserver.url))
+        content_1 = requests.get(httpserver.url).content
+        with requests.get(httpserver.url, stream=True) as resp:
+            content_2 = resp.raw.read()
+        assert content_1 == content_2
+
     run()
     assert_reset()