Skip to content

Commit 1b33fee

Browse files
author
Sergio García Prado
authored
Merge pull request #474 from minos-framework/0.7.1
0.7.1.dev1
2 parents 5c647f0 + af4b0e9 commit 1b33fee

File tree

30 files changed

+509
-352
lines changed

30 files changed

+509
-352
lines changed

packages/core/minos-microservice-aggregate/minos/aggregate/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
__author__ = "Minos Framework Devs"
44
__email__ = "[email protected]"
5-
__version__ = "0.7.0"
5+
__version__ = "0.7.1.dev1"
66

77
from .actions import (
88
Action,

packages/core/minos-microservice-aggregate/minos/aggregate/events/models.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ def simplified_name(self) -> str:
6363
return self.name.rsplit(".", 1)[-1]
6464

6565
def __lt__(self, other: Any) -> bool:
66-
return isinstance(other, type(self)) and self.version < other.version
66+
return isinstance(other, type(self)) and (
67+
(self.uuid == other.uuid and self.version < other.version) or (self.created_at < other.created_at)
68+
)
6769

6870
def __getitem__(self, item: str) -> Any:
6971
try:

packages/core/minos-microservice-aggregate/minos/aggregate/queries.py

+6
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,11 @@ def _evaluate(self, value: Model) -> bool:
146146
return self._get_field(value) in self.parameter
147147

148148

149+
class _ContainsCondition(_SimpleCondition):
150+
def _evaluate(self, value: Model) -> bool:
151+
return self.parameter in self._get_field(value)
152+
153+
149154
class _LikeCondition(_SimpleCondition):
150155
def _evaluate(self, value: Model) -> bool:
151156
return bool(self._pattern.fullmatch(self._get_field(value)))
@@ -205,6 +210,7 @@ class Condition:
205210
EQUAL = _EqualCondition
206211
NOT_EQUAL = _NotEqualCondition
207212
IN = _InCondition
213+
CONTAINS = _ContainsCondition
208214
LIKE = _LikeCondition
209215

210216

packages/core/minos-microservice-aggregate/minos/aggregate/testing/snapshots/repositories/testcases.py

+56
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ class SnapshotRepositoryTestCase(MinosTestCase, ABC):
5050

5151
snapshot_repository: SnapshotRepository
5252

53+
class NumbersList(RootEntity):
54+
"""For testing purposes"""
55+
56+
numbers: list[int]
57+
58+
class Number(RootEntity):
59+
"""For testing purposes"""
60+
61+
value: int
62+
5363
class Owner(RootEntity):
5464
"""For testing purposes"""
5565

@@ -386,6 +396,52 @@ async def test_find_by_uuid(self):
386396
]
387397
self.assertEqual(expected, observed)
388398

399+
async def test_find_contains(self):
400+
a = FieldDiffContainer([FieldDiff("numbers", list[int], [1, 2, 3])])
401+
b = FieldDiffContainer([FieldDiff("numbers", list[int], [4, 5, 6])])
402+
c = FieldDiffContainer([FieldDiff("numbers", list[int], [3, 8, 9])])
403+
await self.event_repository.create(
404+
EventEntry(name=self.NumbersList.classname, data=a.avro_bytes, uuid=self.uuid_1)
405+
)
406+
await self.event_repository.create(
407+
EventEntry(name=self.NumbersList.classname, data=b.avro_bytes, uuid=self.uuid_2)
408+
)
409+
await self.event_repository.create(
410+
EventEntry(name=self.NumbersList.classname, data=c.avro_bytes, uuid=self.uuid_3)
411+
)
412+
await self.synchronize()
413+
414+
condition = Condition.CONTAINS("numbers", 3)
415+
416+
iterable = self.snapshot_repository.find(self.NumbersList, condition, ordering=Ordering.ASC("updated_at"))
417+
observed = [v async for v in iterable]
418+
419+
expected = [
420+
await self.snapshot_repository.get(self.NumbersList, self.uuid_1),
421+
await self.snapshot_repository.get(self.NumbersList, self.uuid_3),
422+
]
423+
self.assertEqual(expected, observed)
424+
425+
async def test_find_equal(self):
426+
a = FieldDiffContainer([FieldDiff("value", int, 1)])
427+
b = FieldDiffContainer([FieldDiff("value", int, 2)])
428+
c = FieldDiffContainer([FieldDiff("value", int, 1)])
429+
await self.event_repository.create(EventEntry(name=self.Number.classname, data=a.avro_bytes, uuid=self.uuid_1))
430+
await self.event_repository.create(EventEntry(name=self.Number.classname, data=b.avro_bytes, uuid=self.uuid_2))
431+
await self.event_repository.create(EventEntry(name=self.Number.classname, data=c.avro_bytes, uuid=self.uuid_3))
432+
await self.synchronize()
433+
434+
condition = Condition.EQUAL("value", 1)
435+
436+
iterable = self.snapshot_repository.find(self.Number, condition, ordering=Ordering.ASC("updated_at"))
437+
observed = [v async for v in iterable]
438+
439+
expected = [
440+
await self.snapshot_repository.get(self.Number, self.uuid_1),
441+
await self.snapshot_repository.get(self.Number, self.uuid_3),
442+
]
443+
self.assertEqual(expected, observed)
444+
389445
async def test_find_with_transaction(self):
390446
await self.populate_and_synchronize()
391447
condition = Condition.IN("uuid", [self.uuid_2, self.uuid_3])

