Skip to content

Commit ac58695

Browse files
committed
Merge pull request #1431 from rtfd/disable-link-to-pdf-builds-in-footer
Disable link to pdf/epub builds in footer if appropriate
2 parents 8cc719e + 86a6236 commit ac58695

File tree

5 files changed

+124
-20
lines changed

5 files changed

+124
-20
lines changed

readthedocs/projects/models.py

+4
Original file line numberDiff line numberDiff line change
@@ -607,9 +607,13 @@ def has_aliases(self):
607607
return self.aliases.exists()
608608

609609
def has_pdf(self, version_slug=LATEST):
610+
if not self.enable_pdf_build:
611+
return False
610612
return os.path.exists(self.get_production_media_path(type='pdf', version_slug=version_slug))
611613

612614
def has_epub(self, version_slug=LATEST):
615+
if not self.enable_epub_build:
616+
return False
613617
return os.path.exists(self.get_production_media_path(type='epub', version_slug=version_slug))
614618

615619
def has_htmlzip(self, version_slug=LATEST):

readthedocs/rtd_tests/mocks/paths.py

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import os
2+
import re
3+
import mock
4+
5+
6+
def fake_paths(check):
7+
"""
8+
>>> with fake_paths(lambda path: True if path.endswith('.pdf') else None):
9+
... assert os.path.exists('my.pdf')
10+
... assert os.path.exists('Nopdf.txt')
11+
12+
The first assertion will be ok, the second assertion is not faked as the
13+
``check`` returned ``None`` for this path.
14+
"""
15+
16+
original_exists = os.path.exists
17+
18+
def patched_exists(path):
19+
result = check(path)
20+
if result is None:
21+
return original_exists(path)
22+
return result
23+
24+
return mock.patch.object(os.path, 'exists', patched_exists)
25+
26+
27+
def fake_paths_lookup(path_dict):
28+
"""
29+
>>> paths = {'my.txt': True, 'no.txt': False}
30+
>>> with fake_paths_lookup(paths):
31+
... assert os.path.exists('my.txt') == True
32+
... assert os.path.exists('no.txt') == False
33+
"""
34+
def check(path):
35+
return path_dict.get(path, None)
36+
return fake_paths(check)
37+
38+
39+
def fake_paths_by_regex(pattern, exists=True):
40+
"""
41+
>>> with fake_paths_by_regex('\.pdf$'):
42+
... assert os.path.exists('my.pdf') == True
43+
>>> with fake_paths_by_regex('\.pdf$', exists=False):
44+
... assert os.path.exists('my.pdf') == False
45+
"""
46+
regex = re.compile(pattern)
47+
48+
def check(path):
49+
if regex.search(path):
50+
return exists
51+
return None
52+
53+
return fake_paths(check)

readthedocs/rtd_tests/tests/test_builds.py

+7-20
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from projects.tasks import build_docs
88
from rtd_tests.factories.projects_factories import ProjectFactory
9+
from rtd_tests.mocks.paths import fake_paths_lookup
910
from doc_builder.loader import get_builder_class
1011

1112

@@ -29,22 +30,6 @@ def build_subprocess_side_effect(*args, **kwargs):
2930
return subprocess.Popen(*args, **kwargs)
3031

3132

32-
def fake_paths(*paths):
33-
"""
34-
Returns a context manager that patches ``os.path.exists`` to return
35-
``True`` for the given ``paths``.
36-
"""
37-
38-
original_exists = os.path.exists
39-
40-
def patched_exists(path):
41-
if path in paths:
42-
return True
43-
return original_exists(path)
44-
45-
return mock.patch.object(os.path, 'exists', patched_exists)
46-
47-
4833
class BuildTests(TestCase):
4934

