1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349
|
from __future__ import annotations
from typing import TYPE_CHECKING
import conftest
import pytest
from sphinx.errors import ExtensionError
if TYPE_CHECKING:
from sphinx.application import Sphinx
def get_tag(tags, tag_type, kind='property', prefix='og'):
return next(tag for tag in tags if tag.get(kind) == f'{prefix}:{tag_type}')
def get_tag_content(tags, tag_type, kind='property', prefix='og'):
# Gets the content of a specific ogp tag
return get_tag(tags, tag_type, kind, prefix).get('content', '')
def get_tag_content_text(tags, tag_type, kind='property', prefix='og'):
# Gets the content of a specific ogp tag
return get_tag(tags, tag_type, kind, prefix).get_text('content', '')
def get_meta_description(tags):
tag = next(tag for tag in tags if tag.get('name') == 'description')
return tag.get('content', '')
@pytest.mark.sphinx('html', testroot='simple')
def test_simple(og_meta_tags):
description = get_tag_content(og_meta_tags, 'description')
assert len(og_meta_tags) > 0
assert get_tag_content(og_meta_tags, 'type') == 'website'
assert len(description) == 200
assert (
description
== 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse at lorem ornare, fringilla massa nec, venenatis mi. Donec erat sapien, tincidunt nec rhoncus nec, scelerisque id diam. Orci vari...'
)
@pytest.mark.sphinx('html', testroot='meta-name-description')
def test_meta_name_description(meta_tags):
og_description = get_tag_content(meta_tags, 'description')
description = get_meta_description(meta_tags)
assert description == og_description
@pytest.mark.sphinx('html', testroot='meta-name-description-escape')
def test_meta_name_description_escape(meta_tags):
og_description = get_tag_content(meta_tags, 'description')
og_description_text = get_tag_content_text(meta_tags, 'description')
assert '<' in og_description
assert '<' not in og_description_text
@pytest.mark.sphinx('html', testroot='meta-name-description-manual-description')
def test_meta_name_manual_description(meta_tags):
og_description = get_tag_content(meta_tags, 'description')
description = get_meta_description(meta_tags)
assert description != og_description
assert description == 'My manual description'
@pytest.mark.sphinx('html', testroot='meta-name-description-manual-og-description')
def test_meta_name_manual_og_description(meta_tags):
og_description = get_tag_content(meta_tags, 'description')
description = get_meta_description(meta_tags)
assert og_description != description
assert og_description == 'My manual og:description'
@pytest.mark.sphinx('html', testroot='simple')
def test_site_url(og_meta_tags):
# Uses the same directory as simple, because it already contains url for a minimal config
assert (
get_tag_content(og_meta_tags, 'url')
== 'http://example.org/en/latest/index.html'
)
@pytest.mark.sphinx('dirhtml', testroot='simple')
def test_dirhtml_url(og_meta_tags):
assert get_tag_content(og_meta_tags, 'url') == 'http://example.org/en/latest/'
@pytest.mark.sphinx('html', testroot='image')
def test_image(og_meta_tags):
assert (
get_tag_content(og_meta_tags, 'image')
== 'http://example.org/en/latest/image.png'
)
@pytest.mark.sphinx('html', testroot='local-image')
def test_local_image(og_meta_tags):
assert (
get_tag_content(og_meta_tags, 'image')
== 'http://example.org/en/latest/_static/sample.jpg'
)
@pytest.mark.sphinx('html', testroot='social-cards-svg')
def test_social_cards_svg(app: Sphinx, og_meta_tags):
"""If the social cards image is an SVG, it should not be in the social card."""
assert app.statuscode == 0
@pytest.mark.sphinx('html', testroot='image')
def test_image_alt(og_meta_tags):
assert get_tag_content(og_meta_tags, 'image:alt') == "Example's Docs!"
@pytest.mark.sphinx('html', testroot='simple')
def test_image_social_cards(meta_tags):
"""Social cards should automatically be added if no og:image is given."""
pytest.importorskip('matplotlib')
# Asserting `in` instead of `==` because of the hash that is generated
assert (
'http://example.org/en/latest/_images/social_previews/summary_index'
in get_tag_content(meta_tags, 'image')
)
# Image alt text should be taken from page content.
assert (
'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
in get_tag_content(meta_tags, 'image:alt')
)
# Make sure the extra tags are in the HTML
assert 'summary_large_image' in get_tag_content(
meta_tags, 'card', kind='name', prefix='twitter'
)
@pytest.mark.sphinx('html', testroot='type')
def test_type(og_meta_tags):
assert get_tag_content(og_meta_tags, 'type') == 'article'
@pytest.mark.sphinx('html', testroot='description-length')
def test_description_length(og_meta_tags):
assert len(get_tag_content(og_meta_tags, 'description')) == 50
@pytest.mark.sphinx('html', testroot='sitename')
def test_site_name(og_meta_tags):
assert get_tag_content(og_meta_tags, 'site_name') == "Example's Docs!"
@pytest.mark.sphinx('html', testroot='sitename-from-project')
def test_site_name_project(og_meta_tags):
assert get_tag_content(og_meta_tags, 'site_name') == 'Project name'
@pytest.mark.sphinx('html', testroot='first-image')
def test_first_image(og_meta_tags):
assert (
get_tag_content(og_meta_tags, 'image')
== 'http://example.org/en/latest/image2.png'
)
assert get_tag_content(og_meta_tags, 'image:alt') == 'Test image alt text'
@pytest.mark.sphinx('html', testroot='first-image-no-image')
def test_first_image_no_image(og_meta_tags):
assert (
get_tag_content(og_meta_tags, 'image')
== 'http://example.org/en/latest/image33.png'
)
assert get_tag_content(og_meta_tags, 'image:alt') == 'TEST'
@pytest.mark.sphinx('html', testroot='image-rel-paths')
def test_image_rel_paths(og_meta_tags, og_meta_tags_sub):
assert (
get_tag_content(og_meta_tags, 'image')
== 'http://example.org/en/latest/_images/sample.jpg'
)
assert (
get_tag_content(og_meta_tags_sub, 'image')
== 'http://example.org/en/latest/_images/sample.jpg'
)
@pytest.mark.sphinx('html', testroot='skip-admonitions')
def test_skip_admonitions(og_meta_tags):
assert get_tag_content(og_meta_tags, 'description') == 'This is text.'
@pytest.mark.sphinx('html', testroot='skip-title')
def test_skip_first_title(og_meta_tags):
description = get_tag_content(og_meta_tags, 'description')
assert 'A Title' not in description
assert 'Another Title' in description
@pytest.mark.sphinx('html', testroot='skip-title')
def test_skip_title_punctuation(og_meta_tags):
description = get_tag_content(og_meta_tags, 'description')
assert 'Another Title:' in description
@pytest.mark.sphinx('html', testroot='double-spacing')
def test_remove_double_spacing(og_meta_tags):
description = get_tag_content(og_meta_tags, 'description')
assert ' ' not in description
@pytest.mark.sphinx('html', testroot='list')
def test_list_punctuation(og_meta_tags):
description = get_tag_content(og_meta_tags, 'description')
assert description == 'Item 1, Item 2, Item 3, Item 4.'
@pytest.mark.sphinx('html', testroot='nested-lists')
def test_nested_list_punctuation(og_meta_tags):
description = get_tag_content(og_meta_tags, 'description')
assert (
description == 'Item 1, Item 2- Nested Item 1, Nested Item 2., Item 3, Item 4.'
)
@pytest.mark.sphinx('html', testroot='skip-comments')
def test_skip_comments(og_meta_tags):
assert get_tag_content(og_meta_tags, 'description') == 'This is text.'
@pytest.mark.sphinx('html', testroot='custom-tags')
def test_custom_tags(og_meta_tags):
assert get_tag_content(og_meta_tags, 'ignore_canonical') == 'true'
@pytest.mark.sphinx('html', testroot='skip-raw')
def test_skip_raw(og_meta_tags):
description = get_tag_content(og_meta_tags, 'description')
assert '<p>' not in description
assert (
description
== 'This text should be included. This text should also be included.'
)
@pytest.mark.sphinx('html', testroot='skip-code-block')
def test_skip_code_block(og_meta_tags):
description = get_tag_content(og_meta_tags, 'description')
assert '<p>' not in description
assert (
description
== 'This text should be included. This text should also be included.'
)
@pytest.mark.sphinx('html', testroot='quotation-marks')
def test_quotation_marks(og_meta_tags):
# If smart quotes are disabled and the quotes aren't properly escaped, bs4 will fail to parse the tag and the content will be a empty string
description = get_tag_content(og_meta_tags, 'description')
assert (
description
== '"This text should appear in escaped quotation marks" This text should still appear as well "while this is once again in quotations"'
)
@pytest.mark.sphinx('html', testroot='overrides-simple')
def test_overrides_simple(og_meta_tags):
assert get_tag_content(og_meta_tags, 'description') == 'Overridden description'
assert get_tag_content(og_meta_tags, 'title') == 'Overridden Title'
assert get_tag_content(og_meta_tags, 'type') == 'article'
assert (
get_tag_content(og_meta_tags, 'image')
== 'http://example.org/en/latest/overridden-image.png'
)
# Make sure alt text still works even when overriding the image
assert get_tag_content(og_meta_tags, 'image:alt') == "Example's Docs!"
@pytest.mark.sphinx('html', testroot='overrides-complex')
def test_overrides_complex(og_meta_tags):
assert len(get_tag_content(og_meta_tags, 'description')) == 10
assert (
get_tag_content(og_meta_tags, 'image')
== 'http://example.org/en/latest/img/sample.jpg'
)
assert get_tag_content(og_meta_tags, 'image:alt') == 'Overridden Alt Text'
@pytest.mark.sphinx('html', testroot='overrides-disable')
def test_overrides_disable(og_meta_tags):
assert len(og_meta_tags) == 0
@pytest.mark.sphinx('html', testroot='arbitrary-tags')
def test_arbitrary_tags(og_meta_tags):
assert (
get_tag_content(og_meta_tags, 'video')
== 'http://example.org/en/latest/video.mp4'
)
assert get_tag_content(og_meta_tags, 'video:type') == 'video/mp4'
# use same as simple, as configuration is identical to overriden
@pytest.mark.sphinx('html', testroot='simple')
def test_rtd_override(app: Sphinx, monkeypatch):
monkeypatch.setenv('READTHEDOCS', 'True')
app.config.html_baseurl = 'https://failure.com/en/latest/'
app.build()
tags = conftest._og_meta_tags(app)
assert get_tag_content(tags, 'url') == 'http://example.org/en/latest/index.html'
@pytest.mark.sphinx('html', testroot='rtd-default')
def test_rtd_valid(app: Sphinx, monkeypatch):
monkeypatch.setenv('READTHEDOCS', 'True')
monkeypatch.setenv('READTHEDOCS_CANONICAL_URL', 'https://failure.com/en/latest/')
app.build()
tags = conftest._og_meta_tags(app)
assert get_tag_content(tags, 'url') == 'https://failure.com/en/latest/index.html'
# use rtd-default, as we are not changing configuration, but RTD variables
@pytest.mark.sphinx('html', testroot='rtd-invalid')
def test_rtd_invalid(app: Sphinx, monkeypatch):
monkeypatch.setenv('READTHEDOCS', 'True')
app.config.html_baseurl = None
with pytest.raises(ExtensionError, match='did not provide a valid canonical URL'):
app.build()
# Test no breakage with no configuration
@pytest.mark.sphinx('html', testroot='rtd-default')
def test_no_configuration_html(og_meta_tags):
assert get_tag_content(og_meta_tags, 'type') == 'website'
# Test no breakage with no configuration
@pytest.mark.sphinx('dirhtml', testroot='rtd-default')
def test_no_configuration_dirhtml(og_meta_tags):
assert get_tag_content(og_meta_tags, 'type') == 'website'
|