@@ -76,8 +76,12 @@ def test_plugin_soft_delete_marks_as_deleted(self):
7676 self .assertTrue (plugin .is_deleted )
7777 self .assertIsNotNone (plugin .deleted_on )
7878
79- def test_soft_deleted_plugin_excluded_from_approved_objects (self ):
80- """Test that soft-deleted plugins don't appear in approved_objects."""
79+ def test_soft_deleted_plugin_still_in_approved_objects (self ):
80+ """Test that soft-deleted plugins still appear in approved_objects.
81+
82+ Plugins marked for deletion should remain visible in the public listing
83+ until they are permanently deleted (see issue #253).
84+ """
8185 # First, approve and verify plugin appears
8286 self .version1 .approved = True
8387 self .version1 .save ()
@@ -88,8 +92,8 @@ def test_soft_deleted_plugin_excluded_from_approved_objects(self):
8892 self .plugin .deleted_on = timezone .now ()
8993 self .plugin .save ()
9094
91- # Plugin should not appear in approved_objects
92- self .assertNotIn (self .plugin , Plugin .approved_objects .all ())
95+ # Plugin should still appear in approved_objects (visible in listings)
96+ self .assertIn (self .plugin , Plugin .approved_objects .all ())
9397
9498 def test_soft_deleted_plugin_visible_in_my_plugins (self ):
9599 """Test that soft-deleted plugins are visible to owners in My Plugins."""
@@ -162,6 +166,44 @@ def test_only_soft_deleted_plugins_can_be_permanently_deleted(self):
162166 # Should get 404
163167 self .assertEqual (response .status_code , 404 )
164168
169+ def test_soft_deleted_plugin_visible_in_approved_listing (self ):
170+ """Test that soft-deleted plugins still appear in the approved plugin listing.
171+
172+ Plugins marked for deletion remain accessible until permanently deleted
173+ so users can still download them during the grace period (see issue #253).
174+ """
175+ # Approve the version so plugin appears in approved listing
176+ self .version1 .approved = True
177+ self .version1 .save ()
178+ self .assertIn (self .plugin , Plugin .approved_objects .all ())
179+
180+ # Soft delete the plugin
181+ self .plugin .is_deleted = True
182+ self .plugin .deleted_on = timezone .now ()
183+ self .plugin .save ()
184+
185+ # Plugin should still appear in approved_objects listing
186+ self .assertIn (self .plugin , Plugin .approved_objects .all ())
187+
188+ # Check it also appears in the view response
189+ response = self .client .get (reverse ("approved_plugins" ))
190+ self .assertEqual (response .status_code , 200 )
191+ self .assertContains (response , self .plugin .name )
192+
193+ def test_soft_deleted_plugin_excluded_from_unapproved_listing (self ):
194+ """Test that soft-deleted plugins don't appear in the unapproval queue."""
195+ # version2 is unapproved, so the plugin appears in unapproved_objects
196+ self .assertIn (self .plugin , Plugin .unapproved_objects .all ())
197+
198+ # Soft delete the plugin
199+ self .plugin .is_deleted = True
200+ self .plugin .deleted_on = timezone .now ()
201+ self .plugin .save ()
202+
203+ # Plugin should NOT appear in unapproved_objects (no need to review
204+ # plugins that are being deleted)
205+ self .assertNotIn (self .plugin , Plugin .unapproved_objects .all ())
206+
165207
166208class TestDeleteMarkedPluginsTask (SetupMixin , TestCase ):
167209 """Test the Celery task for permanent deletion of marked plugins."""
0 commit comments