Skip to content

Commit

Permalink
fix: Handle correct action attempt error status (#125)
Browse files Browse the repository at this point in the history
* Fix poll_until_ready error case

* Add test_wait_for_action_attempt_waits_for_pending_action_attempt

* Add test_wait_for_action_attempt_returns_successful_action_attempt

* Add test_wait_for_action_attempt_times_out

* Add test_wait_for_action_attempt_rejects_when_action_attempt_fails

* Add test_wait_for_action_attempt_times_out_if_waiting_for_polling_interval

* Update fake-seam-connect to 1.71.0

* Fix timeout duration
  • Loading branch information
andrii-balitskyi authored Jul 19, 2024
1 parent 3ef6082 commit 09c208f
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 2 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion seam/modules/action_attempts.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def poll_until_ready(

action_attempt = get_action_attempt(client, action_attempt_id)

if action_attempt.status == "failed":
if action_attempt.status == "error":
raise SeamActionAttemptFailedError(action_attempt)

return action_attempt
Expand Down
160 changes: 159 additions & 1 deletion test/wait_for_action_attempt_test.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import pytest
from threading import Timer
from seam.exceptions import SeamActionAttemptTimeoutError, SeamActionAttemptFailedError
from seam import Seam


Expand All @@ -15,7 +17,7 @@ def test_wait_for_action_attempt_directly_on_returned_action_attempt(server):
assert action_attempt.status == "success"


def test_wait_for_action_attempt_by_default(server):
def test_wait_for_action_attempt_waits_by_default(server):
endpoint, seed = server
seam = Seam.from_api_key(seed["seam_apikey1_token"], endpoint=endpoint)

Expand Down Expand Up @@ -46,3 +48,159 @@ def test_wait_for_action_attempt_can_set_class_default_with_object(server):
action_attempt = seam.locks.unlock_door(device_id=seed["august_device_1"])

assert action_attempt.status == "success"


def test_wait_for_action_attempt_waits_for_pending_action_attempt(server):
endpoint, seed = server
seam = Seam.from_api_key(
seed["seam_apikey1_token"], endpoint=endpoint, wait_for_action_attempt=False
)

action_attempt = seam.locks.unlock_door(device_id=seed["august_device_1"])

assert action_attempt.status == "pending"

seam.client.post(
"/_fake/update_action_attempt",
json={
"action_attempt_id": action_attempt.action_attempt_id,
"status": "pending",
},
)

def update_action_attempt():
seam.client.post(
"/_fake/update_action_attempt",
json={
"action_attempt_id": action_attempt.action_attempt_id,
"status": "success",
},
)

# Use Timer to schedule the update after 1 second
t = Timer(1.0, update_action_attempt)
t.start()

resolved_action_attempt = seam.action_attempts.get(
action_attempt_id=action_attempt.action_attempt_id, wait_for_action_attempt=True
)

assert resolved_action_attempt.status == "success"


def test_wait_for_action_attempt_returns_successful_action_attempt(server):
endpoint, seed = server
seam = Seam.from_api_key(
seed["seam_apikey1_token"], endpoint=endpoint, wait_for_action_attempt=False
)

action_attempt = seam.locks.unlock_door(device_id=seed["august_device_1"])

assert action_attempt.status == "pending"

seam.client.post(
"/_fake/update_action_attempt",
json={
"action_attempt_id": action_attempt.action_attempt_id,
"status": "success",
},
)

successful_action_attempt = seam.action_attempts.get(
action_attempt_id=action_attempt.action_attempt_id
)

assert successful_action_attempt.status == "success"

resolved_action_attempt = seam.action_attempts.get(
action_attempt_id=action_attempt.action_attempt_id, wait_for_action_attempt=True
)

assert resolved_action_attempt == successful_action_attempt


def test_wait_for_action_attempt_times_out(server):
endpoint, seed = server
seam = Seam.from_api_key(
seed["seam_apikey1_token"], endpoint=endpoint, wait_for_action_attempt=False
)

action_attempt = seam.locks.unlock_door(device_id=seed["august_device_1"])

assert action_attempt.status == "pending"

seam.client.post(
"/_fake/update_action_attempt",
json={
"action_attempt_id": action_attempt.action_attempt_id,
"status": "pending",
},
)

with pytest.raises(SeamActionAttemptTimeoutError) as exc_info:
seam.action_attempts.get(
action_attempt_id=action_attempt.action_attempt_id,
wait_for_action_attempt={"timeout": 0.1},
)

assert exc_info.value.action_attempt == action_attempt


def test_wait_for_action_attempt_rejects_when_action_attempt_fails(server):
endpoint, seed = server
seam = Seam.from_api_key(
seed["seam_apikey1_token"], endpoint=endpoint, wait_for_action_attempt=False
)

action_attempt = seam.locks.unlock_door(device_id=seed["august_device_1"])

assert action_attempt.status == "pending"

seam.client.post(
"/_fake/update_action_attempt",
json={
"action_attempt_id": action_attempt.action_attempt_id,
"status": "error",
"error": {"message": "Failed", "type": "foo"},
},
)

with pytest.raises(SeamActionAttemptFailedError, match="Failed") as exc_info:
seam.action_attempts.get(
action_attempt_id=action_attempt.action_attempt_id,
wait_for_action_attempt=True,
)

assert (
exc_info.value.action_attempt.action_attempt_id
== action_attempt.action_attempt_id
)
assert exc_info.value.action_attempt.status == "error"
assert exc_info.value.code == "foo"


def test_wait_for_action_attempt_times_out_if_waiting_for_polling_interval(server):
endpoint, seed = server
seam = Seam.from_api_key(
seed["seam_apikey1_token"], endpoint=endpoint, wait_for_action_attempt=False
)

action_attempt = seam.locks.unlock_door(device_id=seed["august_device_1"])

assert action_attempt.status == "pending"

seam.client.post(
"/_fake/update_action_attempt",
json={
"action_attempt_id": action_attempt.action_attempt_id,
"status": "pending",
},
)

with pytest.raises(SeamActionAttemptTimeoutError) as exc_info:
seam.action_attempts.get(
action_attempt_id=action_attempt.action_attempt_id,
wait_for_action_attempt={"timeout": 0.5, "polling_interval": 5},
)

assert exc_info.value.action_attempt == action_attempt

0 comments on commit 09c208f

Please sign in to comment.