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

1import typing 

2 

3import hypothesis 

4import hypothesis.strategies as st 

5import pytest 

6 

7from meta_tags_parser import parse_snippets_from_source, structs 

8 

9 

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 

46 

47 

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 

51 

52 

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 ) 

57 

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() 

61 

62 

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 ) 

73 

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 

77 

78 

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 ) 

83 

84 assert snippet_result.open_graph == structs.SocialMediaSnippet() 

85 

86 

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 ) 

93 

94 assert snippet_result.open_graph.title == "Заголовок" 

95 

96 

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 ) 

105 

106 assert snippet_result.twitter.image_width == expected_width 

107 

108 

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 ) 

119 

120 assert snippet_result.open_graph.title == snippet_title