Skip to content

Conversation

@caspervonb
Copy link
Collaborator

No description provided.

@caspervonb caspervonb requested a review from Copilot November 4, 2025 12:40
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR migrates the nkeys test suite from unittest to pytest, modernizing the testing framework and adopting pytest idioms. The migration reduces code complexity by eliminating boilerplate test class structures while maintaining test coverage.

  • Converted all unittest-based tests to standalone pytest functions
  • Introduced a parameterized pytest fixture for prefix bytes testing
  • Simplified assertions using pytest's native assert statements

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
tests/nkeys_test.py Converted all test methods from unittest.TestCase classes to standalone pytest functions, replaced unittest assertions with native assert statements, and refactored the roundtrip seed encoding test to use a pytest fixture
tests/conftest.py Added pytest configuration file with a parameterized fixture for prefix bytes used in seed encoding tests

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +69 to +71
with pytest.raises(nkeys.ErrInvalidPrefixByte):
for seed in seeds:
nkeys.from_seed(bytearray(seed.encode()))

def test_from_seed_keypair_invalid_public_prefix_byte(self):
seeds = [
b'SBAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU',
b'SDAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU',
b'PWAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU',
b'PMAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU'
]
with self.assertRaises(nkeys.ErrInvalidPrefixByte):
for seed in seeds:
nkeys.from_seed(bytearray(seed))

def test_keypair_wipe(self):
seed = "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU"
kp = nkeys.from_seed(bytearray(seed.encode()))
self.assertTrue(kp._keys is not None)

kp.wipe()
with self.assertRaises(AttributeError):
kp._keys
with self.assertRaises(AttributeError):
kp._seed

def test_keypair_public_key(self):
seed = "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU"
encoded_seed = bytearray(seed.encode())
kp = nkeys.from_seed(encoded_seed)

self.assertEqual(None, kp._public_key)
self.assertEqual(
"UCK5N7N66OBOINFXAYC2ACJQYFSOD4VYNU6APEJTAVFZB2SVHLKGEW7L",
kp.public_key
)

# Confirm that the public key is wiped as well.
kp.wipe()
with self.assertRaises(AttributeError):
kp._public_key

def test_keypair_use_seed_to_verify_signature(self):
seed = "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU"
encoded_seed = bytearray(seed.encode())
kp = nkeys.from_seed(encoded_seed)
nonce = b'NcMQZSlX2lZ3Y4w'
sig = kp.sign(nonce)
self.assertTrue(kp.verify(nonce, sig))
with self.assertRaises(nkeys.ErrInvalidSignature):
kp.verify(nonce + b'asdf', sig)

def test_keypair_seed_property(self):
seed = bytearray(
b"SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU"
)
kp = nkeys.from_seed(seed)
self.assertEqual(
kp.seed,
bytearray(
b"SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU"
)
)

# Throw away the seed.
kp.wipe()

with self.assertRaises(nkeys.ErrInvalidSeed):
kp.seed

def test_keypair_public_key(self):
seed = "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU"
encoded_seed = bytearray(seed.encode())
kp = nkeys.from_seed(encoded_seed)

self.assertEqual(None, kp._public_key)
self.assertEqual(
b"UCK5N7N66OBOINFXAYC2ACJQYFSOD4VYNU6APEJTAVFZB2SVHLKGEW7L",
kp.public_key
)

# Confirm that the public key is wiped as well.
kp.wipe()
with self.assertRaises(AttributeError):
kp._public_key

def test_keypair_private_key(self):
seed = "SUAMLK2ZNL35WSMW37E7UD4VZ7ELPKW7DHC3BWBSD2GCZ7IUQQXZIORRBU"
encoded_seed = bytearray(seed.encode())
kp = nkeys.from_seed(encoded_seed)
self.assertEqual(None, kp._public_key)

priv = kp.private_key
self.assertEqual(
b"PDC2WWLK67NUTFW7ZH5A7FOPZC32VXYZYWYNQMQ6RQWP2FEEF6KDVFOW7W7PHAXEGS3QMBNABEYMCZHB6K4G2PAHSEZQKS4Q5JKTVVDCJORA",
priv
)

# Confirm that the private_key is wiped as well.
kp.wipe()
with self.assertRaises(AttributeError):
kp._keys
with self.assertRaises(AttributeError):
kp._private_key

def test_roundtrip_seed_encoding(self):
# This test is a low-tech property test in disguise,
# testing the property:
# decode . encode == identity
# Using a proper framework like hypothesis might be preferable.
num_trials = 500
raw_seeds = [os.urandom(32) for _ in range(num_trials)]
for raw_seed in raw_seeds:
for prefix in PREFIXES:
with self.subTest(rawseed=raw_seed, prefix=prefix):
encoded_seed = nkeys.encode_seed(raw_seed, prefix)
decoded_prefix, decoded_seed = nkeys.decode_seed(encoded_seed)
self.assertEqual(prefix, decoded_prefix)
self.assertEqual(raw_seed, decoded_seed)


if __name__ == '__main__':
runner = unittest.TextTestRunner(stream=sys.stdout)
unittest.main(verbosity=2, exit=False, testRunner=runner)
nkeys.from_seed(bytearray(seed))
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pytest.raises context manager will only catch the exception from the first iteration of the loop. If the first seed raises an exception, subsequent seeds won't be tested. Each seed should be tested individually with its own pytest.raises block, or use pytest.mark.parametrize to test each seed separately.

Copilot uses AI. Check for mistakes.
kp = nkeys.from_seed(encoded_seed)

assert kp._public_key is None
assert kp.public_key == "UCK5N7N66OBOINFXAYC2ACJQYFSOD4VYNU6APEJTAVFZB2SVHLKGEW7L"
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assertion expects public_key to return a string, but based on the test_keypair_public_key_bytes function at line 133 and the nkeys implementation, public_key returns bytes. This assertion will fail. Change to: assert kp.public_key == b\"UCK5N7N66OBOINFXAYC2ACJQYFSOD4VYNU6APEJTAVFZB2SVHLKGEW7L\"

Suggested change
assert kp.public_key == "UCK5N7N66OBOINFXAYC2ACJQYFSOD4VYNU6APEJTAVFZB2SVHLKGEW7L"
assert kp.public_key == b"UCK5N7N66OBOINFXAYC2ACJQYFSOD4VYNU6APEJTAVFZB2SVHLKGEW7L"

Copilot uses AI. Check for mistakes.
@caspervonb caspervonb requested a review from wallyqs November 5, 2025 12:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant