From d4c9f96e4391cad123641951cfd0f52aa5a7f7cf Mon Sep 17 00:00:00 2001 From: Raedmund <30367709+Pinstack@users.noreply.github.com> Date: Wed, 15 Jul 2026 15:12:34 +0200 Subject: [PATCH 1/2] ci: provide DATABASE_URL to the test job so the suite can run MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The app instantiates Settings() (which requires DATABASE_URL: PostgresDsn) at import time, so with no DATABASE_URL the CI test job errored at collection ("database_url Field required", 0 items collected) — red since Oct 2025. The suite is fully mocked and opens no real connection, so a valid dummy DSN is enough. A postgres/postgis service can be added later if tests exercise a live DB. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/ci.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80605ac..e8f98ca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,4 +43,11 @@ jobs: - name: Sync dependencies (locked) run: uv sync --all-groups --frozen --python ${{ matrix.python-version }} - name: Run tests + env: + # The app instantiates Settings() at import time, which requires a valid + # DATABASE_URL (PostgresDsn). The test suite is fully mocked and never opens + # a real connection, so a well-formed dummy DSN is sufficient to let the + # package import and the suite collect/run. Add a `postgres` service block + # here (e.g. postgis/postgis image) if/when tests exercise a live database. + DATABASE_URL: postgresql://postgres:postgres@localhost:5432/suhail_pipeline run: uv run pytest From 7217f23e8e55aa68d410184e5fbc69583b853cc2 Mon Sep 17 00:00:00 2001 From: Raedmund <30367709+Pinstack@users.noreply.github.com> Date: Wed, 15 Jul 2026 15:17:25 +0200 Subject: [PATCH 2/2] test: make geometric CLI help test robust to ANSI-coloured output Typer/Rich colourises option names in CI (FORCE_COLOR), rendering '--bbox' as '\x1b[..m-\x1b[0m\x1b[..m-bbox\x1b[0m', so the literal substring check failed there while passing in a plain local terminal. Strip ANSI before matching. Co-Authored-By: Claude Opus 4.8 --- tests/unit/test_geometric_cli.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/tests/unit/test_geometric_cli.py b/tests/unit/test_geometric_cli.py index 182e432..7248089 100644 --- a/tests/unit/test_geometric_cli.py +++ b/tests/unit/test_geometric_cli.py @@ -1,19 +1,33 @@ +import re + from typer.testing import CliRunner from suhail_pipeline.run_geometric_pipeline import app runner = CliRunner() +# Typer/Rich colourises option names in help output (e.g. in CI, FORCE_COLOR), +# rendering "--bbox" as "\x1b[..m-\x1b[0m\x1b[..m-bbox\x1b[0m" so a literal +# substring check fails even though the option is present. Strip ANSI first. +_ANSI_RE = re.compile(r"\x1b\[[0-9;]*m") + + +def _plain(text: str) -> str: + return _ANSI_RE.sub("", text) + + def test_geometric_cli_invalid_bbox(): # Should fail with invalid bbox length result = runner.invoke(app, ["--bbox", "1", "2", "3"]) # Only 3 values assert result.exit_code != 0 # Check both stdout and stderr for the error message - output = result.stdout + getattr(result, 'stderr', '') + output = _plain(result.stdout + getattr(result, "stderr", "")) assert ("Bounding box must be 4 floats" in output) or ("Usage:" in output) + def test_geometric_cli_help(): result = runner.invoke(app, ["--help"]) assert result.exit_code == 0 - assert "--bbox" in result.stdout - assert "--province" in result.stdout - assert "--saudi-arabia" in result.stdout \ No newline at end of file + out = _plain(result.stdout) + assert "--bbox" in out + assert "--province" in out + assert "--saudi-arabia" in out