Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add decrypt files tests #19

Merged
merged 13 commits into from
Jul 17, 2024
Binary file added inputs/hello2.c4gh
Binary file not shown.
67 changes: 64 additions & 3 deletions tests/decryption/test_decrypt.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
"""Tests for decrypt.py"""
from pathlib import Path
from tempfile import NamedTemporaryFile
import shutil

from crypt4gh.keys import get_private_key as get_sk_bytes, get_public_key as get_pk_bytes
from crypt4gh.lib import encrypt
import pytest

from crypt4gh.keys import get_private_key as get_pk_bytes
from decrypt import get_private_keys
from crypt4gh_middleware.decrypt import get_private_keys, decrypt_files

INPUT_DIR = Path(__file__).parents[2]/"inputs"
INPUT_TEXT = "hello world from the input!"


class TestGetPrivateKeys:
Expand All @@ -31,7 +36,63 @@ def test_get_keys(self, files, expected_keys_retrieved):
Ensure that `get_private_keys` gets only private keys from a list of files.
"""
def get_expected_bytes():
return [get_pk_bytes(INPUT_DIR/filename, callback=lambda x: '')
return [get_sk_bytes(INPUT_DIR/filename, callback=lambda x: '')
for filename in expected_keys_retrieved]

assert get_private_keys([INPUT_DIR/file for file in files]) == get_expected_bytes()


class TestDecryptFiles:
"""Test decrypt_files."""

@pytest.fixture()
def key_pair(self):
"""Returns the key pair used to encrypt the input files."""
return INPUT_DIR/"alice.sec", INPUT_DIR/"alice.pub"

@pytest.fixture()
def key_pair_bytes(self, key_pair):
"""Returns the bytes of the key pair."""
sk, pk = key_pair
sk_bytes = get_sk_bytes(filepath=sk, callback=lambda x: '')
pk_bytes = get_pk_bytes(filepath=pk)
return sk_bytes, pk_bytes

@pytest.fixture()
def encrypted_files(self, key_pair_bytes):
"""Returns the encrypted file paths and re-encrypts files after use."""
athith-g marked this conversation as resolved.
Show resolved Hide resolved
encrypted_files = [INPUT_DIR/"hello.c4gh", INPUT_DIR/"hello2.c4gh"]
yield encrypted_files
# Re-encrypt files after decryption to ensure files are encrypted for each test
sk, pk = key_pair_bytes
for file_path in encrypted_files:
with open(file_path, "rb") as f_in, NamedTemporaryFile() as f_out:
encrypt(keys=[(0, sk, pk)], infile=f_in, outfile=f_out)
shutil.move(f_out.name, file_path)

@pytest.fixture()
def unencrypted_files(self):
"""Returns the unencrypted file paths"""
return [INPUT_DIR/"hello.txt"]

@pytest.mark.parametrize("files", ["encrypted_files", "unencrypted_files", []])
def test_decrypt_files_handles_encrypted_and_unencrypted_files(self, files, key_pair_bytes, request):
"""Test that decrypt_files decrypts only encrypted files in-place.

Ensure no exception is thrown when attempting to decrypt unencrypted files.
athith-g marked this conversation as resolved.
Show resolved Hide resolved
"""
# Handles fixture arguments
if isinstance(files, str):
athith-g marked this conversation as resolved.
Show resolved Hide resolved
files = request.getfixturevalue(files)

for file_path in files:
assert file_path.exists()

decrypt_files(file_paths=files,
private_keys=[key_pair_bytes[0]])

for file_path in files:
athith-g marked this conversation as resolved.
Show resolved Hide resolved
assert file_path.exists()
with open(file_path, encoding="utf-8") as f:
output = f.read()
assert output == INPUT_TEXT