Skip to content

Commit 8745d0b

Browse files
committed
add chat events, tests
1 parent 715c0d9 commit 8745d0b

File tree

10 files changed

+85
-7
lines changed

10 files changed

+85
-7
lines changed

Dockerfile

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
FROM python:3.12.1-slim-bookworm
22

3+
ENV PYTHONDONTWRITEBYTECODE 1
4+
ENV PYTHONUNBUFFERED 1
5+
36
WORKDIR /app
47

58
RUN apt update -y && \

Makefile

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,8 @@ app-shell:
1919

2020
.PHONY: app-logs
2121
app-logs:
22-
${LOGS} ${APP_CONTAINER} -f
22+
${LOGS} ${APP_CONTAINER} -f
23+
24+
.PHONY: test
25+
test:
26+
${EXEC} ${APP_CONTAINER} pytest tests

app/domain/entities/base.py

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
from abc import ABC
2+
from copy import copy
23
from dataclasses import dataclass, field
34
from datetime import datetime
45
from uuid import uuid4
56

7+
from domain.events.base import BaseEvent
68

7-
@dataclass(frozen=True)
9+
10+
@dataclass
811
class BaseEntity(ABC):
912
oid: str = field(
1013
default_factory=lambda: str(uuid4()),
@@ -16,8 +19,21 @@ class BaseEntity(ABC):
1619
kw_only=True,
1720
)
1821

22+
_events: list[BaseEvent] = field(
23+
default_factory=list,
24+
kw_only=True,
25+
)
26+
1927
def __hash__(self) -> int:
2028
return hash(self.oid)
2129

22-
def __eq__(self, __value: "BaseEntity") -> bool:
30+
def __eq__(self, __value: "BaseEvent") -> bool:
2331
return self.oid == __value.oid
32+
33+
def register_event(self, event: BaseEvent) -> None:
34+
self._events.append(event)
35+
36+
def pull_events(self) -> list[BaseEvent]:
37+
registered_events = copy(self._events)
38+
self._events.clear()
39+
return registered_events

app/domain/entities/messages.py

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,35 @@
11
from dataclasses import dataclass, field
22

33
from domain.entities.base import BaseEntity
4+
from domain.events.messages import NewMessageReceivedEvent
45
from domain.values.messages import Text, Title
56

67

7-
@dataclass(frozen=True)
8+
@dataclass(eq=False)
89
class Message(BaseEntity):
910
text: Text
1011

1112

12-
@dataclass(frozen=True)
13+
@dataclass(eq=False)
1314
class Chat(BaseEntity):
1415
title: Title
1516
messages: set[Message] = field(
1617
default_factory=set,
1718
kw_only=True,
1819
)
1920

21+
def __hash__(self) -> int:
22+
return hash(self.oid)
23+
24+
def __eq__(self, __value: "Chat") -> bool:
25+
return self.oid == __value.oid
26+
2027
def add_message(self, message: Message):
2128
self.messages.add(message)
29+
self.register_event(
30+
NewMessageReceivedEvent(
31+
message_text=message.text.as_generic_type(),
32+
chat_oid=self.oid,
33+
message_oid=message.oid,
34+
)
35+
)

app/domain/events/__init__.py

Whitespace-only changes.

app/domain/events/base.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from abc import ABC
2+
from dataclasses import dataclass, field
3+
from uuid import uuid4, UUID
4+
5+
6+
@dataclass
7+
class BaseEvent(ABC):
8+
event_id: UUID = field(default_factory=uuid4, kw_only=True)

app/domain/events/messages.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from dataclasses import dataclass
2+
3+
from domain.events.base import BaseEvent
4+
5+
6+
@dataclass
7+
class NewMessageReceivedEvent(BaseEvent):
8+
message_oid: str
9+
message_text: str
10+
chat_oid: str

app/domain/values/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ def __post_init__(self):
1616
def validate(self): ...
1717

1818
@abstractmethod
19-
def as_generic_type(self): ...
19+
def as_generic_type(self) -> VT: ...

app/domain/values/messages.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ def validate(self):
2626
if len(self.value) > 255:
2727
raise TitleTooLongException(self.value)
2828

29-
def as_generic_type(self):
29+
def as_generic_type(self) -> str:
3030
return str(self.value)

app/tests/domain/values/test_messages.py

+23
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import pytest
44

55
from domain.entities.messages import Message, Chat
6+
from domain.events.messages import NewMessageReceivedEvent
67
from domain.exceptions.messages import TitleTooLongException
78
from domain.values.messages import Text, Title
89

@@ -38,3 +39,25 @@ def test_add_message_to_chat():
3839

3940
chat.add_message(message)
4041
assert message in chat.messages
42+
43+
44+
def test_new_message_events():
45+
text = Text("Hello word")
46+
message = Message(text=text)
47+
48+
title = Title("title")
49+
chat = Chat(title=title)
50+
51+
chat.add_message(message)
52+
events = chat.pull_events()
53+
pulled_events = chat.pull_events()
54+
55+
assert not pulled_events, pulled_events
56+
assert len(events) == 1, events
57+
58+
new_event = events[0]
59+
60+
assert isinstance(new_event, NewMessageReceivedEvent), new_event
61+
assert new_event.message_oid == message.oid
62+
assert new_event.message_text == message.text.as_generic_type()
63+
assert new_event.chat_oid == chat.oid

0 commit comments

Comments
 (0)