5035
@mock.patch('slumber.Resource')
@@ -68,11 +53,13 @@ def test_build(self, mock_Popen, mock_api_versions, mock_chdir, mock_apiv2_downl
6853

6954
mock_apiv2_downloads.get.return_value = {'downloads': "no_url_here"}
7055

71-
conf_path = os.path.join(project.checkout_path(version.slug), project.conf_py_file)
56+
conf_path = os.path.join(
57+
project.checkout_path(version.slug),
58+
project.conf_py_file)
7259

7360
# Mock open to simulate existing conf.py file
7461
with mock.patch('codecs.open', mock.mock_open(), create=True):
75-
with fake_paths(conf_path):
62+
with fake_paths_lookup({conf_path: True}):
7663
built_docs = build_docs(version,
7764
False,
7865
False,
@@ -136,7 +123,7 @@ def test_build_respects_pdf_flag(self,
136123

137124
# Mock open to simulate existing conf.py file
138125
with mock.patch('codecs.open', mock.mock_open(), create=True):
139-
with fake_paths(conf_path):
126+
with fake_paths_lookup({conf_path: True}):
140127
built_docs = build_docs(version,
141128
False,
142129
False,
@@ -180,7 +167,7 @@ def test_build_respects_epub_flag(self,
180167

181168
# Mock open to simulate existing conf.py file
182169
with mock.patch('codecs.open', mock.mock_open(), create=True):
183-
with fake_paths(conf_path):
170+
with fake_paths_lookup({conf_path: True}):
184171
built_docs = build_docs(version,
185172
False,
186173
False,

readthedocs/rtd_tests/tests/test_footer.py

+28
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from django.test import TestCase
44

5+
from rtd_tests.mocks.paths import fake_paths_by_regex
56
from projects.models import Project
67

78

@@ -28,3 +29,30 @@ def test_footer(self):
2829
self.assertEqual(resp['version_active'], False)
2930
self.assertEqual(r.status_code, 200)
3031

32+
def test_pdf_build_mentioned_in_footer(self):
33+
with fake_paths_by_regex('\.pdf$'):
34+
response = self.client.get(
35+
'/api/v2/footer_html/?project=pip&version=latest&page=index', {})
36+
self.assertContains(response, 'pdf')
37+
38+
def test_pdf_not_mentioned_in_footer_when_build_is_disabled(self):
39+
self.pip.enable_pdf_build = False
40+
self.pip.save()
41+
with fake_paths_by_regex('\.pdf$'):
42+
response = self.client.get(
43+
'/api/v2/footer_html/?project=pip&version=latest&page=index', {})
44+
self.assertNotContains(response, 'pdf')
45+
46+
def test_epub_build_mentioned_in_footer(self):
47+
with fake_paths_by_regex('\.epub$'):
48+
response = self.client.get(
49+
'/api/v2/footer_html/?project=pip&version=latest&page=index', {})
50+
self.assertContains(response, 'epub')
51+
52+
def test_epub_not_mentioned_in_footer_when_build_is_disabled(self):
53+
self.pip.enable_epub_build = False
54+
self.pip.save()
55+
with fake_paths_by_regex('\.epub$'):
56+
response = self.client.get(
57+
'/api/v2/footer_html/?project=pip&version=latest&page=index', {})
58+
self.assertNotContains(response, 'epub')

readthedocs/rtd_tests/tests/test_project.py

+32
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
from bamboo_boy.utils import with_canopy
22
import json
33
from django.test import TestCase
4+
from builds.constants import LATEST
45
from projects.models import Project
56
from rtd_tests.factories.projects_factories import OneProjectWithTranslationsOneWithout,\
67
ProjectFactory
78
from rest_framework.reverse import reverse
89
from restapi.serializers import ProjectSerializer
10+
from rtd_tests.mocks.paths import fake_paths_by_regex
911

1012

1113
@with_canopy(OneProjectWithTranslationsOneWithout)
@@ -50,3 +52,33 @@ def test_token(self):
5052
resp = json.loads(r.content)
5153
self.assertEqual(r.status_code, 200)
5254
self.assertEqual(resp['token'], None)
55+
56+
def test_has_pdf(self):
57+
# The project has a pdf if the PDF file exists on disk.
58+
with fake_paths_by_regex('\.pdf$'):
59+
self.assertTrue(self.pip.has_pdf(LATEST))
60+
61+
# The project has no pdf if there is no file on disk.
62+
with fake_paths_by_regex('\.pdf$', exists=False):
63+
self.assertFalse(self.pip.has_pdf(LATEST))
64+
65+
def test_has_pdf_with_pdf_build_disabled(self):
66+
# The project has NO pdf if pdf builds are disabled
67+
self.pip.enable_pdf_build = False
68+
with fake_paths_by_regex('\.pdf$'):
69+
self.assertFalse(self.pip.has_pdf(LATEST))
70+
71+
def test_has_epub(self):
72+
# The project has a epub if the PDF file exists on disk.
73+
with fake_paths_by_regex('\.epub$'):
74+
self.assertTrue(self.pip.has_epub(LATEST))
75+
76+
# The project has no epub if there is no file on disk.
77+
with fake_paths_by_regex('\.epub$', exists=False):
78+
self.assertFalse(self.pip.has_epub(LATEST))
79+
80+
def test_has_epub_with_epub_build_disabled(self):
81+
# The project has NO epub if epub builds are disabled
82+
self.pip.enable_epub_build = False
83+
with fake_paths_by_regex('\.epub$'):
84+
self.assertFalse(self.pip.has_epub(LATEST))

0 commit comments

Comments
 (0)