@@ -193,14 +193,50 @@ def test_07_update_sound_file(self, api_client):
193193 response = api_client .put (f'sound-files/{ sound_id } ' , update_data )
194194 assert_api_success (response , "Failed to update sound file" )
195195
196- # Verify update
197- updated = assert_record_exists (api_client , 'sound-files' , sound_id )
198- assert '(Updated)' in updated ['name' ]
196+ # Verify update with retry logic (async API processing via Redis queue + worker)
197+ # Worker may still be processing the update, causing 422 validation errors
198+ max_verify_attempts = 5
199+ updated = None
200+ for attempt in range (max_verify_attempts ):
201+ try :
202+ updated = assert_record_exists (api_client , 'sound-files' , sound_id )
203+
204+ # Check if update actually applied (worker completed processing)
205+ if '(Updated)' in updated ['name' ]:
206+ break # Update successful
207+ else :
208+ # Update not yet visible - worker still processing
209+ if attempt < max_verify_attempts - 1 :
210+ print (f" Waiting for update to complete (attempt { attempt + 1 } /{ max_verify_attempts } )..." )
211+ time .sleep (1 )
212+ else :
213+ pytest .fail (f"Update not applied after { max_verify_attempts } attempts. Name: { updated ['name' ]} " )
214+
215+ except Exception as e :
216+ # Handle 422 errors during async processing
217+ if '422' in str (e ):
218+ # Validation error - record in intermediate state, worker still processing
219+ if attempt < max_verify_attempts - 1 :
220+ print (f" Record validation failed (worker processing), retrying (attempt { attempt + 1 } /{ max_verify_attempts } )..." )
221+ time .sleep (1 )
222+ else :
223+ pytest .fail (f"Persistent 422 validation error after { max_verify_attempts } attempts: { e } " )
224+ # Handle record deletion during update
225+ elif 'not found' in str (e ).lower () or '404' in str (e ):
226+ pytest .skip (f"Sound file { sound_id } deleted during update (system restore)" )
227+ else :
228+ raise
229+
230+ # Final assertion - ensure we got the updated data
231+ assert updated is not None , "Failed to retrieve updated record"
232+ assert '(Updated)' in updated ['name' ], f"Update not reflected. Expected '(Updated)' in name, got: { updated ['name' ]} "
199233
200234 print (f"✓ Updated sound file: { updated ['name' ]} " )
201235
202236 def test_08_patch_sound_file (self , api_client ):
203237 """Test PATCH /sound-files/{id} - Partial update"""
238+ import time
239+
204240 if not self .created_ids :
205241 pytest .skip ("No sound files created yet" )
206242
@@ -221,9 +257,40 @@ def test_08_patch_sound_file(self, api_client):
221257 response = api_client .patch (f'sound-files/{ sound_id } ' , patch_data )
222258 assert_api_success (response , "Failed to patch sound file" )
223259
224- # Verify patch
225- updated = assert_record_exists (api_client , 'sound-files' , sound_id )
226- assert updated ['description' ] == 'Patched description'
260+ # Verify patch with retry logic (async API processing via Redis queue + worker)
261+ max_verify_attempts = 5
262+ updated = None
263+ for attempt in range (max_verify_attempts ):
264+ try :
265+ updated = assert_record_exists (api_client , 'sound-files' , sound_id )
266+
267+ # Check if patch actually applied
268+ if updated ['description' ] == 'Patched description' :
269+ break # Patch successful
270+ else :
271+ # Patch not yet visible - worker still processing
272+ if attempt < max_verify_attempts - 1 :
273+ print (f" Waiting for patch to complete (attempt { attempt + 1 } /{ max_verify_attempts } )..." )
274+ time .sleep (1 )
275+ else :
276+ pytest .fail (f"Patch not applied after { max_verify_attempts } attempts. Description: { updated ['description' ]} " )
277+
278+ except Exception as e :
279+ # Handle 422 errors during async processing
280+ if '422' in str (e ):
281+ if attempt < max_verify_attempts - 1 :
282+ print (f" Record validation failed (worker processing), retrying (attempt { attempt + 1 } /{ max_verify_attempts } )..." )
283+ time .sleep (1 )
284+ else :
285+ pytest .fail (f"Persistent 422 validation error after { max_verify_attempts } attempts: { e } " )
286+ elif 'not found' in str (e ).lower () or '404' in str (e ):
287+ pytest .skip (f"Sound file { sound_id } deleted during patch (system restore)" )
288+ else :
289+ raise
290+
291+ # Final assertion
292+ assert updated is not None , "Failed to retrieve patched record"
293+ assert updated ['description' ] == 'Patched description' , f"Patch not reflected. Expected 'Patched description', got: { updated ['description' ]} "
227294
228295 print (f"✓ Patched sound file description" )
229296
0 commit comments