Skip to content

Commit 09c208f

Browse files
fix: Handle correct action attempt error status (#125)
* 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
1 parent 3ef6082 commit 09c208f

File tree

3 files changed

+161
-2
lines changed

3 files changed

+161
-2
lines changed

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

seam/modules/action_attempts.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def poll_until_ready(
3737

3838
action_attempt = get_action_attempt(client, action_attempt_id)
3939

40-
if action_attempt.status == "failed":
40+
if action_attempt.status == "error":
4141
raise SeamActionAttemptFailedError(action_attempt)
4242

4343
return action_attempt

test/wait_for_action_attempt_test.py

Lines changed: 159 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import pytest
2+
from threading import Timer
3+
from seam.exceptions import SeamActionAttemptTimeoutError, SeamActionAttemptFailedError
24
from seam import Seam
35

46

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

1719

18-
def test_wait_for_action_attempt_by_default(server):
20+
def test_wait_for_action_attempt_waits_by_default(server):
1921
endpoint, seed = server
2022
seam = Seam.from_api_key(seed["seam_apikey1_token"], endpoint=endpoint)
2123

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

4850
assert action_attempt.status == "success"
51+
52+
53+
def test_wait_for_action_attempt_waits_for_pending_action_attempt(server):
54+
endpoint, seed = server
55+
seam = Seam.from_api_key(
56+
seed["seam_apikey1_token"], endpoint=endpoint, wait_for_action_attempt=False
57+
)
58+
59+
action_attempt = seam.locks.unlock_door(device_id=seed["august_device_1"])
60+
61+
assert action_attempt.status == "pending"
62+
63+
seam.client.post(
64+
"/_fake/update_action_attempt",
65+
json={
66+
"action_attempt_id": action_attempt.action_attempt_id,
67+
"status": "pending",
68+
},
69+
)
70+
71+
def update_action_attempt():
72+
seam.client.post(
73+
"/_fake/update_action_attempt",
74+
json={
75+
"action_attempt_id": action_attempt.action_attempt_id,
76+
"status": "success",
77+
},
78+
)
79+
80+
# Use Timer to schedule the update after 1 second
81+
t = Timer(1.0, update_action_attempt)
82+
t.start()
83+
84+
resolved_action_attempt = seam.action_attempts.get(
85+
action_attempt_id=action_attempt.action_attempt_id, wait_for_action_attempt=True
86+
)
87+
88+
assert resolved_action_attempt.status == "success"
89+
90+
91+
def test_wait_for_action_attempt_returns_successful_action_attempt(server):
92+
endpoint, seed = server
93+
seam = Seam.from_api_key(
94+
seed["seam_apikey1_token"], endpoint=endpoint, wait_for_action_attempt=False
95+
)
96+
97+
action_attempt = seam.locks.unlock_door(device_id=seed["august_device_1"])
98+
99+
assert action_attempt.status == "pending"
100+
101+
seam.client.post(
102+
"/_fake/update_action_attempt",
103+
json={
104+
"action_attempt_id": action_attempt.action_attempt_id,
105+
"status": "success",
106+
},
107+
)
108+
109+
successful_action_attempt = seam.action_attempts.get(
110+
action_attempt_id=action_attempt.action_attempt_id
111+
)
112+
113+
assert successful_action_attempt.status == "success"
114+
115+
resolved_action_attempt = seam.action_attempts.get(
116+
action_attempt_id=action_attempt.action_attempt_id, wait_for_action_attempt=True
117+
)
118+
119+
assert resolved_action_attempt == successful_action_attempt
120+
121+
122+
def test_wait_for_action_attempt_times_out(server):
123+
endpoint, seed = server
124+
seam = Seam.from_api_key(
125+
seed["seam_apikey1_token"], endpoint=endpoint, wait_for_action_attempt=False
126+
)
127+
128+
action_attempt = seam.locks.unlock_door(device_id=seed["august_device_1"])
129+
130+
assert action_attempt.status == "pending"
131+
132+
seam.client.post(
133+
"/_fake/update_action_attempt",
134+
json={
135+
"action_attempt_id": action_attempt.action_attempt_id,
136+
"status": "pending",
137+
},
138+
)
139+
140+
with pytest.raises(SeamActionAttemptTimeoutError) as exc_info:
141+
seam.action_attempts.get(
142+
action_attempt_id=action_attempt.action_attempt_id,
143+
wait_for_action_attempt={"timeout": 0.1},
144+
)
145+
146+
assert exc_info.value.action_attempt == action_attempt
147+
148+
149+
def test_wait_for_action_attempt_rejects_when_action_attempt_fails(server):
150+
endpoint, seed = server
151+
seam = Seam.from_api_key(
152+
seed["seam_apikey1_token"], endpoint=endpoint, wait_for_action_attempt=False
153+
)
154+
155+
action_attempt = seam.locks.unlock_door(device_id=seed["august_device_1"])
156+
157+
assert action_attempt.status == "pending"
158+
159+
seam.client.post(
160+
"/_fake/update_action_attempt",
161+
json={
162+
"action_attempt_id": action_attempt.action_attempt_id,
163+
"status": "error",
164+
"error": {"message": "Failed", "type": "foo"},
165+
},
166+
)
167+
168+
with pytest.raises(SeamActionAttemptFailedError, match="Failed") as exc_info:
169+
seam.action_attempts.get(
170+
action_attempt_id=action_attempt.action_attempt_id,
171+
wait_for_action_attempt=True,
172+
)
173+
174+
assert (
175+
exc_info.value.action_attempt.action_attempt_id
176+
== action_attempt.action_attempt_id
177+
)
178+
assert exc_info.value.action_attempt.status == "error"
179+
assert exc_info.value.code == "foo"
180+
181+
182+
def test_wait_for_action_attempt_times_out_if_waiting_for_polling_interval(server):
183+
endpoint, seed = server
184+
seam = Seam.from_api_key(
185+
seed["seam_apikey1_token"], endpoint=endpoint, wait_for_action_attempt=False
186+
)
187+
188+
action_attempt = seam.locks.unlock_door(device_id=seed["august_device_1"])
189+
190+
assert action_attempt.status == "pending"
191+
192+
seam.client.post(
193+
"/_fake/update_action_attempt",
194+
json={
195+
"action_attempt_id": action_attempt.action_attempt_id,
196+
"status": "pending",
197+
},
198+
)
199+
200+
with pytest.raises(SeamActionAttemptTimeoutError) as exc_info:
201+
seam.action_attempts.get(
202+
action_attempt_id=action_attempt.action_attempt_id,
203+
wait_for_action_attempt={"timeout": 0.5, "polling_interval": 5},
204+
)
205+
206+
assert exc_info.value.action_attempt == action_attempt

0 commit comments

Comments
 (0)