44import requests
55
66from pulp_python .tests .functional .constants import (
7+ PYPI_SIMPLE_V1_JSON ,
78 PYTHON_FIXTURES_URL ,
89 TWINE_EGG_FILENAME ,
910 TWINE_EGG_URL ,
@@ -66,6 +67,16 @@ def test_yank_and_unyank(
6667 summary = python_content_summary (repository = repo , version = 2 )
6768 assert summary .added ["python.python_yank" ]["count" ] == 1
6869
70+ # Simple API JSON check - yanked files should have yanked reason
71+ simple_url = f"{ urljoin (distro .base_url , 'simple/' )} { TWINE_NAME } "
72+ response = requests .get (simple_url , headers = {"Accept" : PYPI_SIMPLE_V1_JSON })
73+ assert response .json ()["files" ][0 ]["yanked" ] == "broken"
74+ assert response .json ()["files" ][1 ]["yanked" ] == "broken"
75+
76+ # Simple API HTML check - data-yanked attribute should be present
77+ response = requests .get (simple_url )
78+ assert response .text .count ('data-yanked="broken"' ) == 2
79+
6980 # Yank again - idempotent, no new repo version
7081 response = yank (distro , TWINE_NAME , TWINE_VERSION , yanked_reason = "broken" )
7182 assert response .status_code == 202
@@ -85,6 +96,15 @@ def test_yank_and_unyank(
8596 summary = python_content_summary (repository = repo , version = 3 )
8697 assert summary .removed ["python.python_yank" ]["count" ] == 1
8798
99+ # Simple API JSON - yanked should be False after unyank
100+ response = requests .get (simple_url , headers = {"Accept" : PYPI_SIMPLE_V1_JSON })
101+ assert response .json ()["files" ][0 ]["yanked" ] == False
102+ assert response .json ()["files" ][1 ]["yanked" ] == False
103+
104+ # Simple API HTML - data-yanked should not be present
105+ response = requests .get (simple_url )
106+ assert "data-yanked" not in response .text
107+
88108 # Unyank again - idempotent, no new repo version
89109 response = unyank (distro , TWINE_NAME , TWINE_VERSION )
90110 assert response .status_code == 202
@@ -94,6 +114,36 @@ def test_yank_and_unyank(
94114 assert repo .latest_version_href == version_3
95115
96116
117+ def test_yank_sync (
118+ delete_orphans_pre ,
119+ python_remote_factory ,
120+ python_repo_with_sync ,
121+ python_content_summary ,
122+ python_distribution_factory ,
123+ ):
124+ """
125+ Syncing a yanked package from upstream creates a PackageYank marker.
126+ """
127+ remote = python_remote_factory (includes = ["twine==5.1.0" ])
128+ repo = python_repo_with_sync (remote )
129+ distro = python_distribution_factory (repository = repo )
130+
131+ # Sync should have created a yank marker for twine 5.1.0
132+ summary = python_content_summary (repository = repo , version = 1 )
133+ assert summary .added ["python.python" ]["count" ] == 2
134+ assert summary .added ["python.python_yank" ]["count" ] == 1
135+
136+ # Simple API JSON check - yanked reason from upstream
137+ simple_url = f"{ urljoin (distro .base_url , 'simple/' )} { TWINE_NAME } "
138+ response = requests .get (simple_url , headers = {"Accept" : PYPI_SIMPLE_V1_JSON })
139+ assert response .json ()["files" ][0 ]["yanked" ] == "https://github.com/pypa/twine/issues/1125"
140+ assert response .json ()["files" ][1 ]["yanked" ] == "https://github.com/pypa/twine/issues/1125"
141+
142+ # Simple API HTML check - data-yanked attribute present
143+ response = requests .get (simple_url )
144+ assert response .text .count ("data-yanked=" ) == 2
145+
146+
97147@pytest .mark .parallel
98148def test_partial_yank (
99149 monitor_task ,
0 commit comments