def test_getting_event_as_dict(self): """ Getting event as dict """ event = Event(payload=dict(prop='value'), payload_rollback=dict(prop='value')) self.assertTrue(type(event.to_dict()) is dict) self.assertTrue(type(event.to_dict()['payload']) is dict) self.assertTrue(type(event.to_dict()['payload_rollback']) is dict)
def test_raise_when_setting_non_dictionary_payload(self): """ Raise when setting a payload that is not a dict """ event = Event() with self.assertRaises(x.EventError) as cm: event.payload = [123] self.assertIn('Payload must be a dictionary', str(cm.exception))
def test_property_access_set(self): """ Property access for setting event props""" dt = 'datetime!' event = Event() event.created = dt self.assertEquals(dt, event.props['created']) event.props = 'something' self.assertEquals('something', event.props)
def test_handle_event(self): """ Handler Dummy2 handles event""" handler = Dummy2() event = Event(type='DUMMY_EVENT', payload={'prop': 'val'}) event = handler.handle(event) self.assertIn('dummy_handler2', event.payload)
def event(self, type, author, object_id=None, payload=None, payload_rollback=None): """ Persist an event Creates a new event object, validates it and saves to the database. May throw a validation exception if some event data is invalid. :param type: str, event type :param author: str, author id in external system :param object_id: str, an id of the object being affected :param payload: dict, event payload :param payload_rollback: dict, payload to roll back an event :return: shiftevent.event.Event """ # create event = Event(type=type, author=author, object_id=object_id, payload=payload, payload_rollback=payload_rollback) event = self.save_event(event) return event
def test_raise_on_rolling_back_unsaved_event(self): """ Raise error when trying to roll back unsaved event""" event = Event(type='DUMMY_EVENT') handler = Dummy1() with self.assertRaises(x.ProcessingUnsavedEvent) as cm: handler.rollback_event(event) self.assertIn('Unable to roll back unsaved event', str(cm.exception))
def test_raise_error_on_rolling_back_usupported_event(self): """ Raise error when rolling back unsupported event """ event = Event(type='UNSUPPORTED', id=123) handler = Dummy1() with self.assertRaises(x.UnsupportedEventType) as cm: handler.rollback_event(event) self.assertIn('can\'t support events of this type', str(cm.exception))
def test_raise_when_handler_not_defined_as_a_class(self): """ Raise an error when handler is not a class """ handler_definitions = dict(DUMMY_EVENT=[Dummy1()]) service = EventService(db=self.db, handlers=handler_definitions) event = Event(type='DUMMY_EVENT', id=123, payload=dict(some='payload')) with self.assertRaises(x.HandlerInstantiationError) as cm: service.emit(event) self.assertIn('has to be a class, got', str(cm.exception))
def test_raise_exception_on_saving_event_with_no_handlers(self): """ Raise when saving event with no handlers """ event = Event(type='UNKNOWN_EVENT_TYPE', object_id=123, author=456, payload={'what': 'IS THIS'}) with self.assertRaises(x.EventError): service = EventService(db=self.db) service.save_event(event)
def test_raise_on_missing_handler_when_emitting_an_event(self): """ Raise exception on missing event handler when emitting an event""" service = EventService(db=self.db) event = Event(type='UNKNOWN_EVENT_TYPE', object_id=123, author=456, payload={'what': 'IS THIS'}) with self.assertRaises(x.EventError): service.emit(event)
def test_rollback_event(self): """ Handler Dummy2 rolling back an event """ handler = Dummy2() event = Event(type='DUMMY_EVENT', payload={'prop': 'val'}) event = handler.handle(event) self.assertIn('dummy_handler2', event.payload) handler.rollback(event) self.assertNotIn('dummy_handler2', event.payload)
def test_save_can_update_existing_event(self): """ Save event can update existing event """ service = EventService(db=self.db) # create first event = Event( type='DUMMY_EVENT', object_id=123, author=123, payload={'body': 'I am the payload 😂'}, payload_rollback={'body': 'I am rollback payload 😂'}, ) service.save_event(event) # now update event = service.get_event(event.id) event.payload = {'body': 'I am updated body 👻'} event = service.save_event(event) self.assertEquals('I am updated body 👻', event.payload['body']) self.assertEquals(1, event.id)
def test_populate_event_from_dict(self): """ Can populate event from dict """ data = dict(type="TEST", author='1', object_id=123, payload={'what': 'some payload'}, payload_rollback={'what': 'some payload'}) event = Event(**data) for prop in data.keys(): self.assertEquals(data[prop], getattr(event, prop))
def test_instantiate_handler(self): """ Instantiating handler """ handler_definitions = dict(DUMMY_EVENT=[Dummy1]) service = EventService(db=self.db, handlers=handler_definitions) event = Event(type='DUMMY_EVENT', id=123, author=123, payload=dict(some='payload')) event = service.emit(event) self.assertIn('dummy_handler1', event.payload)
def test_raise_exception_on_saving_invalid_event(self): """ Raise exception when saving invalid event """ event = Event( type='DUMMY_EVENT', object_id=123, payload={'body': 'I am the payload 😂'}, payload_rollback={'body': 'I am rollback payload 😂'}, ) with self.assertRaises(x.InvalidEvent) as cm: service = EventService(db=self.db) service.save_event(event) self.assertIn('author', cm.exception.validation_errors)
def test_save_inserts_an_event(self): """ Save event can insert a new event """ event = Event( type='DUMMY_EVENT', object_id=123, author=123, payload={'body': 'I am the payload 😂'}, payload_rollback={'body': 'I am rollback payload 😂'}, ) service = EventService(db=self.db) service.save_event(event) self.assertEquals(1, event.id)
def get_event(self, id): """ Get event Returns event found by unique id. :param id: int, event id :return: shiftevent.event.Event """ event = None events = self.db.tables['events'] with self.db.engine.begin() as conn: select = events.select().where(events.c.id == id) data = conn.execute(select).fetchone() if data: event = Event(**data) return event
def test_save_skips_updates_on_nonexistent_items(self): """ Save event method silently skips when updating nonexistent item """ service = EventService(db=self.db) event = Event( id=456, type='DUMMY_EVENT', object_id=123, author=123, payload={'body': 'I am the payload 😂'}, payload_rollback={'body': 'I am rollback payload 😂'}, ) service.save_event(event) found = service.get_event(id=456) self.assertIsNone(found)
def test_raise_when_handler_doesnt_inherit_from_base(self): """ Raise error when handler does not extend from base """ class Handler: def __init__(self, *args, **kwargs): pass def handle(self, *args, **kwargs): pass handler_definitions = dict(DUMMY_EVENT=[Handler]) service = EventService(db=self.db, handlers=handler_definitions) event = Event(type='DUMMY_EVENT', id=123, payload=dict(some='payload')) with self.assertRaises(x.HandlerInstantiationError) as cm: service.emit(event) self.assertIn('Handler implementations must extend BaseHandler', str(cm.exception))
def test_get_db_representation(self): """ Getting db representation of an event """ event = Event(payload=dict(prop='value')) result = event.to_db() self.assertTrue(type(result['payload']) is str)
def test_raise_when_fails_to_decode_payload_string(self): """ Raise when payload string can not be decoded """ event = Event() with self.assertRaises(x.EventError) as cm: event.payload = 'no-a-json-string' self.assertIn('Failed to decode payload string', str(cm.exception))
def test_setting_event_payload_as_json(self): """ Setting event payload as json string """ event = Event(payload=json.dumps(dict(something='else'))) self.assertTrue(type(event.payload) is dict)
def test_getting_event_payload(self): """ Getting event payload """ data = json.dumps(dict(some='payload_goes_here')) event = Event(payload=data) self.assertTrue(type(event.payload) is dict)
def test_event_gets_creation_date_upon_instantiation(self): """ Event gets creation date upon instantiating """ event = Event() self.assertIsInstance(event.props['created'], datetime)
def test_getting_event_payload_as_json_string(self): """ Getting payload as json string """ data = json.dumps(dict(some='payload_goes_here')) event = Event(payload=data) self.assertTrue(type(event.payload_json) is str) self.assertEquals(data, event.payload_json)
def test_printable_repr(self): """ Getting printable representation of an event """ event = Event() repr = event.__repr__() self.assertIn('<Event', repr)
def test_can_check_for_attribute_presence(self): """ Can use hasattr to check for prop existence""" event = Event() self.assertFalse(hasattr(event, 'whatever'))
def test_instantiating_event(self): """ Instantiating event """ event = Event() self.assertIsInstance(event, Event)
def test_getting_event_payload_rollback(self): """ Getting event rollback payload """ data = dict(some='payload_goes_here') event = Event(payload_rollback=data) self.assertTrue(type(event.payload_rollback) is dict)
def test_property_access(self): """ Can use property access for getting event props """ event = Event() self.assertIsInstance(event.created, datetime)