Testing ======= Run everything with ``task test`` and ``task lint``. Both are run by the same commands on a developer machine and in CI. Backend ------- The backend uses pytest with ``pytest-asyncio`` (auto mode) and Hypothesis. Tests live in ``backend/tests`` and mirror the layers of the application: ``tests/domain`` Pure unit tests of parsing, hashing, validation and approval rules. No database, no I/O. ``tests/sources`` The filesystem and GitLab source adapters. ``tests/services`` Polling, ingest, search and the other service-layer behaviour. ``tests/storage`` Integration tests of the PostgreSQL store. ``tests/routers`` HTTP tests through FastAPI's ``TestClient``, including permissions and the approval workflow. ``tests/auth`` Token claims and the command line. Test doubles ^^^^^^^^^^^^ Nothing in the suite talks to the network or to a real provider. ``tests/fakes.py`` ``FakeSource``, an in-memory implementation of the source port. It records every call and scripts failures and incomplete listings. ``tests/gitlab_fake.py`` ``FakeGitLab``, a GitLab REST API v4 served through ``httpx.MockTransport`` with realistic pagination and scripted failures. ``tests/auth_helpers.py`` A throwaway dev secret and helpers to mint tokens. Test database ^^^^^^^^^^^^^ Storage, service and router tests use a real PostgreSQL database. Start it with: .. code-block:: sh task db:up The container listens on host port 55432 and contains two databases: ``adriano`` for development and ``adriano_test`` for the tests. The tests read ``ADRIANO_TEST_DATABASE_URL`` and never touch the development database. The storage fixtures build the schema once per session by running the real Alembic migrations (including ``downgrade base``) and truncate all tables before each test. Running tests ^^^^^^^^^^^^^ .. code-block:: sh cd backend uv run pytest # everything uv run pytest tests/domain # one directory uv run pytest tests/domain/test_hashing.py::test_name uv run pytest -k "approval and not parity" Test docstrings begin with "Ensure ..." and state the behaviour under test. Frontend -------- The frontend uses Vitest with jsdom and Vue Test Utils. Tests live in ``frontend/tests`` and mirror ``src/``: ``api``, ``auth``, ``components``, ``composables``, ``plugins``, ``utils`` and ``views``. ``tests/setup.ts`` supplies the browser APIs Vuetify needs and jsdom lacks. .. code-block:: sh cd frontend npm ci npm run test # whole suite, once npx vitest run tests/utils/diff.test.ts npx vitest run -t "pattern" # by test name ``task test`` unsets ``VITE_DEV_AUTH`` so that a developer's ``.env`` cannot change the outcome. Some tests guard conventions rather than behaviour: - ``style-blocks.test.ts`` fails when a ``