@@ -132,3 +132,141 @@ def test_file_upload(webtest, upload_url, additional_data):
132
132
assert len (project .releases ) == 1
133
133
release = project .releases [0 ]
134
134
assert release .version == "3.0.0"
135
+
136
+
137
+ def test_duplicate_file_upload_error (webtest ):
138
+ user = UserFactory .create (
139
+ with_verified_primary_email = True ,
140
+ password = ( # 'password'
141
+ "$argon2id$v=19$m=1024,t=6,p=6$EiLE2Nsbo9S6N+acs/beGw$ccyZDCZstr1/+Y/1s3BVZ"
142
+ "HOJaqfBroT0JCieHug281c"
143
+ ),
144
+ )
145
+
146
+ # Construct the macaroon
147
+ dm = MacaroonFactory .create (
148
+ user_id = user .id ,
149
+ caveats = [caveats .RequestUser (user_id = str (user .id ))],
150
+ )
151
+
152
+ m = pymacaroons .Macaroon (
153
+ location = "localhost" ,
154
+ identifier = str (dm .id ),
155
+ key = dm .key ,
156
+ version = pymacaroons .MACAROON_V2 ,
157
+ )
158
+ for caveat in dm .caveats :
159
+ m .add_first_party_caveat (caveats .serialize (caveat ))
160
+ serialized_macaroon = f"pypi-{ m .serialize ()} "
161
+
162
+ credentials = base64 .b64encode (f"__token__:{ serialized_macaroon } " .encode ()).decode (
163
+ "utf-8"
164
+ )
165
+
166
+ with open ("./tests/functional/_fixtures/sampleproject-3.0.0.tar.gz" , "rb" ) as f :
167
+ content = f .read ()
168
+
169
+ params = MultiDict (
170
+ {
171
+ ":action" : "file_upload" ,
172
+ "protocol_version" : "1" ,
173
+ "name" : "sampleproject" ,
174
+ "sha256_digest" : (
175
+ "117ed88e5db073bb92969a7545745fd977ee85b7019706dd256a64058f70963d"
176
+ ),
177
+ "filetype" : "sdist" ,
178
+ "metadata_version" : "2.1" ,
179
+ "version" : "3.0.0" ,
180
+ }
181
+ )
182
+
183
+ webtest .post (
184
+ "/legacy/" ,
185
+ headers = {"Authorization" : f"Basic { credentials } " },
186
+ params = params ,
187
+ upload_files = [("content" , "sampleproject-3.0.0.tar.gz" , content )],
188
+ status = HTTPStatus .OK ,
189
+ )
190
+
191
+ assert user .projects
192
+ assert len (user .projects ) == 1
193
+ project = user .projects [0 ]
194
+ assert project .name == "sampleproject"
195
+ assert project .releases
196
+ assert len (project .releases ) == 1
197
+ release = project .releases [0 ]
198
+ assert release .version == "3.0.0"
199
+
200
+ # Add some duplicate keys to ensure that this doesn't result in a error due
201
+ # to the duplicate key detector
202
+ params .add ("project-url" , "https://example.com/foo" )
203
+ params .add ("project-url" , "https://example.com/bar" )
204
+ params .add ("classifiers" , "Programming Language :: Python :: 3.10" )
205
+ params .add ("classifiers" , "Programming Language :: Python :: 3.11" )
206
+
207
+ resp = webtest .post (
208
+ "/legacy/" ,
209
+ headers = {"Authorization" : f"Basic { credentials } " },
210
+ params = params ,
211
+ upload_files = [("content" , "sampleproject-3.0.1.tar.gz" , content )],
212
+ status = HTTPStatus .BAD_REQUEST ,
213
+ )
214
+ assert "File already exists" in resp .body .decode ()
215
+
216
+
217
+ def test_invalid_classifier_upload_error (webtest ):
218
+ user = UserFactory .create (
219
+ with_verified_primary_email = True ,
220
+ password = ( # 'password'
221
+ "$argon2id$v=19$m=1024,t=6,p=6$EiLE2Nsbo9S6N+acs/beGw$ccyZDCZstr1/+Y/1s3BVZ"
222
+ "HOJaqfBroT0JCieHug281c"
223
+ ),
224
+ )
225
+
226
+ # Construct the macaroon
227
+ dm = MacaroonFactory .create (
228
+ user_id = user .id ,
229
+ caveats = [caveats .RequestUser (user_id = str (user .id ))],
230
+ )
231
+
232
+ m = pymacaroons .Macaroon (
233
+ location = "localhost" ,
234
+ identifier = str (dm .id ),
235
+ key = dm .key ,
236
+ version = pymacaroons .MACAROON_V2 ,
237
+ )
238
+ for caveat in dm .caveats :
239
+ m .add_first_party_caveat (caveats .serialize (caveat ))
240
+ serialized_macaroon = f"pypi-{ m .serialize ()} "
241
+
242
+ credentials = base64 .b64encode (f"__token__:{ serialized_macaroon } " .encode ()).decode (
243
+ "utf-8"
244
+ )
245
+
246
+ with open ("./tests/functional/_fixtures/sampleproject-3.0.0.tar.gz" , "rb" ) as f :
247
+ content = f .read ()
248
+
249
+ params = MultiDict (
250
+ {
251
+ ":action" : "file_upload" ,
252
+ "protocol_version" : "1" ,
253
+ "name" : "sampleproject" ,
254
+ "sha256_digest" : (
255
+ "117ed88e5db073bb92969a7545745fd977ee85b7019706dd256a64058f70963d"
256
+ ),
257
+ "filetype" : "sdist" ,
258
+ "metadata_version" : "2.1" ,
259
+ "version" : "3.0.0" ,
260
+ }
261
+ )
262
+ params .add ("classifiers" , "Programming Language :: Python :: 3.10" )
263
+ params .add ("classifiers" , "This :: Is :: Invalid" )
264
+
265
+ resp = webtest .post (
266
+ "/legacy/" ,
267
+ headers = {"Authorization" : f"Basic { credentials } " },
268
+ params = params ,
269
+ upload_files = [("content" , "sampleproject-3.0.1.tar.gz" , content )],
270
+ status = HTTPStatus .BAD_REQUEST ,
271
+ )
272
+ assert "'This :: Is :: Invalid' is not a valid classifier" in resp .body .decode ()
0 commit comments