Ctrl K
ComunidadGuías…

tests/e2e/test_requests_overseerr_e2e.py

Rama dev · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""Routing requests through Overseerr/Jellyseerr, driven through the real screens (discussion #110).

Round-tripped through the API rather than asserted on the DOM alone: a chooser that renders and
saves nothing would pass a render-only check, and what the target setting is worth is entirely the
value that reaches a run.

Nothing here answers as Overseerr — no fake serves its API — which is deliberate. The account list
is fetched, so this covers the case the card has to survive: the target is chosen, saved and
reloaded even when the instance behind it never replies.
"""

from __future__ import annotations

import pytest
from playwright.sync_api import Page, expect

from tests.e2e.conftest import ShortlistApp

pytestmark = pytest.mark.e2e

LOAD = 15_000


def _saved_status(page: Page):
    """The Requests tab's own "Saved" readout (it has no save bar)."""
    return page.get_by_role("status").get_by_text("Saved", exact=True)


def _panel(page: Page):
    """The Requests panel alone.

    Scoped, not page-wide: Settings → Connections carries its own Radarr, Sonarr and Overseerr cards,
    which stay on screen whichever route is chosen. A page-wide locator therefore matches the
    connection card as well as the control under test — "Overseerr / Jellyseerr" resolves to two
    buttons, and "Radarr" is present no matter what the target is set to.
    """
    return page.locator("section#requests")


def _connect_overseerr(app: ShortlistApp) -> None:
    """Requests on, with Overseerr's address and key saved — what makes the card render its controls."""
    app.api(
        "PUT",
        "/api/settings",
        json={
            "values": {
                "requests.enabled": True,
                "requests.overseerr.url": "http://overseerr.invalid",
                "requests.overseerr.apikey": "fake-key",
            }
        },
    )


def test_switching_the_target_saves_and_survives_a_reload(page: Page, app: ShortlistApp):
    _connect_overseerr(app)
    page.goto("/settings#requests")

    expect(_panel(page).get_by_role("button", name="Radarr & Sonarr")).to_have_attribute(
        "aria-pressed", "true", timeout=LOAD
    )
    _panel(page).get_by_role("button", name="Overseerr / Jellyseerr", exact=True).click()

    # Autosave has no button; the stored value is the real wait.
    expect(_saved_status(page)).to_be_visible(timeout=LOAD)
    app.wait_for_setting("requests.target", "overseerr")

    page.reload()
    expect(_panel(page).get_by_role("button", name="Overseerr / Jellyseerr", exact=True)).to_have_attribute(
        "aria-pressed", "true", timeout=LOAD
    )


def test_the_overseerr_card_replaces_the_two_arr_cards(page: Page, app: ShortlistApp):
    _connect_overseerr(app)
    app.api("PUT", "/api/settings", json={"values": {"requests.target": "overseerr"}})
    page.goto("/settings#requests")

    expect(_panel(page).get_by_label("Request as")).to_be_visible(timeout=LOAD)
    expect(_panel(page).get_by_text("Radarr", exact=True)).to_have_count(0)
    expect(_panel(page).get_by_text("Sonarr", exact=True)).to_have_count(0)
    # Guardrails belong to Shortlist, not to the app doing the fetching, so they stay on both routes.
    expect(_panel(page).get_by_text("Guardrails", exact=True)).to_be_visible()


def test_the_tag_fields_are_gone_because_overseerr_cannot_carry_them(page: Page, app: ShortlistApp):
    """Overseerr's POST /request body has no tags field, so offering the setting would be a lie."""
    _connect_overseerr(app)
    app.api("PUT", "/api/settings", json={"values": {"requests.target": "overseerr"}})
    page.goto("/settings#requests")

    expect(_panel(page).get_by_label("Request as")).to_be_visible(timeout=LOAD)
    expect(_panel(page).get_by_label("Tag added items")).to_have_count(0)
    expect(_panel(page).get_by_label("Also tag by person")).to_have_count(0)


def test_the_default_route_still_shows_radarr_and_sonarr(page: Page, app: ShortlistApp):
    """The control case. Adding a second route must not change what an existing install sees."""
    app.api("PUT", "/api/settings", json={"values": {"requests.enabled": True}})
    page.goto("/settings#requests")

    expect(_panel(page).get_by_text("Radarr", exact=True).first).to_be_visible(timeout=LOAD)
    expect(_panel(page).get_by_text("Sonarr", exact=True).first).to_be_visible()
    expect(_panel(page).get_by_label("Request as")).to_have_count(0)