gabrielfalcao / HTTPretty

Intercept HTTP requests at the Python socket level. Fakes the whole socket module
https://httpretty.readthedocs.org
MIT License
2.11k stars 277 forks source link

When URL regex patterns conflict, there is no control over the matching order #211

Open rodrigoalmeidaee opened 9 years ago

rodrigoalmeidaee commented 9 years ago

the following sample will raise errors with 50% probability (with something like I have no entries for method POST: URLMatcher(http\:\/\/geekiepedia\.testing/learning_objects/[a-zA-Z0-9]+))

httpretty.register_uri(
    httpretty.POST,
    re.compile(prefix + r"/learning_objects/fetch"),
    body=self._search_learning_objects,
)

httpretty.register_uri(
    httpretty.GET,
    re.compile(prefix + r"/learning_objects/[a-zA-Z0-9]+"),
    body=self._get_learning_object_by_id,
)

This is counter intuitive since the routes don't actually conflict (request methods are different), but looking at the source I can see that the request method does not take in part in the matching process, and I could open an issue about that specifically.

However, there are still conflict scenarios that cannot be disambiguated by the request method itself, like:

httpretty.register_uri(
    httpretty.GET,
    re.compile(prefix + r"/learning_objects/published"),
    body=self._get_published_learning_objects,
)

httpretty.register_uri(
    httpretty.GET,
    re.compile(prefix + r"/learning_objects/[a-zA-Z0-9]+"),
    body=self._get_learning_object_by_id,
)

If we replace the _entries dict with an OrderedDict, we have control of the iteration order (the route we add first will try to be matched first) and we have our setups disambiguate between routes simply by changing the order they're added.

So we applied this hack in the end, prior to registering URIs:

httpretty.httpretty._entries = collections.OrderedDict(httpretty.httpretty._entries)

But we are wondering if this change makes sense for all users?

catskul commented 9 years ago

+1

jhorman commented 8 years ago

httpretty.register_uri does take a priority parameter which allows some control over match order, I think.