Skip to content

Commit f0c6d00

Browse files
committed
fix tests
1 parent fbc4761 commit f0c6d00

File tree

10 files changed

+45
-51
lines changed

10 files changed

+45
-51
lines changed

.idea/python-ddd.iml

Lines changed: 0 additions & 17 deletions
This file was deleted.

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ repos:
1919
- --ignore-init-module-imports
2020

2121
- repo: https://github.com/pycqa/isort
22-
rev: 5.11.2
22+
rev: 5.12.0
2323
hooks:
2424
- id: isort
2525
name: isort (python)

src/modules/bidding/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class BiddingModule(BusinessModule):
1212
supported_events = ()
1313

1414
def configure_unit_of_work(self, uow):
15-
"""Here we have a chance to add extra UOW attributes to be injected into command/query handers"""
15+
"""Here we have a chance to add extra UOW attributes to be injected into command/query handlers"""
1616
uow.listing_repository = PostgresJsonListingRepository(
1717
db_session=uow.db_session
1818
)

src/seedwork/application/event_dispatcher.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def __init__(self):
2323
def add_event_handler(self, event_class: type[Event], event_handler: callable):
2424
self._handlers[event_class].add(event_handler)
2525

26-
def dispatch(self, event: type[Event], sender: any = None):
26+
def dispatch(self, event: type[Event]):
2727
event_class = type(event)
2828
for event_handler in self._handlers[event_class]:
29-
event_handler(event, sender)
29+
event_handler(event)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
class ApplicationException(Exception):
22
pass
3+
4+
5+
class UnitOfWorkNotSetException(ApplicationException):
6+
pass

src/seedwork/application/modules.py

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from seedwork.application.event_dispatcher import EventDispatcher
2+
from seedwork.application.exceptions import UnitOfWorkNotSetException
23
from seedwork.infrastructure.logging import logger
34

45

@@ -110,18 +111,19 @@ def unit_of_work(self, **kwargs):
110111

111112
def create_unit_of_work(self, correlation_id, db_session, kwargs):
112113
"""Unit of Work factory, creates new unit of work"""
113-
uow = self.unit_of_work_class(
114+
uow_kwargs = dict(
114115
module=self,
115116
correlation_id=correlation_id,
116117
db_session=db_session,
117118
**self.get_unit_of_work_init_kwargs(),
118119
**kwargs,
119120
)
121+
uow = self.unit_of_work_class(**uow_kwargs)
120122
return uow
121123

122124
def get_unit_of_work_init_kwargs(self):
123125
"""Returns additional kwargs used for initialization of new Unit of Work"""
124-
return self.init_kwargs
126+
return {}
125127

126128
def configure_unit_of_work(self, uow):
127129
"""Allows to alter Unit of Work (i.e. add extra attributes) after it is instantiated"""
@@ -158,7 +160,10 @@ def execute_query(self, query):
158160
def uow(self) -> UnitOfWork:
159161
"""Get current unit of work. Use self.unit_of_work() to create a new instance of UoW"""
160162
uow = self._uow.get()
161-
assert uow, f"Unit of work not set in {self}, use context manager"
163+
if uow is None:
164+
raise UnitOfWorkNotSetException(
165+
f"Unit of work not set in {self}, use context manager"
166+
)
162167
return uow
163168

164169
def resolve_handler_kwargs(self, kwarg_params) -> dict:
@@ -172,29 +177,14 @@ def resolve_handler_kwargs(self, kwarg_params) -> dict:
172177

173178
def publish_domain_events(self, events):
174179
for event in events:
175-
self._domain_event_dispatcher.dispatch(event=event, sender=self)
180+
self._domain_event_dispatcher.dispatch(event=event)
176181

177-
def handle_domain_event(
178-
self, event: type[DomainEvent], sender: type["BusinessModule"]
179-
):
182+
def handle_domain_event(self, event: type[DomainEvent]):
180183
"""Execute all registered handlers within this module for this event type"""
181-
event_was_sent_by_other_module = self is not sender
182-
183-
if event_was_sent_by_other_module:
184-
# The sender executed the command that resulted in an event being published.
185-
# as a rule of thumb we want to handle the domain event within same transaction,
186-
# thus within same Unit of Work.
187-
# Therefore, the receiver must use UoW of sender
188-
original_uow = self._uow.get()
189-
self._uow.set(sender.uow)
190184

191185
for handler in self.event_handlers:
192186
event_class, handler_parameters = self.registry.inspect_handler_parameters(
193187
handler
194188
)
195189
if event_class is type(event):
196190
handler(event, self)
197-
198-
if event_was_sent_by_other_module:
199-
# restore the original UoW
200-
self._uow.set(original_uow)

src/seedwork/tests/application/test_module.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from seedwork.application.command_handlers import CommandResult
66
from seedwork.application.commands import Command
77
from seedwork.application.event_dispatcher import InMemoryEventDispatcher
8-
from seedwork.application.modules import BusinessModule
8+
from seedwork.application.modules import BusinessModule, UnitOfWork
99
from seedwork.application.registry import Registry
1010
from seedwork.domain.events import DomainEvent
1111

@@ -33,7 +33,13 @@ def on_user_created(event: UserCreatedEvent, module: type[BusinessModule]):
3333
module.on_user_created_fired = True
3434

3535

36+
@dataclass
37+
class CustomUnitOfWork(UnitOfWork):
38+
prefix: str
39+
40+
3641
class SampleModule(BusinessModule):
42+
unit_of_work_class = CustomUnitOfWork
3743
registry = registry
3844
supported_commands = (CreateUserCommand,)
3945
supported_queries = ()

src/seedwork/tests/application/test_mono_module_branching.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ class MonoModule(BusinessModule):
118118
when_order_is_shipped_sit_and_relax_policy,
119119
)
120120

