11import pytest
2+ from threading import Timer
3+ from seam .exceptions import SeamActionAttemptTimeoutError , SeamActionAttemptFailedError
24from 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