Adding entities
Entities form the domain model of the application.
An entity can be an object with methods, or it can be a set of data structures and functions. It should be a regular class, a dataclass, or a value object (if all the properties are the same, two objects are identical). Entities hold data (state) and logic reusable for various applications.
from dataclasses import asdict, dataclass, fields
@dataclass(frozen=True)
class TodoItem:
id: str
user_id: str
title: str
is_completed: bool = False
def to_dict(self) -> dict[str, str | bool]:
return asdict(self)
@classmethod
def from_dict(cls, dict_: dict[str, str | bool]) -> "TodoItem":
class_fields = {f.name for f in fields(cls)}
if "_id" in dict_:
dict_["id"] = dict_.pop("_id")
data = {k: v for k, v in dict_.items() if k in class_fields}
return TodoItem(**data) # type:ignore
info
Entities must not depend on anything, except possibly other entities.
Entities should be the most stable code within your application.
Entities should not be affected by any change external to them.
Testing entities
import uuid
from features.todo.entities.todo_item import TodoItem
def test_todo_item_init():
id = str(uuid.uuid4())
todo = TodoItem(id=id, title="title 1", is_completed=False, user_id="xyz")
assert todo.id == id
assert todo.title == "title 1"
assert not todo.is_completed
def test_todo_item_from_dict():
id = str(uuid.uuid4())
init_dict = {"id": id, "title": "title 1", "is_completed": False, "user_id": "xyz"}
todo = TodoItem.from_dict(init_dict)
assert todo.id == id
assert todo.title == "title 1"
assert not todo.is_completed
def test_todo_item_comparison():
id = str(uuid.uuid4())
init_dict = {"id": id, "title": "title 1", "is_completed": False, "user_id": "xyz"}
todo1 = TodoItem.from_dict(init_dict)
todo2 = TodoItem.from_dict(init_dict)
assert todo1 == todo2