From 98058a03a28f01e492a8301eebde4c2c40a02b3d Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Thu, 26 Sep 2019 15:34:57 +0200
Subject: [PATCH] wcs: use wcs category order in backoffice submission cell
 (#29187)

---
 combo/apps/wcs/models.py                      | 20 ++++++
 .../combo/wcs/backoffice_submission.html      |  3 +-
 tests/test_wcs.py                             | 63 +++++++++++++++----
 3 files changed, 71 insertions(+), 15 deletions(-)

diff --git a/combo/apps/wcs/models.py b/combo/apps/wcs/models.py
index c305336..474f3ba 100644
--- a/combo/apps/wcs/models.py
+++ b/combo/apps/wcs/models.py
@@ -557,4 +557,24 @@ class BackofficeSubmissionCell(WcsDataBaseCell):
             for formdef in site_formdefs['data']:
                 if not 'category' in formdef:
                     formdef['category'] = _('Misc')
+
+        # group formdef by categories, keeping the w.c.s. categories order
+        for site_formdefs in context['all_formdefs'].values():
+            category_names = []
+            tmp_categories = {}
+            for formdef in site_formdefs['data']:
+                category_name = formdef['category']
+
+                # remind first seen category order
+                if category_name not in category_names:
+                    category_names.append(category_name)
+                    tmp_categories[category_name] = []
+                    site_formdefs['formdefs_by_category'] = []
+
+                tmp_categories[category_name].append(formdef)
+            for category_name in category_names:
+                site_formdefs['formdefs_by_category'].append({
+                    'grouper': category_name,
+                    'list': tmp_categories[category_name]
+                })
         return context
diff --git a/combo/apps/wcs/templates/combo/wcs/backoffice_submission.html b/combo/apps/wcs/templates/combo/wcs/backoffice_submission.html
index 83e431b..bcd0dd0 100644
--- a/combo/apps/wcs/templates/combo/wcs/backoffice_submission.html
+++ b/combo/apps/wcs/templates/combo/wcs/backoffice_submission.html
@@ -5,8 +5,7 @@
   <div class="links-list">
   {% if all_formdefs.keys|length > 1 %}<h3>{{ site_formdefs.title }}</h3>{% endif %}
   <ul>
-  {% regroup site_formdefs.data|dictsort:"category" by category as categories_formdefs %}
-  {% for category_formdefs in categories_formdefs %}
+  {% for category_formdefs in site_formdefs.formdefs_by_category %}
     <li><h4>{{ category_formdefs.grouper }}</h4></li>
     {% for formdef in category_formdefs.list|dictsort:"title" %}
       <li><a href="{{formdef.backoffice_submission_url}}?NameID={{name_id}}&ReturnURL={{ absolute_uri|iriencode }}">{{formdef.title}}</a></li>
diff --git a/tests/test_wcs.py b/tests/test_wcs.py
index 4f03bf9..6be06f1 100644
--- a/tests/test_wcs.py
+++ b/tests/test_wcs.py
@@ -72,6 +72,7 @@ for i in range(1, 10):
    cat = Category()
    cat.name = 'Test %d' % i
    cat.description = 'Hello world'
+   cat.position = 10-i  # not using alphabetical order
    cat.store()
    cats.append(cat)
 
@@ -139,17 +140,19 @@ if '127.0.0.2' in get_publisher().get_frontoffice_url():
     code.id = 'CNPHNTFB'
     code.formdata = formdata
 
-# a private formdef
+# private formdefs
 role = Role(name='Blah')
 role.store()
 
-formdef = FormDef()
-formdef.name = 'a private form'
-formdef.category_id = cats[2].id
-formdef.roles = [role.id]
-formdef.backoffice_submission_roles = [role.id]
-formdef.fields = []
-formdef.store()
+for i in range(4,0,-1):  # not using aphabetical order
+    category_id = 2+i%2  # not ordered by categories
+    formdef = FormDef()
+    formdef.category_id = cats[category_id].id
+    formdef.name = 'private form %d (category %s)' % (i, formdef.category_id)
+    formdef.roles = [role.id]
+    formdef.backoffice_submission_roles = [role.id]
+    formdef.fields = []
+    formdef.store()
 
 user2 = get_publisher().user_class()  # agent
 user2.name = 'foo2 bar2'
@@ -259,13 +262,19 @@ def test_form_cell_setup():
     form_class = cell.get_default_form_class()
     form = form_class()
     assert form.fields['formdef_reference'].widget.choices == [
-            (u'default:a-private-form', u'test : a private form'),
             (u'default:a-second-form-title', u'test : a second form title'),
             (u'default:form-title', u'test : form title'),
+            (u'default:private-form-1-category-4', u'test : private form 1 (category 4)'),
+            (u'default:private-form-2-category-3', u'test : private form 2 (category 3)'),
+            (u'default:private-form-3-category-4', u'test : private form 3 (category 4)'),
+            (u'default:private-form-4-category-3', u'test : private form 4 (category 3)'),
             (u'default:third-form-title', u'test : third form title'),
-            (u'other:a-private-form', u'test2 : a private form'),
             (u'other:a-second-form-title', u'test2 : a second form title'),
             (u'other:form-title', u'test2 : form title'),
+            (u'other:private-form-1-category-4', u'test2 : private form 1 (category 4)'),
+            (u'other:private-form-2-category-3', u'test2 : private form 2 (category 3)'),
+            (u'other:private-form-3-category-4', u'test2 : private form 3 (category 4)'),
+            (u'other:private-form-4-category-3', u'test2 : private form 4 (category 3)'),
             (u'other:third-form-title', u'test2 : third form title')]
 
 
@@ -471,8 +480,10 @@ def test_forms_of_category_cell_setup():
     form = form_class()
     assert form.fields['category_reference'].widget.choices == [
             (u'default:test-3', u'test : Test 3'),
+            (u'default:test-4', u'test : Test 4'),
             (u'default:test-9', u'test : Test 9'),
             (u'other:test-3', u'test2 : Test 3'),
+            (u'other:test-4', u'test2 : Test 4'),
             (u'other:test-9', u'test2 : Test 9')]
 
 @wcs_present
@@ -589,8 +600,9 @@ def test_manager_current_forms(app, admin_user):
 
     resp = app.get('/manage/pages/%s/' % page.id)
     assert ('data-cell-reference="%s"' % cells[0].get_reference()) in resp.text
-    assert len(resp.form['c%s-categories' % cells[0].get_reference()].options) == 4
-    resp.form['c%s-categories' % cells[0].get_reference()].value = ['default:test-3', 'default:test-9']
+    assert len(resp.form['c%s-categories' % cells[0].get_reference()].options) == 6
+    resp.form['c%s-categories' % cells[0].get_reference()].value = [
+        'default:test-3', 'default:test-9']
     resp = resp.form.submit().follow()
     assert resp.form['c%s-categories' % cells[0].get_reference()].value == ['default:test-3', 'default:test-9']
 
@@ -781,4 +793,29 @@ def test_backoffice_submission_cell_render(context):
     context['request'].user = MockUser2()
 
     result = cell.render(context)
-    assert '/backoffice/submission/a-private-form/' in result
+    # wcs already return a flat ordered structure
+    site_formdefs = context['all_formdefs'].values()[0]
+    assert [x['title'] for x in site_formdefs['data']] == [
+        'private form 1 (category 4)',  # category.order = 6
+        'private form 3 (category 4)',
+        'private form 2 (category 3)',  # category.order = 7
+        'private form 4 (category 3)']
+    # cell grouped by categories using the same order policy
+    assert [c['grouper'] for c in
+            [c for c in site_formdefs['formdefs_by_category']]] == [
+        'Test 4', 'Test 3']
+    assert [x['title'] for x in
+            [f for f in
+             site_formdefs['formdefs_by_category'][0]['list']]] == [
+        'private form 1 (category 4)',
+        'private form 3 (category 4)']
+    assert [x['title'] for x in
+            [f for f in
+             site_formdefs['formdefs_by_category'][1]['list']]] == [
+        'private form 2 (category 3)',
+        'private form 4 (category 3)']
+    assert result.count('/backoffice/submission/private-form-') == 4
+    index = {}
+    for i in range(1, 5):
+        index['form%d' % i] = result.find('/private-form-%d' % i)
+    assert index['form1'] < index['form3'] < index['form2'] < index['form4']
-- 
2.23.0

