Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 61 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ jobs:
prod-install-smoke:
name: Verify prod requirements.txt is sufficient
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false

- uses: actions/setup-python@v5
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.12"
cache: pip
Expand All @@ -41,10 +45,14 @@ jobs:

pytest:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false

- uses: actions/setup-python@v5
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.12"
cache: pip
Expand Down Expand Up @@ -79,3 +87,52 @@ jobs:

- name: Run mypy on tests (non-strict smoke)
run: mypy tests --config-file mypy-tests.ini --follow-imports skip

integration-tests:
name: API integration tests + coverage
runs-on: ubuntu-latest
permissions:
contents: read
actions: write
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false

- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.12"
cache: pip
cache-dependency-path: |
requirements.txt
requirements-dev.txt

- name: Install dev dependencies
run: pip install -r requirements-dev.txt

# Subset run: skip fail-under (full suite enforces 60% in pytest job).
- name: Run integration tests with coverage
run: pytest tests/test_api_integration.py tests/test_search.py -v --cov=api --cov=utils --cov-report=xml --cov-fail-under=0

- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: coverage-report
path: coverage.xml

js-tests:
name: Frontend unit tests (vitest)
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false

- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: "20"
cache: npm

- run: npm ci
- run: npm test
Comment thread
coderabbitai[bot] marked this conversation as resolved.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ build/
.vscode/
*.swp
*.swo
node_modules/
.coverage
coverage/
coverage.xml
9 changes: 5 additions & 4 deletions api/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,20 @@
search_bp = Blueprint("search", __name__)

_DEFAULT_LIMIT = 50
_MAX_LIMIT = 500


def _parse_limit(raw: str | None, default: int = _DEFAULT_LIMIT) -> int:
"""Parse a positive integer limit from a query string value."""
if raw is None or raw.strip() == "":
return default
try:
value = int(raw)
except ValueError:
raise ValueError("Invalid limit: must be a positive integer") from None
value = int(raw.strip())
except ValueError as exc:
raise ValueError("Invalid limit: must be a positive integer") from exc
if value < 1:
raise ValueError("Invalid limit: must be a positive integer")
return value
return min(value, _MAX_LIMIT)


@search_bp.route("/api/search")
Expand Down
Loading
Loading