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 (
@@ -2005,15 +2006,24 @@ def test_manage_projects(self, db_request):
2005
2006
2006
2007
class TestManageProjectSettings :
2007
2008
def test_manage_project_settings (self ):
2008
- request = pretend .stub ()
2009
+ request = pretend .stub (
2010
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False ))
2011
+ )
2009
2012
project = pretend .stub ()
2010
2013
2011
- assert views .manage_project_settings (project , request ) == {"project" : project }
2014
+ assert views .manage_project_settings (project , request ) == {
2015
+ "disallow_deletion" : False ,
2016
+ "project" : project ,
2017
+ }
2018
+ assert request .flags .enabled .calls == [
2019
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2020
+ ]
2012
2021
2013
2022
def test_delete_project_no_confirm (self ):
2014
2023
project = pretend .stub (normalized_name = "foo" )
2015
2024
request = pretend .stub (
2016
2025
POST = {},
2026
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False )),
2017
2027
session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2018
2028
route_path = lambda * a , ** kw : "/foo/bar/" ,
2019
2029
)
@@ -2023,6 +2033,9 @@ def test_delete_project_no_confirm(self):
2023
2033
assert exc .value .status_code == 303
2024
2034
assert exc .value .headers ["Location" ] == "/foo/bar/"
2025
2035
2036
+ assert request .flags .enabled .calls == [
2037
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2038
+ ]
2026
2039
assert request .session .flash .calls == [
2027
2040
pretend .call ("Confirm the request" , queue = "error" )
2028
2041
]
@@ -2031,6 +2044,7 @@ def test_delete_project_wrong_confirm(self):
2031
2044
project = pretend .stub (normalized_name = "foo" )
2032
2045
request = pretend .stub (
2033
2046
POST = {"confirm_project_name" : "bar" },
2047
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False )),
2034
2048
session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2035
2049
route_path = lambda * a , ** kw : "/foo/bar/" ,
2036
2050
)
@@ -2040,13 +2054,46 @@ def test_delete_project_wrong_confirm(self):
2040
2054
assert exc .value .status_code == 303
2041
2055
assert exc .value .headers ["Location" ] == "/foo/bar/"
2042
2056
2057
+ assert request .flags .enabled .calls == [
2058
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2059
+ ]
2043
2060
assert request .session .flash .calls == [
2044
2061
pretend .call (
2045
2062
"Could not delete project - 'bar' is not the same as 'foo'" ,
2046
2063
queue = "error" ,
2047
2064
)
2048
2065
]
2049
2066
2067
+ def test_delete_project_disallow_deletion (self ):
2068
+ project = pretend .stub (name = "foo" , normalized_name = "foo" )
2069
+ request = pretend .stub (
2070
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : True )),
2071
+ route_path = pretend .call_recorder (lambda * a , ** kw : "/the-redirect" ),
2072
+ session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2073
+ )
2074
+
2075
+ result = views .delete_project (project , request )
2076
+ assert isinstance (result , HTTPSeeOther )
2077
+ assert result .headers ["Location" ] == "/the-redirect"
2078
+
2079
+ assert request .flags .enabled .calls == [
2080
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2081
+ ]
2082
+
2083
+ assert request .session .flash .calls == [
2084
+ pretend .call (
2085
+ (
2086
+ "Project deletion temporarily disabled. "
2087
+ "See https://pypi.org/help#admin-intervention for details."
2088
+ ),
2089
+ queue = "error" ,
2090
+ )
2091
+ ]
2092
+
2093
+ assert request .route_path .calls == [
2094
+ pretend .call ("manage.project.settings" , project_name = "foo" )
2095
+ ]
2096
+
2050
2097
def test_delete_project (self , db_request ):
2051
2098
project = ProjectFactory .create (name = "foo" )
2052
2099
@@ -2159,29 +2206,84 @@ def test_manage_project_releases(self, db_request):
2159
2206
filename = f"foobar-{ release .version } .tar.gz" ,
2160
2207
packagetype = "sdist" ,
2161
2208
)
2209
+ db_request .flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False ))
2162
2210
2163
2211
assert views .manage_project_releases (project , db_request ) == {
2212
+ "disallow_deletion" : False ,
2164
2213
"project" : project ,
2165
2214
"version_to_file_counts" : {
2166
2215
release .version : {"total" : 1 , release_file .packagetype : 1 }
2167
2216
},
2168
2217
}
2169
2218
2219
+ assert db_request .flags .enabled .calls == [
2220
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2221
+ ]
2222
+
2170
2223
2171
2224
class TestManageProjectRelease :
2172
2225
def test_manage_project_release (self ):
2173
2226
files = pretend .stub ()
2174
2227
project = pretend .stub ()
2175
2228
release = pretend .stub (project = project , files = pretend .stub (all = lambda : files ))
2176
- request = pretend .stub ()
2229
+ request = pretend .stub (
2230
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False ))
2231
+ )
2177
2232
view = views .ManageProjectRelease (release , request )
2178
2233
2179
2234
assert view .manage_project_release () == {
2235
+ "disallow_deletion" : False ,
2180
2236
"project" : project ,
2181
2237
"release" : release ,
2182
2238
"files" : files ,
2183
2239
}
2184
2240
2241
+ assert request .flags .enabled .calls == [
2242
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2243
+ ]
2244
+
2245
+ def test_delete_project_release_disallow_deletion (self , monkeypatch ):
2246
+ release = pretend .stub (
2247
+ version = "1.2.3" ,
2248
+ canonical_version = "1.2.3" ,
2249
+ project = pretend .stub (
2250
+ name = "foobar" , record_event = pretend .call_recorder (lambda * a , ** kw : None )
2251
+ ),
2252
+ )
2253
+ request = pretend .stub (
2254
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : True )),
2255
+ method = "POST" ,
2256
+ route_path = pretend .call_recorder (lambda * a , ** kw : "/the-redirect" ),
2257
+ session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2258
+ )
2259
+ view = views .ManageProjectRelease (release , request )
2260
+
2261
+ result = view .delete_project_release ()
2262
+ assert isinstance (result , HTTPSeeOther )
2263
+ assert result .headers ["Location" ] == "/the-redirect"
2264
+
2265
+ assert request .flags .enabled .calls == [
2266
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2267
+ ]
2268
+
2269
+ assert request .session .flash .calls == [
2270
+ pretend .call (
2271
+ (
2272
+ "Project deletion temporarily disabled. "
2273
+ "See https://pypi.org/help#admin-intervention for details."
2274
+ ),
2275
+ queue = "error" ,
2276
+ )
2277
+ ]
2278
+
2279
+ assert request .route_path .calls == [
2280
+ pretend .call (
2281
+ "manage.project.release" ,
2282
+ project_name = release .project .name ,
2283
+ version = release .version ,
2284
+ )
2285
+ ]
2286
+
2185
2287
def test_delete_project_release (self , monkeypatch ):
2186
2288
release = pretend .stub (
2187
2289
version = "1.2.3" ,
@@ -2197,6 +2299,7 @@ def test_delete_project_release(self, monkeypatch):
2197
2299
delete = pretend .call_recorder (lambda a : None ),
2198
2300
add = pretend .call_recorder (lambda a : None ),
2199
2301
),
2302
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False )),
2200
2303
route_path = pretend .call_recorder (lambda * a , ** kw : "/the-redirect" ),
2201
2304
session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2202
2305
user = pretend .stub (username = pretend .stub ()),
@@ -2215,6 +2318,9 @@ def test_delete_project_release(self, monkeypatch):
2215
2318
2216
2319
assert request .db .delete .calls == [pretend .call (release )]
2217
2320
assert request .db .add .calls == [pretend .call (journal_obj )]
2321
+ assert request .flags .enabled .calls == [
2322
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2323
+ ]
2218
2324
assert journal_cls .calls == [
2219
2325
pretend .call (
2220
2326
name = release .project .name ,
@@ -2247,6 +2353,7 @@ def test_delete_project_release_no_confirm(self):
2247
2353
POST = {"confirm_version" : "" },
2248
2354
method = "POST" ,
2249
2355
db = pretend .stub (delete = pretend .call_recorder (lambda a : None )),
2356
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False )),
2250
2357
route_path = pretend .call_recorder (lambda * a , ** kw : "/the-redirect" ),
2251
2358
session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2252
2359
)
@@ -2261,6 +2368,9 @@ def test_delete_project_release_no_confirm(self):
2261
2368
assert request .session .flash .calls == [
2262
2369
pretend .call ("Confirm the request" , queue = "error" )
2263
2370
]
2371
+ assert request .flags .enabled .calls == [
2372
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2373
+ ]
2264
2374
assert request .route_path .calls == [
2265
2375
pretend .call (
2266
2376
"manage.project.release" ,
@@ -2275,6 +2385,7 @@ def test_delete_project_release_bad_confirm(self):
2275
2385
POST = {"confirm_version" : "invalid" },
2276
2386
method = "POST" ,
2277
2387
db = pretend .stub (delete = pretend .call_recorder (lambda a : None )),
2388
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False )),
2278
2389
route_path = pretend .call_recorder (lambda * a , ** kw : "/the-redirect" ),
2279
2390
session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2280
2391
)
@@ -2286,6 +2397,9 @@ def test_delete_project_release_bad_confirm(self):
2286
2397
assert result .headers ["Location" ] == "/the-redirect"
2287
2398
2288
2399
assert request .db .delete .calls == []
2400
+ assert request .flags .enabled .calls == [
2401
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2402
+ ]
2289
2403
assert request .session .flash .calls == [
2290
2404
pretend .call (
2291
2405
"Could not delete release - "
@@ -2301,6 +2415,42 @@ def test_delete_project_release_bad_confirm(self):
2301
2415
)
2302
2416
]
2303
2417
2418
+ def test_delete_project_release_file_disallow_deletion (self ):
2419
+ release = pretend .stub (version = "1.2.3" , project = pretend .stub (name = "foobar" ))
2420
+ request = pretend .stub (
2421
+ method = "POST" ,
2422
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : True )),
2423
+ route_path = pretend .call_recorder (lambda * a , ** kw : "/the-redirect" ),
2424
+ session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2425
+ )
2426
+ view = views .ManageProjectRelease (release , request )
2427
+
2428
+ result = view .delete_project_release_file ()
2429
+
2430
+ assert isinstance (result , HTTPSeeOther )
2431
+ assert result .headers ["Location" ] == "/the-redirect"
2432
+
2433
+ assert request .flags .enabled .calls == [
2434
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2435
+ ]
2436
+
2437
+ assert request .session .flash .calls == [
2438
+ pretend .call (
2439
+ (
2440
+ "Project deletion temporarily disabled. "
2441
+ "See https://pypi.org/help#admin-intervention for details."
2442
+ ),
2443
+ queue = "error" ,
2444
+ )
2445
+ ]
2446
+ assert request .route_path .calls == [
2447
+ pretend .call (
2448
+ "manage.project.release" ,
2449
+ project_name = release .project .name ,
2450
+ version = release .version ,
2451
+ )
2452
+ ]
2453
+
2304
2454
def test_delete_project_release_file (self , db_request ):
2305
2455
user = UserFactory .create ()
2306
2456
@@ -2359,6 +2509,7 @@ def test_delete_project_release_file_no_confirm(self):
2359
2509
POST = {"confirm_project_name" : "" },
2360
2510
method = "POST" ,
2361
2511
db = pretend .stub (delete = pretend .call_recorder (lambda a : None )),
2512
+ flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False )),
2362
2513
route_path = pretend .call_recorder (lambda * a , ** kw : "/the-redirect" ),
2363
2514
session = pretend .stub (flash = pretend .call_recorder (lambda * a , ** kw : None )),
2364
2515
)
@@ -2370,6 +2521,9 @@ def test_delete_project_release_file_no_confirm(self):
2370
2521
assert result .headers ["Location" ] == "/the-redirect"
2371
2522
2372
2523
assert request .db .delete .calls == []
2524
+ assert request .flags .enabled .calls == [
2525
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2526
+ ]
2373
2527
assert request .session .flash .calls == [
2374
2528
pretend .call ("Confirm the request" , queue = "error" )
2375
2529
]
@@ -2396,6 +2550,7 @@ def no_result_found():
2396
2550
filter = lambda * a : pretend .stub (one = no_result_found )
2397
2551
),
2398
2552
)
2553
+ db_request .flags = pretend .stub (enabled = pretend .call_recorder (lambda * a : False ))
2399
2554
db_request .route_path = pretend .call_recorder (lambda * a , ** kw : "/the-redirect" )
2400
2555
db_request .session = pretend .stub (
2401
2556
flash = pretend .call_recorder (lambda * a , ** kw : None )
@@ -2409,6 +2564,9 @@ def no_result_found():
2409
2564
assert result .headers ["Location" ] == "/the-redirect"
2410
2565
2411
2566
assert db_request .db .delete .calls == []
2567
+ assert db_request .flags .enabled .calls == [
2568
+ pretend .call (AdminFlagValue .DISALLOW_DELETION )
2569
+ ]
2412
2570
assert db_request .session .flash .calls == [
2413
2571
pretend .call ("Could not find file" , queue = "error" )
2414
2572
]
0 commit comments