"""Integration: the Ansible Runs tab (#5329) and the Inventory page (#5333) against real Postgres. The Runs tab's verdict counts the last 30 days; the filter bar narrows by playbook, status and origin; an HTMX request from the bar gets the table alone, and the next page as the reader scrolls keeps the filters. Requires STEWARD_DATABASE_URL.""" from __future__ import annotations import asyncio import os import time import uuid from datetime import datetime, timedelta, timezone import pytest pytestmark = pytest.mark.integration @pytest.fixture def app(): if not os.environ.get("STEWARD_DATABASE_URL"): pytest.skip("needs Postgres") from steward.app import create_app return create_app(testing=False) def test_the_runs_tab_counts_and_filters(app): from steward.models.ansible import AnsibleRun, AnsibleRunStatus from steward.models.users import User, UserRole async def _go(): tag = uuid.uuid4().hex[:8] uid = str(uuid.uuid4()) now = datetime.now(timezone.utc) def run(name, status, mins, origin=None, by=None, results=None): return AnsibleRun(playbook_path=f"it{tag}/{name}.yml", source_name="steward-builtin", inventory_scope="steward:all", status=status, origin=origin, triggered_by=by, started_at=now - timedelta(minutes=mins), finished_at=now - timedelta(minutes=mins - 1), results=results) async with app.db_sessionmaker() as s: async with s.begin(): s.add(User(id=uid, username=f"runs-{tag}", email=f"runs-{tag}@test", password_hash="x", role=UserRole.viewer, is_active=True)) async with s.begin(): s.add_all([ run("prune", AnsibleRunStatus.success, 10, origin="schedule", results={"hosts": {"a": {"ok": 2, "changed": 1}, "b": {"ok": 2, "changed": 1}}}), run("update", AnsibleRunStatus.failed, 20, by=uid, results={"hosts": {f"db-{tag}": {"ok": 1, "failed": 1}}}), ]) client = app.test_client() async with client.session_transaction() as sess: sess.update(user_id=uid, user_role="viewer", username=f"runs-{tag}", login_at=time.time()) async def get(url, **kw): resp = await client.get(url, **kw) return resp.status_code, await resp.get_data(as_text=True) out = {"page": await get(f"/ansible/?q=it{tag}"), "failed": await get(f"/ansible/?q=it{tag}&status=failed", headers={"HX-Request": "true"}), "sched": await get(f"/ansible/?q=it{tag}&origin=schedule", headers={"HX-Request": "true"}), "person": await get(f"/ansible/?q=it{tag}&origin=manual", headers={"HX-Request": "true"}), # The Playbooks tab and a built-in playbook's page (#5331): their # newest-run and schedule queries against Postgres. "playbooks": await get("/ansible/playbooks"), "playbook": await get("/ansible/playbooks/steward-builtin/maintenance/docker_prune.yml"), "missing": await get("/ansible/playbooks/steward-builtin/nope.yml")} async with app.db_sessionmaker() as s: async with s.begin(): from sqlalchemy import delete await s.execute(delete(AnsibleRun).where(AnsibleRun.playbook_path.like(f"it{tag}/%"))) await s.delete(await s.get(User, uid)) return tag, out tag, out = asyncio.run(_go()) status, page = out["page"] assert status == 200 assert '

' in page and "in the last 30 days" in page # the verdict queries ran assert f"it{tag}/prune.yml" in page and f"it{tag}/update.yml" in page assert "2 hosts ยท 2 changed" in page and f'failed on db-{tag}' in page assert '