def test_that_class_reference_is_tracked_at_the_domain_level(self): domain = Domain() class Post(BaseAggregate): content = Text(required=True) comments = HasMany("Comment") domain.register(Post) # Still a string assert isinstance(declared_fields(Post)["comments"].to_cls, str) class Comment(BaseEntity): content = Text() added_on = DateTime() post = Reference("Post") class Meta: aggregate_cls = Post domain.register(Comment) assert len(domain._pending_class_resolutions) == 2 assert all(field_name in domain._pending_class_resolutions for field_name in ["Comment", "Post"])
def test_that_class_reference_is_resolved_on_domain_activation(self): domain = Domain("Inline Domain") class Post(BaseAggregate): content = Text(required=True) comments = HasMany("Comment") domain.register(Post) # Still a string assert isinstance(declared_fields(Post)["comments"].to_cls, str) class Comment(BaseEntity): content = Text() added_on = DateTime() post = Reference("Post") class Meta: aggregate_cls = Post domain.register(Comment) with domain.domain_context(): # Resolved references assert declared_fields(Post)["comments"].to_cls == Comment assert declared_fields(Comment)["post"].to_cls == Post assert len(domain._pending_class_resolutions) == 0
def test_that_domain_throws_exception_on_unknown_class_references_during_activation( self, ): domain = Domain("Inline Domain") class Post(BaseAggregate): content = Text(required=True) comments = HasMany("Comment") domain.register(Post) # Still a string assert isinstance(declared_fields(Post)["comments"].to_cls, str) class Comment(BaseEntity): content = Text() added_on = DateTime() post = Reference("Post") foo = Reference("Foo") class Meta: aggregate_cls = Post domain.register(Comment) with pytest.raises(ConfigurationError) as exc: with domain.domain_context(): pass assert (exc.value.args[0]["element"] == "Element Foo not registered in domain Inline Domain") # Remove domain context manually, as we lost it when the exception was raised from protean.globals import _domain_context_stack _domain_context_stack.pop()
class PasswordChanged(BaseEvent): id = Identifier() password_hash = String() class User(BaseEventSourcedAggregate): email = String() name = String() password_hash = String() def count_up(): print("Counting...") class UserEventHandler(BaseEventHandler): @handle(Registered) def send_notification(self, event: Registered) -> None: count_up() @handle(PasswordChanged) def reset_token(self, event: PasswordChanged) -> None: pass baz.register(User) baz.register(UserCommandHandler, aggregate_cls=User) baz.register(UserEventHandler, aggregate_cls=User)