Created
February 10, 2020 13:00
-
-
Save RichardFord/ac26b726f33330c4d06d1bd3ef423e31 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import unittest | |
from urllib.parse import quote | |
def walk(k, v): | |
join_list = [] | |
for sk, sv in v.items(): | |
if isinstance(sv, dict): | |
walk(sk, sv) | |
sub_value = "{}[{}]={}".format(quote(str(k)), quote(str(sk)), quote(str(sv))) | |
join_list.append(sub_value) | |
return '&'.join(join_list) | |
def encodeUrl(params): | |
""" | |
This function is expected to return the URL encoded version of the input dictionary. | |
For example: | |
- Input: { "name": Marco, "surname": "Pracucci" } | |
- Output: "name=Marco&surname=Pracucci" | |
Reserved characters in parameter names and values should be percent encoded | |
using the `quote` function from `urllib.parse`. | |
If a nested dictionary is encountered as a paramter value, it should be encoded as | |
TOP-LEVEL-KEY[SUB-KEY]=VALUE. For example: | |
- Input: { "person": { "name": "Marco", "surname": "Pracucci" }} | |
- Output: "person[name]=Marco&person[surname]=Pracucci" | |
You are NOT allowed to use any of the other function offered by `urllib` or other | |
Python modules / libraries already implementing this functionality. | |
You ARE allowed to look for online reference whenever required. | |
""" | |
join_list = [] | |
for key, value in params.items(): | |
if isinstance(value, dict): | |
joined = walk(key, value) | |
join_list.append(joined) | |
elif value: | |
val = "{}={}".format(quote(key), quote(str(value))) | |
join_list.append(val) | |
return '&'.join(join_list) | |
class EncodeUrlTest(unittest.TestCase): | |
def testShouldEncodeEmptyParameters(self): | |
self.assertEqual(encodeUrl({}), "") | |
def testShouldEncodePlainStringParameters(self): | |
self.assertEqual(encodeUrl({ | |
"name": "Marco", | |
"surname": "Pracucci" | |
}), "name=Marco&surname=Pracucci") | |
def testShouldEncodePlainNumericParameters(self): | |
self.assertEqual(encodeUrl({ | |
"name": "Marco", | |
"surname": "Pracucci", | |
"age": 36 | |
}), "name=Marco&surname=Pracucci&age=36") | |
def testShouldEncodeWhitespacesInParameterNames(self): | |
self.assertEqual(encodeUrl({ | |
"name": "Marco", | |
"surname": "Pracucci", | |
"street address": "123" | |
}), "name=Marco&surname=Pracucci&street%20address=123") | |
def testShouldEncodeWhitespacesInParameterNamesAndValues(self): | |
self.assertEqual(encodeUrl({ | |
"name": "Marco", | |
"surname": "Pracucci", | |
"street address": "123 Main Road" | |
}), "name=Marco&surname=Pracucci&street%20address=123%20Main%20Road") | |
def testShouldEncodeNestedObjectsOnOneLevel(self): | |
self.assertEqual(encodeUrl({ | |
"name": "Marco", | |
"surname": "Pracucci", | |
"address": { | |
"street": "123 Main Road", | |
"city": "New York", | |
} | |
}), "name=Marco&surname=Pracucci&address[street]=123%20Main%20Road&address[city]=New%20York") | |
def testShouldEncodeNestedObjectsOnMultipleLevels(self): | |
self.assertEqual(encodeUrl({ | |
"name": "Marco", | |
"surname": "Pracucci", | |
"address": { | |
"street": { | |
"name": "Main Road", | |
"number": 123 | |
}, | |
"city": "New York", | |
} | |
}), "name=Marco&surname=Pracucci&address[street][name]=Main%20Road&address[street][number]=123&address[city]=New%20York") | |
def testShouldFilterOutNoneValues(self): | |
self.assertEqual(encodeUrl({ | |
"name": "Marco", | |
"surname": "Pracucci", | |
"address": None | |
}), "name=Marco&surname=Pracucci") | |
if __name__ == "__main__": | |
unittest.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment