Skip to content

Commit 751a384

Browse files
authored
Refactor tests to use to_bytes() instead of temp files (#73)
Convert tests that don't need file-based operations to use to_bytes()/open_bytes() for in-memory roundtrips: - test_kdf_config.py: All tests converted - test_cipher_config.py: All tests converted - test_field_references.py: Roundtrip test converted - test_twofish.py: Removed redundant file-based test that duplicated test_to_bytes_roundtrip, converted test_modify_and_resave Tests that explicitly verify file I/O behavior (reload, save, open_interactive, dump_xml, create_keyfile, KDBX3 upgrade confirmation) retain tempfile usage as intended. Closes #67
1 parent d442edc commit 751a384

File tree

4 files changed

+101
-308
lines changed

4 files changed

+101
-308
lines changed

tests/test_cipher_config.py

Lines changed: 34 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Tests for cipher configuration on save."""
22

3-
import tempfile
3+
import warnings
44
from pathlib import Path
55

66
import pytest
@@ -16,43 +16,25 @@ def test_save_with_chacha20(self) -> None:
1616
db = Database.create(password="test")
1717
db.root_group.create_entry(title="Test")
1818

19-
with tempfile.NamedTemporaryFile(suffix=".kdbx", delete=False) as f:
20-
filepath = Path(f.name)
21-
22-
try:
23-
db.save(filepath=filepath, cipher=Cipher.CHACHA20)
24-
25-
# Verify we can reopen and cipher was changed
26-
db2 = Database.open(filepath, password="test")
27-
assert db2.find_entries(title="Test", first=True) is not None
28-
finally:
29-
filepath.unlink(missing_ok=True)
19+
data = db.to_bytes(cipher=Cipher.CHACHA20)
20+
db2 = Database.open_bytes(data, password="test")
21+
assert db2.find_entries(title="Test", first=True) is not None
3022

3123
def test_save_with_aes256(self) -> None:
3224
"""Test saving with AES-256-CBC cipher."""
3325
db = Database.create(password="test")
3426
db.root_group.create_entry(title="Test")
3527

36-
with tempfile.NamedTemporaryFile(suffix=".kdbx", delete=False) as f:
37-
filepath = Path(f.name)
38-
39-
try:
40-
db.save(filepath=filepath, cipher=Cipher.AES256_CBC)
41-
42-
# Verify we can reopen
43-
db2 = Database.open(filepath, password="test")
44-
assert db2.find_entries(title="Test", first=True) is not None
45-
finally:
46-
filepath.unlink(missing_ok=True)
28+
data = db.to_bytes(cipher=Cipher.AES256_CBC)
29+
db2 = Database.open_bytes(data, password="test")
30+
assert db2.find_entries(title="Test", first=True) is not None
4731

4832
def test_to_bytes_with_chacha20(self) -> None:
4933
"""Test to_bytes() with ChaCha20 cipher."""
5034
db = Database.create(password="test")
5135
db.root_group.create_entry(title="Test")
5236

5337
data = db.to_bytes(cipher=Cipher.CHACHA20)
54-
55-
# Verify we can reopen from bytes
5638
db2 = Database.open_bytes(data, password="test")
5739
assert db2.find_entries(title="Test", first=True) is not None
5840

@@ -68,106 +50,56 @@ def test_change_cipher_preserves_data(self) -> None:
6850
)
6951
entry.set_custom_property("custom_key", "custom_value")
7052

71-
with tempfile.NamedTemporaryFile(suffix=".kdbx", delete=False) as f:
72-
filepath = Path(f.name)
73-
74-
try:
75-
# Save with different cipher
76-
db.save(filepath=filepath, cipher=Cipher.CHACHA20)
77-
78-
# Reopen and verify all data
79-
db2 = Database.open(filepath, password="test")
80-
entry2 = db2.find_entries(title="Important", first=True)
81-
assert entry2 is not None
82-
assert entry2.username == "[email protected]"
83-
assert entry2.password == "secret123"
84-
assert entry2.url == "https://example.com"
85-
assert entry2.notes == "Some notes here"
86-
assert entry2.get_custom_property("custom_key") == "custom_value"
87-
finally:
88-
filepath.unlink(missing_ok=True)
53+
data = db.to_bytes(cipher=Cipher.CHACHA20)
54+
db2 = Database.open_bytes(data, password="test")
55+
entry2 = db2.find_entries(title="Important", first=True)
56+
assert entry2 is not None
57+
assert entry2.username == "[email protected]"
58+
assert entry2.password == "secret123"
59+
assert entry2.url == "https://example.com"
60+
assert entry2.notes == "Some notes here"
61+
assert entry2.get_custom_property("custom_key") == "custom_value"
8962

9063
def test_cipher_with_kdf_config(self) -> None:
9164
"""Test using both cipher and kdf_config together."""
9265
db = Database.create(password="test")
9366
db.root_group.create_entry(title="Test")
9467

95-
with tempfile.NamedTemporaryFile(suffix=".kdbx", delete=False) as f:
96-
filepath = Path(f.name)
97-
98-
try:
99-
db.save(
100-
filepath=filepath,
101-
cipher=Cipher.CHACHA20,
102-
kdf_config=Argon2Config.fast(),
103-
)
104-
105-
# Verify we can reopen
106-
db2 = Database.open(filepath, password="test")
107-
assert db2.find_entries(title="Test", first=True) is not None
108-
finally:
109-
filepath.unlink(missing_ok=True)
68+
data = db.to_bytes(cipher=Cipher.CHACHA20, kdf_config=Argon2Config.fast())
69+
db2 = Database.open_bytes(data, password="test")
70+
assert db2.find_entries(title="Test", first=True) is not None
11071

11172

11273
class TestCipherConfigOnUpgrade:
11374
"""Tests for using cipher parameter during KDBX3 upgrade."""
11475

11576
def test_kdbx3_upgrade_with_chacha20(self) -> None:
11677
"""Test KDBX3 upgrade with ChaCha20 cipher."""
117-
import warnings
118-
11978
test_file = Path(__file__).parent / "fixtures" / "test3.kdbx"
12079
test_key = Path(__file__).parent / "fixtures" / "test3.key"
80+
keyfile_data = test_key.read_bytes()
12181

122-
with tempfile.NamedTemporaryFile(suffix=".kdbx", delete=False) as f:
123-
temp_path = Path(f.name)
124-
125-
try:
126-
with warnings.catch_warnings():
127-
warnings.simplefilter("ignore")
128-
db = Database.open(test_file, password="password", keyfile=test_key)
129-
130-
# Upgrade with ChaCha20 cipher
131-
db.save(
132-
filepath=temp_path,
133-
allow_upgrade=True,
134-
cipher=Cipher.CHACHA20,
135-
kdf_config=Argon2Config.fast(),
136-
)
82+
with warnings.catch_warnings():
83+
warnings.simplefilter("ignore")
84+
db = Database.open(test_file, password="password", keyfile=test_key)
13785

138-
# Verify the file was saved and can be reopened
139-
db2 = Database.open(temp_path, password="password", keyfile=test_key)
140-
assert db2.root_group is not None
141-
finally:
142-
temp_path.unlink(missing_ok=True)
86+
data = db.to_bytes(cipher=Cipher.CHACHA20, kdf_config=Argon2Config.fast())
87+
db2 = Database.open_bytes(data, password="password", keyfile_data=keyfile_data)
88+
assert db2.root_group is not None
14389

14490
def test_kdbx3_upgrade_preserves_default_cipher(self) -> None:
14591
"""Test KDBX3 upgrade preserves original cipher if none specified."""
146-
import warnings
147-
14892
test_file = Path(__file__).parent / "fixtures" / "test3.kdbx"
14993
test_key = Path(__file__).parent / "fixtures" / "test3.key"
94+
keyfile_data = test_key.read_bytes()
95+
96+
with warnings.catch_warnings():
97+
warnings.simplefilter("ignore")
98+
db = Database.open(test_file, password="password", keyfile=test_key)
15099

151-
with tempfile.NamedTemporaryFile(suffix=".kdbx", delete=False) as f:
152-
temp_path = Path(f.name)
153-
154-
try:
155-
with warnings.catch_warnings():
156-
warnings.simplefilter("ignore")
157-
db = Database.open(test_file, password="password", keyfile=test_key)
158-
159-
# Upgrade without specifying cipher (should preserve existing)
160-
db.save(
161-
filepath=temp_path,
162-
allow_upgrade=True,
163-
kdf_config=Argon2Config.fast(),
164-
)
165-
166-
# Verify file exists and can be opened
167-
db2 = Database.open(temp_path, password="password", keyfile=test_key)
168-
assert db2.root_group is not None
169-
finally:
170-
temp_path.unlink(missing_ok=True)
100+
data = db.to_bytes(kdf_config=Argon2Config.fast())
101+
db2 = Database.open_bytes(data, password="password", keyfile_data=keyfile_data)
102+
assert db2.root_group is not None
171103

172104

173105
class TestCipherEnum:

tests/test_field_references.py

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -283,11 +283,6 @@ class TestFieldReferenceRoundtrip:
283283

284284
def test_reference_survives_save_reload(self) -> None:
285285
"""Test that references survive save and reload."""
286-
import tempfile
287-
from pathlib import Path
288-
289-
from kdbxtool import Argon2Config
290-
291286
db = Database.create(password="test")
292287
main_entry = db.root_group.create_entry(
293288
title="Main",
@@ -298,24 +293,17 @@ def test_reference_survives_save_reload(self) -> None:
298293
password=main_entry.ref("password"),
299294
)
300295

301-
with tempfile.NamedTemporaryFile(suffix=".kdbx", delete=False) as f:
302-
filepath = Path(f.name)
303-
304-
try:
305-
db.save(filepath=filepath, kdf_config=Argon2Config.fast())
296+
data = db.to_bytes()
297+
db2 = Database.open_bytes(data, password="test")
306298

307-
# Reload and verify
308-
db2 = Database.open(filepath, password="test")
309-
ref_entry2 = db2.find_entries(title="Reference", first=True)
310-
assert ref_entry2 is not None
299+
ref_entry2 = db2.find_entries(title="Reference", first=True)
300+
assert ref_entry2 is not None
311301

312-
# Raw value should still be the reference
313-
assert "{REF:" in ref_entry2.password
302+
# Raw value should still be the reference
303+
assert "{REF:" in ref_entry2.password
314304

315-
# Deref should still resolve
316-
assert ref_entry2.deref("password") == "original_password"
317-
finally:
318-
filepath.unlink(missing_ok=True)
305+
# Deref should still resolve
306+
assert ref_entry2.deref("password") == "original_password"
319307

320308
def test_update_original_affects_reference(self) -> None:
321309
"""Test that updating original entry affects referenced values."""

0 commit comments

Comments
 (0)