def create_article(cls, command: CreateArticleCommand): user_repo = current_domain.repository_for(User) user = user_repo.get_by_token(command.token) if user is not None: # Convert a Command Object into a DTO, to pass into the domain article_dto = CreateArticleDTO(title=command.title, description=command.description, body=command.body, tag_list=command.tag_list, author=user) # Call a factory method to construct a Articl object article = Article.create(article_dto) # Persist the new Article object article_repo = current_domain.repository_for(Article) article_repo.add(article) # Convert the persisted article object into a resource # to be passed onto the callee article_resource = ArticleRepresentation().dump(article) return article_resource return None
def test_persistence_of_json_with_array_data(test_domain): test_domain.register(Event) event = Event( name="UserCreated", payload=[ { "email": "*****@*****.**", "password": "******" }, { "email": "*****@*****.**", "password": "******" }, ], ) current_domain.repository_for(Event).add(event) refreshed_event = current_domain.repository_for(Event).get(event.id) assert refreshed_event is not None assert refreshed_event.payload == [ { "email": "*****@*****.**", "password": "******" }, { "email": "*****@*****.**", "password": "******" }, ]
def test_fetching_non_existing_aggregates(test_domain): with pytest.raises(ObjectNotFoundError) as exc: current_domain.repository_for(User).get("foobar") assert exc is not None # FIXME errors should be a list assert exc.value.messages == { "_entity": "`User` object with identifier foobar does not exist." }
def delete_article(cls, command: DeleteArticleCommand): user_repo = current_domain.repository_for(User) user = user_repo.get_by_token(command.token) if user is not None: article_repo = current_domain.repository_for(Article) article = article_repo.get_by_slug(command.slug) if article is not None: article_repo.remove(article) return None
def delete_comment(cls, command: DeleteCommentCommand): user_repo = current_domain.repository_for(User) logged_in_user = user_repo.get_by_token(command.token) if logged_in_user is not None: article_repo = current_domain.repository_for(Article) article = article_repo.get_by_slug(command.slug) if article is not None: article.delete_comment(command.comment_identifier) article_repo.add(article) return None
def get_comments(cls, command: GetAllCommentsCommand): user_repo = current_domain.repository_for(User) logged_in_user = user_repo.get_by_token(command.token) if logged_in_user is not None: article_repo = current_domain.repository_for(Article) article = article_repo.get_by_slug(command.slug) if article is not None: comment_resource = CommentRepresentation().dump(article.comments, many=True) return comment_resource return None
def _fetch_objects(self, instance, key, value): """Fetch linked entities. This method returns a well-formed query, containing the foreign-key constraint. """ children_repo = current_domain.repository_for(self.to_cls) temp_data = children_repo._dao.query.filter(**{key: value}).all().items # Set up linkage with owner element for item in temp_data: setattr(item, key, value) # Add objects in temporary cache for _, item in instance._temp_cache[self.field_name]["added"].items(): temp_data.append(item) # Update objects in temporary cache new_temp_data = [] for value in temp_data: if value.id in instance._temp_cache[self.field_name]["updated"]: new_temp_data.append( instance._temp_cache[self.field_name]["updated"][value.id]) else: new_temp_data.append(value) temp_data = new_temp_data # Remove objects in temporary cache for _, item in instance._temp_cache[ self.field_name]["removed"].items(): temp_data[:] = [ value for value in temp_data if value.id != item.id ] return temp_data
def list_articles(cls, command: ListArticlesCommand): article_repo = current_domain.repository_for(Article) articles = None if command.tag is not None: articles = article_repo.get_by_tag(command.tag, command.limit, command.offset) elif command.author is not None: articles = article_repo.get_by_author(command.author, command.limit, command.offset) elif command.favorited is not None: articles = article_repo.get_by_favorited(command.favorited, command.limit, command.offset) else: articles = article_repo.list_articles(command.limit, command.offset) if articles is not None: article_resource = ArticleRepresentation().dump(articles, many=True) return article_resource return None
def add_comment(cls, command: AddCommentCommand): user_repo = current_domain.repository_for(User) logged_in_user = user_repo.get_by_token(command.token) if logged_in_user is not None: article_repo = current_domain.repository_for(Article) article = article_repo.get_by_slug(command.slug) if article is not None: updated_article, new_comment = article.add_comment(command.body, logged_in_user) article_repo.add(updated_article) fetch_command = GetCommentCommand(slug=article.slug, identifier=new_comment.id) return cls.get_comment(fetch_command) return None
def test_for_any_lookup(test_domain): test_domain.register(User) user_repo = current_domain.repository_for(User) user_repo.add(User(emails=["*****@*****.**", "*****@*****.**"])) user_repo.add(User(emails=["*****@*****.**", "*****@*****.**"])) user_repo.add(User(emails=["*****@*****.**"])) # One result users = user_repo._dao.query.filter( emails__any=["*****@*****.**"]).all().items assert len(users) == 1 # Scalar value to `any` users = user_repo._dao.query.filter( emails__any="*****@*****.**").all().items assert len(users) == 1 # Multiple results users = user_repo._dao.query.filter( emails__any=["*****@*****.**"]).all().items assert len(users) == 2 # Multiple input values users = (user_repo._dao.query.filter( emails__any=["*****@*****.**", "*****@*****.**"]).all().items) assert len(users) == 2 # Single value in target list users = user_repo._dao.query.filter( emails__any=["*****@*****.**"]).all().items assert len(users) == 1
def get_by_favorited(self, favorited: str, limit: int, offset: int): user_repo = current_domain.repository_for(User) user = user_repo.get_by_username(favorited) if user is not None: return [favorite.article for favorite in user.favorites] return None
def change_address(self, command: ChangeAddress) -> None: user_repo = current_domain.repository_for(User) user = user_repo.get(command.user_id) user.change_address(command.address) user_repo.add(user)
def test_loading_aggregates_from_multiple_events(test_domain): identifier = str(uuid4()) UserCommandHandler().register_user( Register( user_id=identifier, email="*****@*****.**", name="John Doe", password_hash="hash", ) ) UserCommandHandler().change_address( ChangeAddress( user_id=identifier, address="foobar", ) ) user = current_domain.repository_for(User).get(identifier) assert user is not None assert user == User( user_id=identifier, email="*****@*****.**", name="John Doe", password_hash="hash", address="foobar", is_registered=True, ) # Ensure that the first event is applied as well assert user.is_registered is True assert user._version == 1
def add(cls, command: PersonCommand): with UnitOfWork(): newcomer = Person.add_newcomer(command.to_dict()) person_repo = current_domain.repository_for(Person) person_repo.add(newcomer) return newcomer
def register(cls, command: Register) -> User: user = cls( id=command.id, email=command.email, name=command.name, password_hash=command.password_hash, ) user.raise_( Registered( id=command.id, email=command.email, name=command.name, password_hash=command.password_hash, )) current_domain.repository_for(User).add(user) return user
def get_article(cls, command: GetArticleCommand): article_repo = current_domain.repository_for(Article) article = article_repo.get_by_slug(command.slug) if article is not None: article_resource = ArticleRepresentation().dump(article) return article_resource return None
def get_by_author(self, author: str, limit: int, offset: int): user_repo = current_domain.repository_for(User) article_dao = current_domain.get_dao(Article) user = user_repo.get_by_username(author) if user is not None: return (article_dao.query.filter(author_id=user.id).limit( limit).offset(offset).order_by('-updated_at').all()) return None
def check_and_publish(self, event: Created): repo = current_domain.repository_for(Post) post = repo.get(event.id) # Do some intensive work to verify post content # ... and then publish post.publish() repo.add(post)
def update_article(cls, command: UpdateArticleCommand): user_repo = current_domain.repository_for(User) user = user_repo.get_by_token(command.token) if user is not None: article_repo = current_domain.repository_for(Article) article = article_repo.get_by_slug(command.slug) if article is not None: kwargs = command.to_dict() kwargs.pop('token', None) kwargs = {k: v for k, v in kwargs.items() if v is not None} article.update(**kwargs) article_repo.add(article) article_resource = ArticleRepresentation().dump(article) return article_resource return None
def test_that_events_are_empty_after_uow(): user = User(name="John Doe", email="*****@*****.**") user.change_name("Jane Doe") user.activate() with UnitOfWork(): user_repo = current_domain.repository_for(User) user_repo.add(user) assert len(user._events) == 0
def get_tags(cls): tag_repo = current_domain.repository_for(Tag) tags = tag_repo.get_all() if tags is not None: tags_list = [tag.name for tag in tags] tags_resource = TagsRepresentation().dump(tags_list) return tags_resource return None
def fetch_logged_in_user(cls, command: CurrentUserCommand): user_repo = current_domain.repository_for(User) user = user_repo.get_by_token(command.token) if user is not None: # Convert the persisted user object into a resource # to be passed onto the callee user_resource = UserRepresentation().dump(user) return user_resource return None
def unfavorite_article(cls, command: UnfavoriteArticleCommand): user_repo = current_domain.repository_for(User) user = user_repo.get_by_token(command.token) if user is not None: article_repo = current_domain.repository_for(Article) article = article_repo.get_by_slug(command.slug) if article is not None: user.unfavorite(article) user_repo.add(user) updated_user = user_repo.get( user.id ) # FIXME Do we need to refresh the underlying object always? article_dto = ArticleDTO.for_article(article, updated_user) article_resource = ArticleRepresentation().dump(article_dto) return article_resource return None
def get_comment(cls, command: GetCommentCommand): article_repo = current_domain.repository_for(Article) article = article_repo.get_by_slug(command.slug) if article is not None: comment = article.get_comment_by_identifier(command.identifier) comment_resource = CommentRepresentation().dump(comment) return comment_resource return None
def test_that_a_has_many_entity_can_be_added(self, persisted_post): post_repo = current_domain.repository_for(Post) comment = Comment(content='So La Ti Do') persisted_post.comments.add(comment) post_repo.add(persisted_post) refreshed_post = post_repo.get(persisted_post.id) assert refreshed_post is not None assert refreshed_post.comments is not None assert comment.id in [comment.id for comment in refreshed_post.comments]
def fetch_profile(cls, command: FetchProfileCommand): user_repo = current_domain.repository_for(User) logged_in_user = user_repo.get_by_token(command.token) if logged_in_user is not None: profile_user = user_repo.get_by_username(command.username) if profile_user is not None: profile_rep = ProfileDTO.for_user(logged_in_user, profile_user) profile_resource = ProfileRepresentation().dump(profile_rep) return profile_resource return None
def add_tags(cls, command: NewTagsCommand): tag_repo = current_domain.repository_for(Tag) for tag_name in command.tag_list: tag = tag_repo.get_by_tag_name(tag_name) if tag: tag.touch(command.added_at) else: tag = Tag.create(tag_name, command.added_at) tag_repo.add(tag)
def test_for_sorting_without_nulls(test_domain): test_domain.register(User) user_repo = current_domain.repository_for(User) user_repo.add(User(name="John", seq=1)) user_repo.add(User(name="Jane", seq=2)) user_repo.add(User(name="Baby1", seq=3)) user_repo.add(User(name="Baby2", seq=4)) user_repo._dao.query.order_by("seq").all().first.name == "John" user_repo._dao.query.order_by("-seq").all().first.name == "Baby2"
def test_that_has_one_entity_can_be_added(self, persisted_post): post_repo = current_domain.repository_for(Post) meta = PostMeta(likes=1) persisted_post.post_meta = meta post_repo.add(persisted_post) refreshed_post = post_repo.get(persisted_post.id) assert refreshed_post is not None assert refreshed_post.post_meta is not None assert isinstance(refreshed_post.post_meta, PostMeta) assert refreshed_post.post_meta == meta
def _fetch_objects(self, instance, key, identifier): """Fetch single linked object""" try: repo = current_domain.repository_for(self.to_cls) value = repo._dao.find_by(**{key: identifier}) # Set up linkage with owner element setattr(value, key, identifier ) # This overwrites any existing linkage, which is correct return value except exceptions.ObjectNotFoundError: return None