121+
def get_unit_of_work_init_kwargs(self):
122+
return dict(history=self.init_kwargs["history"])
123+
121124

122125
@pytest.mark.integration
123126
def test_mono_module_command_branching_flow():

src/seedwork/tests/application/test_mono_module_linear.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ class MonoModule(BusinessModule):
108108
when_order_is_shipped_sit_and_relax_policy,
109109
)
110110

111+
def get_unit_of_work_init_kwargs(self):
112+
return dict(history=self.init_kwargs["history"])
113+
111114

112115
@pytest.mark.integration
113116
def test_mono_module_command_linear_flow():

src/seedwork/tests/application/test_two_modules_interacting.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from seedwork.application.command_handlers import CommandResult
66
from seedwork.application.commands import Command
77
from seedwork.application.event_dispatcher import InMemoryEventDispatcher
8+
from seedwork.application.exceptions import UnitOfWorkNotSetException
89
from seedwork.application.modules import BusinessModule, UnitOfWork
910
from seedwork.application.registry import Registry
1011
from seedwork.domain.events import DomainEvent
@@ -73,6 +74,9 @@ class PingModule(BusinessModule):
7374
supported_queries = ()
7475
event_handlers = (when_pong_received_sit_and_relax_policy,)
7576

77+
def get_unit_of_work_init_kwargs(self):
78+
return dict(history=self.init_kwargs["history"])
79+
7680

7781
class PongModule(BusinessModule):
7882
registry = registry
@@ -83,18 +87,19 @@ class PongModule(BusinessModule):
8387

8488

8589
@pytest.mark.integration
86-
def test_ping_pong_flow():
87-
"""This tests the linear code flow:
88-
CompleteOrderCommand → OrderCompletedEvent → when_order_is_completed_process_payment_policy →
89-
→ ProcessPaymentCommand → PaymentProcessedEvent → when_payment_is_processed_ship_order_policy →
90-
→ ShipOrderCommand → OrderShippedEvent → when_order_is_shipped_sit_and_relax_policy
90+
def test_handing_of_domain_event_across_modules_is_not_possible():
91+
"""
92+
In this scenario, a domain event published by ping module,
93+
cannot be handled by pong module, because these modules
94+
have separate unit of works. This is by design.
95+
If such inter module communication is requires, is should be carried out
96+
by integration events.
9197
"""
9298
history = []
9399
dispatcher = InMemoryEventDispatcher()
94100
ping_module = PingModule(domain_event_dispatcher=dispatcher, history=history)
95101
pong_module = PongModule(domain_event_dispatcher=dispatcher, history=history)
96102

97-
with ping_module.unit_of_work():
98-
ping_module.execute_command(SendPing())
99-
100-
assert history == ["SendPing", "PingSent", "SendPong", "PongSent"]
103+
with pytest.raises(UnitOfWorkNotSetException):
104+
with ping_module.unit_of_work():
105+
ping_module.execute_command(SendPing())

0 commit comments

Comments
 (0)