diff --git a/duniterpy/documents/certification.py b/duniterpy/documents/certification.py index 9b3b857b2aa9932532063ae067c5ebcee254bc4f..0ee90038820afd95b6ee59ac3891fa299d6f8da8 100644 --- a/duniterpy/documents/certification.py +++ b/duniterpy/documents/certification.py @@ -14,7 +14,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. import re -from typing import Optional, Type, TypeVar, Union +from typing import Any, Optional, Type, TypeVar, Union from ..constants import ( BLOCK_ID_REGEX, @@ -80,6 +80,31 @@ class Certification(Document): if signing_key is not None: self.sign(signing_key) + def __eq__(self, other: Any) -> bool: + """ + Check Certification instances equality + """ + if not isinstance(other, Certification): + return NotImplemented + return ( + super().__eq__(other) + and self.pubkey_from == other.pubkey_from + and self.identity == other.identity + and self.block_id == other.block_id + ) + + def __hash__(self) -> int: + return hash( + ( + self.pubkey_from, + self.identity, + self.block_id, + self.version, + self.currency, + self.signature, + ) + ) + @classmethod def from_signed_raw( cls: Type[CertificationType], signed_raw: str diff --git a/tests/documents/test_certification.py b/tests/documents/test_certification.py index 94ee536550d2ecf397d8b5a9f9ab73f4a2da5116..dfee42c96a90e2a18fe9e96eca6de71c13678a87 100644 --- a/tests/documents/test_certification.py +++ b/tests/documents/test_certification.py @@ -15,11 +15,16 @@ import unittest -from duniterpy.constants import EMPTY_HASH +import pytest + +from duniterpy.constants import EMPTY_HASH, G1_TEST_CURRENCY_CODENAME +from duniterpy.documents import Certification, Identity, Revocation from duniterpy.documents.block import BlockID -from duniterpy.documents.certification import Certification -from duniterpy.documents.identity import Identity -from duniterpy.documents.revocation import Revocation + +PUBKEY = "A" +UID = "test" +BLOCK_ID = "0-NRSATU" +IDENTITY_KWARGS = [PUBKEY, UID, BLOCK_ID] selfcert_inlines = [ "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk:\ @@ -223,3 +228,27 @@ SoKwoa8PFfCDJWZ6dNCv7XstezHcc2BbKiJgVDXv82R5zYR83nis9dShLgWJ5w48noVUHimdngzYQneN revocation = Revocation.from_signed_raw(signed_raw) self.assertTrue(isinstance(Revocation.extract_self_cert(signed_raw), Identity)) self.assertEqual(revocation.signed_raw(), signed_raw) + + +def test_certification_equality(): + cert1 = Certification(PUBKEY, Identity(*IDENTITY_KWARGS), BLOCK_ID) + cert2 = Certification(PUBKEY, Identity(*IDENTITY_KWARGS), BLOCK_ID) + assert cert1 == cert2 + + +@pytest.mark.parametrize( + "pubkey, uid, block_id, currency", + [ + ("pubkey", UID, BLOCK_ID, None), + (PUBKEY, "uid", BLOCK_ID, None), + (PUBKEY, UID, "1-TEST", None), + IDENTITY_KWARGS + [G1_TEST_CURRENCY_CODENAME], + ], +) +def test_certification_inequality(pubkey, uid, block_id, currency): + cert1 = Certification(pubkey, Identity(*IDENTITY_KWARGS), block_id) + idty2 = Identity(pubkey, uid, block_id) + cert2 = Certification(pubkey, idty2, block_id) + if currency: + cert2.currency = currency + assert not cert1 == cert2