Skip to content

Commit 155fd61

Browse files
committed
GH-1564: Add "Last Modified" trailer to PEP HTML pages
Obtain the last modified date by making GET request to GitHub. Don't render anything if there's any error with the GET request. Add tests, and mock the network call. Closes #1564
1 parent 6902c19 commit 155fd61

File tree

3 files changed

+113
-14
lines changed

3 files changed

+113
-14
lines changed

peps/converters.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import os
55

66
from bs4 import BeautifulSoup
7+
import requests
78

89
from django.conf import settings
910
from django.core.exceptions import ImproperlyConfigured
@@ -181,9 +182,11 @@ def get_pep_page(artifact_path, pep_number, commit=True):
181182
artifact_path, 'pep-{}.rst'.format(pep_number),
182183
)
183184
pep_ext = '.rst' if os.path.exists(pep_rst_source) else '.txt'
184-
source_link = 'https://github.com/python/peps/blob/master/pep-{}{}'.format(
185-
pep_number, pep_ext)
186-
pep_content['content'] += """Source: <a href="{0}">{0}</a>""".format(source_link)
185+
pep_filename = 'pep-{}{}'.format(pep_number, pep_ext)
186+
source_link = 'https://github.com/python/peps/blob/master/{}'.format(pep_filename)
187+
pep_footer = """<div>Source: <a href="{0}">{0}</a></div>""".format(source_link)
188+
pep_footer += get_commit_history_info(pep_filename)
189+
pep_content['content'] += pep_footer
187190

188191
pep_page, _ = Page.objects.get_or_create(path=pep_url(pep_number))
189192

@@ -199,6 +202,28 @@ def get_pep_page(artifact_path, pep_number, commit=True):
199202
return pep_page
200203

201204

205+
def get_commit_history_info(pep_filename):
206+
commit_info = ''
207+
208+
try:
209+
data = requests.get(
210+
'https://api.github.com/repos/python/peps/commits?path={}'.format(pep_filename)
211+
)
212+
except Exception:
213+
return commit_info
214+
215+
json_data = data.json()
216+
if len(json_data) > 0:
217+
commit_date = json_data[0]['commit']['committer']['date']
218+
commit_url = 'https://github.com/python/peps/commits/master/{}'.format(
219+
pep_filename
220+
)
221+
commit_info = """<div>Last modified: <a href="{0}">{1}</a></div>""".format(
222+
commit_url, commit_date
223+
)
224+
return commit_info
225+
226+
202227
def add_pep_image(artifact_path, pep_number, path):
203228
image_path = os.path.join(artifact_path, path)
204229
if not os.path.exists(image_path):

peps/tests/test_commands.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
import responses
1111

12+
from unittest.mock import patch
13+
1214
from pages.models import Image
1315

1416
from . import FAKE_PEP_ARTIFACT
@@ -32,22 +34,30 @@ def setUp(self):
3234
)
3335

3436
@responses.activate
35-
def test_generate_pep_pages_real_with_remote_artifact(self):
37+
@patch('peps.converters.get_commit_history_info')
38+
def test_generate_pep_pages_real_with_remote_artifact(
39+
self, mock_get_commit_history
40+
):
41+
mock_get_commit_history.return_value = ''
3642
call_command('generate_pep_pages')
3743

3844
@override_settings(PEP_ARTIFACT_URL=FAKE_PEP_ARTIFACT)
3945
def test_generate_pep_pages_real_with_local_artifact(self):
4046
call_command('generate_pep_pages')
4147

4248
@responses.activate
43-
def test_image_generated(self):
49+
@patch('peps.converters.get_commit_history_info')
50+
def test_image_generated(self, mock_get_commit_history):
51+
mock_get_commit_history.return_value = ''
4452
call_command('generate_pep_pages')
4553
img = Image.objects.get(page__path='dev/peps/pep-3001/')
4654
soup = BeautifulSoup(img.page.content.raw, 'lxml')
4755
self.assertIn(settings.MEDIA_URL, soup.find('img')['src'])
4856

4957
@responses.activate
50-
def test_dump_pep_pages(self):
58+
@patch('peps.converters.get_commit_history_info')
59+
def test_dump_pep_pages(self, mock_get_commit_history):
60+
mock_get_commit_history.return_value = ''
5161
call_command('generate_pep_pages')
5262
stdout = io.StringIO()
5363
call_command('dump_pep_pages', stdout=stdout)

peps/tests/test_converters.py

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
from django.test import TestCase, override_settings
2-
from django.core.exceptions import ImproperlyConfigured
32
from django.test.utils import captured_stdout
43

