"""URL fragments never change server-rendered content, and a storefront's
related-products widget appends unique tracking query strings to every link
to the same product -- both must not make the crawler think a page it has
already visited is new."""
from unittest.mock import AsyncMock, patch

import pytest

from app.services.content import website


def _rendered(url, links, title="Page"):
    return (
        f"<html><title>{title}</title></html>",
        [{"href": href, "text": text} for href, text in links],
        {"title": title},
    )


def test_fragment_only_variants_share_a_dedup_key():
    base = "https://shop.example.com/products/shirt"
    assert website._dedup_key(base) == website._dedup_key(f"{base}#")
    assert website._dedup_key(base) == website._dedup_key(f"{base}#main-content")


def test_tracking_query_variants_of_a_product_url_share_a_dedup_key():
    a = "https://shop.example.com/products/shirt?pr_rec_id=abc&pr_ref_pid=1"
    b = "https://shop.example.com/products/shirt?pr_rec_id=xyz&pr_ref_pid=2"
    assert website._dedup_key(a) == website._dedup_key(b) == website._dedup_key(
        "https://shop.example.com/products/shirt")


def test_non_product_urls_keep_their_query_string_distinct():
    # extract_text_from_url is shared with the general site-scrape path,
    # where a query string can mean real pagination -- collapsing these
    # would silently skip content on that path.
    a = "https://shop.example.com/blog?page=1"
    b = "https://shop.example.com/blog?page=2"
    assert website._dedup_key(a) != website._dedup_key(b)


@pytest.mark.asyncio
async def test_fragment_and_tracking_param_variants_are_visited_once():
    home = "https://shop.example.com/"
    product = "https://shop.example.com/products/shirt"

    async def fake_render(current_url, *a, **kw):
        if current_url == home:
            return _rendered(home, [
                (f"{product}?pr_rec_id=aaa&pr_ref_pid=1", "Shirt"),
                (f"{product}#main-content", "Shirt again"),
                (f"{product}?pr_rec_id=bbb&pr_ref_pid=2", "Shirt via another widget"),
            ])
        return _rendered(current_url, [])

    fake_browser = AsyncMock()
    fake_browser.get_rendered_content = fake_render

    with patch.object(website, "get_browser", AsyncMock(return_value=fake_browser)):
        result = await website.extract_text_from_url(home, max_depth=2, max_pages=10)

    assert len(result["urls_visited"]) == 2
    assert home in result["urls_visited"]
    assert sum(1 for u in result["urls_visited"] if u.startswith(product)) == 1
