earthsnake/tests/test_identity.py

186 lines
5.1 KiB
Python
Raw Normal View History

2022-04-11 13:45:45 +00:00
"""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 dont 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 dont 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) == '<Identity @test.bcz76z52y5dlpohtkmpuj3jsdcvfmebzpcgfmtmhu4u7hlexzreya>'
)
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'
)