From 0ae366af299e62c98342b049252ab4d07a6822b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Thu, 24 Oct 2019 10:15:47 +0200
Subject: [PATCH 2/2] pages: add navigation buttons on page view (#12437)

---
 combo/manager/static/css/combo.manager.css   | 20 +++++++++--
 combo/manager/templates/combo/page_view.html | 13 ++++++++
 combo/manager/views.py                       |  7 ++++
 tests/test_manager.py                        | 35 ++++++++++++++++++--
 4 files changed, 70 insertions(+), 5 deletions(-)

diff --git a/combo/manager/static/css/combo.manager.css b/combo/manager/static/css/combo.manager.css
index 99d49e7..83dde76 100644
--- a/combo/manager/static/css/combo.manager.css
+++ b/combo/manager/static/css/combo.manager.css
@@ -129,8 +129,6 @@ div.cell-list .empty-cell {
 	margin-left: 2em;
 }
 
-.icon-eye-open:before             { content: "\f06e "; }
-
 div.objects-list {
 	clear: both;
 }
@@ -191,6 +189,24 @@ p#redirection {
 
 .icon-eye-open:before { content: "\f06e "; }
 .icon-edit:before { content: "\f044"; }
+.icon {
+    content: "";
+    font-family: FontAwesome;
+    padding-right: 1ex;
+}
+.icon-chevron-left:before {
+    content: "\f053";
+}
+.icon-chevron-right:before {
+    content: "\f054";
+}
+.icon-chevron-up:before {
+    content: "\f077";
+}
+
+p.navigation a:link {
+    border-bottom: none;
+}
 
 #assets-browser {
 	display: flex;
diff --git a/combo/manager/templates/combo/page_view.html b/combo/manager/templates/combo/page_view.html
index 83646bc..a591b00 100644
--- a/combo/manager/templates/combo/page_view.html
+++ b/combo/manager/templates/combo/page_view.html
@@ -24,6 +24,19 @@
 <div class="page-options">
 <h3>{% trans 'Parameters' %}</h3>
 
+<p class="navigation">
+<label>{% trans 'Navigation:' %}</label>
+{% if object.parent_id %}
+<a href="{% url 'combo-manager-page-view' pk=object.parent_id %}"><i class="icon icon-chevron-up"></i></a>
+{% endif %}
+{% if previous_page %}
+<a href="{% url 'combo-manager-page-view' pk=previous_page.pk %}"><i class="icon icon-chevron-left"></i></a>
+{% endif %}
+{% if next_page %}
+<a href="{% url 'combo-manager-page-view' pk=next_page.pk %}"><i class="icon icon-chevron-right"></i></a>
+{% endif %}
+</p>
+
 <p>
 <label>{% trans 'Title:' %}</label>
 {{object.title}}
diff --git a/combo/manager/views.py b/combo/manager/views.py
index 6b051ba..f514f2b 100644
--- a/combo/manager/views.py
+++ b/combo/manager/views.py
@@ -255,8 +255,15 @@ class PageView(DetailView):
             placeholders.append(placeholder_dict)
 
         context['placeholders'] = placeholders
+
+        context.update({
+            'previous_page': self.object.get_previous_page(check_visibility=False),
+            'next_page': self.object.get_next_page(check_visibility=False),
+        })
+
         return context
 
+
 page_view = requires_csrf_token(PageView.as_view())
 
 
diff --git a/tests/test_manager.py b/tests/test_manager.py
index d5c67aa..286fd87 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -186,6 +186,31 @@ def test_page_edit_picture(app, admin_user):
     assert '<img' in resp.text
     assert Page.objects.get(id=page.id).picture.url in resp.text
 
+
+def test_edit_page_navigation(app, admin_user):
+    page1 = Page.objects.create(title='One', slug='one', parent=None, template_name='standard')
+    page2 = Page.objects.create(title='Two', slug='two', parent=page1, template_name='standard')
+    page3 = Page.objects.create(title='Three', slug='three', parent=page1, template_name='standard')
+    page4 = Page.objects.create(title='Four', slug='four', parent=None, template_name='standard')
+
+    app = login(app)
+
+    resp = app.get('/manage/pages/%s/' % page1.pk)
+    assert '<i class="icon icon-chevron-up"></i></a>' not in resp.text
+    assert '<i class="icon icon-chevron-left"></i></a>' not in resp.text
+    assert '<a href="/manage/pages/%s/"><i class="icon icon-chevron-right"></i></a>' % page2.pk in resp.text
+
+    resp = app.get('/manage/pages/%s/' % page2.pk)
+    assert '<a href="/manage/pages/%s/"><i class="icon icon-chevron-up"></i></a>' % page1.pk in resp.text
+    assert '<a href="/manage/pages/%s/"><i class="icon icon-chevron-left"></i></a>' % page1.pk in resp.text
+    assert '<a href="/manage/pages/%s/"><i class="icon icon-chevron-right"></i></a>' % page3.pk in resp.text
+
+    resp = app.get('/manage/pages/%s/' % page4.pk)
+    assert '<i class="icon icon-chevron-up"></i></a>' not in resp.text
+    assert '<a href="/manage/pages/%s/"><i class="icon icon-chevron-left"></i></a>' % page3.pk in resp.text
+    assert '<i class="icon icon-chevron-right"></i></a>' not in resp.text
+
+
 def test_delete_page(app, admin_user):
     Page.objects.all().delete()
     page = Page(title='One', slug='one', template_name='standard')
@@ -1005,6 +1030,7 @@ def test_menu_json(app, admin_user):
     assert resp.headers['content-type'] == 'application/javascript'
     assert resp.text.startswith('fooBar([{"')
 
+
 def test_page_multiple_link_cells(app, admin_user):
     Page.objects.all().delete()
     page = Page(title='One', slug='one', template_name='standard')
@@ -1017,9 +1043,12 @@ def test_page_multiple_link_cells(app, admin_user):
     patched_orig = Page.get_as_reordered_flat_hierarchy
     app = login(app)
     with mock.patch('combo.data.models.Page.get_as_reordered_flat_hierarchy') as func:
-        func.return_value = []
-        resp = app.get('/manage/pages/%s/' % page.id)
-        assert func.call_count == 1
+        func.side_effect = lambda *args, **kwargs: patched_orig(*args, **kwargs)
+        app.get('/manage/pages/%s/' % page.id)
+        # only 1 call for combo.data.forms.get_page_choices
+        # 1 call for get_previous_page and 1 call for get_next_page
+        assert func.call_count == 3
+
 
 def test_page_cell_placeholder(app, admin_user):
     page = Page(title='One', slug='one', template_name='standard')
-- 
2.20.1

