Python implementation of [Earthstar](https://earthstar-project.org/)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
5.0 KiB
170 lines
5.0 KiB
"""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) == '<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')
|
|
|