Skip to content

Commit e9cf9b8

Browse files
Merge pull request #7 from sebastienrousseauhsbc/main
Add unit tests and documentation for helper modules
2 parents 196efac + 7e43317 commit e9cf9b8

20 files changed

+785
-25
lines changed

encryption_helper/common/strings.py

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,30 @@
1-
private_key_suffix = 'private-key.pem'
2-
public_key_suffix = 'public_key.pem'
3-
encrypted_file_suffix = '.bin'
1+
"""
2+
Strings module for the encryption_helper package.
3+
4+
This module provides a collection of string constants used throughout the
5+
encryption_helper package. These constants include file suffixes for various
6+
key and encrypted file types.
7+
8+
Attributes:
9+
private_key_suffix (str): The file suffix for private key files.
10+
public_key_suffix (str): The file suffix for public key files.
11+
encrypted_file_suffix (str): The file suffix for encrypted files.
12+
"""
13+
14+
private_key_suffix = "private-key.pem"
15+
"""
16+
str: The file suffix for private key files.
17+
"""
18+
19+
public_key_suffix = "public_key.pem"
20+
"""
21+
str: The file suffix for public key files.
22+
"""
23+
24+
encrypted_file_suffix = ".bin"
25+
"""
26+
str: The file suffix for encrypted files.
27+
"""
28+
29+
# The module defines string constants for use in the encryption_helper package.
30+
# These constants help standardize file naming conventions across the package.

encryption_helper/context/context.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
"""
2-
context.py
2+
Context module for the encryption_helper package.
33
44
This module provides a Context class for managing application-wide settings and logging.
55
It implements the Singleton pattern to ensure only one instance of the context exists.
6+
7+
Classes:
8+
Context: A singleton class for managing application context and logging.
69
"""
710

811
import logging
Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,41 @@
1+
"""
2+
Checks module for the encryption_helper package.
3+
4+
This module provides utility functions to validate input strings. It includes
5+
functions to check if strings are `None` or empty.
6+
7+
Functions:
8+
str_none_or_empty: Checks if one or more input strings are `None` or empty.
9+
"""
10+
11+
112
def str_none_or_empty(*argv):
13+
"""
14+
Check if one or more input strings are `None` or empty.
15+
16+
This function takes a variable number of string arguments and checks each
17+
one to determine if it is either `None` or an empty string (including strings
18+
that are only whitespace).
19+
20+
Args:
21+
*argv: A variable number of string arguments to be checked.
22+
23+
Returns:
24+
bool: `True` if any of the input strings is `None` or empty; otherwise `False`.
25+
26+
Examples:
27+
>>> str_none_or_empty('test', 'hello', 'world')
28+
False
29+
>>> str_none_or_empty('test', None, 'world')
30+
True
31+
>>> str_none_or_empty('test', '', 'world')
32+
True
33+
>>> str_none_or_empty('test', ' ', 'world')
34+
True
35+
>>> str_none_or_empty()
36+
False
37+
"""
238
for arg in argv:
3-
if arg is None or len(arg.strip()) == 0:
39+
if arg is None or not isinstance(arg, str) or len(arg.strip()) == 0:
440
return True
541
return False
Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,77 @@
1+
"""
2+
Read File module for the encryption_helper package.
3+
4+
This module provides functions to read text files in binary mode. It includes
5+
functions to read files given a directory and file name or an absolute file path.
6+
7+
Functions:
8+
read_text_in_binary_mode: Reads a file in binary mode given a directory and file name.
9+
read_text_in_binary_mode_abs: Reads a file in binary mode given an absolute file path.
10+
"""
11+
112
import os
2-
from rsa.utils.checks import checks
3-
from rsa.context import context
13+
from encryption_helper.utils.checks import checks
14+
from encryption_helper.context import context
415

516

617
def read_text_in_binary_mode(directory, file_name):
7-
logger = context.Context.getinstance().get_logger()
18+
"""
19+
Read a file in binary mode given a directory and file name.
20+
21+
This function constructs the absolute file path from the given directory and file name,
22+
checks if the inputs are valid, and reads the file in binary mode.
23+
24+
Args:
25+
directory (str): The directory containing the file.
26+
file_name (str): The name of the file to be read.
27+
28+
Returns:
29+
bytes: The contents of the file in binary mode.
30+
31+
Raises:
32+
Exception: If one or more arguments are empty.
33+
OSError: If there is an error reading the file.
34+
35+
Examples:
36+
>>> data = read_text_in_binary_mode('path/to/dir', 'file.txt')
37+
>>> print(data)
38+
39+
"""
40+
logger = context.Context.get_instance().get_logger()
841
if checks.str_none_or_empty(directory, file_name):
9-
logger.exception('One or more arguments are empty')
10-
raise Exception('One or more arguments are empty')
42+
logger.exception("One or more arguments are empty")
43+
raise Exception("One or more arguments are empty")
1144

1245
absolute_file_path = os.path.join(directory, file_name)
1346
return read_text_in_binary_mode_abs(absolute_file_path)
1447

1548

1649
def read_text_in_binary_mode_abs(absolute_file_path):
17-
logger = context.Context.getinstance().get_logger()
50+
"""
51+
Read a file in binary mode given an absolute file path.
52+
53+
This function checks if the input is valid and reads the file in binary mode.
54+
55+
Args:
56+
absolute_file_path (str): The absolute path to the file to be read.
57+
58+
Returns:
59+
bytes: The contents of the file in binary mode.
60+
61+
Raises:
62+
Exception: If the argument is empty.
63+
OSError: If there is an error reading the file.
64+
65+
Examples:
66+
>>> data = read_text_in_binary_mode_abs('/path/to/dir/file.txt')
67+
>>> print(data)
68+
69+
"""
70+
logger = context.Context.get_instance().get_logger()
1871
if checks.str_none_or_empty(absolute_file_path):
19-
logger.exception('One or more arguments are empty')
20-
raise Exception('One or more arguments are empty')
72+
logger.exception("One or more arguments are empty")
73+
raise Exception("One or more arguments are empty")
2174

