Goal
Add direct, hermetic tests for the GitHub Project GraphQL data-access paths so malformed mutation payloads, pagination regressions, and failure translation are caught before basectl gh project changes a live Project.
Background
A fresh coverage run on current main (685d538) passed all 1,051 Python tests and the repository ratchet at 88.12% statements, 77.67% branches, and 85.55% combined coverage. The hosted Python 3.10-3.13 jobs reported the same statement result and at least 77.62% branch / 85.53% combined coverage.
The aggregate result hides the largest package-level gap. base_github_projects is at 78.44% statement and 64.49% branch coverage. Its lowest-covered modules include:
engine.py: 53.28% statements, 27.27% branches, 48.00% combined.
project_graphql.py: 56.25% statements, 25.00% branches, 50.00% combined.
project_item_fields.py: 67.21% statements, 52.27% branches, 63.25% combined.
project_git.py: 75.68% statements, 50.00% branches, 68.63% combined.
The uncovered engine.py paths include the mutations and cursor loops used to create, copy, update, link, and backfill GitHub Projects. These are live mutation boundaries where an argument or pagination defect can affect real repository planning state even while the repo-wide coverage floor remains green.
Scope
- Add mocked unit tests for
fetch_project_repository_names, fetch_repository_issues, and fetch_project_issue_content_ids, including single-page and multi-page responses.
- Cover mutation payloads and response parsing for project create/copy/update, single-select field create/update, repository linking, issue backfill, and item updates.
- Cover missing-node, missing-repository, missing-issue, authentication, scope, timeout, and GraphQL error translation where those branches are currently untested.
- Cover
project_item_fields.py pagination plus copy/default planning and application, including skipped missing fields/options and preservation of existing values.
- Keep all tests hermetic by mocking the GitHub CLI/GraphQL boundary; do not require credentials or mutate a live Project.
Acceptance Criteria
Validation
BASE_CLI_SOURCE_DIR=../base-cli/lib/python \
PYTHONPATH=../base-cli/lib/python:lib/python:cli/python \
python -m pytest cli/python/base_github_projects/tests -q
BASE_CLI_SOURCE_DIR=../base-cli/lib/python \
PYTHONPATH=../base-cli/lib/python:lib/python:cli/python \
python -m pytest --cov=cli/python --cov-report=term-missing --cov-report=json:coverage.json
python -m tests.coverage_gate coverage.json
BASE_BASH_LIBS_DIR=../base-bash-libs/lib/bash \
BASE_CLI_SOURCE_DIR=../base-cli/lib/python \
env -u BASE_HOME ./bin/base-test
Non-Goals
- Calling or mutating a live GitHub Project from unit tests.
- Refactoring the Project command architecture or changing public command behavior.
- Requiring 100% coverage or covering generated/static GraphQL query strings for their own sake.
Project Fields
- Status: Ready
- Priority: P2
- Area: Python
- Initiative: Contract Hardening
- Size: M
Agent Assignment
Copilot candidate after triage. The GraphQL boundary is mockable and the expected request/response contracts are explicit; a human should still review the mutation assertions before merge.
Goal
Add direct, hermetic tests for the GitHub Project GraphQL data-access paths so malformed mutation payloads, pagination regressions, and failure translation are caught before
basectl gh projectchanges a live Project.Background
A fresh coverage run on current
main(685d538) passed all 1,051 Python tests and the repository ratchet at 88.12% statements, 77.67% branches, and 85.55% combined coverage. The hosted Python 3.10-3.13 jobs reported the same statement result and at least 77.62% branch / 85.53% combined coverage.The aggregate result hides the largest package-level gap.
base_github_projectsis at 78.44% statement and 64.49% branch coverage. Its lowest-covered modules include:engine.py: 53.28% statements, 27.27% branches, 48.00% combined.project_graphql.py: 56.25% statements, 25.00% branches, 50.00% combined.project_item_fields.py: 67.21% statements, 52.27% branches, 63.25% combined.project_git.py: 75.68% statements, 50.00% branches, 68.63% combined.The uncovered
engine.pypaths include the mutations and cursor loops used to create, copy, update, link, and backfill GitHub Projects. These are live mutation boundaries where an argument or pagination defect can affect real repository planning state even while the repo-wide coverage floor remains green.Scope
fetch_project_repository_names,fetch_repository_issues, andfetch_project_issue_content_ids, including single-page and multi-page responses.project_item_fields.pypagination plus copy/default planning and application, including skipped missing fields/options and preservation of existing values.Acceptance Criteria
base_github_projectsreaches at least 85% statement coverage and 75% branch coverage without excluding additional production files.Validation
Non-Goals
Project Fields
Agent Assignment
Copilot candidate after triage. The GraphQL boundary is mockable and the expected request/response contracts are explicit; a human should still review the mutation assertions before merge.