getsentry/responses

Responses lacks support for escaped <-> unescaped matching

jcampbell05 opened this issue · 4 comments

Describe the bug

If a request makes a request to a path that has been escaped but your responses mock uses an unescaped request, it will fail.

Currently we have to manually escape the url being passed to the responses mock, which creates more boilerplate as we also have to specify the safe characters each time and it also makes failed matches less readable as responses will list a bunch of mocked urls with escaped characters.

Additional context

No response

Version of responses

0.23.1

Steps to Reproduce

Run this in pytest, you will get an exception

import responses
import requests

@responsed.activate
def test_request():

            invoices_response = responses.Response(
                method="GET",
                url="http://hello.cominvoices?customer_id[iis]=fake_customer&offset=&limit=20")
            responses.add(invoices_response)
            requests.get("http://hello.cominvoices?customer_id%5Bis%5D=fake_customer&offset=&limit=20")

But this works

import responses
import requests
import urllib

@responsed.activate
def test_request():

            invoices_response = responses.Response(
                method="GET",
                url=urllib.parse.quote("http://hello.cominvoices?customer_id%5Bis%5D=fake_customer&offset=&limit=20", safe='/:&?='))
            responses.add(invoices_response)
            requests.get("http://hello.cominvoices?customer_id%5Bis%5D=fake_customer&offset=&limit=20")

Expected Result

Response should have a build in method for requesting it to escape requested URLs back to their human readable form.

This could simply be handled by adding a escape attribute to the Response that would allow provided urls to automatically be escaped and in additional potentially allow urls sent by requests to be unescaped when logged.

Actual Result

It doesn't transform them to an unescaped format.

From examples you submitted I assume by "escaped" you mean percent encoded?

Yes exactly. At the moment one has to maintain a percent encoded mock and have to parse a list of percent encoded mocks in order to verify why the responses library is indicating a percent encoded request hasn't been mocked.

it looks like your code is invalid
there is a difference between iis and is

import responses
import requests

@responses.activate
def test_request():
    invoices_response = responses.Response(
        method="GET",
        url="http://hello.cominvoices?customer_id[iis]=fake_customer&offset=&limit=20")
    responses.add(invoices_response)
    requests.get("http://hello.cominvoices?customer_id%5Biis%5D=fake_customer&offset=&limit=20")

@jcampbell05
also, please do not use query as part of the URL, it is better in query matcher: https://github.com/getsentry/responses#query-parameters-as-a-dictionary

if you see that it fails with matcher, pls file another issue