import pytest from .....src.email_composer import models base_class = models.BaseAttachment subclasses = base_class.__subclasses__() class TestAttachmentSubclasses: must_implement_properties = ["is_b64_string", "attachment_data"] @pytest.mark.parametrize("subclass", subclasses) def test_subclass_implement_field_attachment(self, subclass): """Ensure that each subclass of BaseAttachment implements the `attachment` field. """ # noinspection PyUnresolvedReferences field = subclass.model_fields.get("attachment") assert field is not None, "Subclass must have the field" assert field.is_required() is True, "Field must be mandatory" assert field.annotation == str, "Field value must be a string" @pytest.mark.parametrize("subclass", subclasses) @pytest.mark.parametrize("property_name", must_implement_properties) def test_subclass_implements_properties(self, subclass, property_name): """Ensure that each subclass of BaseAttachment implements the required properties. """ try: prop = getattr(subclass, property_name) except AttributeError: pytest.fail( f"Subclass '{subclass.__name__}' must implement the property " f"'{property_name}'" ) else: assert isinstance(prop, property), ( f"Subclass '{subclass.__name__}' property '{property_name}' must be a" f" property but is not." ) class TestAttachmentInstances: @pytest.fixture def instance(self): def _(_class): return _class( file_name="test.txt", mime_type="text/plain", attachment="test" ) return _ @pytest.mark.parametrize( "subclass,expected", [ (subclass, subclass.__name__ == models.Base64Attachment.__name__) for subclass in subclasses ], ) def test_instance_is_b64_string(self, instance, subclass, expected): """Ensure the value returned by is_b64_string is false, except for Base64Attachment. """ assert instance(subclass).is_b64_string == expected @pytest.mark.parametrize( "subclass,attachment,expected", [ (models.Base64Attachment, "dGVzdA==", b"test"), ], ) def test_instance_attachment_data(self, instance, subclass, attachment, expected): """Ensure the value returned by attachment_data is the same as the attachment value. """ _instance = instance(subclass) _instance.attachment = attachment assert ( _instance.attachment_data == expected ), "Attachment data is not correctly extracted as bytes"