Files
notifications-admin/tests/notifications_utils/test_serialised_model.py
Carlo Costino 9a83ba7475 Localize notification_utils to the admin
This changeset pulls in all of the notification_utils code directly into the admin and removes it as an external dependency. We are doing this to cut down on operational maintenance of the project and will begin removing parts of it no longer needed for the admin.

Signed-off-by: Carlo Costino <carlo.costino@gsa.gov>
2024-05-16 10:37:37 -04:00

221 lines
5.3 KiB
Python

import sys
import pytest
from notifications_utils.serialised_model import (
SerialisedModel,
SerialisedModelCollection,
)
def test_cant_be_instatiated_with_abstract_properties():
class Custom(SerialisedModel):
pass
class CustomCollection(SerialisedModelCollection):
pass
with pytest.raises(TypeError) as e:
SerialisedModel()
if sys.version_info < (3, 9):
assert str(e.value) == (
"Can't instantiate abstract class SerialisedModel with abstract methods ALLOWED_PROPERTIES"
)
else:
assert "Can't instantiate abstract class SerialisedModel with abstract method ALLOWED_PROPERTIES"
with pytest.raises(TypeError) as e:
Custom()
if sys.version_info < (3, 9):
assert str(e.value) == (
"Can't instantiate abstract class Custom with abstract methods ALLOWED_PROPERTIES"
)
else:
assert str(e.value) == (
"Can't instantiate abstract class Custom without an implementation for abstract method 'ALLOWED_PROPERTIES'"
)
with pytest.raises(TypeError) as e:
SerialisedModelCollection()
if sys.version_info < (3, 9):
assert str(e.value) == (
"Can't instantiate abstract class SerialisedModelCollection with abstract methods model"
)
else:
assert str(e.value).startswith(
"Can't instantiate abstract class SerialisedModelCollection without an implementation"
)
with pytest.raises(TypeError) as e:
CustomCollection()
if sys.version_info < (3, 9):
assert str(e.value) == (
"Can't instantiate abstract class CustomCollection with abstract methods model"
)
else:
assert str(e.value) == (
"Can't instantiate abstract class CustomCollection without an implementation for abstract method 'model'"
)
def test_looks_up_from_dict():
class Custom(SerialisedModel):
ALLOWED_PROPERTIES = {"foo"}
assert Custom({"foo": "bar"}).foo == "bar"
def test_cant_override_custom_property_from_dict():
class Custom(SerialisedModel):
ALLOWED_PROPERTIES = {"foo"}
@property
def foo(self):
return "bar"
with pytest.raises(AttributeError) as e:
assert Custom({"foo": "NOPE"}).foo == "bar"
assert (
str(e.value)
== "property 'foo' of 'test_cant_override_custom_property_from_dict.<locals>.Custom' object has no setter"
)
@pytest.mark.parametrize(
"json_response",
(
{},
{"foo": "bar"}, # Should still raise an exception
),
)
def test_model_raises_for_unknown_attributes(json_response):
class Custom(SerialisedModel):
ALLOWED_PROPERTIES = set()
model = Custom(json_response)
assert model.ALLOWED_PROPERTIES == set()
with pytest.raises(AttributeError) as e:
model.foo
assert str(e.value) == ("'Custom' object has no attribute 'foo'")
def test_model_raises_keyerror_if_item_missing_from_dict():
class Custom(SerialisedModel):
ALLOWED_PROPERTIES = {"foo"}
with pytest.raises(KeyError) as e:
Custom({}).foo
assert str(e.value) == "'foo'"
@pytest.mark.parametrize(
"json_response",
(
{},
{"foo": "bar"}, # Should be ignored
),
)
def test_model_doesnt_swallow_attribute_errors(json_response):
class Custom(SerialisedModel):
ALLOWED_PROPERTIES = set()
@property
def foo(self):
raise AttributeError("Something has gone wrong")
with pytest.raises(AttributeError) as e:
Custom(json_response).foo
assert str(e.value) == "Something has gone wrong"
def test_dynamic_properties_are_introspectable():
class Custom(SerialisedModel):
ALLOWED_PROPERTIES = {"foo", "bar", "baz"}
instance = Custom({"foo": "", "bar": "", "baz": ""})
assert dir(instance)[-3:] == ["bar", "baz", "foo"]
def test_empty_serialised_model_collection():
class CustomCollection(SerialisedModelCollection):
model = None
instance = CustomCollection([])
assert not instance
assert len(instance) == 0
def test_serialised_model_collection_returns_models_from_list():
class Custom(SerialisedModel):
ALLOWED_PROPERTIES = {"x"}
class CustomCollection(SerialisedModelCollection):
model = Custom
instance = CustomCollection(
[
{"x": "foo"},
{"x": "bar"},
{"x": "baz"},
]
)
assert instance
assert len(instance) == 3
assert instance[0].x == "foo"
assert instance[1].x == "bar"
assert instance[2].x == "baz"
assert [item.x for item in instance] == [
"foo",
"bar",
"baz",
]
assert [type(item) for item in instance + [1, 2, 3]] == [
Custom,
Custom,
Custom,
int,
int,
int,
]
instance_2 = CustomCollection(
[
{"x": "red"},
{"x": "green"},
{"x": "blue"},
]
)
assert [item.x for item in instance + instance_2] == [
"foo",
"bar",
"baz",
"red",
"green",
"blue",
]
assert [item.x for item in instance_2 + instance] == [
"red",
"green",
"blue",
"foo",
"bar",
"baz",
]