support deleting extensions #69
@ -80,6 +80,12 @@
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if user.is_moderator %}
|
||||
<a href="{{ extension.get_delete_url }}" class="btn btn-danger">
|
||||
<i class="i-trash"></i> {% trans 'Delete Extension' %}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if request.user.is_staff %}
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-admin dropdown-toggle js-dropdown-toggle" data-toggle-menu-id="extension-admin-menu">
|
||||
|
@ -1,12 +1,14 @@
|
||||
from django.contrib.auth.models import Group
|
||||
from django.test import TestCase
|
||||
|
||||
from common.tests.factories.extensions import create_approved_version
|
||||
from common.tests.factories.users import UserFactory
|
||||
|
||||
|
||||
class DeleteTest(TestCase):
|
||||
fixtures = ['dev', 'licenses']
|
||||
|
||||
def test_happy_path(self):
|
||||
def test_happy_path_maintainer(self):
|
||||
extension = create_approved_version().extension
|
||||
|
||||
url = extension.get_delete_url()
|
||||
@ -18,3 +20,30 @@ class DeleteTest(TestCase):
|
||||
extension.refresh_from_db()
|
||||
self.assertIsNotNone(extension.date_deleted)
|
||||
self.assertTrue(all(v.date_deleted is not None for v in extension.versions.all()))
|
||||
|
||||
def test_happy_path_moderator(self):
|
||||
extension = create_approved_version().extension
|
||||
|
||||
url = extension.get_delete_url()
|
||||
user = UserFactory()
|
||||
user.groups.add(Group.objects.get(name='moderators'))
|
||||
self.client.force_login(user)
|
||||
response = self.client.post(url)
|
||||
|
||||
self.assertEqual(response.status_code, 302)
|
||||
extension.refresh_from_db()
|
||||
self.assertIsNotNone(extension.date_deleted)
|
||||
self.assertTrue(all(v.date_deleted is not None for v in extension.versions.all()))
|
||||
|
||||
def test_random_user_cant_delete(self):
|
||||
extension = create_approved_version().extension
|
||||
|
||||
url = extension.get_delete_url()
|
||||
user = UserFactory()
|
||||
self.client.force_login(user)
|
||||
response = self.client.post(url)
|
||||
|
||||
self.assertEqual(response.status_code, 403)
|
||||
extension.refresh_from_db()
|
||||
self.assertIsNone(extension.date_deleted)
|
||||
self.assertTrue(all(v.date_deleted is None for v in extension.versions.all()))
|
||||
|
@ -162,7 +162,7 @@ class UpdateExtensionView(
|
||||
|
||||
class DeleteExtensionView(
|
||||
LoginRequiredMixin,
|
||||
MaintainedExtensionMixin,
|
||||
UserPassesTestMixin,
|
||||
DeleteView,
|
||||
):
|
||||
model = Extension
|
||||
@ -170,7 +170,7 @@ class DeleteExtensionView(
|
||||
form_class = ExtensionDeleteForm
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('extensions:manage-list')
|
||||
return reverse('extensions:home')
|
||||
|
||||
def get_object(self, queryset=None):
|
||||
return get_object_or_404(
|
||||
@ -184,6 +184,10 @@ class DeleteExtensionView(
|
||||
context['confirm_url'] = self.object.get_delete_url()
|
||||
return context
|
||||
|
||||
def test_func(self) -> bool:
|
||||
# Only maintainers and moderators allowed
|
||||
return self.get_object().has_maintainer(self.request.user) or self.request.user.is_moderator
|
||||
|
||||
|
||||
class VersionDeleteView(
|
||||
LoginRequiredMixin,
|
||||
|
@ -33,6 +33,12 @@
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if user.is_moderator %}
|
||||
<a href="{{ extension.get_delete_url }}" class="btn btn-danger">
|
||||
<i class="i-trash"></i> {% trans 'Delete Extension' %}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if request.user.is_staff %}
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-admin dropdown-toggle js-dropdown-toggle" data-toggle-menu-id="extension-admin-menu">
|
||||
|
Loading…
Reference in New Issue
Block a user