From 4de3c285f06662aa672b42483f7813fb352ccd82 Mon Sep 17 00:00:00 2001
From: gloas <gloas@afi-sa.fr>
Date: Wed, 30 May 2018 16:06:20 +0200
Subject: [PATCH] dev #75742 : Thesauri list view mode

---
 .../admin/controllers/ThesauriController.php  |  51 +++++
 library/Class/CodifThesaurus.php              |  49 ++++-
 .../Action/Helper/AbstractListViewMode.php    |  22 ++-
 .../Action/Helper/ThesauriListViewMode.php    | 184 ++++++++++++++++++
 .../Controller/Plugin/Manager/Thesauri.php    |  37 ++++
 .../Plugin/ResourceDefinition/Thesauri.php    |  37 ++++
 .../ZendAfi/View/Helper/Admin/ContentNav.php  |   6 +-
 library/ZendAfi/View/Helper/TagModelTable.php |   6 +-
 tests/scenarios/Thesauri/ThesauriTest.php     | 157 +++++++++++++++
 9 files changed, 542 insertions(+), 7 deletions(-)
 create mode 100644 application/modules/admin/controllers/ThesauriController.php
 create mode 100644 library/ZendAfi/Controller/Action/Helper/ThesauriListViewMode.php
 create mode 100644 library/ZendAfi/Controller/Plugin/Manager/Thesauri.php
 create mode 100644 library/ZendAfi/Controller/Plugin/ResourceDefinition/Thesauri.php
 create mode 100644 tests/scenarios/Thesauri/ThesauriTest.php

diff --git a/application/modules/admin/controllers/ThesauriController.php b/application/modules/admin/controllers/ThesauriController.php
new file mode 100644
index 00000000000..c9ae9edb79a
--- /dev/null
+++ b/application/modules/admin/controllers/ThesauriController.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class Admin_ThesauriController extends ZendAfi_Controller_Action {
+  public function getPlugins() {
+    return ['ZendAfi_Controller_Plugin_ResourceDefinition_Thesauri',
+            'ZendAfi_Controller_Plugin_Manager_Thesauri'];
+  }
+
+
+  public function indexAction() {
+    parent::indexAction();
+
+    if($this->_request->isPost())
+      return $this->_redirectToRefererWithNewParams(['title_search' => $this->_getPost()['title_search'],
+                                                     'page' => $this->_getParam('page', 1),
+                                                     'order' => $this->_getParam('order', 'libelle')]);
+
+
+    $thesauri = $this->_getParam('parent_id')
+      ? Class_CodifThesaurus::find($this->_getParam('parent_id'))
+      : Class_CodifThesaurus::root();
+
+    $this->view->list = $this->_helper
+      ->thesauriListViewMode(['model' => $thesauri,
+                              'order' => $this->_getParam('order'),
+                              'page' => $this->_getParam('page', 0),
+                              'search_value' => $this->_getParam('title_search', '')]);
+
+    return $this->renderScript('admin/listViewMode.phtml');
+  }
+}
\ No newline at end of file
diff --git a/library/Class/CodifThesaurus.php b/library/Class/CodifThesaurus.php
index 2b77afde53a..10830d8297c 100644
--- a/library/Class/CodifThesaurus.php
+++ b/library/Class/CodifThesaurus.php
@@ -131,6 +131,13 @@ class CodifThesaurusLoader extends Storm_Model_Loader {
   }
 
 
+  public function countChildrenOf($id_thesaurus) {
+    return  Class_CodifThesaurus::countBy(['where' => 'id_thesaurus like "'.$id_thesaurus.'%" and LENGTH(id_thesaurus)>'.strlen($id_thesaurus)
+                                           ]);
+
+  }
+
+
   public function findRootOfId($id, $code, $label) {
     if ($codif = Class_CodifThesaurus::findFirstBy(['id_thesaurus' => $id]))
       return $codif;
@@ -425,6 +432,11 @@ class CodifThesaurusLoader extends Storm_Model_Loader {
 
     return array_unique($params);
   }
+
+
+  public function root() {
+    return Class_CodifThesaurus::newInstance();
+  }
 }
 
 
