`[tool.ruff]` set a line length and a target version and nothing else, so which rules ran depended on the installed ruff's defaults — fine while nobody ran it, not fine for a CI job that can turn a push red because a tool changed its mind. The set is named explicitly (E, F, I, UP, SIM, B, RUF) with three ignores that are each a real decision rather than a shrug: B008, because FastAPI's whole dependency idiom is a call in a default argument; E501, because wrapping prose is a formatter's business; and RUF001, because the reports and the bot speak Russian and "ambiguous character" is the wrong complaint about a string the user is meant to read. The 73 findings that remained are fixed — mostly `datetime.timezone.utc` → `datetime.UTC`, `typing.Callable` → `collections.abc.Callable`, import order, and unused `noqa` markers — plus seven by hand: `contextlib.suppress` for two try/except/pass pairs, unpacking instead of list concatenation, one negated return. `ruff format` is deliberately *not* adopted: it would reformat 51 files, and some of the layout here is hand-set (the comment tables, the DNS wire-format structs) in ways a formatter flattens. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
71 lines
1.8 KiB
Python
71 lines
1.8 KiB
Python
"""Test fixtures.
|
|
|
|
The engine is built at import time from the environment, so the database URL has
|
|
to be set before anything from `app` is imported — hence the env juggling here
|
|
rather than in a fixture.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import tempfile
|
|
|
|
import pytest
|
|
|
|
# Before anything imports the settings: no `.env`, ever. A developer's real
|
|
# file would otherwise point the suite at live Jira, Telegram and laundry.
|
|
os.environ["KADENCE_NO_DOTENV"] = "1"
|
|
os.environ.setdefault("DATABASE_URL", "sqlite:///" + tempfile.mktemp(suffix=".db"))
|
|
os.environ["SCHEDULER_ENABLED"] = "false"
|
|
os.environ["TELEGRAM_BOT_ENABLED"] = "false"
|
|
# Keep the seeded settings empty so tests never reach a real Jira/Todoist.
|
|
for name in (
|
|
"JIRA_BASE_URL",
|
|
"JIRA_EMAIL",
|
|
"JIRA_API_TOKEN",
|
|
"TODOIST_API_TOKEN",
|
|
"GOOGLE_CLIENT_ID",
|
|
"GOOGLE_CLIENT_SECRET",
|
|
"GOOGLE_REFRESH_TOKEN",
|
|
"LAUNDRY_SESSION",
|
|
"TELEGRAM_BOT_TOKEN",
|
|
"TELEGRAM_CHAT_ID",
|
|
"SLACK_WEBHOOK_URL",
|
|
"AUTH_PASSWORD",
|
|
"TELEGRAM_OWNER_ID",
|
|
"TELEGRAM_BOT_USERNAME",
|
|
"API_TOKEN",
|
|
):
|
|
os.environ.pop(name, None)
|
|
|
|
from app.db import Base, SessionLocal, engine, init_db # noqa: E402
|
|
from app.services import settings_service # noqa: E402
|
|
from app.settings_schema import AppSettings # noqa: E402
|
|
|
|
|
|
@pytest.fixture()
|
|
def session():
|
|
Base.metadata.drop_all(bind=engine)
|
|
init_db()
|
|
db = SessionLocal()
|
|
try:
|
|
yield db
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@pytest.fixture()
|
|
def settings(session) -> AppSettings:
|
|
return settings_service.load_settings(session)
|
|
|
|
|
|
@pytest.fixture()
|
|
def client():
|
|
from app.main import app
|
|
from fastapi.testclient import TestClient
|
|
|
|
Base.metadata.drop_all(bind=engine)
|
|
init_db()
|
|
with TestClient(app) as test_client:
|
|
yield test_client
|