diff --git a/zulip/tests/test_hash_util_decode.py b/zulip/tests/test_hash_util_decode.py new file mode 100644 index 0000000..fd50399 --- /dev/null +++ b/zulip/tests/test_hash_util_decode.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 + +import unittest +import zulip + +from unittest import TestCase + +class TestHashUtilDecode(TestCase): + def test_hash_util_decode(self) -> None: + tests = [ + ('topic', 'topic'), + ('.2Edot', '.dot'), + ('.23stream.20name', '#stream name'), + ('(no.20topic)', '(no topic)'), + ('.3Cstrong.3Ebold.3C.2Fstrong.3E', 'bold'), + ('.3Asome_emoji.3A', ':some_emoji:'), + ] + for encoded_string, decoded_string in tests: + with self.subTest(encoded_string=encoded_string): + self.assertEqual(zulip.hash_util_decode(encoded_string), decoded_string) + +if __name__ == '__main__': + unittest.main() diff --git a/zulip/zulip/__init__.py b/zulip/zulip/__init__.py index 3ed7168..97bedfc 100644 --- a/zulip/zulip/__init__.py +++ b/zulip/zulip/__init__.py @@ -1574,3 +1574,15 @@ class ZulipStream: def flush(self) -> None: pass + +def hash_util_decode(string: str) -> str: + """ + Returns a decoded string given a hash_util_encode() [present in zulip/zulip's zerver/lib/url_encoding.py] encoded string. + + Example usage: + >>> zulip.hash_util_decode('test.20here') + 'test here' + """ + # Acknowledge custom string replacements in zulip/zulip's zerver/lib/url_encoding.py before unquoting. + # NOTE: urllib.parse.unquote already does .replace('%2E', '.'). + return urllib.parse.unquote(string.replace('.', '%'))