def test_get_entity_events(self): repo = PythonObjectsStoredEventRepository() event_store = EventStore(stored_event_repo=repo) # Check there are zero stored events in the repo. entity_events = event_store.get_entity_events(stored_entity_id='Example::entity1') entity_events = list(entity_events) self.assertEqual(0, len(entity_events)) # Store a domain event. event1 = Example.Created(entity_id='entity1', a=1, b=2) event_store.append(event1) # Check there is one event in the event store. entity_events = event_store.get_entity_events(stored_entity_id='Example::entity1') entity_events = list(entity_events) self.assertEqual(1, len(entity_events)) # Store another domain event. event1 = Example.AttributeChanged(entity_id='entity1', a=1, b=2, entity_version=1) event_store.append(event1) # Check there are two events in the event store. entity_events = event_store.get_entity_events(stored_entity_id='Example::entity1') entity_events = list(entity_events) self.assertEqual(2, len(entity_events)) # Check there are two events in the event store. entity_events = event_store.get_entity_events(stored_entity_id='Example::entity1') entity_events = list(entity_events) self.assertEqual(2, len(entity_events))
def test_equality_comparison(self): event1 = Example.Created(entity_id='entity1', a=1, b=2, domain_event_id=3) event2 = Example.Created(entity_id='entity1', a=1, b=2, domain_event_id=3) event3 = Example.Created(entity_id='entity1', a=3, b=2, domain_event_id=3) self.assertEqual(event1, event2) self.assertNotEqual(event1, event3) self.assertNotEqual(event2, event3) self.assertNotEqual(event2, None)
def test_get_entity(self): # Setup an event store, using Python objects. event_store = EventStore( stored_event_repo=PythonObjectsStoredEventRepository()) # Store example events. event1 = Example.Created(entity_id='entity1', a=1, b=2) event_store.append(event1) event2 = Example.Created(entity_id='entity2', a=2, b=4) event_store.append(event2) event3 = Example.Created(entity_id='entity3', a=3, b=6) event_store.append(event3) event4 = Example.Discarded(entity_id='entity3', entity_version=1) event_store.append(event4) # Check the event sourced entities are correct. # - just use a trivial mutate that always instantiates the 'Example'. event_player = EventPlayer(event_store=event_store, id_prefix='Example', mutate_func=Example.mutate) # The the reconstituted entity has correct attribute values. self.assertEqual('entity1', event_player.replay_events('entity1').id) self.assertEqual(1, event_player.replay_events('entity1').a) self.assertEqual(2, event_player.replay_events('entity2').a) self.assertEqual(None, event_player.replay_events('entity3')) # Check entity3 raises KeyError. self.assertEqual(event_player.replay_events('entity3'), None) # Check it works for "short" entities (should be faster, but the main thing is that it still works). # - just use a trivial mutate that always instantiates the 'Example'. event5 = Example.AttributeChanged(entity_id='entity1', entity_version=1, name='a', value=10) event_store.append(event5) event_player = EventPlayer(event_store=event_store, id_prefix='Example', mutate_func=Example.mutate) self.assertEqual(10, event_player.replay_events('entity1').a) event_player = EventPlayer( event_store=event_store, id_prefix='Example', mutate_func=Example.mutate, is_short=True, ) self.assertEqual(10, event_player.replay_events('entity1').a)
def test_event_attributes(self): event = Example.Created(entity_id='entity1', a=1, b=2) # Check constructor keyword args lead to read-only attributes. self.assertEqual(1, event.a) self.assertEqual(2, event.b) self.assertRaises(AttributeError, getattr, event, 'c') self.assertRaises(AttributeError, setattr, event, 'c', 3) # Check domain event has auto-generated timestamp. self.assertIsInstance(event.timestamp, float) # Check timestamp value can be given to domain events. self.assertEqual(3, Example.Created(entity_id='entity1', a=1, b=2, domain_event_id=3).domain_event_id) domain_event_id = uuid1().hex self.assertEqual(timestamp_from_uuid(domain_event_id), Example.Created(entity_id='entity1', a=1, b=2, domain_event_id=domain_event_id).timestamp)
def test_get_item(self): # Setup an event store. stored_event_repo = PythonObjectsStoredEventRepository() event_store = EventStore(stored_event_repo=stored_event_repo) # Put an event in the event store. entity_id = 'entity1' event_store.append(Example.Created(entity_id=entity_id, a=1, b=2)) # Setup an example repository. example_repo = ExampleRepo(event_store=event_store) # Check the repo has the example. self.assertIn(entity_id, example_repo) self.assertNotIn('xxxxxxxx', example_repo) # Check the entity attributes. example = example_repo[entity_id] self.assertEqual(1, example.a) self.assertEqual(2, example.b) self.assertEqual(entity_id, example.id)
def test_entity_lifecycle(self): # Check the factory creates an instance. example1 = register_new_example(a=1, b=2) self.assertIsInstance(example1, Example) # Check the properties of the Example class. self.assertEqual(1, example1.a) self.assertEqual(2, example1.b) # Check the properties of the EventSourcedEntity class. self.assertTrue(example1.id) self.assertEqual(1, example1.version) self.assertTrue(example1.created_on) # Check a second instance with the same values is not "equal" to the first. example2 = register_new_example(a=1, b=2) self.assertNotEqual(example1, example2) # Setup the repo. repo = ExampleRepo(self.event_store) # Check the example entities can be retrieved from the example repository. entity1 = repo[example1.id] self.assertIsInstance(entity1, Example) self.assertEqual(1, entity1.a) self.assertEqual(2, entity1.b) entity2 = repo[example2.id] self.assertIsInstance(entity2, Example) self.assertEqual(1, entity2.a) self.assertEqual(2, entity2.b) # Check the entity can be updated. entity1.a = 100 self.assertEqual(100, repo[entity1.id].a) entity1.b = -200 self.assertEqual(-200, repo[entity1.id].b) self.assertEqual(0, entity1.count_heartbeats()) entity1.beat_heart() entity1.beat_heart() entity1.beat_heart() self.assertEqual(3, entity1.count_heartbeats()) self.assertEqual(3, repo[entity1.id].count_heartbeats()) # Check the entity can be discarded. entity1.discard() # Check the repo now raises a KeyError. self.assertRaises(RepositoryKeyError, repo.__getitem__, entity1.id) # Check the entity can't be discarded twice. self.assertRaises(AssertionError, entity1.discard) # Should fail to validate event with wrong entity ID. self.assertRaises( EntityIDConsistencyError, entity2._validate_originator, DomainEvent(entity_id=entity2.id + 'wrong', entity_version=0)) # Should fail to validate event with wrong entity version. self.assertRaises(EntityVersionConsistencyError, entity2._validate_originator, DomainEvent(entity_id=entity2.id, entity_version=0)) # Should validate event with correct entity ID and version. entity2._validate_originator( DomainEvent(entity_id=entity2.id, entity_version=entity2.version)) # Check an entity can be reregistered with the same ID. replacement_event = Example.Created(entity_id=entity1.id, a=11, b=12) # replacement = Example.mutate(event=replacement_event) publish(event=replacement_event) # Check the replacement entity can be retrieved from the example repository. replacement = repo[entity1.id] assert isinstance(replacement, Example) self.assertEqual(replacement.a, 11) self.assertEqual(replacement.b, 12)
def test_repr(self): event1 = Example.Created(entity_id='entity1', a=1, b=2, domain_event_id=3) self.assertEqual("Example.Created(a=1, b=2, domain_event_id=3, entity_id='entity1', entity_version=0)", repr(event1))
def test_hash(self): event1 = Example.Created(entity_id='entity1', a=1, b=2, domain_event_id=3) event2 = Example.Created(entity_id='entity1', a=1, b=2, domain_event_id=3) self.assertEqual(hash(event1), hash(event2))