# retoor from devplacepy.services.jobs.seo.checks import registry from devplacepy.services.jobs.seo.checks.base import ( Check, PageContext, SiteContext, PASS, WARN, FAIL, INFO, SKIP, CRITICAL, HIGH, LOW, ) def _check(status, severity, category="meta"): return Check( id=f"{category}.{status}", category=category, title="t", status=status, severity=severity, ) def test_all_pass_scores_100_grade_a(): checks = [_check(PASS, HIGH), _check(PASS, CRITICAL)] result = registry.compute_score(checks) assert result["score"] == 100 assert result["grade"] == "A" def test_all_fail_scores_0_grade_f(): checks = [_check(FAIL, HIGH), _check(FAIL, CRITICAL)] result = registry.compute_score(checks) assert result["score"] == 0 assert result["grade"] == "F" def test_warn_gives_half_credit(): result = registry.compute_score([_check(WARN, HIGH)]) assert result["score"] == 50 def test_info_and_skip_excluded_from_weight(): checks = [_check(INFO, LOW), _check(SKIP, LOW), _check(PASS, HIGH)] result = registry.compute_score(checks) assert result["score"] == 100 assert result["counts"]["info"] == 1 assert result["counts"]["skip"] == 1 assert result["counts"]["pass"] == 1 def test_informational_severity_zero_weight_ignored(): checks = [_check(FAIL, "info"), _check(PASS, HIGH)] result = registry.compute_score(checks) assert result["score"] == 100 def test_severity_weighting_favours_critical(): checks = [_check(FAIL, CRITICAL), _check(PASS, LOW)] result = registry.compute_score(checks) assert result["score"] < 50 def test_grade_boundaries(): assert registry._grade(90) == "A" assert registry._grade(89) == "B" assert registry._grade(80) == "B" assert registry._grade(70) == "C" assert registry._grade(55) == "D" assert registry._grade(54) == "F" def test_categories_reported_per_bucket(): checks = [ _check(PASS, HIGH, category="meta"), _check(FAIL, HIGH, category="links"), ] result = registry.compute_score(checks) assert result["categories"]["meta"]["score"] == 100 assert result["categories"]["links"]["score"] == 0 def test_empty_checks_scores_zero(): result = registry.compute_score([]) assert result["score"] == 0 assert result["grade"] == "F" def test_run_page_checks_returns_checks(): page = PageContext( requested_url="https://example.com", url="https://example.com", status=200, ok=True, rendered_html="Hi", ) site = SiteContext(target_url="https://example.com", base_host="example.com") checks = registry.run_page_checks(page, site) assert isinstance(checks, list) assert all(isinstance(c, Check) for c in checks) def test_run_site_checks_returns_checks(): site = SiteContext(target_url="https://example.com", base_host="example.com") checks = registry.run_site_checks(site) assert isinstance(checks, list) assert all(isinstance(c, Check) for c in checks) def test_bad_page_check_does_not_abort(monkeypatch): def explode(page, site): raise RuntimeError("boom") monkeypatch.setattr(registry, "PAGE_CHECKS", [explode]) page = PageContext(url="https://example.com", ok=True) site = SiteContext(target_url="https://example.com") checks = registry.run_page_checks(page, site) assert len(checks) == 1 assert checks[0].status == INFO assert "explode" in checks[0].id