"""Tests for the Identity class """ import bip39 from ed25519 import SigningKey, create_keypair import pytest from pytest_mock.plugin import MockerFixture from earthsnake.exc import ValidationError from earthsnake.identity import Identity from .helpers import random_name TEST_SEED = ( b'\xe5:\xc9\x95$\x9d\xc5F\xee\xe6\x84\xbe\xcc\xda^\xc4' b'z\x84\xb7\xd2\x02q\xfa\xe8W\xd8z\x05E\xfb2\xd5' ) TEST_MNEMONIC = bip39.encode_bytes(TEST_SEED) @pytest.mark.parametrize( 'name', [ pytest.param('s', id='veryshort'), pytest.param('sho', id='short'), pytest.param('longy', id='long'), pytest.param('verylong', id='verylong'), pytest.param('0num', id='numberstart'), ], ) def test_init_bad_name(name: str) -> None: """Test if initialisation is not possible with an invalid name""" sign, verify = create_keypair() with pytest.raises(ValidationError) as ctx: Identity(name, verify_key=verify, sign_key=sign) assert 'Invalid name' in str(ctx.value) def test_init_key_mismatch() -> None: """Test if initialisation fails if the signing and verifying keys don’t match""" sign1, _ = create_keypair() _, verify2 = create_keypair() with pytest.raises(ValidationError) as ctx: Identity('name', verify_key=verify2, sign_key=sign1) assert 'Signing and verifying keys don’t match' in str(ctx.value) def test_init_no_keys() -> None: """Test if initialisation is not possible without keys""" with pytest.raises(ValidationError) as ctx: Identity('name') assert 'At least verify_key must be present' in str(ctx.value) @pytest.mark.id_key_seed(TEST_SEED) @pytest.mark.id_name('test') def test_str(identity: Identity) -> None: """Test if the __str__ method returns the author address""" assert str(identity) == '@test.bcz76z52y5dlpohtkmpuj3jsdcvfmebzpcgfmtmhu4u7hlexzreya' @pytest.mark.id_key_seed(TEST_SEED) @pytest.mark.id_name('test') def test_repr(identity: Identity) -> None: """Test if the __str__ method returns the author address""" assert ( repr(identity) == '' ) def test_from_address() -> None: """Test loading an identity from an author address""" skey = SigningKey(TEST_SEED) vkey = skey.get_verifying_key() identity = Identity.from_address('@test.bcz76z52y5dlpohtkmpuj3jsdcvfmebzpcgfmtmhu4u7hlexzreya') assert identity.name == 'test' assert identity.sign_key is None assert identity.verify_key.to_bytes() == vkey.to_bytes() def test_from_invalid_address() -> None: """Test loading an identity from an invalid address""" with pytest.raises(ValidationError) as ctx: Identity.from_address('@inva.lid') assert 'Invalid address @inva.lid' in str(ctx.value) def test_generate(mocker: MockerFixture) -> None: """Test the generate property""" skey = SigningKey(TEST_SEED) vkey = skey.get_verifying_key() mocker.patch('earthsnake.identity.create_keypair', return_value=(skey, vkey)) identity = Identity.generate('test') assert str(identity) == '@test.bcz76z52y5dlpohtkmpuj3jsdcvfmebzpcgfmtmhu4u7hlexzreya' assert identity.sign_key assert identity.verify_key assert identity.name == 'test' @pytest.mark.id_key_seed(TEST_SEED) @pytest.mark.id_name('test') def test_mnemonic(identity: Identity) -> None: """Test the mnemonic property""" assert identity.mnemonic == f'test {TEST_MNEMONIC}' def test_mnemonic_no_signing_key() -> None: """Test if the mnemonic property returns None if there is no signing key""" identity = Identity.from_address('@test.bcz76z52y5dlpohtkmpuj3jsdcvfmebzpcgfmtmhu4u7hlexzreya') assert identity.mnemonic is None def test_from_mnemonic() -> None: """Test if identities can be loaded from mnemonics""" name = random_name() identity = Identity.from_mnemonic(f'{name} {TEST_MNEMONIC}') assert identity.name == name assert identity.sign_key assert identity.sign_key.to_seed() == TEST_SEED assert str(identity) == f'@{name}.bcz76z52y5dlpohtkmpuj3jsdcvfmebzpcgfmtmhu4u7hlexzreya' @pytest.mark.parametrize( 'address', [ pytest.param('noat.bcz76z52y5dlpohtkmpuj3jsdcvfmebzpcgfmtmhu4u7hlexzreya', id='no_at'), pytest.param( '@toolong.bcz76z52y5dlpohtkmpuj3jsdcvfmebzpcgfmtmhu4u7hlexzreya', id='too_long', ), pytest.param('@test.invalidkey', id='invalid_key'), pytest.param( '@test.cz76z52y5dlpohtkmpuj3jsdcvfmebzpcgfmtmhu4u7hlexzreya', id='nonprefixed_key', ), pytest.param('@test.many.periods', id='many_periods'), ], ) def test_valid_address_invalid(address: str) -> None: """Test if valid_address fails for invalid addresses""" assert Identity.valid_address(address) is False def test_valid_address() -> None: """Test if valid_address passes on valid addresses""" assert Identity.valid_address('@test.bcz76z52y5dlpohtkmpuj3jsdcvfmebzpcgfmtmhu4u7hlexzreya')