@@ -444,7 +456,8 @@ class Class_CodifThesaurus extends Storm_Model_Abstract {
   protected $_loader_class = 'CodifThesaurusLoader';
   protected $_table_name = 'codif_thesaurus';
   protected $_table_primary = 'id';
-  protected $_default_attribute_values = ['libelle_facette' => '',
+  protected $_default_attribute_values = ['libelle' => '',
+                                          'libelle_facette' => '',
                                           'id_thesaurus' =>null,
                                           'id_origine' => null,
                                           'rules' => null,
@@ -502,7 +515,9 @@ class Class_CodifThesaurus extends Storm_Model_Abstract {
 
 
   public function getRulesLabel() {
-    return json_decode($this->getRules())->label;
+    return ($json = $this->getRules())
+      ? json_decode($json)->label
+      : '';
   }
 
 
@@ -570,4 +585,34 @@ class Class_CodifThesaurus extends Storm_Model_Abstract {
   public function getChildren() {
     return $this->getLoader()->findChildrenOf($this);
   }
+
+
+  public function getParentChildren() {
+    return array_filter($this->getChildren(),
+                        function ($children)
+                        {
+                          return ($children->hasChildren());
+                        });
+  }
+
+
+  public function getChildrenItems() {
+    return array_filter($this->getChildren(),
+                        function ($children)
+                        {
+                          return (!$children->hasChildren());
+                        });
+  }
+
+  public function getParent() {
+    return $this->getLoader()->findParent($this->getIdThesaurus());
+  }
+
+  public function getTitre() {
+    return $this->getLibelleFacette();
+  }
+
+  public function numberOfChildrens() {
+    return $this->getLoader()->countChildrenOf($this->getIdThesaurus());
+  }
 }
\ No newline at end of file
diff --git a/library/ZendAfi/Controller/Action/Helper/AbstractListViewMode.php b/library/ZendAfi/Controller/Action/Helper/AbstractListViewMode.php
index 218b36c5205..42f44d399af 100644
--- a/library/ZendAfi/Controller/Action/Helper/AbstractListViewMode.php
+++ b/library/ZendAfi/Controller/Action/Helper/AbstractListViewMode.php
@@ -49,7 +49,17 @@ abstract class ZendAfi_Controller_Action_Helper_AbstractListViewMode extends Zen
                              }],
                             $this->getItemsId(),
                             $this->getItemsGroupBy(),
-                            $this->isSearching() ? [$this->getItemsLabelAttrib() => $callback] : []);
+                                $this->isSearching() ? [$this->getItemsLabelAttrib() => $callback] : [], $this->enabledPager(), $this->enabledSorter());
+  }
+
+
+  protected function enabledPager() {
+    return false;
+  }
+
+
+  protected function enabledSorter() {
+    return true;
   }
 
 
@@ -321,6 +331,16 @@ abstract class ZendAfi_Controller_Action_Helper_AbstractListViewMode extends Zen
   }
 
 
