Skip to content

Commit

Permalink
Fix JSON endpoint 404 when only yanked releases are available (#9411)
Browse files Browse the repository at this point in the history
* Potential fix to 404 issue

Addresses #8966

* Reformatted

* Added unit tests for 404 issue

* Added an additional yanked test

* Swapped prioritization in release ordering
  • Loading branch information
AustinTSchaffer authored Apr 22, 2021
1 parent 5d15bfe commit 011cdf2
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 2 deletions.
70 changes: 70 additions & 0 deletions tests/unit/legacy/api/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,76 @@ def test_only_prereleases(self, monkeypatch, db_request):
assert resp is response
assert json_release.calls == [pretend.call(release, db_request)]

def test_all_releases_yanked(self, monkeypatch, db_request):
"""
If all releases are yanked, the endpoint should return the same release as
if none of the releases are yanked.
"""

project = ProjectFactory.create()

ReleaseFactory.create(project=project, version="1.0", yanked=True)
ReleaseFactory.create(project=project, version="2.0", yanked=True)
ReleaseFactory.create(project=project, version="4.0.dev0", yanked=True)

release = ReleaseFactory.create(project=project, version="3.0", yanked=True)

response = pretend.stub()
json_release = pretend.call_recorder(lambda ctx, request: response)
monkeypatch.setattr(json, "json_release", json_release)

resp = json.json_project(project, db_request)

assert resp is response
assert json_release.calls == [pretend.call(release, db_request)]

def test_latest_release_yanked(self, monkeypatch, db_request):
"""
If the latest version is yanked, the endpoint should fall back on the
latest non-prerelease version that is not yanked, if one is available.
"""

project = ProjectFactory.create()

ReleaseFactory.create(project=project, version="1.0")
ReleaseFactory.create(project=project, version="3.0", yanked=True)
ReleaseFactory.create(project=project, version="3.0.dev0")

release = ReleaseFactory.create(project=project, version="2.0")

response = pretend.stub()
json_release = pretend.call_recorder(lambda ctx, request: response)
monkeypatch.setattr(json, "json_release", json_release)

resp = json.json_project(project, db_request)

assert resp is response
assert json_release.calls == [pretend.call(release, db_request)]

def test_all_non_prereleases_yanked(self, monkeypatch, db_request):
"""
If all non-prerelease versions are yanked, the endpoint should return the
latest prerelease version that is not yanked.
"""

project = ProjectFactory.create()

ReleaseFactory.create(project=project, version="1.0", yanked=True)
ReleaseFactory.create(project=project, version="2.0", yanked=True)
ReleaseFactory.create(project=project, version="3.0", yanked=True)
ReleaseFactory.create(project=project, version="3.0.dev0", yanked=True)

release = ReleaseFactory.create(project=project, version="2.0.dev0")

response = pretend.stub()
json_release = pretend.call_recorder(lambda ctx, request: response)
monkeypatch.setattr(json, "json_release", json_release)

resp = json.json_project(project, db_request)

assert resp is response
assert json_release.calls == [pretend.call(release, db_request)]


class TestJSONProjectSlash:
def test_normalizing_redirects(self, db_request):
Expand Down
8 changes: 6 additions & 2 deletions warehouse/legacy/api/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,12 @@ def json_project(project, request):
try:
release = (
request.db.query(Release)
.filter(Release.project == project, Release.yanked.is_(False))
.order_by(Release.is_prerelease.nullslast(), Release._pypi_ordering.desc())
.filter(Release.project == project)
.order_by(
Release.yanked.asc(),
Release.is_prerelease.nullslast(),
Release._pypi_ordering.desc(),
)
.limit(1)
.one()
)
Expand Down

0 comments on commit 011cdf2

Please sign in to comment.