Skip to content

Commit

Permalink
Replace create & edit with unified commit method
Browse files Browse the repository at this point in the history
  • Loading branch information
disrupted committed Dec 14, 2024
1 parent 9db7c79 commit fc35a6c
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 56 deletions.
6 changes: 3 additions & 3 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@ def main():

# create a project
project = TodoItem(title="Things Cloud Project").as_project()
things.create(project)
things.commit(project)
log.debug("created project", uuid=project.uuid)

sleep(10)
# create a todo inside project
todo = TodoItem(title="Try out Things Cloud")
todo.project = project
things.create(todo)
things.commit(todo)

sleep(10)
# schedule for today
todo.today()
things.edit(todo)
things.commit(todo)


if __name__ == "__main__":
Expand Down
20 changes: 10 additions & 10 deletions tests/test_todo.py
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ def test_todo_from_api_object():

def test_to_new(task: TodoItem):
assert task._api_object is None
new = task.to_new()
new = task._to_new()
# we simulate what happens when we commit the changes
task._commit(new)
assert task._api_object
Expand All @@ -450,52 +450,52 @@ def test_to_new(task: TodoItem):

def test_to_new_exists(task: TodoItem):
assert task._api_object is None
new = task.to_new()
new = task._to_new()
# we simulate what happens when we commit the changes
task._commit(new)

with pytest.raises(
ValueError, match="^current version exists for todo, use to_edit instead$"
):
task.to_new()
task._to_new()


def test_to_edit_does_not_exist(task: TodoItem):
with pytest.raises(
ValueError, match="^no current version exists for todo, use to_new instead$"
):
task.to_edit()
task._to_edit()


def test_to_edit_unchanged(task: TodoItem):
assert task._api_object is None
new = task.to_new()
new = task._to_new()
# we simulate what happens when we commit the changes
task._commit(new)

with pytest.raises(ValueError, match="^no changes found$"):
task.to_edit()
task._to_edit()


def test_to_edit(task: TodoItem):
assert task._api_object is None
new = task.to_new()
new = task._to_new()
# we simulate what happens when we commit the changes
task._commit(new)

task.title = "updated task"
delta = task.to_edit()
delta = task._to_edit()
assert delta
assert delta.model_dump(exclude_none=True) == {"title": "updated task"}


def test_to_edit_detect_reverts(task: TodoItem):
assert task._api_object is None
new = task.to_new()
new = task._to_new()
# we simulate what happens when we commit the changes
task._commit(new)

task.title = "updated task" # first we change something
task.title = "test task" # but then we revert to the old value
with pytest.raises(ValueError, match="no changes found"):
task.to_edit()
task._to_edit()
52 changes: 13 additions & 39 deletions things_cloud/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from things_cloud.api.exceptions import ThingsCloudException
from things_cloud.models.todo import (
CommitResponse,
EditBody,
HistoryResponse,
NewBody,
TodoItem,
Expand Down Expand Up @@ -65,13 +64,15 @@ def update(self) -> None:
self._process_updates(data)
self._offset = data.current_item_index

def create(self, item: TodoItem) -> None:
self.update()
item.index = self._offset + 1
self.__create_todo(self._offset, item)

def edit(self, item: TodoItem) -> None:
self.__modify_todo(self._offset, item)
def commit(self, item: TodoItem) -> None:
update = item.to_update()
try:
commit = self.__commit(update)
item._commit(update.body.payload)
self._offset = commit.server_head_index
except ThingsCloudException as e:
log.error("Error commiting")
raise e

def __request(self, method: str, endpoint: str, **kwargs) -> Response:
try:
Expand Down Expand Up @@ -120,11 +121,10 @@ def today(self) -> list[TodoItem]:
if item.scheduled_date == Util.today()
]

def __commit(
self,
index: int,
update: Update,
) -> CommitResponse:
def __commit(self, update: Update) -> CommitResponse:
index = self._offset
if update.body.type is UpdateType.NEW:
index += 1
response = self.__request(
method="POST",
endpoint="/commit",
Expand All @@ -135,29 +135,3 @@ def __commit(
content=update.to_api_payload(),
)
return CommitResponse.model_validate_json(response.read())

def __create_todo(self, index: int, item: TodoItem) -> None:
complete = item.to_new()
body = NewBody(payload=complete)
update = Update(id=item.uuid, body=body)

try:
commit = self.__commit(index, update)
self._offset = commit.server_head_index
item._commit(complete)
except ThingsCloudException as e:
log.error("Error creating todo")
raise e

def __modify_todo(self, index: int, item: TodoItem) -> None:
delta = item.to_edit()
body = EditBody(payload=delta)
update = Update(id=item.uuid, body=body)

try:
commit = self.__commit(index, update)
self._offset = commit.server_head_index
item._commit(delta)
except ThingsCloudException as e:
log.error("Error modifying todo")
raise e
19 changes: 15 additions & 4 deletions things_cloud/models/todo.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,21 @@ class TodoItem(pydantic.BaseModel):
note: Note = pydantic.Field(default_factory=Note)
_api_object: TodoApiObject | None = pydantic.PrivateAttr(default=None)

def to_new(self) -> TodoApiObject:
def to_update(self) -> Update:
if not self._api_object:
complete = self._to_new()
body = NewBody(payload=complete)
update = Update(id=self.uuid, body=body)
else:
delta = self._to_edit()
body = EditBody(payload=delta)
update = Update(id=self.uuid, body=body)
return update

def _to_new(self) -> TodoApiObject:
if self._api_object:
msg = (
f"current version exists for todo, use {self.to_edit.__name__} instead"
f"current version exists for todo, use {self._to_edit.__name__} instead"
)
raise ValueError(msg)

Expand Down Expand Up @@ -357,9 +368,9 @@ def to_new(self) -> TodoApiObject:
note=self.note,
)

def to_edit(self) -> TodoDeltaApiObject:
def _to_edit(self) -> TodoDeltaApiObject:
if not self._api_object:
msg = f"no current version exists for todo, use {self.to_new.__name__} instead"
msg = f"no current version exists for todo, use {self._to_new.__name__} instead"
raise ValueError(msg)

keys = self.model_dump(by_alias=False).keys()
Expand Down

0 comments on commit fc35a6c

Please sign in to comment.