from __future__ import annotations from conftest import fixture_text from companyatlas.sdk import normalize as N from companyatlas.sdk.diff import compare from companyatlas.taxonomy import ChangeKind, change_kind URL = "https://www.acme-cloud.example/pricing" def _page(name: str, url: str = URL) -> N.NormalizedPage: return N.parse(fixture_text("generic_html", name), url=url) def test_same_page_twice_is_zero() -> None: a = _page("pricing.html") d = compare(a.blocks, a.blocks, surface="pricing", before_text=a.text, after_text=a.text) assert d.significance == 0.0 and d.is_empty and d.reasons == ["identical"] def test_footer_year_change_is_noise() -> None: html = fixture_text("generic_html", "pricing.html") a, b = N.parse(html, url=URL), N.parse(html.replace("© 2025", "© 2026"), url=URL) d = compare(a.blocks, b.blocks, surface="pricing", before_text=a.text, after_text=b.text) assert d.significance < 0.20 assert change_kind(d.significance) is ChangeKind.NOISE def test_nav_only_churn_is_noise() -> None: html = fixture_text("generic_html", "pricing.html") b = N.parse(html.replace('Docs', 'Docs Partners'), url=URL) a = N.parse(html, url=URL) d = compare(a.blocks, b.blocks, surface="pricing", before_text=a.text, after_text=b.text) assert d.significance < 0.20 assert any("nav/footer" in r for r in d.reasons) def test_price_change_with_typed_delta_is_major() -> None: a, b = _page("pricing.html"), _page("pricing_v2.html") delta = {"plans": {"added": [], "removed": [], "price_changed": [{"plan_name": "Starter", "before": 29, "after": 39, "currency": "USD", "billing_period": "month", "pct": 34.5}]}} d = compare(a.blocks, b.blocks, surface="pricing", before_text=a.text, after_text=b.text, structured_delta=delta) assert d.significance >= 0.65 assert len(d.modified) == 1 and d.modified[0].kind == "pricing_plan" assert any("typed delta plans.price_changed" in r for r in d.reasons) def test_tiny_text_edit_without_typed_delta_is_noise() -> None: html = fixture_text("generic_html", "pricing.html") a = N.parse(html, url=URL) b = N.parse(html.replace("No credit card required.", "No credit card needed."), url=URL) d = compare(a.blocks, b.blocks, surface="pricing", before_text=a.text, after_text=b.text) assert d.significance < 0.20 def test_new_job_listings_are_meaningful() -> None: a = _page("careers.html", "https://www.acme-cloud.example/careers") b = _page("careers_v2.html", "https://www.acme-cloud.example/careers") delta = {"jobs": {"added": [{"title": "AI Research Scientist"}, {"title": "Data Platform Engineer"}], "removed": [{"title": "People Operations Lead"}], "open_before": 5, "open_after": 6}} d = compare(a.blocks, b.blocks, surface="careers", before_text=a.text, after_text=b.text, structured_delta=delta) assert change_kind(d.significance) in (ChangeKind.MEANINGFUL, ChangeKind.MAJOR) assert len(d.added) >= 2 and len(d.removed) >= 1 def test_whole_redesign_is_major() -> None: a = _page("legal_terms.html", "https://www.acme-cloud.example/") b = _page("homepage.html", "https://www.acme-cloud.example/") d = compare(a.blocks, b.blocks, surface="homepage", before_text=a.text, after_text=b.text) assert change_kind(d.significance) in (ChangeKind.MAJOR, ChangeKind.CRITICAL) assert d.text_delta_ratio > 0.5 def test_reordered_blocks_are_moves_not_add_remove() -> None: html = fixture_text("generic_html", "legal_terms.html") a = N.parse(html, url=URL) sec2 = html[html.index("