Coverage for tests/test_served_page.py: 100%
41 statements
« prev ^ index » next coverage.py v7.15.3, created at 2026-08-03 00:00 +0000
« prev ^ index » next coverage.py v7.15.3, created at 2026-08-03 00:00 +0000
1import typing
3import hypothesis
4import pytest
5from hypothesis import strategies as st
7from archdocs import settings
8from tests.rendered_diagram import build_named_settings
9from tests.served_page import ALL_PAGE_RENDERERS, FRAMEWORK_IDS, PageRenderer
12# Minifying the template by joining on "" used to glue attributes onto their tags, turning the
13# mermaid script tag into `<scriptsrc=...>`: the served document is the only proof there is.
14_SERVICE_NAME: typing.Final = "page-svc"
15_MARKED_UP_SERVICE_NAME: typing.Final = "svc<b>&x"
16_RENDERER_ARGUMENT: typing.Final = "render_page"
17_HYPOTHESIS_EXAMPLES: typing.Final = 20
18_TEMPLATE_WITHOUT_A_SLOT: typing.Final = "<!DOCTYPE html><html lang='en'><body>no room here</body></html>"
19_REQUIRED_PAGE_TAGS: typing.Final = (
20 "<!DOCTYPE html>",
21 '<html lang="en">',
22 '<script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js">',
23 '<pre class="archdoc__diagram">',
24 "graph TB",
25)
26_NAME_ALPHABET: typing.Final = st.characters(whitelist_categories=["Ll", "Lu"], whitelist_characters=["_", "-"])
27_NAME_STRATEGY: typing.Final = st.text(min_size=1, max_size=10, alphabet=_NAME_ALPHABET)
30@pytest.mark.parametrize(_RENDERER_ARGUMENT, ALL_PAGE_RENDERERS, ids=FRAMEWORK_IDS)
31def test_default_route_serves_a_whole_document(render_page: PageRenderer) -> None:
32 page_html: typing.Final = render_page(build_named_settings(_SERVICE_NAME), None)
34 for one_required_tag in _REQUIRED_PAGE_TAGS:
35 assert one_required_tag in page_html, one_required_tag
36 assert _SERVICE_NAME in page_html
39# Without settings the scan starts from the working directory, which under pytest is the
40# repository itself: the page has to name the default service and draw its node.
41@pytest.mark.parametrize(_RENDERER_ARGUMENT, ALL_PAGE_RENDERERS, ids=FRAMEWORK_IDS)
42def test_omitted_settings_draw_the_default(render_page: PageRenderer) -> None:
43 page_html: typing.Final = render_page(None, None)
45 assert 'example_service{"example-service' in page_html
48# A template shipped without a `<pre>` slot has nowhere to put the diagram: the page still has
49# to be a page.
50@pytest.mark.parametrize(_RENDERER_ARGUMENT, ALL_PAGE_RENDERERS, ids=FRAMEWORK_IDS)
51def test_template_without_a_slot_is_served_whole(
52 render_page: PageRenderer,
53 monkeypatch: pytest.MonkeyPatch,
54) -> None:
55 monkeypatch.setattr(settings, "UI_HTML_TEMPLATE", _TEMPLATE_WITHOUT_A_SLOT)
57 page_html: typing.Final = render_page(build_named_settings(_SERVICE_NAME), None)
59 assert page_html == _TEMPLATE_WITHOUT_A_SLOT
62@pytest.mark.parametrize(_RENDERER_ARGUMENT, ALL_PAGE_RENDERERS, ids=FRAMEWORK_IDS)
63def test_markup_characters_are_escaped(render_page: PageRenderer) -> None:
64 page_html: typing.Final = render_page(build_named_settings(_MARKED_UP_SERVICE_NAME), None)
66 assert 'svc<b>&x"}' in page_html
67 assert "svc<b>" not in page_html
70@pytest.mark.parametrize(_RENDERER_ARGUMENT, ALL_PAGE_RENDERERS, ids=FRAMEWORK_IDS)
71@hypothesis.settings(deadline=None, max_examples=_HYPOTHESIS_EXAMPLES)
72@hypothesis.given(service_name=_NAME_STRATEGY, route_value=_NAME_STRATEGY)
73def test_any_service_name_and_route_are_served(
74 render_page: PageRenderer,
75 service_name: str,
76 route_value: str,
77) -> None:
78 page_html: typing.Final = render_page(build_named_settings(service_name), f"/{route_value}")
80 assert service_name in page_html