+  public function getCategoriesCols() {
+    return [''];
+  }
+
+
+  public function getItemsCols($view) {
+    return [''];
+  }
+
+
   protected function _getSearchForm($view) {
     return (new ZendAfi_Form())
       ->setAction($view->url(array_filter($this->getSearchUrl()), null, true))
diff --git a/library/ZendAfi/Controller/Action/Helper/ThesauriListViewMode.php b/library/ZendAfi/Controller/Action/Helper/ThesauriListViewMode.php
new file mode 100644
index 00000000000..7e19b20191b
--- /dev/null
+++ b/library/ZendAfi/Controller/Action/Helper/ThesauriListViewMode.php
@@ -0,0 +1,184 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class ZendAfi_Controller_Action_Helper_ThesauriListViewMode extends ZendAfi_Controller_Action_Helper_AbstractListViewMode {
+
+  public function thesauriListViewMode($params) {
+    $this->_params = $params;
+    return $this;
+  }
+
+
+  public function direct($params) {
+    return $this->thesauriListViewMode($params);
+  }
+
+  protected function enabledSorter() {
+    return false;
+  }
+
+  public function getBaseUrl() {
+    return ['module' => 'admin',
+            'controller' => 'thesauri'];
+  }
+
+
+  public function getParamKey() {
+    return 'parent_id';
+  }
+
+
+  public function getBreadcrumb() {
+    $breadcrumb = [['url' => ['module' => 'admin',
+                              'controller' => 'thesauri',
+                              'action' => 'index'],
+                    'label' => $this->_('Racine'),
+                    'options' => []]];
+
+    if($this->getModel()->isNew())
+      return $breadcrumb;
+
+    return array_merge($breadcrumb,
+                       $this->getBreadcrumbFor($this->getModel()));
+  }
+
+
+  public function getCategories() {
+    $model = $this->getModel();
+
+    if($model->isNew())
+      return Class_CodifThesaurus::getIndices('root',true);
+
+    return $model->getParentChildren();
+  }
+
+
+  public function getItems() {
+    $model = $this->getModel();
+    if ($this->isSearching())
+      return Class_CodifThesaurus::findAllBy($this->getItemsParams());
+    if($model->isNew())
+      return [];
+
+    $where = sprintf('id_thesaurus like "%s%%" and LENGTH(id_thesaurus) = %s',
+                     $model->getIdThesaurus(), strlen($model->getIdThesaurus()) + 4);
+
+    return Class_CodifThesaurus::findAllBy(['where' => $where,
+                                            'limitPage' => [$this->getPage(),
+                                                            $this->_items_by_page],
+                                            'order' => $this->getParam('order','libelle')]);
+
+  }
+
+
+  public function countItemsFor($model) {
+    return count($model->getChildrenItems());
+  }
+
+
+  public function countItemsInTreeFrom($model) {
+    if ($model->isNew())
+      return 0;
+    return $model->numberOfChildrens();
+
+  }
+
+
+  public function getItemsCols($view) {
+    $order = $this->getOrder();
+    $anchor_wrapper = function($key, $label) use ($view, $order) {
+      xdebug_break();
+      $order_param = $key;
+      if((0 === strpos($order, $key)) && (false === strpos($order, 'desc')))
+        $order_param .= ' desc';
+
+      $data_order = (false === strpos($order, $key))
+      ? ''
+      : str_replace(' ', '_', 'order_' . $order_param);
+
+      $url = ['order' => $order_param,
+              'page' => null];
+
+      return  $view->tagAnchor($url, $label, ['data-order' => $data_order]);
+    };
+
+    $cols = [$anchor_wrapper('libelle', $this->_('Thesaurus')),
+             $anchor_wrapper('libelle_facette', $this->_('Libellé facette')),
+             $anchor_wrapper('code', $this->_('Code')),
+             $anchor_wrapper('id_thesaurus', $this->_('ID Thesaurus')),
+             $anchor_wrapper('rules_label', $this->_('Règle'))];
+
+    xdebug_break();
+    return $cols;
+  }
+
+
+  public function getCategoriesCols() {
+    return [$this->_('Thesaurus'),
+            $this->_('Libellé facette'),
+            $this->_('Code'),
+            $this->_('ID Thesaurus'),
+            $this->_('Règle')];
+  }
+
+
+  public function getItemsAttribs() {
+    return $this->getCategoriesAttribs();
+  }
+
+
+  public function getCategoriesAttribs() {
+    return ['libelle',
+            'libelle_facette',
+            'code',
+            'id_thesaurus',
+            'rules_label'];
+  }
+
+  public function getSearchParams() {
+    $columns = ['libelle',
+                'libelle_facette',
+                'code',
+                'id_thesaurus',
+                'rules'
+    ];
+    $where = [];
+    $search_param = Zend_Db_Table::getDefaultAdapter()->quote('%' . $this->getSearch() . '%');
+    foreach ($columns as $col) {
+      $where [] = '('.$col.' like '.$search_param.')';
+    }
+    return ['where' => implode(' or ',$where),
+            'order' => $this->getOrder()];
+  }
+
+
+  public function getCountSearchResult() {
+    $params = $this->getItemsParams();
+    unset($params['limitPage']);
+    return Class_CodifThesaurus::countBy($params);
+  }
+
+
+  public function getOrder() {
+    return $this->getParam('order', 'libelle');
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/Controller/Plugin/Manager/Thesauri.php b/library/ZendAfi/Controller/Plugin/Manager/Thesauri.php
new file mode 100644
index 00000000000..7468ea6ac06
--- /dev/null
+++ b/library/ZendAfi/Controller/Plugin/Manager/Thesauri.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class ZendAfi_Controller_Plugin_Manager_Thesauri extends ZendAfi_Controller_Plugin_Manager_Manager {
+
+
+  public function getActions() {
+    return [
+            ['url' => ['module' => 'admin',
+                       'controller' => 'thesauri',
+                       'action' => 'edit',
+                       'id' =>  '%s'],
+             'icon' => 'edit',
+             'label' => $this->_('Modifier le thesaurus')],
+];
+  }
+
+}
diff --git a/library/ZendAfi/Controller/Plugin/ResourceDefinition/Thesauri.php b/library/ZendAfi/Controller/Plugin/ResourceDefinition/Thesauri.php
new file mode 100644
index 00000000000..a64c14863f3
--- /dev/null
+++ b/library/ZendAfi/Controller/Plugin/ResourceDefinition/Thesauri.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class ZendAfi_Controller_Plugin_ResourceDefinition_Thesauri extends ZendAfi_Controller_Plugin_ResourceDefinition_Abstract {
+  public function getDefinitions() {
+    return
+      ['model' => ['class' => 'Class_CodifThesaurus',
+                   'name' => 'thesauri',
+                   'order' => 'libelle'],
+
+       'messages' => ['successful_save' => $this->_('Thesaurus "%s" sauvegardé')],
+
+       'actions' => ['index' => ['title' => $this->_('Parcourir les Thesaurus')],
+                     'edit' => ['title' => $this->_("Modifier un thesaurus")]],
+
+       'form_class_name' => 'ZendAfi_Form_Admin_Thesauri'];
+  }
+}
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/Admin/ContentNav.php b/library/ZendAfi/View/Helper/Admin/ContentNav.php
index 477decff9a4..77810a13421 100644
--- a/library/ZendAfi/View/Helper/Admin/ContentNav.php
+++ b/library/ZendAfi/View/Helper/Admin/ContentNav.php
@@ -169,7 +169,11 @@ class ZendAfi_View_Helper_Admin_ContentNav extends ZendAfi_View_Helper_BaseHelpe
                      [], function($user) { return defined('DEVELOPMENT') && $user->isAdmin();}],
 
                     ["thesaurus_edit",$this->_("Modification Thesaurus"),    "/admin/systeme/updatethesaurus",
-                     [], function($user) { return defined('DEVELOPMENT') && $user->isAdmin();}]
+                     [], function($user) { return defined('DEVELOPMENT') && $user->isAdmin();}],
+                    ["thesaurus_edit",
+                     $this->_("Parcourir les Thesaurus"),    "/admin/thesauri/index",
+                     [],
+                     function($user) { return $user->isAdmin();}]
                    ]);
   }
 
