From e57a9b85eff71056f4f0efa2a3b5fb36dd2fc399 Mon Sep 17 00:00:00 2001 From: Finn-Thorben Sell Date: Thu, 24 Mar 2022 14:37:22 +0100 Subject: [PATCH] add tests for example generators --- configurations/example_generators.py | 22 ++++++++++++++----- tests/test_example_generators.py | 32 ++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 tests/test_example_generators.py diff --git a/configurations/example_generators.py b/configurations/example_generators.py index e52983c..f0833aa 100644 --- a/configurations/example_generators.py +++ b/configurations/example_generators.py @@ -1,8 +1,17 @@ from typing import Callable import secrets import base64 + +import django from django.core.management.utils import get_random_secret_key -from django.utils.crypto import get_random_string, RANDOM_STRING_CHARS +from django.utils.crypto import get_random_string + +if django.VERSION[0] > 3 or \ + (django.VERSION[0] == 3 and django.VERSION[1] >= 2): + # RANDOM_STRING_CHARS was only introduced in django 3.2 + from django.utils.crypto import RANDOM_STRING_CHARS +else: + RANDOM_STRING_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" def gen_django_secret_key() -> str: @@ -17,9 +26,11 @@ def gen_random_string(length: int, allowed_chars: str = RANDOM_STRING_CHARS) -> Create a parameterized generator which generates a cryptographically secure random string of the given length containing the given characters. """ - def generate() -> str: + + def _gen_random_string() -> str: return get_random_string(length, allowed_chars) - return generate + + return _gen_random_string def gen_bytes(length: int, encoding: str) -> Callable[[], str]: @@ -36,7 +47,7 @@ def gen_bytes(length: int, encoding: str) -> Callable[[], str]: raise ValueError(f"Cannot gen_bytes with encoding '{encoding}'. Valid encodings are 'base64', 'base64_urlsafe'" f" and 'hex'") - def generate() -> str: + def _gen_bytes() -> str: b = secrets.token_bytes(length) if encoding == "base64": return base64.standard_b64encode(b).decode("ASCII") @@ -44,4 +55,5 @@ def generate() -> str: return base64.urlsafe_b64encode(b).decode("ASCII") elif encoding == "hex": return b.hex().upper() - return generate + + return _gen_bytes diff --git a/tests/test_example_generators.py b/tests/test_example_generators.py new file mode 100644 index 0000000..4e916a1 --- /dev/null +++ b/tests/test_example_generators.py @@ -0,0 +1,32 @@ +import base64 +from django.test import TestCase +from configurations.example_generators import gen_bytes, gen_random_string, gen_django_secret_key + + +class ExampleGeneratorsTestCase(TestCase): + def test_generators_dont_raise_exceptions(self): + for gen in [gen_bytes(64, "hex"), gen_bytes(64, "base64"), gen_bytes(64, "base64_urlsafe"), + gen_random_string(16, "ab"), gen_random_string(5), + gen_django_secret_key]: + with self.subTest(gen.__name__): + gen() + + # gen_django_secret_key() and gen_random_string() are not tested beyond the above general test case + # because they are just wrappers around existing django utilities. + # They are thus assumed to work. + + def test_gen_bytes(self): + with self.subTest("base64"): + result = gen_bytes(64, "base64")() + b = base64.standard_b64decode(result.encode("ASCII")) + self.assertEqual(len(b), 64) + + with self.subTest("base64_urlsafe"): + result = gen_bytes(64, "base64_urlsafe")() + b = base64.urlsafe_b64decode(result.encode("ASCII")) + self.assertEqual(len(b), 64) + + with self.subTest("hex"): + result = gen_bytes(64, "hex")() + b = bytes.fromhex(result) + self.assertEqual(len(b), 64)