22-
logger.info('Reading from file : {0}'.format(absolute_file_path))
75+
logger.info("Reading from file : {0}".format(absolute_file_path))
2376
with open(absolute_file_path, "rb") as f:
2477
return f.read()
Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,82 @@
1-
from rsa.utils.checks import checks
2-
from rsa.context import context
1+
"""
2+
Write File module for the encryption_helper package.
3+
4+
This module provides functions to write text files in binary mode. It includes
5+
functions to write files given a directory and file name or an absolute file path.
6+
7+
Functions:
8+
write_text_in_binary_mode: Writes text to a file in binary mode given a directory and file name.
9+
write_text_in_binary_mode_abs: Writes text to a file in binary mode given an absolute file path.
10+
"""
11+
312
import os
13+
from encryption_helper.utils.checks import checks
14+
from encryption_helper.context import context
415

516

617
def write_text_in_binary_mode(directory, file_name, text):
7-
logger = context.Context.getinstance().get_logger()
18+
"""
19+
Write text to a file in binary mode given a directory and file name.
20+
21+
This function constructs the absolute file path from the given directory and file name,
22+
checks if the inputs are valid, and writes the text to the file in binary mode.
23+
24+
Args:
25+
directory (str): The directory containing the file.
26+
file_name (str): The name of the file to be written.
27+
text (bytes): The text to be written to the file.
28+
29+
Returns:
30+
str: The absolute file path of the written file.
31+
32+
Raises:
33+
Exception: If one or more arguments are empty.
34+
OSError: If there is an error writing to the file.
35+
36+
Examples:
37+
>>> path = write_text_in_binary_mode('path/to/dir', 'file.txt', b'test data')
38+
>>> print(path)
39+
40+
"""
41+
logger = context.Context.get_instance().get_logger()
842
if checks.str_none_or_empty(directory, file_name, text):
9-
logger.exception('One or more arguments are empty')
10-
raise Exception('One or more arguments are empty')
43+
logger.exception("One or more arguments are empty")
44+
raise Exception("One or more arguments are empty")
1145

1246
absolute_file_path = os.path.join(directory, file_name)
1347
return write_text_in_binary_mode_abs(absolute_file_path, text)
1448

1549

1650
def write_text_in_binary_mode_abs(absolute_file_path, text):
17-
logger = context.Context.getinstance().get_logger()
51+
"""
52+
Write text to a file in binary mode given an absolute file path.
53+
54+
This function checks if the inputs are valid and writes the text to the file in binary mode.
55+
56+
Args:
57+
absolute_file_path (str): The absolute path to the file to be written.
58+
text (bytes): The text to be written to the file.
59+
60+
Returns:
61+
str: The absolute file path of the written file.
62+
63+
Raises:
64+
Exception: If one or more arguments are empty.
65+
OSError: If there is an error writing to the file.
66+
67+
Examples:
68+
>>> path = write_text_in_binary_mode_abs('/path/to/dir/file.txt', b'test data')
69+
>>> print(path)
70+
71+
"""
72+
logger = context.Context.get_instance().get_logger()
1873
if checks.str_none_or_empty(absolute_file_path, text):
19-
logger.exception('One or more arguments are empty')
20-
raise Exception('One or more arguments are empty')
74+
logger.exception("One or more arguments are empty")
75+
raise Exception("One or more arguments are empty")
2176

22-
logger.info('Writing to file : {0}'.format(absolute_file_path))
23-
with open(absolute_file_path, 'wb') as f:
77+
logger.info("Writing to file : {0}".format(absolute_file_path))
78+
with open(absolute_file_path, "wb") as f:
2479
f.write(text)
25-
logger.info('Writing to file complete')
80+
logger.info("Writing to file complete")
2681

2782
return absolute_file_path

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pycryptodome = "^3.20.0"
2525

2626
[tool.poetry.dev-dependencies]
2727
pytest = "^8.3.2"
28+
pytest-mock = "^3.14.0"
2829

2930
[tool.poetry.scripts]
3031
encryption-helper = "encryption_helper.__main__:main"

tests/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# tests/__init__.py
2+
3+
# This file can be left empty, but it must exist to make Python treat the
4+
# directory as a package, which is necessary for relative imports.

tests/common/__init__.py

Whitespace-only changes.

tests/common/test_strings.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import unittest
2+
from encryption_helper.common.strings import (
3+
private_key_suffix,
4+
public_key_suffix,
5+
encrypted_file_suffix,
6+
)
7+
8+
9+
class TestStrings(unittest.TestCase):
10+
11+
def test_private_key_suffix(self):
12+
# Test the private key suffix
13+
self.assertEqual(private_key_suffix, "private-key.pem")
14+
15+
def test_public_key_suffix(self):
16+
# Test the public key suffix
17+
self.assertEqual(public_key_suffix, "public_key.pem")
18+
19+
def test_encrypted_file_suffix(self):
20+
# Test the encrypted file suffix
21+
self.assertEqual(encrypted_file_suffix, ".bin")
22+
23+
24+
if __name__ == "__main__":
25+
unittest.main()

tests/context/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)