]> gitweb.fperrin.net Git - djsite.git/commitdiff
Create an administrative interface
authorFrédéric Perrin <frederic.perrin@resel.fr>
Wed, 9 Nov 2016 23:59:50 +0000 (23:59 +0000)
committerFrédéric Perrin <frederic.perrin@resel.fr>
Wed, 9 Nov 2016 23:59:50 +0000 (23:59 +0000)
djsite/urls.py
quotes/adminviews.py [new file with mode: 0644]
quotes/conftest.py
quotes/templates/quotes/listadmintools.html [new file with mode: 0644]
quotes/test_massimport.py
quotes/urls.py
quotes/views.py

index 3ffc7fc3ead6c0fc2bc47494fc1d2819be687c24..6eaff7d92d754dc9fd16ae942fd134ea1ef15cfe 100644 (file)
@@ -17,7 +17,7 @@ from django.conf.urls import include, url
 from django.contrib import admin
 
 urlpatterns = [
-    url(r'^admin/', include(admin.site.urls)),
+    url(r'^cntrl/', include(admin.site.urls)),
     url(r'^tinymce/', include('tinymce.urls')),
     url(r'^quotes/', include('quotes.urls', namespace='quotes')),
 ]
diff --git a/quotes/adminviews.py b/quotes/adminviews.py
new file mode 100644 (file)
index 0000000..757418c
--- /dev/null
@@ -0,0 +1,19 @@
+from django.shortcuts import render
+from django.contrib.auth.decorators import permission_required
+
+from quotes.massimport import domassimport
+
+check_admin = permission_required('quotes.can_add',
+                                  login_url='/quotes/admin/login')
+
+@check_admin
+def massimport(request):
+    if 'quotes' in request.POST:
+        resultcontext = domassimport(request.POST['quotes'])
+        return render(request, 'quotes/domassimport.html', resultcontext)
+    else:
+        return render(request, 'quotes/massimport.html', {})
+
+@check_admin
+def listadmintools(request):
+    return render(request, 'quotes/listadmintools.html', {})
index 5cdf30a8431f17093e24322ca3e8ba8892103adb..b87a6baf2a756894143ec20c6f2db398144f8f01 100644 (file)
@@ -17,18 +17,24 @@ class ValidatingClient(object):
         else:
             raise RuntimeError('Unknown method %s for %s' % (method, url))
         assert response.status_code == exp_status
+        if response.status_code != 200:
+            return None
         assert response.charset == 'utf-8'
         document = response.content.decode(response.charset)
         lxml.etree.fromstring(document)
         assert '<script>' not in document
         return document
 
-    def getPage(self, url):
-        return self.request(url, 'get')
+    def getPage(self, url, exp_status=200):
+        return self.request(url, 'get', exp_status=exp_status)
 
-    def postPage(self, url, params):
-        return self.request(url, 'post', params=params)
+    def postPage(self, url, params, exp_status=200):
+        return self.request(url, 'post', params=params, exp_status=exp_status)
 
 @pytest.fixture
 def c(client):
     return ValidatingClient(client)
+
+@pytest.fixture
+def c_adm(admin_client):
+    return ValidatingClient(admin_client)
diff --git a/quotes/templates/quotes/listadmintools.html b/quotes/templates/quotes/listadmintools.html
new file mode 100644 (file)
index 0000000..a114110
--- /dev/null
@@ -0,0 +1,15 @@
+{% extends 'quotes/base.html' %}
+
+{% block title %}Administration tools{% endblock %}
+
+{% block body %}
+
+<p>Available administration tools:</p>
+
+<ul>
+  <li><a href="/cntrl/quotes/">Manage individual quotes</a>, in
+    particular add and edit single quotes</li>
+  <li><a href="/quotes/admin/massimport/">Import many quotes at once</a></li>
+</ul>
+
+{% endblock %}
index 0a9fb4f70fafe6ea0ceb622b59f4904ae4dcfb81..fb5ea368aca5f93de9d033cbd5e7a87d4995ac57 100644 (file)
@@ -11,7 +11,7 @@ class Test_MassImport():
         return q1
 
     @pytest.mark.django_db
