Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix double-query-encoding bug #232

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion aioresponses/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def merge_params(
def normalize_url(url: 'Union[URL, str]') -> 'URL':
"""Normalize url to make comparisons."""
url = URL(url)
return url.with_query(urlencode(sorted(parse_qsl(url.query_string))))
return url.with_query(sorted(url.query.items()))


try:
Expand Down
48 changes: 46 additions & 2 deletions tests/test_compat.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
from itertools import product
from typing import Union
from unittest import TestCase

from ddt import ddt, data
from ddt import ddt, data, unpack
from yarl import URL

from aioresponses.compat import merge_params
from aioresponses.compat import merge_params, normalize_url


def get_url(url: str, as_str: bool) -> Union[URL, str]:
Expand Down Expand Up @@ -46,3 +47,46 @@ def test_base_without_params_returns_corrected_url__as_str(self, as_str):
url = get_url(self.url_without_parameters, as_str)

self.assertEqual(merge_params(url, {'x': 42}), expected_url)

@data(
*(
(original_url, expected_url, as_str)
for (original_url, expected_url), as_str
in product(
[
(
# Trivial example.
"http://example.com/api?var2=baz&var1=foo",
"http://example.com/api?var1=foo&var2=baz",
),
(
# Multi-occurrence of keys and proper query string encoding/decoding.
"https://example.com/api?var3=gaz%3Bdar&var1=foo:bar&var1=bar/baz&var2=baz%26gaz",
"https://example.com/api?var1=bar/baz&var1=foo:bar&var2=baz%26gaz&var3=gaz%3Bdar",
),
(
# Same as above, but input already encoded.
"https://example.com/api?var3=gaz%3Bdar&var1=foo%3Abar&var1=bar%2Fbaz&var2=baz%26gaz",
"https://example.com/api?var1=bar/baz&var1=foo:bar&var2=baz%26gaz&var3=gaz%3Bdar",
),
(
# Testing encoding/decoding for non-ascii characters.
"https://example.com/api?var=путь",
"https://example.com/api?var=%D0%BF%D1%83%D1%82%D1%8C",
),
(
# Same as above, but input already encoded.
"https://example.com/api?var=%D0%BF%D1%83%D1%82%D1%8C",
"https://example.com/api?var=%D0%BF%D1%83%D1%82%D1%8C",
),
],
[True, False]
)
)
)
@unpack
def test_normalize_url(self, original_url, expected_url, as_str):
original_url = get_url(original_url, as_str)
received_url = normalize_url(original_url)
assert isinstance(received_url, URL)
assert expected_url == str(received_url)