Skip to content

Commit

Permalink
finished testing notification
Browse files Browse the repository at this point in the history
  • Loading branch information
briehl committed Oct 26, 2018
1 parent 290c6b7 commit 6f4a127
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 13 deletions.
38 changes: 30 additions & 8 deletions feeds/activity/notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
from .. import verbs
from ..actor import validate_actor
from .. import notification_level
from feeds.exceptions import InvalidExpirationError
from feeds.exceptions import (
InvalidExpirationError,
InvalidNotificationError
)
import datetime
from feeds.config import get_config

Expand Down Expand Up @@ -145,7 +148,7 @@ def user_view(self):

def serialize(self):
"""
Serializes this notification for caching / simple storage.
Serializes this notification to a string for caching / simple storage.
Assumes it's been validated.
Just dumps it all to a json string.
"""
Expand All @@ -159,7 +162,8 @@ def serialize(self):
"l": self.level.id,
"c": self.created,
"e": self.expires,
"x": self.external_key
"x": self.external_key,
"n": self.context
}
return json.dumps(serial, separators=(',', ':'))

Expand All @@ -168,17 +172,26 @@ def deserialize(cls, serial):
"""
Deserializes and returns a new Notification instance.
"""
if serial is None:
return None
struct = json.loads(serial)
try:
assert serial
except AssertionError:
raise InvalidNotificationError("Can't deserialize an input of 'None'")
try:
struct = json.loads(serial)
except json.JSONDecodeError:
raise InvalidNotificationError("Can only deserialize a JSON string")
required_keys = set(['a', 'v', 'o', 's', 'l', 't', 'c', 'i', 'e'])
missing_keys = required_keys.difference(struct.keys())
if missing_keys:
raise InvalidNotificationError('Missing keys: {}'.format(missing_keys))
deserial = cls(
struct['a'],
str(struct['v']),
struct['o'],
struct['s'],
level=str(struct['l']),
target=struct.get('t'),
context=struct.get('c'),
context=struct.get('n'),
external_key=struct.get('x')
)
deserial.created = struct['c']
Expand All @@ -191,7 +204,16 @@ def from_dict(cls, serial):
"""
Returns a new Notification from a serialized dictionary (e.g. used in Mongo)
"""
assert serial
try:
assert serial is not None and isinstance(serial, dict)
except AssertionError:
raise InvalidNotificationError("Can only run 'from_dict' on a dict.")
required_keys = set([
'actor', 'verb', 'object', 'source', 'level', 'created', 'expires', 'id'
])
missing_keys = required_keys.difference(set(serial.keys()))
if missing_keys:
raise InvalidNotificationError('Missing keys: {}'.format(missing_keys))
deserial = cls(
serial['actor'],
str(serial['verb']),
Expand Down
7 changes: 7 additions & 0 deletions feeds/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,10 @@ class InvalidExpirationError(Exception):
Raised when trying to give a Notification an invalid expiration time.
"""
pass


class InvalidNotificationError(Exception):
"""
Raised when trying to deserialize a Notification that has been stored badly.
"""
pass
96 changes: 91 additions & 5 deletions test/activity/test_notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
from feeds.exceptions import (
MissingVerbError,
MissingLevelError,
InvalidExpirationError
InvalidExpirationError,
InvalidNotificationError
)

cfg = test_config()
Expand Down Expand Up @@ -239,9 +240,94 @@ def test_from_dict():
note = Notification.from_dict(note_d)
assert_note_ok(note, **note_d)

def test_serialize():
pass

def test_from_dict_missing_keys():
d = {
"actor": actor
}
with pytest.raises(InvalidNotificationError) as e:
Notification.from_dict(d)
assert "Missing keys" in str(e.value)

with pytest.raises(InvalidNotificationError) as e:
Notification.from_dict(None)
assert "Can only run 'from_dict' on a dict" in str(e.value)

def test_deserialize():
pass

def test_serialization():
note = Notification(actor, verb_inf, note_object, source, level=level_id)
serial = note.serialize()
json_serial = json.loads(serial)
# serial = {
# "i": self.id,
# "a": self.actor,
# "v": self.verb.id,
# "o": self.object,
# "s": self.source,
# "t": self.target,
# "l": self.level.id,
# "c": self.created,
# "e": self.expires,
# "x": self.external_key
# }
assert "i" in json_serial
assert_is_uuid(json_serial['i'])
assert "a" in json_serial and json_serial['a'] == actor
assert "v" in json_serial and json_serial['v'] == verb_id
assert "o" in json_serial and json_serial['o'] == note_object
assert "s" in json_serial and json_serial['s'] == source
assert "l" in json_serial and json_serial['l'] == level_id
assert "c" in json_serial and json_serial['c'] == note.created
assert "e" in json_serial and json_serial['e'] == note.expires
assert "n" in json_serial and json_serial['n'] == None
assert "x" in json_serial and json_serial['x'] == None
assert "t" in json_serial and json_serial['t'] == None


def test_serialization_all_kwargs():
note = Notification(actor, verb_inf, note_object, source, level=level_id,
target=target, external_key=external_key, context=context)
serial = note.serialize()
json_serial = json.loads(serial)
assert "i" in json_serial
assert_is_uuid(json_serial['i'])
assert "a" in json_serial and json_serial['a'] == actor
assert "v" in json_serial and json_serial['v'] == verb_id
assert "o" in json_serial and json_serial['o'] == note_object
assert "s" in json_serial and json_serial['s'] == source
assert "l" in json_serial and json_serial['l'] == level_id
assert "c" in json_serial and json_serial['c'] == note.created
assert "e" in json_serial and json_serial['e'] == note.expires
assert "n" in json_serial and json_serial['n'] == context
assert "x" in json_serial and json_serial['x'] == external_key
assert "t" in json_serial and json_serial['t'] == target


def test_deserialization():
note = Notification(actor, verb_inf, note_object, source, level=level_id,
target=target, external_key=external_key, context=context)
serial = note.serialize()
note2 = Notification.deserialize(serial)
assert note2.id == note.id
assert note2.actor == note.actor
assert note2.verb.id == note.verb.id
assert note2.object == note.object
assert note2.source == note.source
assert note2.level.id == note.level.id
assert note2.target == note.target
assert note2.external_key == note.external_key
assert note2.context == note.context


def test_deserialize_bad():
with pytest.raises(InvalidNotificationError) as e:
Notification.deserialize(None)
assert "Can't deserialize an input of 'None'" in str(e.value)

with pytest.raises(InvalidNotificationError) as e:
Notification.deserialize(json.dumps({'a': actor}))
assert "Missing keys" in str(e.value)

with pytest.raises(InvalidNotificationError) as e:
Notification.deserialize("foo")
assert "Can only deserialize a JSON string" in str(e.value)

0 comments on commit 6f4a127

Please sign in to comment.