-    def test_massimport_1(self, q1, c):
+    def test_massimport_1(self, q1, c_adm):
         allquotes = """\
 Ich bin ein Berliner
 ---
@@ -42,7 +42,7 @@ Romeo and Juliet
 tag1, tag555
 ==="""
 
-        results = c.postPage('massimport/', {'quotes': allquotes})
+        results = c_adm.postPage('massimport/', {'quotes': allquotes})
 
         assert "rejected" not in results
 
@@ -58,10 +58,10 @@ tag1, tag555
         assert hamlet.author == Author.objects.get(name="William Shakespeare")
 
         for quote in Quote.objects.all():
-            assert c.getPage(quote.get_absolute_url())
+            assert c_adm.getPage(quote.get_absolute_url())
 
     @pytest.mark.django_db
-    def test_massimport_2(self, q1, c):
+    def test_massimport_2(self, q1, c_adm):
         allquotes = """\
 <script>somethingevil()</script>
 A rose by any other name...
@@ -73,13 +73,13 @@ Romeo and Juliet
 tag1, tag555
 ==="""
 
-        results = c.postPage('massimport/', {'quotes': allquotes})
+        results = c_adm.postPage('massimport/', {'quotes': allquotes})
         assert "<script>" not in results
         with pytest.raises(Quote.DoesNotExist):
             Quote.objects.get(text__contains="<script>")
 
     @pytest.mark.django_db
-    def test_massimport_3(self, c):
+    def test_massimport_3(self, c_adm):
         """Whitespace and stuff"""
         allquotes = """\
 A rose by any other name...
@@ -106,7 +106,7 @@ Hamlet
 
 """
 
-        results = c.postPage('massimport/', {'quotes': allquotes})
+        results = c_adm.postPage('massimport/', {'quotes': allquotes})
         assert "rejected" not in results
         assert Quote.objects.get(text="<p>A rose by any other name...</p>")
         assert Author.objects.get(name="William Shakespeare")
@@ -119,3 +119,6 @@ Hamlet
         assert tirade.work.author.name == "William Shakespeare"
         assert Author.objects.filter(name__contains="Shakespeare").count() == 1
 
+    def test_massimport_noaccess(self, c):
+        c.getPage('massimport/', exp_status=302)
+        c.postPage('massimport/', {}, exp_status=302)
index 55577bb5e7b16fa8cdedc6694642155c542dd438..a8cc355c150d32021d0ac80ac04ac9e5ef7f6dc4 100644 (file)
@@ -1,6 +1,7 @@
 from django.conf.urls import url
+from django.contrib.auth.views import login
 
-from . import views
+from . import views, adminviews
 
 urlpatterns = [
     url(r'^$', views.index, name='index'),
@@ -15,7 +16,10 @@ urlpatterns = [
 
     url(r'^cloud/$', views.cloud, name="cloud"),
     url(r'^search/$', views.searchpage, name="search"),
-    url(r'^massimport/$', views.massimport, name="massimport"),
+
+    url(r'^admin/$', adminviews.listadmintools, name='listadmintools'),
+    url(r'^admin/login$', login, {'template_name': 'admin/login.html'}),
+    url(r'^admin/massimport/$', adminviews.massimport, name='massimport'),
 
     url(r'^all/$', views.all, name="all"),
 ]
index 9ff7aacc996bd07db6077490ace90d4b8c7b9d7d..d6ca24035c4a9316ad68e9b2b54c715ebd88376e 100644 (file)
@@ -5,7 +5,6 @@ from random import randint
 from quotes.models import Author, Work, Quote, QuoteTag
 from quotes import search
 from quotes import tagcloud
-from quotes.massimport import domassimport
 
 # create your views here.
 def index(request):
@@ -52,10 +51,3 @@ def searchpage(request):
 def cloud(request):
     clouddata = tagcloud.build_cloud()
     return render(request, 'quotes/cloud.html', clouddata)
-
-def massimport(request):
-    if 'quotes' in request.POST:
-        resultcontext = domassimport(request.POST['quotes'])
-        return render(request, 'quotes/domassimport.html', resultcontext)
-    else:
-        return render(request, 'quotes/massimport.html', {})