support deleting extensions #69
@ -80,6 +80,12 @@
|
|||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% 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 %}
|
{% if request.user.is_staff %}
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button class="btn btn-admin dropdown-toggle js-dropdown-toggle" data-toggle-menu-id="extension-admin-menu">
|
<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 django.test import TestCase
|
||||||
|
|
||||||
from common.tests.factories.extensions import create_approved_version
|
from common.tests.factories.extensions import create_approved_version
|
||||||
|
from common.tests.factories.users import UserFactory
|
||||||
|
|
||||||
|
|
||||||
class DeleteTest(TestCase):
|
class DeleteTest(TestCase):
|
||||||
fixtures = ['dev', 'licenses']
|
fixtures = ['dev', 'licenses']
|
||||||
|
|
||||||
def test_happy_path(self):
|
def test_happy_path_maintainer(self):
|
||||||
extension = create_approved_version().extension
|
extension = create_approved_version().extension
|
||||||
|
|
||||||
url = extension.get_delete_url()
|
url = extension.get_delete_url()
|
||||||
@ -18,3 +20,30 @@ class DeleteTest(TestCase):
|
|||||||
extension.refresh_from_db()
|
extension.refresh_from_db()
|
||||||
self.assertIsNotNone(extension.date_deleted)
|
self.assertIsNotNone(extension.date_deleted)
|
||||||
self.assertTrue(all(v.date_deleted is not None for v in extension.versions.all()))
|
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(
|
class DeleteExtensionView(
|
||||||
LoginRequiredMixin,
|
LoginRequiredMixin,
|
||||||
MaintainedExtensionMixin,
|
UserPassesTestMixin,
|
||||||
DeleteView,
|
DeleteView,
|
||||||
):
|
):
|
||||||
model = Extension
|
model = Extension
|
||||||
@ -170,7 +170,7 @@ class DeleteExtensionView(
|
|||||||
form_class = ExtensionDeleteForm
|
form_class = ExtensionDeleteForm
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return reverse('extensions:manage-list')
|
return reverse('extensions:home')
|
||||||
|
|
||||||
def get_object(self, queryset=None):
|
def get_object(self, queryset=None):
|
||||||
return get_object_or_404(
|
return get_object_or_404(
|
||||||
@ -184,6 +184,10 @@ class DeleteExtensionView(
|
|||||||
context['confirm_url'] = self.object.get_delete_url()
|
context['confirm_url'] = self.object.get_delete_url()
|
||||||
return context
|
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(
|
class VersionDeleteView(
|
||||||
LoginRequiredMixin,
|
LoginRequiredMixin,
|
||||||
|
@ -33,6 +33,12 @@
|
|||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% 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 %}
|
{% if request.user.is_staff %}
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button class="btn btn-admin dropdown-toggle js-dropdown-toggle" data-toggle-menu-id="extension-admin-menu">
|
<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