"""The sync route. Storage correctness is covered elsewhere; this checks the
route's contract and that a caller cannot trigger a sync for a source that is
not connected.
"""
import pytest
from fastapi.testclient import TestClient

from app.main import app

client = TestClient(app)
TENANT = "org_8c32bf3e-6a18-4739-9b1c-94c0cf11125f"


def test_unknown_tenant_returns_404():
    resp = client.post("/catalog/sync", data={"tenant_id": "org_does_not_exist"})
    assert resp.status_code == 404


def test_unknown_source_ref_returns_404():
    resp = client.post("/catalog/sync", data={
        "tenant_id": TENANT, "source_ref": "not-a-real-shop.myshopify.com"})
    assert resp.status_code == 404


def test_tenant_id_is_required():
    assert client.post("/catalog/sync", data={}).status_code == 422


def test_route_is_registered():
    # This FastAPI version wraps included routers in a lazy _IncludedRouter
    # that has no `.path`, so registered routes must be walked recursively.
    def collect_paths(routes):
        paths = set()
        for r in routes:
            path = getattr(r, "path", None)
            if path:
                paths.add(path)
            elif hasattr(r, "original_router"):
                paths |= collect_paths(r.original_router.routes)
        return paths

    assert "/catalog/sync" in collect_paths(app.routes)


def test_a_failing_source_reports_an_error_without_failing_the_request(monkeypatch):
    # One broken source must not hide the results of the others. wait=true
    # keeps the pre-job-polling contract: synchronous, report inline.
    from app.api import endpoints

    async def boom(tenant_id, source):
        raise RuntimeError("token rejected")

    monkeypatch.setattr(endpoints, "sync_source", boom)
    monkeypatch.setattr(endpoints, "get_sources", lambda t: [
        {"kind": "shopify", "external_ref": "s.myshopify.com", "config": {}}])

    resp = client.post("/catalog/sync", data={"tenant_id": TENANT, "wait": "true"})
    assert resp.status_code == 200
    assert "error" in resp.json()["results"][0]
