"""Unit tests for the SEO Checker.""" import sys import os import pytest sys.path.insert(0, os.path.join( os.path.dirname(__file__), "..", "marketing-skill", "seo-audit", "scripts" )) from seo_checker import SEOParser, analyze_html, compute_overall_score class TestSEOParser: def test_extracts_title(self): p = SEOParser() p.feed("My Page Title") assert p.title == "My Page Title" def test_extracts_meta_description(self): p = SEOParser() p.feed('') assert p.meta_description == "A great page" def test_extracts_og_description_fallback(self): p = SEOParser() p.feed('') assert p.meta_description == "OG desc" def test_meta_description_takes_priority_over_og(self): p = SEOParser() p.feed('') assert p.meta_description == "Primary" def test_extracts_headings(self): p = SEOParser() p.feed("

Main Title

Section 1

Subsection

") assert len(p.h_tags) == 3 assert p.h_tags[0] == (1, "Main Title") assert p.h_tags[1] == (2, "Section 1") assert p.h_tags[2] == (3, "Subsection") def test_extracts_images(self): p = SEOParser() p.feed('A photo') assert len(p.images) == 2 assert p.images[0]["alt"] == "A photo" assert p.images[1]["alt"] is None def test_extracts_links(self): p = SEOParser() p.feed('Click hereExternal') assert len(p.links) == 2 assert p.links[0]["href"] == "/internal" assert p.links[1]["href"] == "https://example.com" def test_viewport_meta(self): p = SEOParser() p.feed('') assert p.viewport_meta is True def test_ignores_script_content(self): p = SEOParser() p.feed("

Real content

") body_text = " ".join(p.body_text_parts) assert "var x" not in body_text assert "Real content" in body_text class TestAnalyzeHTML: def test_perfect_title(self): # 55 chars is within 50-60 optimal range title = "A" * 55 html = f"{title}" result = analyze_html(html) assert result["title"]["pass"] is True assert result["title"]["score"] == 100 def test_missing_title(self): result = analyze_html("") assert result["title"]["pass"] is False assert result["title"]["score"] == 0 def test_one_h1_passes(self): result = analyze_html("

Title

") assert result["h1"]["pass"] is True assert result["h1"]["count"] == 1 def test_multiple_h1s_fail(self): result = analyze_html("

First

Second

") assert result["h1"]["pass"] is False assert result["h1"]["count"] == 2 def test_no_h1_fails(self): result = analyze_html("

No H1

") assert result["h1"]["pass"] is False assert result["h1"]["count"] == 0 def test_heading_hierarchy_skip(self): result = analyze_html("

Title

Skipped H2

") assert result["heading_hierarchy"]["pass"] is False assert len(result["heading_hierarchy"]["issues"]) == 1 def test_heading_hierarchy_ok(self): result = analyze_html("

Title

Section

Sub

") assert result["heading_hierarchy"]["pass"] is True def test_image_alt_text_all_present(self): result = analyze_html('PhotoIcon') assert result["image_alt_text"]["pass"] is True assert result["image_alt_text"]["coverage_pct"] == 100.0 def test_image_alt_text_missing(self): result = analyze_html('Photo') assert result["image_alt_text"]["pass"] is False assert result["image_alt_text"]["with_alt"] == 1 def test_no_images_passes(self): result = analyze_html("

No images

") assert result["image_alt_text"]["pass"] is True def test_word_count_sufficient(self): words = " ".join(["word"] * 350) result = analyze_html(f"

{words}

") assert result["word_count"]["pass"] is True assert result["word_count"]["count"] >= 300 def test_word_count_insufficient(self): result = analyze_html("

Too few words here

") assert result["word_count"]["pass"] is False def test_viewport_present(self): result = analyze_html('') assert result["viewport_meta"]["pass"] is True def test_viewport_missing(self): result = analyze_html("") assert result["viewport_meta"]["pass"] is False class TestComputeOverallScore: def test_returns_integer(self): html = "Test

Title

" results = analyze_html(html) score = compute_overall_score(results) assert isinstance(score, int) assert 0 <= score <= 100 def test_demo_html_scores_reasonably(self): from seo_checker import DEMO_HTML results = analyze_html(DEMO_HTML) score = compute_overall_score(results) # Demo page is well-optimized, should score above 70 assert score >= 70 class TestEdgeCases: def test_empty_html(self): result = analyze_html("") assert result["title"]["pass"] is False assert result["h1"]["count"] == 0 def test_malformed_html(self): # Should not crash on malformed HTML result = analyze_html("

Unclosed

Nested badly") assert isinstance(result, dict) assert "h1" in result