# retoor <retoor@molodetz.nl>

from devplacepy.seo_meta_text import (
    DESCRIPTION_MAX,
    KEYWORDS_MAX,
    TITLE_MAX,
    clamp_generated,
    derive_keywords,
    plain_seo_defaults,
    plain_text_from_markdown,
)


def test_plain_text_strips_markdown_markup():
    out = plain_text_from_markdown("# Heading\n\n**bold** and `code` and [link](http://x.test)")
    assert "#" not in out
    assert "**" not in out
    assert "`" not in out
    assert "](" not in out
    assert "bold" in out
    assert "link" in out


def test_plain_seo_defaults_always_filled():
    result = plain_seo_defaults("", "")
    assert result["title"]
    assert result["description"]
    assert set(result) == {"title", "description", "keywords"}


def test_plain_seo_defaults_uses_title_when_body_empty():
    result = plain_seo_defaults("My Great Title", "")
    assert result["title"] == "My Great Title"
    assert result["description"] == "My Great Title"


def test_plain_seo_defaults_description_has_no_markdown():
    body = "## Section\n\nThis is **important** content with a [ref](http://x.test) inside."
    result = plain_seo_defaults("Title here", body)
    assert "##" not in result["description"]
    assert "**" not in result["description"]
    assert "](" not in result["description"]
    assert "important" in result["description"]


def test_plain_seo_defaults_clamps_lengths():
    long_title = "word " * 40
    long_body = "sentence body text " * 60
    result = plain_seo_defaults(long_title, long_body)
    assert len(result["title"]) <= TITLE_MAX
    assert len(result["description"]) <= DESCRIPTION_MAX


def test_plain_seo_defaults_keywords_filled_from_content():
    result = plain_seo_defaults(
        "Async Python Database Tooling",
        "A guide to building async python database tooling with sqlite.",
    )
    assert result["keywords"]
    terms = [term for term in result["keywords"].split(", ") if term]
    assert "python" in terms
    assert "the" not in terms
    assert "a" not in terms


def test_derive_keywords_dedupes_and_skips_stopwords():
    keywords = derive_keywords("Python python", "the python and the database database engine")
    terms = keywords.split(", ")
    assert terms.count("python") == 1
    assert "the" not in terms
    assert "and" not in terms
    assert "database" in terms


def test_derive_keywords_respects_limit():
    body = " ".join(f"keyword{n}" for n in range(40))
    keywords = derive_keywords("title", body)
    terms = [term for term in keywords.split(", ") if term]
    assert len(terms) <= KEYWORDS_MAX


def test_clamp_generated_strips_markup_and_normalizes_keywords():
    result = clamp_generated(
        "**Clean** Title",
        "Some `markdown` description here.",
        "Python, Python,  SQLite ;async\nweb",
    )
    assert "**" not in result["title"]
    assert "`" not in result["description"]
    terms = result["keywords"].split(", ")
    assert terms.count("python") == 1
    assert "sqlite" in terms
    assert "async" in terms
    assert "web" in terms


def test_clamp_generated_honors_keyword_cap():
    raw = ", ".join(f"term{n}" for n in range(40))
    result = clamp_generated("t", "d", raw)
    terms = [term for term in result["keywords"].split(", ") if term]
    assert len(terms) <= KEYWORDS_MAX