diff --git a/library/ZendAfi/View/Helper/TagModelTable.php b/library/ZendAfi/View/Helper/TagModelTable.php
index e5ca6f94f15..d63054d27a4 100644
--- a/library/ZendAfi/View/Helper/TagModelTable.php
+++ b/library/ZendAfi/View/Helper/TagModelTable.php
@@ -33,7 +33,7 @@ class ZendAfi_View_Helper_TagModelTable extends ZendAfi_View_Helper_BaseHelper {
 
                             'relations');
   */
-  public function tagModelTable($models, $cols, $attribs, $actions, $id, $group_by = null, $callbacks = [], $pager = false) {
+  public function tagModelTable($models, $cols, $attribs, $actions, $id, $group_by = null, $callbacks = [], $pager = false, $sorter = true) {
     $description = new Class_TableDescription($id);
     foreach($cols as $i => $col) {
       $attribute = $attribs[$i];
@@ -53,8 +53,8 @@ class ZendAfi_View_Helper_TagModelTable extends ZendAfi_View_Helper_BaseHelper {
 
     return $this->view->renderTable($description,
                                     (new Class_TableDescription_Models($models))->groupBy($group_by),
-                                    ['sorter' => true,
+                                    ['sorter' => $sorter,
                                      'pager' => $pager]);
   }
-}
+}n
 ?>
diff --git a/tests/scenarios/Thesauri/ThesauriTest.php b/tests/scenarios/Thesauri/ThesauriTest.php
new file mode 100644
index 00000000000..84b38f2a14a
--- /dev/null
+++ b/tests/scenarios/Thesauri/ThesauriTest.php
@@ -0,0 +1,157 @@
+<?php
+/**
+ * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+abstract class Thesauri_ThesauriTestCase extends Admin_AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id' => 3,
+                    'libelle' => 'Document',
+                    'libelle_facette' => 'Document',
+                    'id_thesaurus' => 'DOCU',
+                    'id_origine' => null,
+                    'code' => 'DOCU',
+                    'rules' => '{"label":" 99$t "}']);
+
+    $this->fixture('Class_CodifThesaurus',
+                   ['id' => 4,
+                    'libelle' => 'SIFI',
+                    'libelle_facette' => 'Science fiction',
+                    'id_thesaurus' => 'DOCU0001',
+                    'id_origine' => null,
+                    'code' => 'DOCU']);
+  }
+}
+
+
+
+class Thesauri_ThesauriIndexTest extends Thesauri_ThesauriTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    $this->dispatch('/admin/thesauri/index', true);
+  }
+
+
+  /** @test */
+  public function thesauriShouldBeInAdminNav() {
+    $this->assertXPath('//a[contains(@href, "/thesauri/index")]');
+  }
+
+
+  /** @test */
+  public function thesauriTitleShouldBePresent() {
+    $this->assertXPathContentContains('//h1', 'Parcourir les Thesaurus');
+  }
+
+
+  /** @test */
+  public function documentShouldBeDisplay() {
+    $this->assertXpathContentContains('//table', 'Document');
+  }
+
+
+  /** @test */
+  public function rules99DollarTShouldBeDisplay() {
+    $this->assertXpathContentContains('//table', '99$t');
+  }
+
+  /** @test */
+  public function editActionShouldBeDisplayed() {
+    $this->assertXpath('//table//a[contains(@href, "/admin/thesauri/edit/id/3")]');
+  }
+}
+
+
+
+
+class Thesauri_ThesauriIndexChildrenTest extends Thesauri_ThesauriTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    $this->dispatch('/admin/thesauri/index/parent_id/3', true);
+  }
+
+
+  /** @test */
+  public function documentShouldBeDisplay() {
+    $this->assertXpathContentContains('//table', 'Document');
+  }
+
+
+  /** @test */
+  public function changeOrderToLibelleFacetteShouldBePresent() {
+    $this->assertXpathContentContains('//table//a[contains(@href, "order/libelle_facette")]', 'Libellé facette');
+  }
+
+
+  /** @test */
+  public function sifiShouldBeDisplay() {
+    $this->assertXpathContentContains('//table', 'Science fiction');
+  }
+
+
+  /** @test */
+  public function rules99DollarTShouldBeDisplay() {
+    $this->assertXpathContentContains('//table', '99$t');
+  }
+
+
+}
+
+
+class Thesauri_ThesauriIndexChildrenSearchTest extends Thesauri_ThesauriTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    $_SERVER['HTTP_REFERER'] = 'http://test.org/admin/thesauri/index';
+    $this->postDispatch('/admin/thesauri/index',
+                        ['title_search' => 'Docu']);
+  }
+
+
+  /** @test */
+  public function searchShouldRedirect() {
+    $this->assertRedirectTo('/admin/thesauri/index/title_search/Docu/page/1/order/libelle');
+  }
+}
+
+
+
+
+
+class Thesauri_ThesauriIndexOrderTest extends Thesauri_ThesauriTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    $this->dispatch('/admin/thesauri/index/parent_id/3/order/libelle_facette', true);
+  }
+
+
+  /** @test */
+  public function libelleFacetOrderLinkShouldDesc() {
+    $this->assertXpathContentContains('//table//a[contains(@href, "order/libelle_facette+desc")]', 'Libellé facette');
+  }
+}
\ No newline at end of file
-- 
GitLab