CI 8616: the integration test asserted Vary == 'HX-Request', but the session layer appends 'Cookie'. resp.vary.add keeps both; the test asserts membership. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
86 lines
3.9 KiB
Python
86 lines
3.9 KiB
Python
"""Integration: the Hosts list's search, group and status filters and its
|
|
sort (#5294) against real Postgres. Groups are the linked Ansible target's;
|
|
the filter bar's swap (HX-Target: hosts-table) gets the table alone, and a
|
|
history restore gets the whole page."""
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import os
|
|
import time
|
|
import uuid
|
|
|
|
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_hosts_list_filters_by_search_group_and_status(app):
|
|
from steward.models.ansible_inventory import AnsibleGroup, AnsibleTarget
|
|
from steward.models.hosts import Host
|
|
from steward.models.users import User, UserRole
|
|
|
|
async def _go():
|
|
tag = uuid.uuid4().hex[:8]
|
|
uid = str(uuid.uuid4())
|
|
async with app.db_sessionmaker() as s:
|
|
async with s.begin():
|
|
s.add(User(id=uid, username=f"hl-{tag}", email=f"hl-{tag}@test",
|
|
password_hash="x", role=UserRole.viewer, is_active=True))
|
|
swarm = Host(name=f"swarm-{tag}", address="10.9.0.1")
|
|
lone = Host(name=f"lone-{tag}", address="10.9.0.2")
|
|
s.add_all([swarm, lone])
|
|
await s.flush()
|
|
group = AnsibleGroup(name=f"Swarm {tag}")
|
|
target = AnsibleTarget(name=f"t-{tag}", address="10.9.0.1", host_id=swarm.id)
|
|
target.groups = [group]
|
|
s.add_all([group, target])
|
|
|
|
client = app.test_client()
|
|
async with client.session_transaction() as sess:
|
|
sess.update(user_id=uid, user_role="viewer", username=f"hl-{tag}", login_at=time.time())
|
|
|
|
page = await (await client.get(f"/hosts/?q={tag}")).get_data(as_text=True)
|
|
assert 'class="filter-bar"' in page and f"swarm-{tag}" in page and f"lone-{tag}" in page
|
|
assert f'<option value="Swarm {tag}"' in page # the group filter lists it
|
|
assert f'>Swarm {tag}</a>' in page # and swarm's row shows it as a chip
|
|
|
|
swap = {"HX-Request": "true", "HX-Target": "hosts-table"}
|
|
resp = await client.get("/hosts/", query_string={"q": tag, "group": f"Swarm {tag}"}, headers=swap)
|
|
table = await resp.get_data(as_text=True)
|
|
assert "HX-Request" in resp.headers["Vary"]
|
|
assert 'class="filter-bar"' not in table and "<html" not in table
|
|
assert f"swarm-{tag}" in table and f"lone-{tag}" not in table
|
|
|
|
table = await (await client.get("/hosts/", query_string={"q": tag, "group": "__none__"},
|
|
headers=swap)).get_data(as_text=True)
|
|
assert f"lone-{tag}" in table and f"swarm-{tag}" not in table
|
|
|
|
# Neither host has a monitor: "No monitors" has both, "Down" neither.
|
|
table = await (await client.get("/hosts/", query_string={"q": tag, "state": "none"},
|
|
headers=swap)).get_data(as_text=True)
|
|
assert f"swarm-{tag}" in table and f"lone-{tag}" in table
|
|
table = await (await client.get("/hosts/", query_string={"q": tag, "state": "down"},
|
|
headers=swap)).get_data(as_text=True)
|
|
assert "No hosts match these filters." in table
|
|
|
|
# Sorted by name, descending: lone after swarm.
|
|
page = await (await client.get("/hosts/", query_string={"q": tag, "sort": "name", "dir": "desc"})
|
|
).get_data(as_text=True)
|
|
assert page.index(f"swarm-{tag}") < page.index(f"lone-{tag}")
|
|
assert 'aria-sort="descending"' in page
|
|
|
|
# Back to a pushed URL: HTMX asks again, and gets the page.
|
|
restore = {"HX-Request": "true", "HX-History-Restore-Request": "true"}
|
|
page = await (await client.get(f"/hosts/?q={tag}", headers=restore)).get_data(as_text=True)
|
|
assert 'class="filter-bar"' in page
|
|
|
|
asyncio.run(_go())
|