Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raise error when no entities are requested #62

Merged
merged 3 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions link/domain/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ class Command:
"""Base class for all commands."""


@dataclass(frozen=True)
class BatchCommand(Command):
"""Base class for all commands dealing with a batch of entities."""

requested: frozenset[Identifier]


@dataclass(frozen=True)
class PullEntity(Command):
"""Pull the requested entity."""
Expand All @@ -26,19 +33,10 @@ class DeleteEntity(Command):


@dataclass(frozen=True)
class PullEntities(Command):
class PullEntities(BatchCommand):
"""Pull the requested entities."""

requested: frozenset[Identifier]


@dataclass(frozen=True)
class DeleteEntities(Command):
class DeleteEntities(BatchCommand):
"""Delete the requested entities."""

requested: frozenset[Identifier]


@dataclass(frozen=True)
class ListUnsharedEntities(Command):
"""Start the delete process for the requested entities."""
16 changes: 16 additions & 0 deletions link/service/ensure.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""Contains preconditions that are applied to the handlers."""
from link.domain.commands import BatchCommand


class NoEntitiesRequested(Exception):
"""This exception is raised when a batch command that requests no entities is encountered."""

def __init__(self, command: BatchCommand) -> None:
"""Initialize the exception."""
self.command = command


def requests_entities(command: BatchCommand) -> None:
"""Raise an exception if the given command requests no entities."""
if not command.requested:
raise NoEntitiesRequested(command)
3 changes: 3 additions & 0 deletions link/service/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from link.domain import commands, events
from link.domain.state import Processes

from . import ensure
from .messagebus import MessageBus
from .progress import ProgessDisplay
from .uow import UnitOfWork
Expand All @@ -31,6 +32,7 @@ def delete_entity(command: commands.DeleteEntity, *, uow: UnitOfWork, message_bu

def pull(command: commands.PullEntities, *, message_bus: MessageBus) -> None:
"""Pull entities across the link."""
ensure.requests_entities(command)
message_bus.handle(events.BatchProcessingStarted(Processes.PULL, command.requested))
for identifier in command.requested:
message_bus.handle(commands.PullEntity(identifier))
Expand All @@ -39,6 +41,7 @@ def pull(command: commands.PullEntities, *, message_bus: MessageBus) -> None:

def delete(command: commands.DeleteEntities, *, message_bus: MessageBus) -> None:
"""Delete shared entities."""
ensure.requests_entities(command)
message_bus.handle(events.BatchProcessingStarted(Processes.DELETE, command.requested))
for identifier in command.requested:
message_bus.handle(commands.DeleteEntity(identifier))
Expand Down
15 changes: 15 additions & 0 deletions tests/integration/test_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from link.domain import commands, events
from link.domain.state import Components, Processes, State, states
from link.service.ensure import NoEntitiesRequested
from link.service.handlers import delete, delete_entity, pull, pull_entity
from link.service.messagebus import CommandHandlers, EventHandlers, MessageBus
from link.service.uow import UnitOfWork
Expand Down Expand Up @@ -171,3 +172,17 @@ def test_pulled_entity_ends_in_correct_state(state: EntityConfig, expected: type
pull_service(commands.PullEntities(frozenset(create_identifiers("1"))))
with uow:
assert uow.entities.create_entity(create_identifier("1")).state is expected


@pytest.mark.parametrize(
("create_service", "command_cls"),
[(create_pull_service, commands.PullEntities), (create_delete_service, commands.DeleteEntities)],
)
def test_requesting_no_entities_raises_error(
create_service: Callable[[UnitOfWork], Callable[[commands.BatchCommand], None]],
command_cls: type[commands.BatchCommand],
) -> None:
uow = create_uow(**STATES[0])
service = create_service(uow)
with pytest.raises(NoEntitiesRequested):
service(command_cls(frozenset()))
Loading