From 514dc3256abebfceff2d98fb2fde2f261016d925 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Sat, 28 Jun 2025 19:48:44 -0400 Subject: [PATCH] Add unit tests and update docs --- README.md | 9 ++++++ src/requirements.txt | 4 ++- src/tests/test_fingerprint_encryption.py | 38 ++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/tests/test_fingerprint_encryption.py diff --git a/README.md b/README.md index be25cef..2de6008 100644 --- a/README.md +++ b/README.md @@ -159,6 +159,15 @@ SeedPass allows you to manage multiple seed profiles (previously referred to as **Note:** The term "seed profile" is used to represent different sets of seeds you can manage within SeedPass. This provides an intuitive way to handle multiple identities or sets of passwords. +## Running Tests + +SeedPass includes a small suite of unit tests. After activating your virtual environment and installing dependencies, run the tests with **pytest**: + +```bash +pip install -r requirements.txt +pytest +``` + ## Security Considerations **Important:** The password you use to encrypt your parent seed is also required to decrypt the seed index data retrieved from Nostr. **It is imperative to remember this password** and be sure to use it with the same seed, as losing it means you won't be able to access your stored index. Secure your 12-word seed **and** your master password. diff --git a/src/requirements.txt b/src/requirements.txt index 13bbf9c..5042da5 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -7,4 +7,6 @@ monstr @ git+https://github.com/monty888/monstr.git@master#egg=monstr mnemonic aiohttp bcrypt -bip85 \ No newline at end of file +bip85 +pytest>=7.0 + diff --git a/src/tests/test_fingerprint_encryption.py b/src/tests/test_fingerprint_encryption.py new file mode 100644 index 0000000..c871dea --- /dev/null +++ b/src/tests/test_fingerprint_encryption.py @@ -0,0 +1,38 @@ +import hashlib +import sys +from pathlib import Path +from tempfile import TemporaryDirectory + +from cryptography.fernet import Fernet + +sys.path.append(str(Path(__file__).resolve().parents[1])) + +from utils.fingerprint import generate_fingerprint +from password_manager.encryption import EncryptionManager + + +def test_generate_fingerprint_deterministic(): + seed = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" + expected = ( + hashlib.sha256(seed.strip().lower().encode("utf-8")).hexdigest()[:16].upper() + ) + fp1 = generate_fingerprint(seed) + fp2 = generate_fingerprint(seed.upper()) + assert fp1 == expected + assert fp1 == fp2 + + +def test_encryption_round_trip(): + with TemporaryDirectory() as tmpdir: + key = Fernet.generate_key() + manager = EncryptionManager(key, Path(tmpdir)) + data = b"secret data" + rel_path = Path("testfile.enc") + manager.encrypt_and_save_file(data, rel_path) + decrypted = manager.decrypt_file(rel_path) + assert decrypted == data + + # parent seed round trip + seed = "correct horse battery staple" + manager.encrypt_parent_seed(seed) + assert manager.decrypt_parent_seed() == seed