/
test_build_linkcheck.py
162 lines (140 loc) · 5.88 KB
/
test_build_linkcheck.py
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
"""
test_build_linkcheck
~~~~~~~~~~~~~~~~~~~~
Test the build process with manpage builder with the test root.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import json
import re
from unittest import mock
import pytest
@pytest.mark.sphinx('linkcheck', testroot='linkcheck', freshenv=True)
def test_defaults(app, status, warning):
app.builder.build_all()
assert (app.outdir / 'output.txt').exists()
content = (app.outdir / 'output.txt').read_text()
print(content)
# looking for '#top' and '#does-not-exist' not found should fail
assert "Anchor 'top' not found" in content
assert "Anchor 'does-not-exist' not found" in content
# looking for non-existent URL should fail
assert " Max retries exceeded with url: /doesnotexist" in content
# images should fail
assert "Not Found for url: https://www.google.com/image.png" in content
assert "Not Found for url: https://www.google.com/image2.png" in content
# looking for local file should fail
assert "[broken] path/to/notfound" in content
assert len(content.splitlines()) == 6
@pytest.mark.sphinx('linkcheck', testroot='linkcheck', freshenv=True)
def test_defaults_json(app, status, warning):
app.builder.build_all()
assert (app.outdir / 'output.json').exists()
content = (app.outdir / 'output.json').read_text()
print(content)
rows = [json.loads(x) for x in content.splitlines()]
row = rows[0]
for attr in ["filename", "lineno", "status", "code", "uri",
"info"]:
assert attr in row
assert len(content.splitlines()) == 10
assert len(rows) == 10
# the output order of the rows is not stable
# due to possible variance in network latency
rowsby = {row["uri"]:row for row in rows}
assert rowsby["https://www.google.com#!bar"] == {
'filename': 'links.txt',
'lineno': 10,
'status': 'working',
'code': 0,
'uri': 'https://www.google.com#!bar',
'info': ''
}
# looking for non-existent URL should fail
dnerow = rowsby['https://localhost:7777/doesnotexist']
assert dnerow['filename'] == 'links.txt'
assert dnerow['lineno'] == 13
assert dnerow['status'] == 'broken'
assert dnerow['code'] == 0
assert dnerow['uri'] == 'https://localhost:7777/doesnotexist'
assert rowsby['https://www.google.com/image2.png'] == {
'filename': 'links.txt',
'lineno': 18,
'status': 'broken',
'code': 0,
'uri': 'https://www.google.com/image2.png',
'info': '404 Client Error: Not Found for url: https://www.google.com/image2.png'
}
# looking for '#top' and '#does-not-exist' not found should fail
assert "Anchor 'top' not found" == \
rowsby["https://www.google.com/#top"]["info"]
assert "Anchor 'does-not-exist' not found" == \
rowsby["http://www.sphinx-doc.org/en/1.7/intro.html#does-not-exist"]["info"]
# images should fail
assert "Not Found for url: https://www.google.com/image.png" in \
rowsby["https://www.google.com/image.png"]["info"]
@pytest.mark.sphinx(
'linkcheck', testroot='linkcheck', freshenv=True,
confoverrides={'linkcheck_anchors_ignore': ["^!", "^top$"],
'linkcheck_ignore': [
'https://localhost:7777/doesnotexist',
'http://www.sphinx-doc.org/en/1.7/intro.html#',
'https://www.google.com/image.png',
'https://www.google.com/image2.png',
'path/to/notfound']
})
def test_anchors_ignored(app, status, warning):
app.builder.build_all()
assert (app.outdir / 'output.txt').exists()
content = (app.outdir / 'output.txt').read_text()
# expect all ok when excluding #top
assert not content
@pytest.mark.sphinx(
'linkcheck', testroot='linkcheck', freshenv=True,
confoverrides={'linkcheck_auth': [
(r'.+google\.com/image.+', 'authinfo1'),
(r'.+google\.com.+', 'authinfo2'),
]
})
def test_auth(app, status, warning):
mock_req = mock.MagicMock()
mock_req.return_value = 'fake-response'
with mock.patch.multiple('requests', get=mock_req, head=mock_req):
app.builder.build_all()
for c_args, c_kwargs in mock_req.call_args_list:
if 'google.com/image' in c_args[0]:
assert c_kwargs['auth'] == 'authinfo1'
elif 'google.com' in c_args[0]:
assert c_kwargs['auth'] == 'authinfo2'
else:
assert not c_kwargs['auth']
@pytest.mark.sphinx(
'linkcheck', testroot='linkcheck', freshenv=True,
confoverrides={'linkcheck_request_headers': {
"https://localhost:7777/": {
"Accept": "text/html",
},
"http://www.sphinx-doc.org": { # no slash at the end
"Accept": "application/json",
},
"*": {
"X-Secret": "open sesami",
}
}})
def test_linkcheck_request_headers(app, status, warning):
mock_req = mock.MagicMock()
mock_req.return_value = 'fake-response'
with mock.patch.multiple('requests', get=mock_req, head=mock_req):
app.builder.build_all()
for args, kwargs in mock_req.call_args_list:
url = args[0]
headers = kwargs.get('headers', {})
if "https://localhost:7777" in url:
assert headers["Accept"] == "text/html"
elif 'http://www.sphinx-doc.org' in url:
assert headers["Accept"] == "application/json"
elif 'https://www.google.com' in url:
assert headers["Accept"] == "text/html,application/xhtml+xml;q=0.9,*/*;q=0.8"
assert headers["X-Secret"] == "open sesami"
else:
assert headers["Accept"] == "text/html,application/xhtml+xml;q=0.9,*/*;q=0.8"