"""Schedules read as sentences and each has its own page (#5332): the list's row opens it, Run now and Pause stay in the row, and Delete is on the page behind the confirm dialog.""" from datetime import datetime, timedelta, timezone from types import SimpleNamespace as NS from quart import render_template, session from steward.models.ansible import AnsibleRunStatus from tests.test_style_tokens import hex_colours NOW = datetime.now(timezone.utc) def _sched(sid="s1", name="Nightly prune", enabled=True, last_error=None, check=False): return NS(id=sid, name=name, enabled=enabled, source_name="steward-builtin", playbook_path="maintenance/docker_prune.yml", inventory_scope="steward:group:g1", interval_seconds=86400, last_error=last_error, last_run_at=NOW - timedelta(hours=22), last_run_id="r1", params={"check": True} if check else None) def _last(status=AnsibleRunStatus.success): return NS(id="r1", status=status, started_at=NOW - timedelta(hours=22)) async def test_the_schedules_list_reads_as_sentences(app): ok, broken = _sched(), _sched("s2", "Weekly update", last_error="Playbook not found") rows = [{"s": broken, "last_run": None, "scope_label": "group Docker Swarm", "next": None}, {"s": ok, "last_run": _last(), "scope_label": "group Docker Swarm", "next": {"id": "s1", "name": "Nightly prune", "at": NOW + timedelta(hours=2)}}] async with app.test_request_context("/ansible/schedules"): session["user_role"] = "operator" page = await render_template("ansible/schedules.html", rows=rows, failing=1, paused=0, next=rows[1]["next"]) main = page[page.index("1 of 2 failing' in main assert main.count('') == 2 and 'href="/ansible/schedules/s1"' in main assert "maintenance/docker_prune.yml on group Docker Swarm" in main and "daily" in main assert '
Playbook not found' in main assert main.count(">Run now") == 2 and ">Pause" in main assert "/delete" not in main and 'href="/ansible/schedules/new"' in main # Delete is on the schedule's page assert 'Schedules' in main assert not hex_colours(main), hex_colours(main) def _page_ctx(editing): return {"editing": editing, "groups": [NS(id="g1", name="Docker Swarm")], "targets": [], "source_data": [{"name": "steward-builtin", "playbooks": ["maintenance/docker_prune.yml"]}], "sel_source": "steward-builtin", "sel_playbook": "maintenance/docker_prune.yml", "sel_playbooks": ["maintenance/docker_prune.yml"], "interval_presets": [(86400, "Daily")], "edit_variables": [], "edit_description": "", "edit_category": "", "edit_confirm": False, "last_run": _last() if editing else None, "scope_label": "group Docker Swarm" if editing else None, "next": {"id": "s1", "name": "Nightly prune", "at": NOW + timedelta(hours=2)} if editing else None} async def test_a_schedule_page_says_what_it_does_and_deletes_behind_the_dialog(app): async with app.test_request_context("/ansible/schedules/s1"): session["user_role"] = "operator" page = await render_template("ansible/schedule.html", **_page_ctx(_sched(check=True))) main = page[page.index("'):] verdict = verdict[:verdict.index("

")] assert 'href="/ansible/playbooks/steward-builtin/maintenance/docker_prune.yml"' in verdict assert "on group Docker Swarm · daily" in verdict and "dry run" in verdict and "next Succeeded' in verdict assert 'action="/ansible/schedules/s1"' in main and 'value="Nightly prune"' in main assert 'name="check" checked' in main assert 'data-confirm="Delete schedule Nightly prune?' in main and 'action="/ansible/schedules/s1/delete"' in main assert ">Run now" in main assert 'style="' not in main[main.index('id="form"'):] # the form on classes assert not hex_colours(main), hex_colours(main) async def test_a_new_schedule_starts_on_the_chosen_playbook(app): async with app.test_request_context("/ansible/schedules/new"): session["user_role"] = "operator" page = await render_template("ansible/schedule.html", **_page_ctx(None)) assert "New schedule — Steward" in page assert 'action="/ansible/schedules"' in page and "/delete" not in page assert '