Skip to content

Commit 011cdf2

Browse files
Fix JSON endpoint 404 when only yanked releases are available (#9411)
* Potential fix to 404 issue Addresses #8966 * Reformatted * Added unit tests for 404 issue * Added an additional yanked test * Swapped prioritization in release ordering
1 parent 5d15bfe commit 011cdf2

File tree

2 files changed

+76
-2
lines changed

2 files changed

+76
-2
lines changed

tests/unit/legacy/api/test_json.py

+70
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,76 @@ def test_only_prereleases(self, monkeypatch, db_request):
118118
assert resp is response
119119
assert json_release.calls == [pretend.call(release, db_request)]
120120

121+
def test_all_releases_yanked(self, monkeypatch, db_request):
122+
"""
123+
If all releases are yanked, the endpoint should return the same release as
124+
if none of the releases are yanked.
125+
"""
126+
127+
project = ProjectFactory.create()
128+
129+
ReleaseFactory.create(project=project, version="1.0", yanked=True)
130+
ReleaseFactory.create(project=project, version="2.0", yanked=True)
131+
ReleaseFactory.create(project=project, version="4.0.dev0", yanked=True)
132+
133+
release = ReleaseFactory.create(project=project, version="3.0", yanked=True)
134+
135+
response = pretend.stub()
136+
json_release = pretend.call_recorder(lambda ctx, request: response)
137+
monkeypatch.setattr(json, "json_release", json_release)
138+
139+
resp = json.json_project(project, db_request)
140+
141+
assert resp is response
142+
assert json_release.calls == [pretend.call(release, db_request)]
143+
144+
def test_latest_release_yanked(self, monkeypatch, db_request):
145+
"""
146+
If the latest version is yanked, the endpoint should fall back on the
147+
latest non-prerelease version that is not yanked, if one is available.
148+
"""
149+
150+
project = ProjectFactory.create()
151+
152+
ReleaseFactory.create(project=project, version="1.0")
153+
ReleaseFactory.create(project=project, version="3.0", yanked=True)
154+
ReleaseFactory.create(project=project, version="3.0.dev0")
155+
156+
release = ReleaseFactory.create(project=project, version="2.0")
157+
158+
response = pretend.stub()
159+
json_release = pretend.call_recorder(lambda ctx, request: response)
160+
monkeypatch.setattr(json, "json_release", json_release)
161+
162+
resp = json.json_project(project, db_request)
163+
164+
assert resp is response
165+
assert json_release.calls == [pretend.call(release, db_request)]
166+
167+
def test_all_non_prereleases_yanked(self, monkeypatch, db_request):
168+
"""
169+
If all non-prerelease versions are yanked, the endpoint should return the
170+
latest prerelease version that is not yanked.
171+
"""
172+
173+
project = ProjectFactory.create()
174+
175+
ReleaseFactory.create(project=project, version="1.0", yanked=True)
176+
ReleaseFactory.create(project=project, version="2.0", yanked=True)
177+
ReleaseFactory.create(project=project, version="3.0", yanked=True)
178+
ReleaseFactory.create(project=project, version="3.0.dev0", yanked=True)
179+
180+
release = ReleaseFactory.create(project=project, version="2.0.dev0")
181+
182+
response = pretend.stub()
183+
json_release = pretend.call_recorder(lambda ctx, request: response)
184+
monkeypatch.setattr(json, "json_release", json_release)
185+
186+
resp = json.json_project(project, db_request)
187+
188+
assert resp is response
189+
assert json_release.calls == [pretend.call(release, db_request)]
190+
121191

122192
class TestJSONProjectSlash:
123193
def test_normalizing_redirects(self, db_request):

warehouse/legacy/api/json.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,12 @@ def json_project(project, request):
6565
try:
6666
release = (
6767
request.db.query(Release)
68-
.filter(Release.project == project, Release.yanked.is_(False))
69-
.order_by(Release.is_prerelease.nullslast(), Release._pypi_ordering.desc())
68+
.filter(Release.project == project)
69+
.order_by(
70+
Release.yanked.asc(),
71+
Release.is_prerelease.nullslast(),
72+
Release._pypi_ordering.desc(),
73+
)
7074
.limit(1)
7175
.one()
7276
)

0 commit comments

Comments
 (0)