packages/core/minos-microservice-aggregate/poetry.lock

+63-63
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/core/minos-microservice-aggregate/pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "minos-microservice-aggregate"
3-
version = "0.7.0"
3+
version = "0.7.1.dev1"
44
description = "The Aggregate pattern of the Minos Framework"
55
readme = "README.md"
66
repository = "https://github.com/minos-framework/minos-python"

packages/core/minos-microservice-aggregate/tests/test_aggregate/test_events/test_models.py

+5-8
Original file line numberDiff line numberDiff line change
@@ -55,20 +55,17 @@ def test_simplified_name(self):
5555
self.assertEqual("Car", self.diff.simplified_name)
5656

5757
def test_total_ordering(self):
58-
observed = [
58+
values = [
5959
Event.from_root_entity(Car(3, "blue", version=4)),
6060
Event.from_root_entity(Car(3, "blue", version=1)),
6161
Event.from_root_entity(Car(3, "blue", version=3)),
6262
Event.from_root_entity(Car(3, "blue", version=2)),
63+
Event.from_root_entity(Owner("foo", "bar", version=4, updated_at=current_datetime())),
64+
Event.from_root_entity(Owner("foo", "bar", version=3, updated_at=current_datetime())),
6365
]
64-
observed.sort()
66+
observed = sorted(values)
6567

66-
expected = [
67-
Event.from_root_entity(Car(3, "blue", version=1)),
68-
Event.from_root_entity(Car(3, "blue", version=2)),
69-
Event.from_root_entity(Car(3, "blue", version=3)),
70-
Event.from_root_entity(Car(3, "blue", version=4)),
71-
]
68+
expected = [values[5], values[4], values[1], values[3], values[2], values[0]]
7269
self.assertEqual(expected, observed)
7370

7471
def test_from_root_entity(self):

packages/core/minos-microservice-aggregate/tests/test_aggregate/test_queries.py

+11
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ class _Text(DeclarativeModel):
2121
value: str
2222

2323

24+
class _ListInt(DeclarativeModel):
25+
value: list[int]
26+
27+
2428
class TestCondition(unittest.TestCase):
2529
def test_hash(self):
2630
self.assertIsInstance(hash(Condition.EQUAL("value", 3)), int)
@@ -126,6 +130,13 @@ def test_condition_in(self):
126130
self.assertFalse(condition.evaluate(_Number(42)))
127131
self.assertTrue(condition.evaluate(_Number(56)))
128132

133+
def test_condition_contains(self):
134+
condition = Condition.CONTAINS("value", 1)
135+
self.assertEqual("_ContainsCondition('value', 1)", repr(condition))
136+
137+
self.assertFalse(condition.evaluate(_ListInt([42, 3, -5])))
138+
self.assertTrue(condition.evaluate(_ListInt([1, 2, 3])))
139+
129140
def test_condition_like(self):
130141
condition = Condition.LIKE("value", "a%[^ou]")
131142
self.assertEqual("_LikeCondition('value', 'a%[^ou]')", repr(condition))

packages/core/minos-microservice-aggregate/tests/test_aggregate/test_snapshots/test_repositories/test_database.py

+38
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,44 @@ async def test_find_by_uuid(self):
330330
):
331331
await super().test_find_by_uuid()
332332

