FluxIP/tests/test_status_schedule_api.py

168 lines
5.6 KiB
Python

from __future__ import annotations
from typing import Any
import pytest
from fastapi.testclient import TestClient
from tests.conftest import csrf_headers
def create(
client: TestClient,
path: str,
payload: dict[str, object],
) -> dict[str, Any]:
response = client.post(path, json=payload, headers=csrf_headers(client))
assert response.status_code == 201, response.text
return response.json()["data"]
def configure_credentials(client: TestClient, payload: dict[str, object]) -> None:
response = client.put(
"/api/v1/integrations",
json=payload,
headers=csrf_headers(client),
)
assert response.status_code == 200, response.text
def finish_failed(client: TestClient, run_id: str) -> None:
repository = client.app.state.container.rotation_repository
assert repository.acquire_lease(run_id, "api-test-worker") is True
repository.transition_run(run_id, status="running", expected_owner="api-test-worker")
item = repository.current_item(run_id)
assert item is not None
repository.fail_execution(
run_id,
item.id,
error_code="TEST_FAILURE",
error_message="test failure",
outcome="failed",
expected_owner="api-test-worker",
)
def test_dashboard_aggregates_instances_groups_and_schedule_state(
authenticated_client: TestClient,
managed_instance_payload: dict[str, object],
group_payload: dict[str, object],
) -> None:
client = authenticated_client
first = create(client, "/api/v1/instances", managed_instance_payload)
second = create(
client,
"/api/v1/instances",
{
**managed_instance_payload,
"id": "instance-two",
"display_name": "Proxy Two",
"lightsail_instance_name": "proxy-node-two",
"cloudflare_record_name": "two.example.com",
"enabled": False,
},
)
group = create(
client,
"/api/v1/instance-groups",
{**group_payload, "member_ids": [first["id"], second["id"]]},
)
response = client.get("/api/v1/status?refresh=true")
assert response.status_code == 200
data = response.json()["data"]
assert data["summary"] == {
"instances": 2,
"enabled_instances": 1,
"groups": 1,
"enabled_groups": 1,
"active_runs": 0,
"next_run_at": group["next_run_at"],
}
assert data["groups"][0]["member_count"] == 2
assert data["groups"][0]["enabled_member_count"] == 1
assert data["active_run"] is None
assert data["recent_runs"] == []
assert data["server_time"].endswith("Z")
def test_manual_rotation_routes_history_filters_csrf_and_removed_schedule(
authenticated_client: TestClient,
integration_payload: dict[str, object],
managed_instance_payload: dict[str, object],
group_payload: dict[str, object],
monkeypatch: pytest.MonkeyPatch,
) -> None:
client = authenticated_client
configure_credentials(client, integration_payload)
first = create(client, "/api/v1/instances", managed_instance_payload)
second = create(
client,
"/api/v1/instances",
{
**managed_instance_payload,
"id": "instance-two",
"display_name": "Proxy Two",
"lightsail_instance_name": "proxy-node-two",
"cloudflare_record_name": "two.example.com",
},
)
group = create(
client,
"/api/v1/instance-groups",
{**group_payload, "member_ids": [second["id"]]},
)
rotation_service = client.app.state.container.rotation_service
spawned: list[str] = []
monkeypatch.setattr(rotation_service, "_spawn", spawned.append)
denied = client.post(f"/api/v1/instances/{first['id']}/rotations")
assert denied.status_code == 403
instance_run = client.post(
f"/api/v1/instances/{first['id']}/rotations",
headers=csrf_headers(client),
)
assert instance_run.status_code == 202, instance_run.text
instance_run_id = instance_run.json()["data"]["id"]
assert instance_run.headers["location"] == f"/api/v1/rotations/{instance_run_id}"
assert spawned == [instance_run_id]
finish_failed(client, instance_run_id)
group_run = client.post(
f"/api/v1/instance-groups/{group['id']}/rotations",
headers=csrf_headers(client),
)
assert group_run.status_code == 202, group_run.text
group_run_id = group_run.json()["data"]["id"]
assert spawned[-1] == group_run_id
by_instance = client.get(f"/api/v1/rotations?instance_id={first['id']}").json()
assert by_instance["pagination"]["total"] == 1
assert by_instance["data"][0]["id"] == instance_run_id
by_group = client.get(f"/api/v1/rotations?group_id={group['id']}").json()
assert by_group["pagination"]["total"] == 1
assert by_group["data"][0]["id"] == group_run_id
failed = client.get("/api/v1/rotations?status=failed").json()
assert failed["pagination"]["total"] == 1
assert failed["data"][0]["error_code"] == "TEST_FAILURE"
assert failed["summary"] == {
"total": 2,
"completed": 1,
"succeeded": 0,
"latest_success_at": None,
}
detail = client.get(f"/api/v1/rotations/{group_run_id}")
assert detail.status_code == 200
assert detail.json()["data"]["items"][0]["instance_id"] == second["id"]
assert detail.json()["data"]["events"][0]["stage"] == "queued"
assert client.get("/api/v1/schedule").status_code == 404
assert (
client.put(
"/api/v1/schedule",
json={"enabled": True, "interval_minutes": 15},
headers=csrf_headers(client),
).status_code
== 404
)