Rewrite all pad views to class based views

This commit is contained in:
Martin Pépin 2020-01-09 18:05:18 +01:00
parent c0c155fc94
commit 738658e472
No known key found for this signature in database
GPG key ID: E7520278B1774448
6 changed files with 250 additions and 71 deletions

7
gestion/mixins.py Normal file
View file

@ -0,0 +1,7 @@
from django.contrib.auth.mixins import UserPassesTestMixin
class ChefRequiredMixin(UserPassesTestMixin):
def test_func(self):
user = self.request.user
return (user is not None) and hasattr(user, "profile") and user.profile.is_chef

View file

@ -0,0 +1,25 @@
{% extends "gestion/base.html" %}
{% block titre %}Liste des pads{% endblock %}
{% block content %}
<h1>Liste des pads</h1>
{% if user.profile.is_chef %}
<p><a href="{% url "pads:add" %}">Ajouter un pad</a></p>
{% endif %}
<ul class="filelist">
{% for p in pads %}
<li>
<a class="fichier" href="{{ p.url }}">{{ p.nom }}</a>
{% if user.profile.is_chef %}
<a class="telecharger" href="{% url "pads:edit" p.id %}">Modifier</a>
<a class="supprimer" href="{% url "pads:delete" p.id %}">Supprimer</a>
{% endif %}
</li>
{% empty %}
<p>Pas de pad pour le moment</p>
{% endfor %}
</ul>
{% endblock %}

View file

@ -1,24 +0,0 @@
{% extends "gestion/base.html" %}
{% load getresponse %}
{% block titre %}Liste des pads{% endblock %}
{% block content %}<h1>Liste des pads</h1>
{% if error %}
<p>{{ error }}</p>
{% endif %}
{% if user.profile.is_chef %}
<p><a href="{% url "pads:add" %}">Ajouter un pad</a></p>
{% endif %}
<ul class="filelist">
{% for p in pads %}
<li><a class="fichier" href="{{ p.url }}">{{ p.nom }}</a>
{% if user.profile.is_chef %}
<a class="telecharger" href="{% url "pads:edit" p.id %}">Modifier</a>
<a class="supprimer" href="{% url "pads:delete" p.id %}">Supprimer</a>
{% endif %}
</li>
{% empty %}
<p>Pas de pad pour le moment</p>
{% endfor %}
</ul>
{% endblock %}

184
pads/tests.py Normal file
View file

@ -0,0 +1,184 @@
from django.contrib.auth import get_user_model
from django.test import Client, TestCase
from django.urls import reverse, reverse_lazy
from django.utils import timezone
from gestion.models import ErnestoUser
from pads.models import Pad
User = get_user_model()
def new_user(username):
u = User.objects.create_user(username=username)
ErnestoUser.objects.create(user=u, slug=username, is_ernesto=True)
return u
class PadListTest(TestCase):
url = reverse_lazy("pads:list")
def setUp(self):
for name in ["foo", "bar", "baz"]:
Pad.objects.create(
nom=name, url="example.com/{}".format(name), date=timezone.now()
)
def test_anonymous_cannot_get(self):
response = Client().get(self.url)
self.assertRedirects(response, "/login?next={}".format(self.url))
def test_ernesto_user_can_get(self):
client = Client()
client.force_login(new_user("toto"))
response = client.get(self.url)
self.assertEqual(response.status_code, 200)
class PadCreateTest(TestCase):
url = reverse_lazy("pads:add")
def test_anonymous_cannot_get(self):
response = Client().get(self.url)
self.assertRedirects(response, "/login?next={}".format(self.url))
def test_anonymous_cannot_post(self):
response = Client().post(self.url, {"nom": "foo", "url": "http://example.com"})
self.assertRedirects(response, "/login?next={}".format(self.url))
def test_ernesto_cannot_get(self):
client = Client()
client.force_login(new_user("toto"))
response = client.get(self.url)
self.assertEqual(response.status_code, 403)
def test_ernesto_cannot_post(self):
client = Client()
client.force_login(new_user("toto"))
response = client.post(self.url, {"nom": "foo", "url": "http://example.com"})
self.assertEqual(response.status_code, 403)
def test_chef_can_get(self):
user = new_user("toto")
user.profile.is_chef = True
user.profile.save()
client = Client()
client.force_login(user)
response = client.get(self.url)
self.assertEqual(response.status_code, 200)
def test_chef_can_post(self):
user = new_user("toto")
user.profile.is_chef = True
user.profile.save()
client = Client()
client.force_login(user)
client.post(self.url, {"nom": "foo", "url": "http://example.com"})
pads = Pad.objects.all()
self.assertEqual(pads.count(), 1)
pad = pads.get()
self.assertEqual(pad.nom, "foo")
self.assertEqual(pad.url, "http://example.com")
class PadUpdateTest(TestCase):
def setUp(self):
pad = Pad.objects.create(
nom="bar", url="http://djangoproject.com", date=timezone.now()
)
self.url = reverse("pads:edit", args=(pad.id,))
def test_anonymous_cannot_get(self):
response = Client().get(self.url)
self.assertRedirects(response, "/login?next={}".format(self.url))
def test_anonymous_cannot_post(self):
response = Client().post(self.url, {"nom": "foo", "url": "http://example.com"})
self.assertRedirects(response, "/login?next={}".format(self.url))
def test_ernesto_cannot_get(self):
client = Client()
client.force_login(new_user("toto"))
response = client.get(self.url)
self.assertEqual(response.status_code, 403)
def test_ernesto_cannot_post(self):
client = Client()
client.force_login(new_user("toto"))
response = client.post(self.url, {"nom": "foo", "url": "http://example.com"})
self.assertEqual(response.status_code, 403)
def test_chef_can_get(self):
user = new_user("toto")
user.profile.is_chef = True
user.profile.save()
client = Client()
client.force_login(user)
response = client.get(self.url)
self.assertEqual(response.status_code, 200)
def test_chef_can_post(self):
user = new_user("toto")
user.profile.is_chef = True
user.profile.save()
client = Client()
client.force_login(user)
client.post(self.url, {"nom": "foo", "url": "http://example.com"})
pads = Pad.objects.all()
self.assertEqual(pads.count(), 1)
pad = pads.get()
self.assertEqual(pad.nom, "foo")
self.assertEqual(pad.url, "http://example.com")
class PadDeleteTest(TestCase):
def setUp(self):
pad = Pad.objects.create(
nom="bar", url="http://djangoproject.com", date=timezone.now()
)
self.url = reverse("pads:delete", args=(pad.id,))
def test_anonymous_cannot_get(self):
response = Client().get(self.url)
self.assertRedirects(response, "/login?next={}".format(self.url))
def test_anonymous_cannot_post(self):
response = Client().post(self.url, {})
self.assertRedirects(response, "/login?next={}".format(self.url))
def test_ernesto_cannot_get(self):
client = Client()
client.force_login(new_user("toto"))
response = client.get(self.url)
self.assertEqual(response.status_code, 403)
def test_ernesto_cannot_post(self):
client = Client()
client.force_login(new_user("toto"))
response = client.post(self.url, {})
self.assertEqual(response.status_code, 403)
def test_chef_can_get(self):
user = new_user("toto")
user.profile.is_chef = True
user.profile.save()
client = Client()
client.force_login(user)
response = client.get(self.url)
self.assertEqual(response.status_code, 200)
def test_chef_can_post(self):
user = new_user("toto")
user.profile.is_chef = True
user.profile.save()
client = Client()
client.force_login(user)
client.post(self.url, {})
self.assertFalse(Pad.objects.exists())

