75 lines
2.6 KiB
Python
75 lines
2.6 KiB
Python
|
|
"""Tests for the crawlable SEO content pages: the city set, robots/sitemap, and
|
||
|
|
that the server-rendered pages contain the stats in the HTML (with the weather
|
||
|
|
layer faked, like test_api.py)."""
|
||
|
|
import pytest
|
||
|
|
from fastapi.testclient import TestClient
|
||
|
|
|
||
|
|
import app as appmod
|
||
|
|
import cities
|
||
|
|
import climate
|
||
|
|
|
||
|
|
# BASE defaults to /thermograph in tests (THERMOGRAPH_BASE unset).
|
||
|
|
B = "/thermograph"
|
||
|
|
SLUG = "london-england-gb" # present in cities.json
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.fixture
|
||
|
|
def client(monkeypatch, history, recent):
|
||
|
|
monkeypatch.setattr(climate, "load_cached_history", lambda cell: history.clone())
|
||
|
|
monkeypatch.setattr(climate, "get_recent_forecast", lambda cell: recent.clone())
|
||
|
|
monkeypatch.setattr(climate, "get_history", lambda cell: (history.clone(), {"cached": True}))
|
||
|
|
return TestClient(appmod.app)
|
||
|
|
|
||
|
|
|
||
|
|
def test_city_set_slugs_unique_and_lookup():
|
||
|
|
slugs = cities.all_slugs()
|
||
|
|
assert len(slugs) == len(set(slugs)) >= 100
|
||
|
|
assert cities.get(SLUG) is not None
|
||
|
|
assert cities.get("does-not-exist") is None
|
||
|
|
|
||
|
|
|
||
|
|
def test_robots_txt(client):
|
||
|
|
r = client.get(f"{B}/robots.txt")
|
||
|
|
assert r.status_code == 200
|
||
|
|
assert "Sitemap:" in r.text and "/sitemap.xml" in r.text
|
||
|
|
assert "Disallow: /thermograph/api/" in r.text
|
||
|
|
|
||
|
|
|
||
|
|
def test_sitemap_lists_city_urls(client):
|
||
|
|
r = client.get(f"{B}/sitemap.xml")
|
||
|
|
assert r.status_code == 200
|
||
|
|
assert "<urlset" in r.text
|
||
|
|
assert f"/climate/{SLUG}</loc>" in r.text
|
||
|
|
assert f"/climate/{SLUG}/july</loc>" in r.text
|
||
|
|
assert f"/climate/{SLUG}/records</loc>" in r.text
|
||
|
|
|
||
|
|
|
||
|
|
def test_city_page_renders_stats_in_html(client):
|
||
|
|
r = client.get(f"{B}/climate/{SLUG}")
|
||
|
|
assert r.status_code == 200
|
||
|
|
b = r.text
|
||
|
|
assert "London" in b and "climate" in b.lower()
|
||
|
|
assert 'rel="canonical"' in b and f"/climate/{SLUG}" in b
|
||
|
|
assert '"@type":"Dataset"' in b
|
||
|
|
assert "average temperatures by month" in b.lower()
|
||
|
|
# a real number rendered (°F appears in the normals/today text)
|
||
|
|
assert "°F" in b
|
||
|
|
|
||
|
|
|
||
|
|
def test_city_404(client):
|
||
|
|
assert client.get(f"{B}/climate/nope-not-a-city").status_code == 404
|
||
|
|
|
||
|
|
|
||
|
|
def test_month_and_records(client):
|
||
|
|
assert client.get(f"{B}/climate/{SLUG}/july").status_code == 200
|
||
|
|
assert client.get(f"{B}/climate/{SLUG}/records").status_code == 200
|
||
|
|
assert client.get(f"{B}/climate/{SLUG}/notamonth").status_code == 404
|
||
|
|
|
||
|
|
|
||
|
|
def test_hub_glossary_about(client):
|
||
|
|
assert client.get(f"{B}/climate").status_code == 200
|
||
|
|
assert client.get(f"{B}/glossary").status_code == 200
|
||
|
|
assert client.get(f"{B}/glossary/percentile").status_code == 200
|
||
|
|
assert client.get(f"{B}/glossary/not-a-term").status_code == 404
|
||
|
|
assert client.get(f"{B}/about").status_code == 200
|