diff --git a/.context/standards/ci-cd.md b/.context/standards/ci-cd.md index 625ea19..141c210 100644 --- a/.context/standards/ci-cd.md +++ b/.context/standards/ci-cd.md @@ -5,6 +5,12 @@ Every pull request to `main` must pass a fully automated pipeline. No exceptions, no manual override, no "I'll fix it in the next PR." +> **Project rule (chesscom):** integration tests in `tests/integration/` are a +> mandatory CI gate. They are fully mocked with `responses` (offline) and run as a +> dedicated required step in `.github/workflows/ci.yml`, in addition to the combined +> coverage run. The pipeline must fail — and merge is blocked — if any integration +> test fails. Always validate them when checking changes; never skip them. + --- ## 1 · Placeholder Reference diff --git a/.context/standards/testing.md b/.context/standards/testing.md index 86f7309..0a8f2d2 100644 --- a/.context/standards/testing.md +++ b/.context/standards/testing.md @@ -25,6 +25,10 @@ Every layer must pass before code is merged. No exceptions. - **Minimum 90 % line coverage** is enforced on every PR via CI. - Coverage must **never decrease** between commits. New code without tests fails the gate. +- **Integration tests are a mandatory gate.** The suite under `tests/integration/` + mocks all HTTP via `responses` (fully offline) and runs both as part of the default + `pytest` run and as a dedicated required step in CI. A failing integration test fails + the pipeline and blocks merge — they must always be validated, never skipped. - Run locally: ```bash # Generic pattern — substitute your runner and package diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c55021c..6dbe369 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,10 @@ jobs: - name: Lint with ruff run: ruff check . - - name: Run tests with coverage + - name: Run integration tests (mandatory gate) + run: pytest tests/integration -v + + - name: Run full test suite with coverage run: pytest --cov=src --cov-report=term-missing --cov-report=xml --cov-fail-under=90 - name: Upload coverage report diff --git a/AGENTS.md b/AGENTS.md index e3360aa..4c6c265 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -43,6 +43,9 @@ pytest # Run tests with coverage pytest --cov=src --cov-report=term-missing +# Run the mandatory integration-test gate explicitly (mocked, offline) +pytest tests/integration -v + # Lint ruff check . @@ -262,10 +265,14 @@ The following standards are non-negotiable. Do not weaken them. Detailed guidanc - **No `os.getenv()` outside `config.py`** — always read configuration through `AppConfig`. Violations break the single-source-of-truth pattern. -- **Integration tests require network access** — tests in `tests/integration/` - make live calls to `api.chess.com`. Never run them in CI without a network. - Unit tests in `tests/unit/` must be fully offline; use `responses` to mock - HTTP, never `unittest.mock.patch` on `requests` directly. +- **Integration tests are a mandatory, offline pipeline gate** — tests in + `tests/integration/` mock every HTTP call with the `responses` library, so they + run fully offline with **no live network access** to `api.chess.com`. They run + automatically as part of `pytest` (`testpaths = ["tests"]`) and as a dedicated, + required step in CI; the pipeline **must fail** if any integration test fails, and + they must always be run when validating changes — never skip them. Unit tests in + `tests/unit/` must likewise be fully offline; use `responses` to mock HTTP, never + `unittest.mock.patch` on `requests` directly. - **Don't commit generated output** — the `output/` directory is git-ignored. Never add `.xlsx` files to version control. diff --git a/CLAUDE.md b/CLAUDE.md index db58efa..2934b4d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -20,4 +20,7 @@ Assessment, review, planning, and refactoring playbooks are available as Claude - **Chess.com API domain knowledge** — the public API (`api.chess.com/pub`) is unauthenticated. All endpoint methods live in `ChessComClient`. The Chrome `User-Agent` header is required and must not be removed. - **Five report types** — `member-summary`, `match-participation`, `prospects`, `match-eligibility`, `timeout-check`. New report types must follow the `BaseReport` subclass pattern and be registered in `cli.py`. - **Environment variables drive all configuration** — every setting is in `.env.template`. New settings must be added to `AppConfig` in `config.py` first; never use `os.getenv()` directly. -- **Verify tests pass before marking work complete** — run `pytest` after any behaviour change. +- **Verify tests pass before marking work complete** — run the full `pytest` suite + (which includes `tests/integration/`) after any behaviour change. Integration tests + are mocked with `responses` (fully offline) and are a **mandatory** pipeline gate; + always validate them and never skip them.