5-
from peps.converters import get_pep0_page, get_pep_page, add_pep_image
4+
from unittest.mock import Mock, patch
5+
6+
from peps.converters import (
7+
get_pep_page,
8+
add_pep_image,
9+
get_commit_history_info,
10+
)
611

712
from . import FAKE_PEP_REPO
813

914

1015
class PEPConverterTests(TestCase):
1116

12-
def test_source_link(self):
17+
@patch('peps.converters.get_commit_history_info')
18+
def test_source_link(self, mock_get_commit_history):
19+
mock_get_commit_history.return_value = ''
1320
pep = get_pep_page(FAKE_PEP_REPO, '0525')
1421
self.assertEqual(pep.title, 'PEP 525 -- Asynchronous Generators')
1522
self.assertIn(
@@ -18,12 +25,63 @@ def test_source_link(self):
1825
pep.content.rendered
1926
)
2027

21-
def test_source_link_rst(self):
28+
@patch('peps.converters.get_commit_history_info')
29+
def test_source_link_rst(self, mock_get_commit_history):
30+
mock_get_commit_history.return_value = ''
2231
pep = get_pep_page(FAKE_PEP_REPO, '0012')
2332
self.assertEqual(pep.title, 'PEP 12 -- Sample reStructuredText PEP Template')
2433
self.assertIn(
25-
'Source: <a href="https://github.com/python/peps/blob/master/'
26-
'pep-0012.rst">https://github.com/python/peps/blob/master/pep-0012.rst</a>',
34+
'<div>Source: <a href="https://github.com/python/peps/blob/master/'
35+
'pep-0012.rst">https://github.com/python/peps/blob/master/pep-0012.rst</a></div>',
36+
pep.content.rendered
37+
)
38+
39+
@patch('requests.get')
40+
def test_get_commit_history_info_with_data(self, mocked_gh_request):
41+
42+
mocked_gh_request.return_value = Mock(ok=True)
43+
mocked_gh_request.return_value.json.return_value = [
44+
{
45+
"commit": {
46+
"committer": {
47+
"name": "miss-islington",
48+
"date": "2020-02-19T04:06:01Z",
49+
}
50+
}
51+
}
52+
]
53+
54+
info = get_commit_history_info('pep-0012.txt')
55+
self.assertEqual(
56+
info,
57+
'<div>Last modified: <a href="https://github.com/python/peps/commits/master/pep-0012.txt">2020-02-19T04:06:01Z</a></div>'
58+
)
59+
60+
@patch('requests.get')
61+
def test_get_commit_history_info_no_data(self, mocked_gh_request):
62+
mocked_gh_request.return_value = Mock(ok=True)
63+
mocked_gh_request.return_value.json.return_value = []
64+
65+
info = get_commit_history_info('pep-0012.txt')
66+
self.assertEqual(info, '')
67+
68+
@patch('requests.get')
69+
def test_get_page_page_includes_last_modified(self, mocked_gh_request):
70+
mocked_gh_request.return_value = Mock(ok=True)
71+
mocked_gh_request.return_value.json.return_value = [
72+
{
73+
"commit": {
74+
"committer": {
75+
"name": "miss-islington",
76+
"date": "2020-02-19T04:06:01Z",
77+
}
78+
}
79+
}
80+
]
81+
82+
pep = get_pep_page(FAKE_PEP_REPO, '0012')
83+
self.assertIn(
84+
'<div>Last modified: <a href="https://github.com/python/peps/commits/master/pep-0012.rst">2020-02-19T04:06:01Z</a></div>',
2785
pep.content.rendered
2886
)
2987

@@ -43,7 +101,10 @@ def test_add_image_not_found(self):
43101
r"Image Path '(.*)/path/that/does/not/exist(.*)' does not exist, skipping"
44102
)
45103

46-
def test_html_do_not_prettify(self):
104+
@patch('peps.converters.get_commit_history_info')
105+
def test_html_do_not_prettify(self, mock_get_commit_history):
106+
mock_get_commit_history.return_value = ''
107+
47108
pep = get_pep_page(FAKE_PEP_REPO, '3001')
48109
self.assertEqual(
49110
pep.title,
@@ -56,7 +117,10 @@ def test_html_do_not_prettify(self):
56117
pep.content.rendered
57118
)
58119

59-
def test_strip_html_and_body_tags(self):
120+
@patch('peps.converters.get_commit_history_info')
121+
def test_strip_html_and_body_tags(self, mock_get_commit_history):
122+
mock_get_commit_history.return_value = ''
123+
60124
pep = get_pep_page(FAKE_PEP_REPO, '0525')
61125
self.assertNotIn('<html>', pep.content.rendered)
62126
self.assertNotIn('</html>', pep.content.rendered)

0 commit comments

Comments
 (0)