82 lines
3.1 KiB
Python
82 lines
3.1 KiB
Python
"""Online-Hilfe (→ KONZEPT.md 13): alle Themen, Links, Suche, Linter-Regeln."""
|
|
|
|
import re
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
from hugin_app import docs
|
|
from hugin_core.linter.rules import RULES
|
|
from test_app import env # noqa: F401 (Fixture)
|
|
from test_web import browser, csp_clean
|
|
|
|
|
|
@pytest.mark.parametrize("topic", [t.slug for t in docs.TOPICS])
|
|
def test_each_topic_without_and_with_login(env, topic):
|
|
for c in (TestClient(env.client.app), browser(env, "shop-lesen")):
|
|
response = c.get(f"/help/{topic}")
|
|
assert response.status_code == 200
|
|
assert "[[" not in response.text, "Platzhalter nicht ersetzt"
|
|
assert csp_clean(response.text) == []
|
|
assert docs.BY_SLUG[topic].title in response.text
|
|
|
|
|
|
def test_all_help_links_resolve(env):
|
|
c = browser(env, "pub-autor")
|
|
seen = set()
|
|
for t in docs.TOPICS:
|
|
page = c.get(f"/help/{t.slug}").text
|
|
article = page[page.index('<article'):page.index('</article>')]
|
|
for href in re.findall(r'href="([^"]+)"', article):
|
|
if href.startswith("http") or href in seen:
|
|
continue
|
|
seen.add(href)
|
|
response = c.get(href, follow_redirects=True)
|
|
assert response.status_code in (200, 403), f"{t.slug}: Link {href} → {response.status_code}"
|
|
assert "/help/teams" in seen and "/catalog" in seen
|
|
|
|
|
|
def test_each_linter_rule_is_described():
|
|
sources = (Path(__file__).parents[1] / "src").rglob("*.py")
|
|
in_code = {k for p in sources for k in re.findall(r'(?:_error|_hint|Finding)\("(H\d{3})"', p.read_text())}
|
|
described = {k for k, _, _ in RULES}
|
|
assert in_code == described, f"fehlt in REGELN: {in_code - described}, überzählig: {described - in_code}"
|
|
|
|
|
|
def test_rules_table_in_help(env):
|
|
page = TestClient(env.client.app).get("/help/linter").text
|
|
for code, _, _ in RULES:
|
|
assert f"<code>{code}</code>" in page
|
|
|
|
|
|
def test_search(env):
|
|
c = TestClient(env.client.app)
|
|
page = c.get("/help?q=probe").text
|
|
assert "Programm hugin" in page and "Pakete schreiben" in page
|
|
assert "Nichts gefunden" in c.get("/help?q=quantenkuchen").text
|
|
|
|
|
|
def test_server_address_inserted(env):
|
|
assert "hugin init --server http://testserver" in TestClient(env.client.app).get("/help/teams").text
|
|
|
|
|
|
def test_html_in_text_not_executed(monkeypatch):
|
|
monkeypatch.setattr(docs, "source_text", lambda slug: "# T\n\n<script>alert(1)</script> [x](javascript:alert(1))")
|
|
output = docs.html("start", "http://x", lambda h: h)
|
|
assert "<script>" not in output and "<script>" in output and 'href="javascript:' not in output
|
|
|
|
|
|
def test_each_role_explained(env):
|
|
from hugin_app.auth import ROLES
|
|
text = env.client.get("/help/roles").text
|
|
for role in ROLES:
|
|
assert f"<code>{role}</code>" in text, role
|
|
|
|
|
|
def test_each_kind_explained(env):
|
|
"""Jede Art aus dem Manifest hat einen Abschnitt in der Hilfe „Arten von Paketen“."""
|
|
from hugin_core.package import Kind
|
|
text = docs.source_text("kinds")
|
|
for kind in Kind:
|
|
assert f"(`{kind.value}`)" in text, f"Art {kind.value} fehlt in kinds.md"
|