async def test_workflow_cancellation_updates_sync_job_status(self, mock_dicts, mock_sync_job_id):
        """Test that cancelling a workflow properly updates the sync job status to FAILED."""

        async with WorkflowEnvironment() as env:
            # Track what happened
            sync_activity_started = False
            status_update_called = False
            final_status = None
            final_error = None

            async def mock_run_sync_activity(*args, **kwargs):
                """Simulate a long-running sync that will be cancelled."""
                nonlocal sync_activity_started
                sync_activity_started = True

                # Simulate work being done
                for i in range(100):  # Simulate 100 seconds of work
                    await asyncio.sleep(1)
                    # In real activity, this would be checking activity.is_cancelled()
                    # but in test environment we'll be cancelled via the workflow

                # Should not reach here due to cancellation
                pytest.fail("Activity should have been cancelled")

            async def mock_update_status_activity(*args, **kwargs):
                """Capture the status update."""
                nonlocal status_update_called, final_status, final_error

                sync_job_id, status, user_dict, error, failed_at = args

                # Verify correct sync job ID
                assert sync_job_id == mock_sync_job_id

                # Capture the final status and error
                final_status = status
                final_error = error
                status_update_called = True

                print(f"Status update called: job_id={sync_job_id}, status={status}, error={error}")

            # Register mocked activities
            env.set_activity_implementation(run_sync_activity, mock_run_sync_activity)
            env.set_activity_implementation(update_sync_job_status_activity, mock_update_status_activity)

            # Start the workflow
            workflow_handle = await env.client.start_workflow(
                RunSourceConnectionWorkflow.run,
                args=[
                    mock_dicts["sync_dict"],
                    mock_dicts["sync_job_dict"],
                    mock_dicts["sync_dag_dict"],
                    mock_dicts["collection_dict"],
                    mock_dicts["source_connection_dict"],
                    mock_dicts["user_dict"],
                    None,
                ],
                id=f"test-workflow-{mock_sync_job_id}",
                task_queue="test-queue",
            )

            # Give the workflow time to start the activity
            await asyncio.sleep(0.1)

            # Verify the sync activity started
            assert sync_activity_started, "Sync activity should have started"

            # Cancel the workflow (simulating kill signal)
            await workflow_handle.cancel()

            # Wait for the workflow to complete (it should fail due to cancellation)
            with pytest.raises(WorkflowFailureError) as exc_info:
                await workflow_handle.result()

            # Verify the workflow was cancelled
            assert "CancelledError" in str(exc_info.value)

            # Verify the status update was called
            assert status_update_called, "Status update activity should have been called"
            assert final_status == "CANCELLED", f"Expected status to be CANCELLED, got {final_status}"
            assert "cancelled" in final_error.lower(), f"Expected error to mention cancellation, got: {final_error}"
Test that cancelling a workflow properly updates the sync job status to FAILED.
backend/tests/integration/temporal/test_workflow_cancellation.py