|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
| 3 | +import shutil |
| 4 | + |
3 | 5 | from typing import TYPE_CHECKING |
4 | 6 |
|
5 | 7 | import pytest |
|
12 | 14 |
|
13 | 15 |
|
14 | 16 | if TYPE_CHECKING: |
| 17 | + from pathlib import Path |
| 18 | + |
15 | 19 | import responses |
16 | 20 |
|
17 | 21 | from pytest_mock import MockerFixture |
18 | 22 |
|
| 23 | + from poetry.poetry import Poetry |
19 | 24 | from tests.types import FixtureDirGetter |
20 | 25 |
|
21 | 26 |
|
22 | 27 | @pytest.fixture |
23 | | -def uploader(fixture_dir: FixtureDirGetter) -> Uploader: |
24 | | - return Uploader(Factory().create_poetry(fixture_dir("simple_project")), NullIO()) |
| 28 | +def poetry(fixture_dir: FixtureDirGetter) -> Poetry: |
| 29 | + return Factory().create_poetry(fixture_dir("simple_project")) |
| 30 | + |
| 31 | + |
| 32 | +@pytest.fixture |
| 33 | +def uploader(poetry: Poetry) -> Uploader: |
| 34 | + return Uploader(poetry, NullIO()) |
| 35 | + |
| 36 | + |
| 37 | +@pytest.mark.parametrize( |
| 38 | + ("files", "expected_files", "expected_version"), |
| 39 | + [ |
| 40 | + ([], [], ""), |
| 41 | + ( |
| 42 | + ["simple_project-1.2.3.tar.gz", "simple_project-1.2.3-py3-none-any.whl"], |
| 43 | + ["simple_project-1.2.3.tar.gz", "simple_project-1.2.3-py3-none-any.whl"], |
| 44 | + "1.2.3", |
| 45 | + ), |
| 46 | + ( # other names are ignored |
| 47 | + [ |
| 48 | + "simple_project-1.2.3.tar.gz", |
| 49 | + "other_project-1.2.3.tar.gz", |
| 50 | + "simple_project-1.2.3-py3-none-any.whl", |
| 51 | + "other_project-1.2.3-py3-none-any.whl", |
| 52 | + ], |
| 53 | + ["simple_project-1.2.3.tar.gz", "simple_project-1.2.3-py3-none-any.whl"], |
| 54 | + "1.2.3", |
| 55 | + ), |
| 56 | + ( # older versions are ignored |
| 57 | + [ |
| 58 | + "simple_project-1.2.3.tar.gz", |
| 59 | + "simple_project-1.2.4.tar.gz", |
| 60 | + "simple_project-1.2.3-py3-none-any.whl", |
| 61 | + "simple_project-1.2.4-py3-none-any.whl", |
| 62 | + ], |
| 63 | + ["simple_project-1.2.4.tar.gz", "simple_project-1.2.4-py3-none-any.whl"], |
| 64 | + "1.2.4", |
| 65 | + ), |
| 66 | + ( # older versions are ignored - only new sdist |
| 67 | + [ |
| 68 | + "simple_project-1.2.3.tar.gz", |
| 69 | + "simple_project-1.2.4.tar.gz", |
| 70 | + "simple_project-1.2.3-py3-none-any.whl", |
| 71 | + ], |
| 72 | + ["simple_project-1.2.4.tar.gz"], |
| 73 | + "1.2.4", |
| 74 | + ), |
| 75 | + ( # older versions are ignored - only new wheel |
| 76 | + [ |
| 77 | + "simple_project-1.2.3.tar.gz", |
| 78 | + "simple_project-1.2.3-py3-none-any.whl", |
| 79 | + "simple_project-1.2.4-py3-none-any.whl", |
| 80 | + ], |
| 81 | + ["simple_project-1.2.4-py3-none-any.whl"], |
| 82 | + "1.2.4", |
| 83 | + ), |
| 84 | + ( # older versions are ignored - local version |
| 85 | + [ |
| 86 | + "simple_project-1.2.3.tar.gz", |
| 87 | + "simple_project-1.2.3+hash1.tar.gz", |
| 88 | + "simple_project-1.2.3+hash2.tar.gz", |
| 89 | + "simple_project-1.2.3-py3-none-any.whl", |
| 90 | + "simple_project-1.2.3+hash1-py3-none-any.whl", |
| 91 | + "simple_project-1.2.3+hash2-py3-none-any.whl", |
| 92 | + ], |
| 93 | + [ |
| 94 | + "simple_project-1.2.3+hash2.tar.gz", |
| 95 | + "simple_project-1.2.3+hash2-py3-none-any.whl", |
| 96 | + ], |
| 97 | + "1.2.3+hash2", |
| 98 | + ), |
| 99 | + ( # older versions are ignore - pre-release |
| 100 | + [ |
| 101 | + "simple_project-1.2.3rc1.tar.gz", |
| 102 | + "simple_project-1.2.3rc1-py3-none-any.whl", |
| 103 | + "simple_project-1.2.3.tar.gz", |
| 104 | + "simple_project-1.2.3-py3-none-any.whl", |
| 105 | + ], |
| 106 | + [ |
| 107 | + "simple_project-1.2.3.tar.gz", |
| 108 | + "simple_project-1.2.3-py3-none-any.whl", |
| 109 | + ], |
| 110 | + "1.2.3", |
| 111 | + ), |
| 112 | + ], |
| 113 | +) |
| 114 | +def test_uploader_files_only_latest( |
| 115 | + poetry: Poetry, |
| 116 | + tmp_path: Path, |
| 117 | + files: list[str], |
| 118 | + expected_files: list[str], |
| 119 | + expected_version: str, |
| 120 | +) -> None: |
| 121 | + for file in files: |
| 122 | + (tmp_path / file).touch() |
| 123 | + uploader = Uploader(poetry, NullIO(), dist_dir=tmp_path) |
| 124 | + |
| 125 | + assert uploader.files == [tmp_path / f for f in expected_files] |
| 126 | + assert uploader.version == expected_version |
25 | 127 |
|
26 | 128 |
|
27 | 129 | def test_uploader_properly_handles_400_errors( |
@@ -105,16 +207,49 @@ def test_uploader_properly_handles_301_redirects( |
105 | 207 | ) |
106 | 208 |
|
107 | 209 |
|
108 | | -def test_uploader_registers_for_appropriate_400_errors( |
109 | | - mocker: MockerFixture, http: responses.RequestsMock, uploader: Uploader |
| 210 | +def test_uploader_registers_with_sdist_for_appropriate_400_errors( |
| 211 | + http: responses.RequestsMock, uploader: Uploader |
110 | 212 | ) -> None: |
111 | | - register = mocker.patch("poetry.publishing.uploader.Uploader._register") |
112 | 213 | http.post("https://foo.com", status=400, body="No package was ever registered") |
113 | 214 |
|
114 | 215 | with pytest.raises(UploadError): |
115 | 216 | uploader.upload("https://foo.com") |
116 | 217 |
|
117 | | - assert register.call_count == 1 |
| 218 | + assert len(http.calls) == 2 |
| 219 | + bodies = [c.request.body or b"" for c in http.calls] |
| 220 | + assert b'name=":action"\r\n\r\nfile_upload\r\n' in bodies[0] |
| 221 | + assert b'name=":action"\r\n\r\nsubmit\r\n' in bodies[1] |
| 222 | + assert b"sdist" in bodies[0] |
| 223 | + assert b"sdist" in bodies[1] |
| 224 | + assert b"bdist_wheel" not in bodies[0] |
| 225 | + assert b"bdist_wheel" not in bodies[1] |
| 226 | + |
| 227 | + |
| 228 | +def test_uploader_register_uses_wheel_if_no_sdist( |
| 229 | + http: responses.RequestsMock, poetry: Poetry, tmp_path: Path |
| 230 | +) -> None: |
| 231 | + dist_dir = tmp_path / "dist" |
| 232 | + dist_dir.mkdir() |
| 233 | + shutil.copy( |
| 234 | + poetry.file.path.parent / "dist" / "simple_project-1.2.3-py2.py3-none-any.whl", |
| 235 | + dist_dir, |
| 236 | + ) |
| 237 | + |
| 238 | + uploader = Uploader(poetry, NullIO(), dist_dir=dist_dir) |
| 239 | + |
| 240 | + http.post("https://foo.com", status=400, body="No package was ever registered") |
| 241 | + |
| 242 | + with pytest.raises(UploadError): |
| 243 | + uploader.upload("https://foo.com") |
| 244 | + |
| 245 | + assert len(http.calls) == 2 |
| 246 | + bodies = [c.request.body or b"" for c in http.calls] |
| 247 | + assert b'name=":action"\r\n\r\nfile_upload\r\n' in bodies[0] |
| 248 | + assert b'name=":action"\r\n\r\nsubmit\r\n' in bodies[1] |
| 249 | + assert b"sdist" not in bodies[0] |
| 250 | + assert b"sdist" not in bodies[1] |
| 251 | + assert b"bdist_wheel" in bodies[0] |
| 252 | + assert b"bdist_wheel" in bodies[1] |
118 | 253 |
|
119 | 254 |
|
120 | 255 | @pytest.mark.parametrize( |
|
0 commit comments