From 23d2fb24ac6d0a488cc504fed7bc6887037f2268 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 14 May 2026 15:40:47 -0400 Subject: [PATCH] =?UTF-8?q?fix(fc2a):=20three=20unit-test=20failures=20?= =?UTF-8?q?=E2=80=94=20async=20fixture=20decorator,=20name=20convention,?= =?UTF-8?q?=20lazy=20celery=20includes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test_health.py: @pytest.fixture on an `async def` function is rejected by pytest-asyncio 1.x strict mode. Switched to @pytest_asyncio.fixture. backend/app/models/import_settings.py: My constraint name was 'ck_import_settings_singleton' and Base.metadata's naming convention applies 'ck__' on top, so the final ORM name was 'ck_import_settings_ck_import_settings_singleton' (double prefix). The migration creates the DB constraint as 'ck_import_settings_singleton' via raw alembic, so they didn't match. Fix: bare name 'singleton' in the model → convention produces 'ck_import_settings_singleton', matching the migration's literal name. tests/test_tasks_register.py: Celery's include=[...] parameter on the constructor is lazy — task modules aren't imported until a worker boots. The test only imported the Celery instance, so the @celery.task decorators in scan.py / import_file.py / thumbnail.py never ran. Fix: explicit `import` of those modules for side-effect at the top of the test file. Co-Authored-By: Claude Opus 4.7 (1M context) --- backend/app/models/import_settings.py | 4 +++- tests/test_health.py | 3 ++- tests/test_tasks_register.py | 12 +++++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/backend/app/models/import_settings.py b/backend/app/models/import_settings.py index b8d0d83..9af4ed0 100644 --- a/backend/app/models/import_settings.py +++ b/backend/app/models/import_settings.py @@ -12,7 +12,9 @@ from .base import Base class ImportSettings(Base): __tablename__ = "import_settings" - __table_args__ = (CheckConstraint("id = 1", name="ck_import_settings_singleton"),) + # Bare constraint name — Base.metadata's naming convention applies the + # ck_
_ prefix, producing the final ck_import_settings_singleton. + __table_args__ = (CheckConstraint("id = 1", name="singleton"),) id: Mapped[int] = mapped_column(Integer, primary_key=True) import_scan_path: Mapped[str] = mapped_column(Text, nullable=False, default="/import") diff --git a/tests/test_health.py b/tests/test_health.py index d4eb411..b8f9b2a 100644 --- a/tests/test_health.py +++ b/tests/test_health.py @@ -1,11 +1,12 @@ """Health endpoint smoke test.""" import pytest +import pytest_asyncio from backend.app import create_app -@pytest.fixture +@pytest_asyncio.fixture async def client(): app = create_app() async with app.test_client() as c: diff --git a/tests/test_tasks_register.py b/tests/test_tasks_register.py index 5d4e941..a8d4f72 100644 --- a/tests/test_tasks_register.py +++ b/tests/test_tasks_register.py @@ -1,5 +1,15 @@ -"""Confirms every FC-2a task module imports cleanly and registers with Celery.""" +"""Confirms every FC-2a task module imports cleanly and registers with Celery. +Celery's `include=[...]` parameter on the Celery() constructor is lazy — it +only imports those modules when a worker boots. To assert task registration +in a plain pytest run we explicitly import the task modules ourselves. +""" + +# Importing for side-effect: each module's @celery.task decorators register +# the task with the global Celery instance at module import time. +import backend.app.tasks.import_file # noqa: F401 +import backend.app.tasks.scan # noqa: F401 +import backend.app.tasks.thumbnail # noqa: F401 from backend.app.celery_app import celery