27
27
import warehouse .utils .otp as otp
28
28
29
29
from warehouse .accounts .interfaces import IPasswordBreachedService , IUserService
30
+ from warehouse .admin .flags import AdminFlagValue
30
31
from warehouse .macaroons .interfaces import IMacaroonService
31
32
from warehouse .manage import views
32
33
from warehouse .packaging .models import (
@@ -2014,6 +2015,7 @@ def test_delete_project_no_confirm(self):
2014
2015
project = pretend .stub (normalized_name = "foo" )
2015
2016
request = pretend .stub (
2016
2017
POST = {},
2018
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False )),
2017
2019
session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2018
2020
route_path = lambda * a , ** kw : "/foo/bar/" ,
2019
2021
)
@@ -2023,6 +2025,9 @@ def test_delete_project_no_confirm(self):
2023
2025
assert exc .value .status_code == 303
2024
2026
assert exc .value .headers ["Location" ] == "/foo/bar/"
2025
2027
2028
+ assert request .flags .enabled .calls == [
2029
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2030
+ ]
2026
2031
assert request .session .flash .calls == [
2027
2032
pretend .call ("Confirm the request" , queue = "error" )
2028
2033
]
@@ -2031,6 +2036,7 @@ def test_delete_project_wrong_confirm(self):
2031
2036
project = pretend .stub (normalized_name = "foo" )
2032
2037
request = pretend .stub (
2033
2038
POST = {"confirm_project_name" : "bar" },
2039
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False )),
2034
2040
session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2035
2041
route_path = lambda * a , ** kw : "/foo/bar/" ,
2036
2042
)
@@ -2040,13 +2046,46 @@ def test_delete_project_wrong_confirm(self):
2040
2046
assert exc .value .status_code == 303
2041
2047
assert exc .value .headers ["Location" ] == "/foo/bar/"
2042
2048
2049
+ assert request .flags .enabled .calls == [
2050
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2051
+ ]
2043
2052
assert request .session .flash .calls == [
2044
2053
pretend .call (
2045
2054
"Could not delete project - 'bar' is not the same as 'foo'" ,
2046
2055
queue = "error" ,
2047
2056
)
2048
2057
]
2049
2058
2059
+ def test_delete_project_disallow_deletion (self ):
2060
+ project = pretend .stub (name = "foo" , normalized_name = "foo" )
2061
+ request = pretend .stub (
2062
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : True )),
2063
+ route_path = pretend .call_recorder (lambda * a , ** kw : "/the-redirect" ),
2064
+ session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2065
+ )
2066
+
2067
+ result = views .delete_project (project , request )
2068
+ assert isinstance (result , HTTPSeeOther )
2069
+ assert result .headers ["Location" ] == "/the-redirect"
2070
+
2071
+ assert request .flags .enabled .calls == [
2072
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2073
+ ]
2074
+
2075
+ assert request .session .flash .calls == [
2076
+ pretend .call (
2077
+ (
2078
+ "Project deletion temporarily disabled. "
2079
+ "See https://pypi.org/help#admin-intervention for details."
2080
+ ),
2081
+ queue = "error" ,
2082
+ )
2083
+ ]
2084
+
2085
+ assert request .route_path .calls == [
2086
+ pretend .call ("manage.project.settings" , project_name = "foo" )
2087
+ ]
2088
+
2050
2089
def test_delete_project (self , db_request ):
2051
2090
project = ProjectFactory .create (name = "foo" )
2052
2091
@@ -2159,6 +2198,7 @@ def test_manage_project_releases(self, db_request):
2159
2198
filename = f"foobar-{ release .version } .tar.gz" ,
2160
2199
packagetype = "sdist" ,
2161
2200
)
2201
+ db_request .flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False ))
2162
2202
2163
2203
assert views .manage_project_releases (project , db_request ) == {
2164
2204
"project" : project ,
@@ -2182,6 +2222,48 @@ def test_manage_project_release(self):
2182
2222
"files" : files ,
2183
2223
}
2184
2224
2225
+ def test_delete_project_release_disallow_deletion (self , monkeypatch ):
2226
+ release = pretend .stub (
2227
+ version = "1.2.3" ,
2228
+ canonical_version = "1.2.3" ,
2229
+ project = pretend .stub (
2230
+ name = "foobar" , record_event = pretend .call_recorder (lambda * a , ** kw : None )
2231
+ ),
2232
+ )
2233
+ request = pretend .stub (
2234
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : True )),
2235
+ method = "POST" ,
2236
+ route_path = pretend .call_recorder (lambda * a , ** kw : "/the-redirect" ),
2237
+ session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2238
+ )
2239
+ view = views .ManageProjectRelease (release , request )
2240
+
2241
+ result = view .delete_project_release ()
2242
+ assert isinstance (result , HTTPSeeOther )
2243
+ assert result .headers ["Location" ] == "/the-redirect"
2244
+
2245
+ assert request .flags .enabled .calls == [
2246
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2247
+ ]
2248
+
2249
+ assert request .session .flash .calls == [
2250
+ pretend .call (
2251
+ (
2252
+ "Project deletion temporarily disabled. "
2253
+ "See https://pypi.org/help#admin-intervention for details."
2254
+ ),
2255
+ queue = "error" ,
2256
+ )
2257
+ ]
2258
+
2259
+ assert request .route_path .calls == [
2260
+ pretend .call (
2261
+ "manage.project.release" ,
2262
+ project_name = release .project .name ,
2263
+ version = release .version ,
2264
+ )
2265
+ ]
2266
+
2185
2267
def test_delete_project_release (self , monkeypatch ):
2186
2268
release = pretend .stub (
2187
2269
version = "1.2.3" ,
@@ -2197,6 +2279,7 @@ def test_delete_project_release(self, monkeypatch):
2197
2279
delete = pretend .call_recorder (lambda a : None ),
2198
2280
add = pretend .call_recorder (lambda a : None ),
2199
2281
),
2282
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False )),
2200
2283
route_path = pretend .call_recorder (lambda * a , ** kw : "/the-redirect" ),
2201
2284
session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2202
2285
user = pretend .stub (username = pretend .stub ()),
@@ -2215,6 +2298,9 @@ def test_delete_project_release(self, monkeypatch):
2215
2298
2216
2299
assert request .db .delete .calls == [pretend .call (release )]
2217
2300
assert request .db .add .calls == [pretend .call (journal_obj )]
2301
+ assert request .flags .enabled .calls == [
2302
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2303
+ ]
2218
2304
assert journal_cls .calls == [
2219
2305
pretend .call (
2220
2306
name = release .project .name ,
@@ -2247,6 +2333,7 @@ def test_delete_project_release_no_confirm(self):
2247
2333
POST = {"confirm_version" : "" },
2248
2334
method = "POST" ,
2249
2335
db = pretend .stub (delete = pretend .call_recorder (lambda a : None )),
2336
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False )),
2250
2337
route_path = pretend .call_recorder (lambda * a , ** kw : "/the-redirect" ),
2251
2338
session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2252
2339
)
@@ -2261,6 +2348,9 @@ def test_delete_project_release_no_confirm(self):
2261
2348
assert request .session .flash .calls == [
2262
2349
pretend .call ("Confirm the request" , queue = "error" )
2263
2350
]
2351
+ assert request .flags .enabled .calls == [
2352
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2353
+ ]
2264
2354
assert request .route_path .calls == [
2265
2355
pretend .call (
2266
2356
"manage.project.release" ,
@@ -2275,6 +2365,7 @@ def test_delete_project_release_bad_confirm(self):
2275
2365
POST = {"confirm_version" : "invalid" },
2276
2366
method = "POST" ,
2277
2367
db = pretend .stub (delete = pretend .call_recorder (lambda a : None )),
2368
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False )),
2278
2369
route_path = pretend .call_recorder (lambda * a , ** kw : "/the-redirect" ),
2279
2370
session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2280
2371
)
@@ -2301,6 +2392,42 @@ def test_delete_project_release_bad_confirm(self):
2301
2392
)
2302
2393
]
2303
2394
2395
+ def test_delete_project_release_file_disallow_deletion (self ):
2396
+ release = pretend .stub (version = "1.2.3" , project = pretend .stub (name = "foobar" ))
2397
+ request = pretend .stub (
2398
+ method = "POST" ,
2399
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : True )),
2400
+ route_path = pretend .call_recorder (lambda * a , ** kw : "/the-redirect" ),
2401
+ session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2402
+ )
2403
+ view = views .ManageProjectRelease (release , request )
2404
+
2405
+ result = view .delete_project_release_file ()
2406
+
2407
+ assert isinstance (result , HTTPSeeOther )
2408
+ assert result .headers ["Location" ] == "/the-redirect"
2409
+
2410
+ assert request .flags .enabled .calls == [
2411
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2412
+ ]
2413
+
2414
+ assert request .session .flash .calls == [
2415
+ pretend .call (
2416
+ (
2417
+ "Project deletion temporarily disabled. "
2418
+ "See https://pypi.org/help#admin-intervention for details."
2419
+ ),
2420
+ queue = "error" ,
2421
+ )
2422
+ ]
2423
+ assert request .route_path .calls == [
2424
+ pretend .call (
2425
+ "manage.project.release" ,
2426
+ project_name = release .project .name ,
2427
+ version = release .version ,
2428
+ )
2429
+ ]
2430
+
2304
2431
def test_delete_project_release_file (self , db_request ):
2305
2432
user = UserFactory .create ()
2306
2433
@@ -2359,6 +2486,7 @@ def test_delete_project_release_file_no_confirm(self):
2359
2486
POST = {"confirm_project_name" : "" },
2360
2487
method = "POST" ,
2361
2488
db = pretend .stub (delete = pretend .call_recorder (lambda a : None )),
2489
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False )),
2362
2490
route_path = pretend .call_recorder (lambda * a , ** kw : "/the-redirect" ),
2363
2491
session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2364
2492
)
@@ -2370,6 +2498,9 @@ def test_delete_project_release_file_no_confirm(self):
2370
2498
assert result .headers ["Location" ] == "/the-redirect"
2371
2499
2372
2500
assert request .db .delete .calls == []
2501
+ assert request .flags .enabled .calls == [
2502
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2503
+ ]
2373
2504
assert request .session .flash .calls == [
2374
2505
pretend .call ("Confirm the request" , queue = "error" )
2375
2506
]
@@ -2396,6 +2527,7 @@ def no_result_found():
2396
2527
filter = lambda * a : pretend .stub (one = no_result_found )
2397
2528
),
2398
2529
)
2530
+ db_request .flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False ))
2399
2531
db_request .route_path = pretend .call_recorder (lambda * a , ** kw : "/the-redirect" )
2400
2532
db_request .session = pretend .stub (
2401
2533
flash = pretend .call_recorder (lambda * a , ** kw : None )
@@ -2409,6 +2541,9 @@ def no_result_found():
2409
2541
assert result .headers ["Location" ] == "/the-redirect"
2410
2542
2411
2543
assert db_request .db .delete .calls == []
2544
+ assert db_request .flags .enabled .calls == [
2545
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2546
+ ]
2412
2547
assert db_request .session .flash .calls == [
2413
2548
pretend .call ("Could not find file" , queue = "error" )
2414
2549
]
0 commit comments