333+
async def test_find_contains(self):
334+
entities = [
335+
SnapshotRepositoryTestCase.NumbersList([1, 2, 3], uuid=self.uuid_2),
336+
SnapshotRepositoryTestCase.NumbersList([3, 8, 9], uuid=self.uuid_3),
337+
]
338+
with patch.object(DatabaseClient, "fetch_one", return_value=(9999,)):
339+
with patch.object(
340+
DatabaseClient,
341+
"fetch_all",
342+
side_effect=[
343+
FakeAsyncIterator(
344+
[tuple(SnapshotEntry.from_root_entity(entity).as_raw().values()) for entity in entities]
345+
),
346+
FakeAsyncIterator([tuple(SnapshotEntry.from_root_entity(entities[0]).as_raw().values())]),
347+
FakeAsyncIterator([tuple(SnapshotEntry.from_root_entity(entities[1]).as_raw().values())]),
348+
],
349+
):
350+
await super().test_find_contains()
351+
352+
async def test_find_equal(self):
353+
entities = [
354+
SnapshotRepositoryTestCase.Number(1, uuid=self.uuid_2),
355+
SnapshotRepositoryTestCase.Number(1, uuid=self.uuid_3),
356+
]
357+
with patch.object(DatabaseClient, "fetch_one", return_value=(9999,)):
358+
with patch.object(
359+
DatabaseClient,
360+
"fetch_all",
361+
side_effect=[
362+
FakeAsyncIterator(
363+
[tuple(SnapshotEntry.from_root_entity(entity).as_raw().values()) for entity in entities]
364+
),
365+
FakeAsyncIterator([tuple(SnapshotEntry.from_root_entity(entities[0]).as_raw().values())]),
366+
FakeAsyncIterator([tuple(SnapshotEntry.from_root_entity(entities[1]).as_raw().values())]),
367+
],
368+
):
369+
await super().test_find_equal()
370+
333371
async def test_find_with_transaction(self):
334372
entities = [
335373
SnapshotRepositoryTestCase.Car(3, "blue", uuid=self.uuid_2, version=4),

packages/core/minos-microservice-common/minos/common/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""The common core of the Minos Framework."""
22
__author__ = "Minos Framework Devs"
33
__email__ = "[email protected]"
4-
__version__ = "0.7.0"
4+
__version__ = "0.7.1.dev1"
55

66
from .builders import (
77
BuildableMixin,

packages/core/minos-microservice-common/minos/common/model/serializers/avro/data/decoder.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
TYPE_CHECKING,
2525
Any,
2626
Optional,
27-
Type,
2827
TypeVar,
2928
Union,
3029
get_args,
@@ -241,7 +240,7 @@ def _build_uuid(data: Any, **kwargs) -> UUID:
241240
pass
242241
raise DataDecoderTypeException(UUID, data)
243242

244-
def _build_model(self, type_: Type[Model], data: Any, **kwargs) -> Any:
243+
def _build_model(self, type_: type[Model], data: Any, **kwargs) -> Any:
245244
if is_type_subclass(type_) and isinstance(data, type_):
246245
return data
247246
return self._build_model_type(ModelType.from_model(type_), data, **kwargs)
@@ -254,7 +253,7 @@ def _build_model_type(self, type_: ModelType, data: Any, **kwargs) -> Any:
254253
if (ans := type_.model_cls.decode_data(self, data, type_, **kwargs)) is not MissingSentinel:
255254
return ans
256255

257-
if isinstance(data, dict):
256+
if isinstance(data, Mapping):
258257
with suppress(Exception):
259258
decoded_data = {
260259
field_name: self._build(field_type, data[field_name], **kwargs)

0 commit comments

Comments
 (0)