Skip to content

Commit

Permalink
fix: handle query_params tuples in JSONConnection.build_api_url (#34)
Browse files Browse the repository at this point in the history
* fix: handle query_params tuples in JSONConnection.build_api_url

The docstring says both dictionary and list of tuples are allowed,
following the signature of
[urlencode](https://docs.python.org/3.8/library/urllib.parse.html#urllib.parse.urlencode).
Discovered while investigating test regression in the
`google-cloud-translate` library.

* Update google/cloud/_http.py

Co-authored-by: Peter Lamut <plamut@users.noreply.github.com>
  • Loading branch information
tswast and plamut committed Sep 24, 2020
1 parent 20f787a commit 6a9adb3
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
12 changes: 10 additions & 2 deletions google/cloud/_http.py
Expand Up @@ -14,11 +14,13 @@

"""Shared implementation of connections to API servers."""

import collections
import json
import platform
import warnings

from pkg_resources import get_distribution
from six.moves import collections_abc
from six.moves.urllib.parse import urlencode

from google.api_core.client_info import ClientInfo
Expand Down Expand Up @@ -212,9 +214,15 @@ def build_api_url(

query_params = query_params or {}

if "prettyPrint" not in query_params:
if isinstance(query_params, collections_abc.Mapping):
query_params = query_params.copy()
query_params["prettyPrint"] = "false"
else:
query_params_dict = collections.defaultdict(list)
for key, value in query_params:
query_params_dict[key].append(value)
query_params = query_params_dict

query_params.setdefault("prettyPrint", "false")

url += "?" + urlencode(query_params, doseq=True)

Expand Down
19 changes: 19 additions & 0 deletions tests/unit/test__http.py
Expand Up @@ -210,6 +210,25 @@ def test_build_api_url_w_extra_query_params(self):
parms = dict(parse_qs(qs))
self.assertEqual(parms["bar"], ["baz"])
self.assertEqual(parms["qux"], ["quux", "corge"])
self.assertEqual(parms["prettyPrint"], ["false"])

def test_build_api_url_w_extra_query_params_tuples(self):
from six.moves.urllib.parse import parse_qs
from six.moves.urllib.parse import urlsplit

client = object()
conn = self._make_mock_one(client)
uri = conn.build_api_url("/foo", [("bar", "baz"), ("qux", "quux"), ("qux", "corge")])

scheme, netloc, path, qs, _ = urlsplit(uri)
self.assertEqual("%s://%s" % (scheme, netloc), conn.API_BASE_URL)
# Intended to emulate mock_template
PATH = "/".join(["", "mock", conn.API_VERSION, "foo"])
self.assertEqual(path, PATH)
parms = dict(parse_qs(qs))
self.assertEqual(parms["bar"], ["baz"])
self.assertEqual(parms["qux"], ["quux", "corge"])
self.assertEqual(parms["prettyPrint"], ["false"])

def test__make_request_no_data_no_content_type_no_headers(self):
from google.cloud._http import CLIENT_INFO_HEADER
Expand Down

0 comments on commit 6a9adb3

Please sign in to comment.