View file

@ -1,13 +1,12 @@
from django.urls import path
from pads import views
from pads.views import PadUpdate, PadDelete
app_name = "pads"
urlpatterns = [
path("", views.liste_pads, name="list"),
path("ajouter", views.add_pad, name="add"),
path("edition/<int:pk>", PadUpdate.as_view(), name="edit"),
path("supprimer/<int:pk>", PadDelete.as_view(), name="delete"),
path("", views.PadList.as_view(), name="list"),
path("ajouter", views.PadCreate.as_view(), name="add"),
path("edition/<int:pk>", views.PadUpdate.as_view(), name="edit"),
path("supprimer/<int:pk>", views.PadDelete.as_view(), name="delete"),
]

View file

@ -1,53 +1,41 @@
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponseRedirect
from django.urls import reverse_lazy
from django.views.generic import UpdateView, DeleteView
from django.utils.decorators import method_decorator
from datetime import date
from django.utils import timezone
from django.views.generic import CreateView, DeleteView, ListView, UpdateView
from gestion.mixins import ChefRequiredMixin
from pads.models import Pad
from pads.forms import PadForm
from partitions.decorators import chef_required
@login_required
def liste_pads(request):
pads = Pad.objects.all().order_by("-date")
return render(request, "pads/liste.html", locals())
@chef_required
def add_pad(request):
if request.method == "POST":
form = PadForm(request.POST)
if form.is_valid():
obj = form.save(commit=False)
obj.date = date.today()
obj.save()
envoi = True
else:
form = PadForm()
return render(request, "pads/create.html", locals())
class PadUpdate(UpdateView):
class PadList(LoginRequiredMixin, ListView):
model = Pad
context_object_name = "pads"
ordering = ["-date"]
template_name = "pads/list.html"
class PadCreate(ChefRequiredMixin, CreateView):
model = Pad
fields = ["nom", "url"]
template_name = "pads/create.html"
success_url = reverse_lazy("pads:list")
def form_valid(self, form):
pad = form.save(commit=False)
pad.date = timezone.now()
pad.save()
return HttpResponseRedirect(self.success_url)
class PadUpdate(ChefRequiredMixin, UpdateView):
model = Pad
fields = ["nom", "url"]
template_name = "pads/update.html"
success_url = reverse_lazy(liste_pads)
form_class = PadForm
@method_decorator(chef_required)
def dispatch(self, *args, **kwargs):
return super(PadUpdate, self).dispatch(*args, **kwargs)
success_url = reverse_lazy("pads:list")
class PadDelete(DeleteView):
class PadDelete(ChefRequiredMixin, DeleteView):
model = Pad
template_name = "pads/delete.html"
success_url = reverse_lazy(liste_pads)
@method_decorator(chef_required)
def dispatch(self, *args, **kwargs):
return super(PadDelete, self).dispatch(*args, **kwargs)
# Create your views here.
success_url = reverse_lazy("pads:list")