diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2693b0bd..70043663 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -236,12 +236,12 @@ jobs: uv pip install -e . echo "✅ Package installed in editable mode" - - name: Run pytest (v2 suite) with coverage - timeout-minutes: 15 + - name: Run pytest (full non-e2e suite) with coverage + timeout-minutes: 20 run: | uv run pytest tests/ \ --ignore=tests/e2e \ - -m v2 \ + -m "not lifecycle" \ -q \ --tb=short \ --cov=codeframe \ @@ -249,7 +249,8 @@ jobs: --cov-report=xml \ --cov-report=html echo "Coverage measured for reporting purposes." - echo "Note: -m v2 covers v2 code paths only; legacy v1 modules are excluded." + echo "Note: gate runs every non-e2e test except 'lifecycle' (real-LLM," + echo " run locally via scripts/lifecycle before opening a PR)." - name: Upload coverage reports uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4 diff --git a/CLAUDE.md b/CLAUDE.md index 1a04bd22..6c96cedc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -152,10 +152,10 @@ tests/ ### Python / CLI ```bash -uv run pytest # All tests -uv run pytest -m v2 # v2 tests only -uv run pytest tests/core/ # Core module tests -uv run pytest tests/lifecycle/ # Lifecycle tests (no live API calls — uses MockProvider) +uv run pytest # All tests +uv run pytest tests/ --ignore=tests/e2e -m "not lifecycle" # The CI gate (every non-e2e, non-real-LLM test) +uv run pytest tests/core/ # Core module tests +scripts/lifecycle --mode cli|api|web|all # Real-LLM lifecycle tests (run locally before a PR) uv run ruff check . # Web UI diff --git a/pytest.ini b/pytest.ini index 668452e7..6f6cbb83 100644 --- a/pytest.ini +++ b/pytest.ini @@ -45,6 +45,13 @@ markers = edge_case: marks edge case tests for boundary conditions and error handling lifecycle: full end-to-end lifecycle tests (real LLM calls — run via scripts/lifecycle) +# CI gate (the backend job in .github/workflows/test.yml) runs the full non-e2e +# suite EXCEPT real-LLM lifecycle tests: +# pytest tests/ --ignore=tests/e2e -m "not lifecycle" +# The `v2` marker is no longer a CI gate (the v1->v2 refactor is done); it stays +# registered for back-compat / ad-hoc selection. Don't rely on it to gate a +# test — anything non-e2e and non-lifecycle runs in CI by default (#669). +# # To run only unit tests (fast): # pytest -m "not integration and not slow and not e2e" # @@ -54,9 +61,6 @@ markers = # To run all tests except slow ones: # pytest -m "not slow" # -# To run only v2 tests: -# pytest -m v2 -# # To run lifecycle tests (real LLM — use scripts/lifecycle instead): # ANTHROPIC_API_KEY=sk-ant-... pytest -m lifecycle diff --git a/tests/auth/test_query_param_token.py b/tests/auth/test_query_param_token.py index 527e6a39..2b6c014f 100644 --- a/tests/auth/test_query_param_token.py +++ b/tests/auth/test_query_param_token.py @@ -15,8 +15,9 @@ from fastapi import FastAPI, Depends, Request from fastapi.testclient import TestClient +from codeframe.auth import manager from codeframe.auth.dependencies import get_current_user, get_current_user_optional -from codeframe.auth.manager import SECRET, JWT_ALGORITHM, reset_auth_engine +from codeframe.auth.manager import JWT_ALGORITHM, reset_auth_engine from codeframe.platform_store.database import Database pytestmark = pytest.mark.v2 @@ -27,7 +28,13 @@ PLAIN_PATH = "/whoami" -def _make_token(user_id: int = 1, secret: str = SECRET) -> str: +def _make_token(user_id: int = 1, secret: str = None) -> str: + # Read manager.SECRET live, not at import. get_current_user verifies against + # the live global, and any test that starts the app via TestClient refreshes + # it from .env (lifespan -> refresh_secret). Binding at import would make + # these tokens unverifiable once that happens — an order-dependent flake. + if secret is None: + secret = manager.SECRET payload = { "sub": str(user_id), "aud": ["fastapi-users:auth"],