Coverage for tests/integration/test_snippets.py: 100%
36 statements
« prev ^ index » next coverage.py v7.10.3, created at 2026-08-22 19:08 +0000
« prev ^ index » next coverage.py v7.10.3, created at 2026-08-22 19:08 +0000
1import typing
3import hypothesis
4import hypothesis.strategies as st
5import pytest
7from meta_tags_parser import parse_snippets_from_source, structs
10SNIPPET_PAGE_FIXTURE: typing.Final = """
11<html><head>
12<meta property="og:title" content="Meta Tags — Preview, Edit and Generate">
13<meta property="og:description" content="Edit and experiment with your content.">
14<meta property="og:url" content="https://metatags.io/">
15<meta property="og:image" content="https://metatags.io/assets/preview.png">
16<meta property="og:image:width" content="1200">
17<meta property="og:image:height" content="630">
18<meta name="twitter:card" content="summary_large_image">
19<meta name="twitter:title" content="Privet, kak dela to vcelom?">
20<meta name="twitter:description" content="Twitter flavoured description.">
21<meta name="twitter:url" content="https://metatags.io/">
22<meta name="twitter:image" content="https://metatags.io/assets/hm-fail.png">
23<meta name="twitter:image:width" content="800">
24<meta name="twitter:image:height" content="418">
25</head></html>
26"""
27EXPECTED_SNIPPET_GROUP: typing.Final = structs.SnippetGroup(
28 open_graph=structs.SocialMediaSnippet(
29 title="Meta Tags — Preview, Edit and Generate",
30 description="Edit and experiment with your content.",
31 image="https://metatags.io/assets/preview.png",
32 image_width=1200,
33 image_height=630,
34 url="https://metatags.io/",
35 ),
36 twitter=structs.SocialMediaSnippet(
37 title="Privet, kak dela to vcelom?",
38 description="Twitter flavoured description.",
39 image="https://metatags.io/assets/hm-fail.png",
40 image_width=800,
41 image_height=418,
42 url="https://metatags.io/",
43 ),
44)
45REPEATED_PARSE_COUNT: typing.Final = 3
48@pytest.mark.parametrize("_repeat_number", range(REPEATED_PARSE_COUNT))
49def test_snippets_are_stable_across_repeated_parsing(_repeat_number: int) -> None:
50 assert parse_snippets_from_source(SNIPPET_PAGE_FIXTURE) == EXPECTED_SNIPPET_GROUP
53def test_snippets_are_empty_without_social_tags() -> None:
54 snippet_result: typing.Final[structs.SnippetGroup] = parse_snippets_from_source(
55 '<meta name="twitter:title" content="Hi, whatsup kekeke">'
56 )
58 assert snippet_result.twitter.title == "Hi, whatsup kekeke"
59 assert snippet_result.twitter.image_width == 0
60 assert snippet_result.open_graph == structs.SocialMediaSnippet()
63def test_first_duplicated_tag_wins() -> None:
64 """Social networks treat repeated tags as a list where the first entry is the primary one."""
65 snippet_result: typing.Final[structs.SnippetGroup] = parse_snippets_from_source(
66 '<meta property="og:title" content="First title">'
67 '<meta property="og:title" content="Second title">'
68 '<meta property="og:image" content="https://example.com/first.png">'
69 '<meta property="og:image:width" content="640">'
70 '<meta property="og:image" content="https://example.com/second.png">'
71 '<meta property="og:image:width" content="1280">'
72 )
74 assert snippet_result.open_graph.title == "First title"
75 assert snippet_result.open_graph.image == "https://example.com/first.png"
76 assert snippet_result.open_graph.image_width == 640
79def test_unknown_social_tags_do_not_reach_the_snippet() -> None:
80 snippet_result: typing.Final[structs.SnippetGroup] = parse_snippets_from_source(
81 '<meta property="og:video:duration" content="754"><meta property="og:audio" content="x.mp3">'
82 )
84 assert snippet_result.open_graph == structs.SocialMediaSnippet()
87def test_snippets_accept_bytes() -> None:
88 snippet_result: typing.Final[structs.SnippetGroup] = parse_snippets_from_source(
89 '<html><head><meta charset="windows-1251"><meta property="og:title" content="Заголовок"></head></html>'.encode(
90 "windows-1251"
91 )
92 )
94 assert snippet_result.open_graph.title == "Заголовок"
97@pytest.mark.parametrize(
98 ("dimension_text", "expected_width"),
99 [("", 0), ("123", 123), ("abc", 0), ("٥", 0), ("²", 0), (" 55 ", 55)],
100)
101def test_image_width_examples(dimension_text: str, expected_width: int) -> None:
102 snippet_result: typing.Final[structs.SnippetGroup] = parse_snippets_from_source(
103 f'<meta property="twitter:image:width" content="{dimension_text}">'
104 )
106 assert snippet_result.twitter.image_width == expected_width
109@hypothesis.settings(max_examples=50)
110@hypothesis.given(
111 snippet_title=st.text(
112 alphabet=st.characters(blacklist_categories=("Cc", "Cs"), blacklist_characters='<>"&'), max_size=80
113 )
114)
115def test_any_title_survives_the_round_trip(snippet_title: str) -> None:
116 snippet_result: typing.Final[structs.SnippetGroup] = parse_snippets_from_source(
117 f'<meta property="og:title" content="{snippet_title}">'
118 )
120 assert snippet_result.open_graph.title == snippet_title