Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions downloads/tests/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import datetime
import datetime as dt

from django.test import TestCase
from django.utils import timezone
Expand Down Expand Up @@ -32,7 +32,7 @@ def setUp(self):
is_latest=True,
is_published=True,
release_page=self.release_275_page,
release_date=timezone.now() - datetime.timedelta(days=-1)
release_date=dt.datetime.fromisoformat("2013-05-15T00:00Z"),
)
self.release_275_windows_32bit = ReleaseFile.objects.create(
os=self.windows,
Expand Down Expand Up @@ -102,9 +102,31 @@ def setUp(self):

self.python_3 = Release.objects.create(
version=Release.PYTHON3,
name='Python 3.10',
name="Python 3.10.19",
is_latest=True,
is_published=True,
show_on_download_page=True,
release_page=self.release_275_page
release_page=self.release_275_page,
release_date=dt.datetime.fromisoformat("2025-10-09T00:00Z"),
)

self.python_3_10_18 = Release.objects.create(
version=Release.PYTHON3,
name="Python 3.10.18",
is_published=True,
release_date=dt.datetime.fromisoformat("2025-06-03T00:00Z"),
)

self.python_3_8_20 = Release.objects.create(
version=Release.PYTHON3,
name="Python 3.8.20",
is_published=True,
release_date=dt.datetime.fromisoformat("2024-09-06T00:00Z"),
)

self.python_3_8_19 = Release.objects.create(
version=Release.PYTHON3,
name="Python 3.8.19",
is_published=True,
release_date=dt.datetime.fromisoformat("2024-03-19T00:00Z"),
)
8 changes: 4 additions & 4 deletions downloads/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ def test_stringification(self):

def test_published(self):
published_releases = Release.objects.published()
self.assertEqual(len(published_releases), 4)
self.assertEqual(len(published_releases), 7)
self.assertIn(self.release_275, published_releases)
self.assertIn(self.hidden_release, published_releases)
self.assertNotIn(self.draft_release, published_releases)

def test_release(self):
released_versions = Release.objects.released()
self.assertEqual(len(released_versions), 3)
self.assertEqual(len(released_versions), 6)
self.assertIn(self.release_275, released_versions)
self.assertIn(self.hidden_release, released_versions)
self.assertNotIn(self.draft_release, released_versions)
Expand All @@ -37,7 +37,7 @@ def test_draft(self):

def test_downloads(self):
downloads = Release.objects.downloads()
self.assertEqual(len(downloads), 2)
self.assertEqual(len(downloads), 5)
self.assertIn(self.release_275, downloads)
self.assertNotIn(self.hidden_release, downloads)
self.assertNotIn(self.draft_release, downloads)
Expand All @@ -50,7 +50,7 @@ def test_python2(self):

def test_python3(self):
versions = Release.objects.python3()
self.assertEqual(len(versions), 3)
self.assertEqual(len(versions), 6)
self.assertNotIn(self.release_275, versions)
self.assertNotIn(self.draft_release, versions)
self.assertIn(self.hidden_release, versions)
Expand Down
23 changes: 19 additions & 4 deletions downloads/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,21 @@ def test_download(self):
response = self.client.get(url)
self.assertEqual(response.status_code, 200)

def test_download_releases_ordered_by_version(self):
url = reverse("download:download")
response = self.client.get(url)
releases = response.context["releases"]
self.assertEqual(
releases,
[
self.python_3,
self.python_3_10_18,
self.python_3_8_20,
self.python_3_8_19,
self.release_275,
],
)

def test_latest_redirects(self):
latest_python2 = Release.objects.released().python2().latest()
url = reverse('download:download_latest_python2')
Expand Down Expand Up @@ -218,13 +233,13 @@ def test_get_release(self):
self.assertEqual(response.status_code, 200)
content = self.get_json(response)
# 'self.draft_release' won't shown here.
self.assertEqual(len(content), 4)
self.assertEqual(len(content), 7)

# Login to get all releases.
response = self.client.get(url, headers={"authorization": self.Authorization})
self.assertEqual(response.status_code, 200)
content = self.get_json(response)
self.assertEqual(len(content), 5)
self.assertEqual(len(content), 8)
self.assertFalse(content[0]['is_latest'])

def test_post_release(self):
Expand Down Expand Up @@ -594,5 +609,5 @@ def test_feed_item_count(self) -> None:
response = self.client.get(self.url)
content = response.content.decode()

# In BaseDownloadTests, we create 5 releases, 4 of which are published, 1 of those published are hidden..
self.assertEqual(content.count("<item>"), 4)
# In BaseDownloadTests, we create 8 releases, 7 of which are published, 1 of those published are hidden..
self.assertEqual(content.count("<item>"), 7)
11 changes: 10 additions & 1 deletion downloads/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,17 @@ def get_context_data(self, **kwargs):
data['pymanager'] = latest_pymanager.download_file_for_os(o.slug)
python_files.append(data)

def version_key(release: Release) -> tuple[int, ...]:
try:
return tuple(int(x) for x in release.get_version().split("."))
except ValueError:
return (0,)

releases = list(Release.objects.downloads())
releases.sort(key=version_key, reverse=True)

context.update({
'releases': Release.objects.downloads(),
'releases': releases,
'latest_python2': latest_python2,
'latest_python3': latest_python3,
'python_files': python_files,
Expand Down
4 changes: 2 additions & 2 deletions templates/downloads/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ <h1 class="call-to-action">Download the latest version of Python</h1>
<div class="row active-release-list-widget">
{% render_active_banner %}

<h2 class="widget-title">Active Python Releases</h2>
<h2 class="widget-title">Active Python releases</h2>
<p class="success-quote"><a href="https://devguide.python.org/versions/#versions">For more information visit the Python Developer's Guide</a>.</p>

{% box 'downloads-active-releases' %}
Expand All @@ -74,7 +74,7 @@ <h2 class="widget-title">Looking for a specific release?</h2>
<span class="release-number"><a href="{{ r.get_absolute_url }}">{{ r.name }}</a></span>
<span class="release-date">{{ r.release_date|date }}</span>
<span class="release-download"><a href="{{ r.get_absolute_url }}"><span aria-hidden="true" class="icon-download"></span> Download</a></span>
<span class="release-enhancements"><a href="{{ r.release_notes_url }}">Release Notes</a></span>
<span class="release-enhancements"><a href="{{ r.release_notes_url }}">Release notes</a></span>
</li>
{% endfor %}
</ol>
Expand Down