"""Regression test: ensure worker.generate_video Celery task is bound to the real generate_video function, not a helper introduced above it. Context (P0 incident 2026-08-23): a refactor inserted helper function _sync_task_config_to_plan directly under the @celery_app.task decorator, so Celery registered the helper as "worker.generate_video". Calling the task with a single task_id raised TypeError and every generation job failed immediately. This test pins the decorator target. NOTE: CI conftest may mock Celery so that @celery_app.task does NOT return a fully functional Task/PromiseProxy object. Tests therefore use multiple defensive strategies: source-code inspection, __wrapped__.__func__ chain traversal, and direct attribute checks. """ from __future__ import annotations import inspect import re def _get_original_function(generate_video): """Walk the __wrapped__ chain to find the original function object.""" obj = generate_video seen = set() while hasattr(obj, "__wrapped__"): obj_id = id(obj) if obj_id in seen: break seen.add(obj_id) obj = obj.__wrapped__ # __wrapped__ may be a bound method — unwrap to the underlying function if hasattr(obj, "__func__"): return obj.__func__ return obj def test_generate_video_task_has_bind_true(): """The decorator must use bind=True — verified via the original function's first parameter being 'self' (bind=True convention).""" from worker_app.tasks.generation import generate_video original = _get_original_function(generate_video) sig = inspect.signature(original) params = list(sig.parameters) assert params[0] == "self", f"bind=True requires 'self' as first param, got {params}" def test_generate_video_task_signature_has_task_id(): """The original generate_video function must accept task_id as a parameter.""" from worker_app.tasks.generation import generate_video original = _get_original_function(generate_video) sig = inspect.signature(original) params = list(sig.parameters) assert "task_id" in params, f"expected 'task_id' in params, got {params}" def test_generate_video_preserves_original_function(): """The original function wrapped by @celery_app.task must be named 'generate_video' — not '_sync_task_config_to_plan'.""" from worker_app.tasks.generation import generate_video original = _get_original_function(generate_video) assert original.__name__ == "generate_video", f"expected __name__='generate_video', got '{original.__name__}'" def test_sync_task_config_to_plan_is_plain_function(): """Helper must NOT be registered as a Celery task.""" from worker_app.tasks.generation import _sync_task_config_to_plan assert not hasattr( _sync_task_config_to_plan, "run" ), "_sync_task_config_to_plan must be a plain function, not a Celery task"