@@ -407,6 +407,82 @@ def capture_bound_datetimes(
407407 assert all (value .year >= 1000 for value in bound_datetimes )
408408
409409
410+ @pytest .mark .asyncio
411+ @pytest .mark .parametrize (
412+ 'state, legacy_state' ,
413+ [
414+ (TaskState .TASK_STATE_SUBMITTED , 'submitted' ),
415+ (TaskState .TASK_STATE_WORKING , 'working' ),
416+ (TaskState .TASK_STATE_COMPLETED , 'completed' ),
417+ (TaskState .TASK_STATE_FAILED , 'failed' ),
418+ (TaskState .TASK_STATE_CANCELED , 'canceled' ),
419+ (TaskState .TASK_STATE_INPUT_REQUIRED , 'input-required' ),
420+ (TaskState .TASK_STATE_REJECTED , 'rejected' ),
421+ (TaskState .TASK_STATE_AUTH_REQUIRED , 'auth-required' ),
422+ ],
423+ )
424+ async def test_list_tasks_filters_mixed_protocol_states (
425+ db_store_parameterized : DatabaseTaskStore ,
426+ state : TaskState .ValueType ,
427+ legacy_state : str ,
428+ ) -> None :
429+ store = db_store_parameterized
430+ other_context = ServerCallContext (user = SampleUser ('other_user' ))
431+ for owner_context in (TEST_CONTEXT , other_context ):
432+ owner = store .owner_resolver (owner_context )
433+ for prefix , core_state , stored_state in (
434+ ('match' , state , legacy_state ),
435+ ('nonmatch' , TaskState .TASK_STATE_UNSPECIFIED , 'unknown' ),
436+ ):
437+ await store .save (
438+ Task (
439+ id = f'{ owner } -{ prefix } -modern' ,
440+ context_id = 'mixed-context' ,
441+ status = TaskStatus (state = core_state ),
442+ ),
443+ owner_context ,
444+ )
445+ async with store .async_session_maker .begin () as session :
446+ for version in (None , '0.3' ):
447+ await session .execute (
448+ insert (store .task_model ).values (
449+ id = f'{ owner } -{ prefix } -legacy-{ version } ' ,
450+ context_id = 'mixed-context' ,
451+ owner = owner ,
452+ status = {'state' : stored_state },
453+ protocol_version = version ,
454+ )
455+ )
456+
457+ owner = store .owner_resolver (TEST_CONTEXT )
458+ expected_ids = [
459+ f'{ owner } -match-modern' ,
460+ f'{ owner } -match-legacy-None' ,
461+ f'{ owner } -match-legacy-0.3' ,
462+ ]
463+ for params in (
464+ ListTasksRequest (),
465+ ListTasksRequest (status = TaskState .TASK_STATE_UNSPECIFIED ),
466+ ):
467+ unfiltered = await store .list (params , TEST_CONTEXT )
468+ assert unfiltered .total_size == 6
469+ assert {task .id for task in unfiltered .tasks } == {
470+ task_id .replace ('-match-' , f'-{ prefix } -' )
471+ for task_id in expected_ids
472+ for prefix in ('match' , 'nonmatch' )
473+ }
474+
475+ params = ListTasksRequest (status = state , page_size = 1 )
476+ for index , expected_id in enumerate (expected_ids ):
477+ page = await store .list (params , TEST_CONTEXT )
478+ assert page .total_size == 3
479+ assert [task .id for task in page .tasks ] == [expected_id ]
480+ assert page .tasks [0 ].status .state == state
481+ assert page .page_size == 1
482+ assert bool (page .next_page_token ) == (index < len (expected_ids ) - 1 )
483+ params .page_token = page .next_page_token
484+
485+
410486@pytest .mark .asyncio
411487@pytest .mark .parametrize (
412488 'params, expected_error_message' ,
0 commit comments