From d845cbb2bfd91db2da1aa358cafc6603338fe585 Mon Sep 17 00:00:00 2001
From: gloas <gloas@afi-sa.fr>
Date: Tue, 23 Nov 2021 09:06:58 +0100
Subject: [PATCH] sandbox #135407 multiple selection for widgets

---
 FEATURES/135407                               | 12 ++--
 VERSIONS_WIP/135407                           |  2 +-
 library/Class/MultiSelection/Abstract.php     | 14 ++++
 library/Class/MultiSelection/Widget.php       | 59 ++++-----------
 library/Class/Systeme/ModulesAccueil.php      |  4 +-
 library/Class/Systeme/Widget/Widget.php       | 72 ++++++++++++++-----
 .../Plugin/MultiSelection/Abstract.php        | 13 ++--
 .../Plugin/MultiSelection/LeafActions.php     |  2 +-
 .../Plugin/MultiSelection/Widget.php          | 25 +++++--
 library/ZendAfi/Form.php                      |  1 -
 .../Helper/Plugin/MultiSelection/Widget.php   | 26 ++++---
 .../View/Helper/ProfileComposition.php        | 29 ++++++--
 .../Library/Widget/Carousel/Form.php          |  6 +-
 public/admin/css/config_accueil.css           |  4 ++
 public/admin/skins/bokeh74/global.css         | 17 +++++
 .../MultiSelection/MultiSelectionTest.php     |  4 +-
 .../TemplatesWidgetsMultipleSelectionTest.php | 64 ++++++++++++++---
 17 files changed, 242 insertions(+), 112 deletions(-)

diff --git a/FEATURES/135407 b/FEATURES/135407
index 26db9fb18a6..c3a775e3f0d 100644
--- a/FEATURES/135407
+++ b/FEATURES/135407
@@ -1,10 +1,10 @@
         '135407' =>
-            ['Label' => $this->_('Magasin de thème P1 : SOS intégration graphique arborescence des pages + modifications groupées des boites'),
-             'Desc' => '',
+            ['Label' => $this->_('Sélection multiple des boites'),
+             'Desc' => $this->_('Administration : Il est maintenant possible de faire de la sélection multiple de boites dans les profils qui utilisent un thème du magasin'),
              'Image' => '',
-             'Video' => '',
-             'Category' => '',
+             'Video' => 'https://youtu.be/YyVDgqUNCV0',
+             'Category' => $this->_('Administration'),
              'Right' => function($feature_description, $user) {return true;},
-             'Wiki' => '',
+             'Wiki' => 'https://wiki.bokeh-library-portal.org/index.php?title=Boites_-_Traitement_par_lot',
              'Test' => '',
-             'Date' => '2021-11-19'],
\ No newline at end of file
+             'Date' => '2021-12-01'],
\ No newline at end of file
diff --git a/VERSIONS_WIP/135407 b/VERSIONS_WIP/135407
index a546fc0fa51..7daf7080b57 100644
--- a/VERSIONS_WIP/135407
+++ b/VERSIONS_WIP/135407
@@ -1 +1 @@
- - ticket #135407 : Magasin de thème P1 : SOS intégration graphique arborescence des pages + modifications groupées des boites
\ No newline at end of file
+ - ticket #135407 : Administration : Il est maintenant possible de faire de la sélection multiple de boites dans les profils qui utilisent un thème du magasin.
\ No newline at end of file
diff --git a/library/Class/MultiSelection/Abstract.php b/library/Class/MultiSelection/Abstract.php
index 120705ace2b..4eae6938efe 100644
--- a/library/Class/MultiSelection/Abstract.php
+++ b/library/Class/MultiSelection/Abstract.php
@@ -24,6 +24,9 @@ abstract class Class_MultiSelection_Abstract {
   use Trait_Translator;
 
 
+  protected $_ajax = false;
+
+
   public static function isSelected($id) {
     $instance = new static();
     return $instance->_getStorage()->contains($id);
@@ -85,6 +88,17 @@ abstract class Class_MultiSelection_Abstract {
   }
 
 
+  public function beAjax() {
+    $this->_ajax = true;
+    return $this;
+  }
+
+
+  public function isAjax() {
+    return $this->_ajax;
+  }
+
+
   public function acceptWidgetVisitor($visitor) {
     return $this;
   }
diff --git a/library/Class/MultiSelection/Widget.php b/library/Class/MultiSelection/Widget.php
index 73b046b944b..5a5db5415d7 100644
--- a/library/Class/MultiSelection/Widget.php
+++ b/library/Class/MultiSelection/Widget.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved.
+ * Copyright (c) 2012-2021, 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
@@ -28,27 +28,16 @@ class Class_MultiSelection_Widget extends Class_MultiSelection_Abstract {
 
 
   public function getModels() {
-    if(!$values = $this->getValues())
-      return new Storm_Model_Collection([]);
-
-    $widgets = new Storm_Collection;
-
-    foreach($values as $composed_id) { {
-        $ids = explode('-', $composed_id);
-        $profile_id = array_shift($ids);
-
-        if ($widget = (new Class_Systeme_Widget_Widget)
-            ->setId(array_shift($ids))
-            ->setProfileId($profile_id)
-            ->load())
-          $widgets->add($widget);
-      }
-    }
-
-    return $widgets;
+    return
+      Class_Systeme_Widget_Widget::withMixedIdsDo($this->getValues(),
+                                                  function($collection, $widget)
+                                                  {
+                                                    $collection->add($widget);
+                                                  });
   }
 
 
+  /* ZendAfi_View_Helper_Plugin_MultiSelection_Widget $visitor */
   public function acceptWidgetVisitor($visitor) {
     $models = $this->getModels();
     $count = $models->count();
@@ -92,23 +81,16 @@ class Class_MultiSelection_Widget extends Class_MultiSelection_Abstract {
       ->visitStrategy('widget')
       ->visitCategoryLabel(function($model)
                            {
-                             xdebug_break();
                              return $this->_('%s de la %s du profil %s',
                                              $model->getTypeLabel(),
                                              strtolower($model->getDivisionLabel()),
-                                             $model->getUsableProfileId());
+                                             $model->getProfileOrParentProfileId());
                            });
     return $this;
   }
 
 
   public function acceptActionsVisitor($visitor) {
-    $user = Class_Users::getIdentity();
-
-    $permission_closure = function($model) use($user){
-      return true;
-    };
-
     $visitor
       ->visitControllerName('profil')
 
@@ -117,16 +99,14 @@ class Class_MultiSelection_Widget extends Class_MultiSelection_Abstract {
                       return $model->getIdWithProfile();
                     })
 
-      ->visitLeafCondition(function($model) use($permission_closure)
+      ->visitLeafCondition(function($model)
                            {
-                             return $this->isSelected($model->getIdWithProfile())
-                               && $permission_closure($model);
+                             return $this->isSelected($model->getIdWithProfile());
                            })
 
-      ->visitNodeCondition(function($model) use($permission_closure)
+      ->visitNodeCondition(function($model)
                            {
-                             return $this->isCategorySelected($model->getId())
-                               && $permission_closure($model);
+                             return $this->isCategorySelected($model->getId());
                            })
 
       ->visitAddLeaf(function($model)
@@ -139,20 +119,7 @@ class Class_MultiSelection_Widget extends Class_MultiSelection_Abstract {
                         {
                           return $this->_('Supprimer %s de la sélection de boites',
                                           $model->getTitre());
-                        })
-
-      ->visitAddNode(function($model)
-                     {
-                       return $this->_('Ajouter toutes les boites de la catégorie %s à la sélection de boites',
-                                       $model->getLibelle());
-                     })
-
-      ->visitRemoveNode(function($model)
-                        {
-                          return $this->_('Supprimer toutes les boites du profil %s de la sélection de boites',
-                                          $model->getLibelle());
                         });
-
     return $this;
   }
 
diff --git a/library/Class/Systeme/ModulesAccueil.php b/library/Class/Systeme/ModulesAccueil.php
index 63cad982083..c2a0fc5d37a 100644
--- a/library/Class/Systeme/ModulesAccueil.php
+++ b/library/Class/Systeme/ModulesAccueil.php
@@ -191,7 +191,7 @@ class Class_Systeme_ModulesAccueil extends Class_Systeme_ModulesAbstract {
 
   public function getLabel($type) {
     $modules = static::getModules();
-    return isset($type, $modules)
+    return isset($modules[$type])
       ? $modules[$type]->getLibelle()
       : '';
   }
@@ -204,7 +204,7 @@ class Class_Systeme_ModulesAccueil extends Class_Systeme_ModulesAbstract {
 
   public function getDivisionLabel($id) {
     $divisions = $this->getDivisions();
-    return isset($id, $divisions)
+    return isset($divisions[$id])
       ? $divisions[$id]
       : '';
   }
diff --git a/library/Class/Systeme/Widget/Widget.php b/library/Class/Systeme/Widget/Widget.php
index 4930f6e6d09..a980b6a16be 100644
--- a/library/Class/Systeme/Widget/Widget.php
+++ b/library/Class/Systeme/Widget/Widget.php
@@ -115,12 +115,12 @@ class Class_Systeme_Widget_Widget extends Class_Systeme_Widget_Abstract {
 
   public function getIdWithProfile() {
     return sprintf('%s-%s',
-                   $this->getUsableProfileId(),
+                   $this->getProfileOrParentProfileId(),
                    $this->getId());
   }
 
 
-  public function getUsableProfileId() {
+  public function getProfileOrParentProfileId() {
     if ( !$division = $this->getdivision())
       return $this->getProfileId();
 
@@ -150,28 +150,54 @@ class Class_Systeme_Widget_Widget extends Class_Systeme_Widget_Abstract {
 
 
   public function getTypeLabel() {
-    return
-      (new Class_Systeme_ModulesAccueil)
-       ->getLabel($this->getModuleType());
+    return (new Class_Systeme_ModulesAccueil)
+      ->getLabel($this->getModuleType());
   }
 
 
   public static function deleteBy($ids) {
-    if ( ! isset($ids[ZendAfi_Controller_Plugin_MultiSelection_Widget::MODEL_ID_KEY]))
+    isset($ids[ZendAfi_Controller_Plugin_MultiSelection_Widget::MODEL_ID_KEY])
+      ? static::withMixedIdsDo($ids[ZendAfi_Controller_Plugin_MultiSelection_Widget::MODEL_ID_KEY],
+                               function($collection, $widget)
+                               {
+                                 $widget->delete();
+                               })
+      : null;
+  }
+
+
+  public static function withMixedIdsDo($ids, $callback) {
+    $collection = new Storm_Collection;
+
+    if ( ! $ids )
+      return $collection;
+
+    if ( ! $callback )
+      return $collection;
+
+    foreach($ids as $mixed_id)
+      static::withMixedIdDo($mixed_id, $callback, $collection);
+
+    return $collection;
+  }
+
+
+  public static function withMixedIdDo($mixed_id, $callback, $collection) {
+    $ids_as_array = explode('-', $mixed_id);
+
+    if ( ! $profile_id = array_shift($ids_as_array) )
       return;
 
-    $composed_ids = $ids[ZendAfi_Controller_Plugin_MultiSelection_Widget::MODEL_ID_KEY];
+    if ( ! $widget_id = array_shift($ids_as_array) )
+      return;
 
-    foreach($composed_ids as $composed_id) { {
-        $ids_as_array = explode('-', $composed_id);
-        $profile_id = array_shift($ids_as_array);
-        if ($widget = (new Class_Systeme_Widget_Widget)
-            ->setId(array_shift($ids_as_array))
-            ->setProfileId($profile_id)
-            ->load())
-          $widget->delete();
-      }
-    }
+    if ( ! $widget = (new Class_Systeme_Widget_Widget)
+        ->setId($widget_id)
+        ->setProfileId($profile_id)
+        ->load())
+      return;
+
+    $callback($collection, $widget);
   }
 
 
@@ -196,4 +222,16 @@ class Class_Systeme_Widget_Widget extends Class_Systeme_Widget_Abstract {
   public function save() {
     return $this->_update();
   }
+
+
+  public function updateAttributes($data) {
+    $this
+      ->setNewDatas($data);
+    return parent::updateAttributes($data);
+  }
+
+
+  public function isCarousel() {
+    return $this->getResourcesDefinition() instanceOf Intonation_Library_Widget_Carousel_Definition;
+  }
 }
diff --git a/library/ZendAfi/Controller/Plugin/MultiSelection/Abstract.php b/library/ZendAfi/Controller/Plugin/MultiSelection/Abstract.php
index 70dda0e532a..a1e3f393555 100644
--- a/library/ZendAfi/Controller/Plugin/MultiSelection/Abstract.php
+++ b/library/ZendAfi/Controller/Plugin/MultiSelection/Abstract.php
@@ -44,20 +44,25 @@ abstract class ZendAfi_Controller_Plugin_MultiSelection_Abstract extends ZendAfi
     $values = $this->_getValuesFromParams();
     $limit = (int) Class_AdminVar::getValueOrDefault('LIMIT_MULTIPLE_SELECTION');
 
-    if($this->_getMultiSelection()->isFullWith($values, $limit)) {
+    $multi_selection = $this->_getMultiSelection()->beAjax();
+
+    if($multi_selection->isFullWith($values, $limit)) {
       return $this->_helper->json(['selection' => $this->renderWidget(),
                                    'response' => $this->_('Il n\'est pas possible de sélectionner plus de %d éléments',
                                                           $limit)]);
     }
 
-    $this->_multi_selection = $this->_getMultiSelection()->addValues($values);
+    $this->_multi_selection = $multi_selection->addValues($values);
     return $this->_helper->json(['selection' => $this->renderWidget(),
                                  'response' => 'ok']);
   }
 
 
   public function removeModelFromSelectionAjaxAction() {
-    $this->_getMultiSelection()->removeValues($this->_getValuesFromParams());
+    $this
+      ->_getMultiSelection()
+      ->beAjax()
+      ->removeValues($this->_getValuesFromParams());
 
     return $this->_helper->json(['selection' => $this->renderWidget(),
                                  'response' => 'ok']);
@@ -87,7 +92,7 @@ abstract class ZendAfi_Controller_Plugin_MultiSelection_Abstract extends ZendAfi
                                    $this->_pluralizeModelName());
 
     if ($this->_setupFormAndUpdateModels($models->getArrayCopy())) {
-      $this->_helper->notify($this->_('Les %d %s sélectionnés ont bien été sauvegardés',
+      $this->_helper->notify($this->_('Les %d %s sélectionné(e)s ont bien été sauvegardé(e)s',
                                       $count,
                                       $this->_pluralizeModelName()));
       $this->_redirectToReferer();
diff --git a/library/ZendAfi/Controller/Plugin/MultiSelection/LeafActions.php b/library/ZendAfi/Controller/Plugin/MultiSelection/LeafActions.php
index f2e9c70d7f7..0ce3e3a26fb 100644
--- a/library/ZendAfi/Controller/Plugin/MultiSelection/LeafActions.php
+++ b/library/ZendAfi/Controller/Plugin/MultiSelection/LeafActions.php
@@ -1,4 +1,4 @@
- <?php
+<?php
 /**
  * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved.
  *
diff --git a/library/ZendAfi/Controller/Plugin/MultiSelection/Widget.php b/library/ZendAfi/Controller/Plugin/MultiSelection/Widget.php
index bd32f8bebd9..c396ae9a663 100644
--- a/library/ZendAfi/Controller/Plugin/MultiSelection/Widget.php
+++ b/library/ZendAfi/Controller/Plugin/MultiSelection/Widget.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved.
+ * Copyright (c) 2012-2021, 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
@@ -35,7 +35,7 @@ class ZendAfi_Controller_Plugin_MultiSelection_Widget extends ZendAfi_Controller
     if (!$model)
       return [];
 
-    if ('Class_Profil' == get_class($model))
+    if ( $model instanceOf Class_Profil)
       return (new ZendAfi_Controller_Plugin_MultiSelection_NodeActions($this->_multi_selection))
         ->getActions();
 
@@ -69,12 +69,29 @@ class ZendAfi_Controller_Plugin_MultiSelection_Widget extends ZendAfi_Controller
 
   protected function _getDefaultModel($models) {
     return (new Class_Systeme_Widget_Widget)
-      ->setForm(ZendAfi_Form_Configuration_Widget_Base::class);
+      ->setForm($this->_getFormClass($models));
+  }
+
+
+  protected function _getFormClass($models) {
+    $defaults_widget = (new Storm_Collection($models))
+      ->reject(function($widget)
+               {
+                 return $widget->isCarousel();
+               });
+
+    return $defaults_widget->isEmpty()
+      ? Intonation_Library_Widget_Carousel_Form::class
+      : ZendAfi_Form_Configuration_Widget_Base::class;
   }
 
 
   protected function _getForm($model) {
-    return $model->getFormInstance();
+    $form = $model->getFormInstance();
+    $form->removeElement('order');
+    $form->removeElement('data_sources');
+    $form->removeDisplayGroup('selection_group');
+    return $form;
   }
 
 
diff --git a/library/ZendAfi/Form.php b/library/ZendAfi/Form.php
index 1fd2c34fefd..5a0adde1f9d 100644
--- a/library/ZendAfi/Form.php
+++ b/library/ZendAfi/Form.php
@@ -132,7 +132,6 @@ class ZendAfi_Form extends Zend_Form {
 
 
   public function isValidModelAndArray($model, $array) {
-    xdebug_break();
     $valid = parent::isValid($array) && $model->isValid();
     $this->addModelErrors($model);
     $this->_errorsExist = !$valid;
diff --git a/library/ZendAfi/View/Helper/Plugin/MultiSelection/Widget.php b/library/ZendAfi/View/Helper/Plugin/MultiSelection/Widget.php
index 78db27f53d6..a5ffad543d8 100644
--- a/library/ZendAfi/View/Helper/Plugin/MultiSelection/Widget.php
+++ b/library/ZendAfi/View/Helper/Plugin/MultiSelection/Widget.php
@@ -32,9 +32,11 @@ class ZendAfi_View_Helper_Plugin_MultiSelection_Widget extends ZendAfi_View_Help
     $_count,
     $_title_key,
     $_strategy,
-    $_category_label;
+    $_category_label,
+    $_multi_selection;
 
   public function Plugin_MultiSelection_Widget($multi_selection) {
+    $this->_multi_selection = $multi_selection;
     $this->_current_skin = Class_Admin_Skin::current();
 
     $icon_add = $this->_current_skin->renderActionIconOn('basket',
@@ -75,9 +77,15 @@ class ZendAfi_View_Helper_Plugin_MultiSelection_Widget extends ZendAfi_View_Help
              $this->_getActions(),
              $this->_getSelectedItems()];
 
-    return $this->_tag('div',
-                       $this->_tag('div', implode($html)),
-                       ['class' => 'selected_items_widget show']);
+    $content = $this->_tag('div',
+                           implode($html),
+                           ['class' => 'selected_items_widget_content']);
+
+    return $this->_multi_selection->isAjax()
+      ? $content
+      :  $this->_tag('div',
+                     $content,
+                     ['class' => 'selected_items_widget show']);
   }
 
 
@@ -109,11 +117,11 @@ class ZendAfi_View_Helper_Plugin_MultiSelection_Widget extends ZendAfi_View_Help
                                                'title' => $this->_delete_selection]);
     }
 
-    $action_list[] = $this->view->tagAnchor('#',
-                                            $this->_('Afficher'),
-                                            ['class' => 'multiple_widget_action',
-                                             'onclick' => "\$('.selected_items_widget').toggleClass('list');",
-                                             'title' => $this->_show_selection]);
+    $action_list[] = $this->view->tag('a',
+                                      $this->_('Afficher'),
+                                      ['class' => 'multiple_widget_action',
+                                       'onclick' => "\$('.selected_items_widget').toggleClass('list');",
+                                       'title' => $this->_show_selection]);
 
     $actions= implode($action_list);
 
diff --git a/library/ZendAfi/View/Helper/ProfileComposition.php b/library/ZendAfi/View/Helper/ProfileComposition.php
index da92bbbaa00..76c09b1f625 100644
--- a/library/ZendAfi/View/Helper/ProfileComposition.php
+++ b/library/ZendAfi/View/Helper/ProfileComposition.php
@@ -149,17 +149,18 @@ class ZendAfi_View_Helper_ProfileComposition extends ZendAfi_View_Helper_BaseHel
 
   protected function _getHTMLForDivision($division) {
     $profil = Class_Profil::getCurrentProfil();
-    $html = '';
     $modules = $profil->getBoitesDivision($division);
-
     $helper = $this->view->getHelper('FonctionsAdmin_Boite');
+
+    $html = [];
     foreach($modules as $id_module => $module)
-      $html .= $this->_getItemModule($module['type_module'],
-                                     Class_Systeme_ModulesAccueil::moduleByCode($module['type_module'])->getLibelle(),
-                                     $id_module,
-                                     $this->_getWidgetActions($helper, $id_module, $module['type_module'], $division));
+      $html [] =
+        $this->_getItemModule($module['type_module'],
+                              $this->_getLabel($module),
+                              $id_module,
+                              $this->_getWidgetActions($helper, $id_module, $module['type_module'], $division));
 
-    return $html;
+    return implode($html);
   }
 
 
@@ -168,4 +169,18 @@ class ZendAfi_View_Helper_ProfileComposition extends ZendAfi_View_Helper_BaseHel
                               $type_module,
                               $division);
   }
+
+
+  protected function _getLabel($module) {
+    $module_label = Class_Systeme_ModulesAccueil::moduleByCode($module['type_module'])->getLibelle();
+
+    $title = (isset($module['preferences']) && isset($module['preferences']['titre']))
+      ? $module['preferences']['titre']
+      : '';
+
+    return $module_label
+      . ($title
+         ? ' : ' . $title
+         : '');
+  }
 }
\ No newline at end of file
diff --git a/library/templates/Intonation/Library/Widget/Carousel/Form.php b/library/templates/Intonation/Library/Widget/Carousel/Form.php
index 6b4c366c3f4..15578db45ea 100644
--- a/library/templates/Intonation/Library/Widget/Carousel/Form.php
+++ b/library/templates/Intonation/Library/Widget/Carousel/Form.php
@@ -20,7 +20,7 @@
  */
 
 
-abstract class Intonation_Library_Widget_Carousel_Form extends ZendAfi_Form_Configuration_Widget_Base {
+class Intonation_Library_Widget_Carousel_Form extends ZendAfi_Form_Configuration_Widget_Base {
 
   public function init() {
     parent::init();
@@ -176,5 +176,7 @@ abstract class Intonation_Library_Widget_Carousel_Form extends ZendAfi_Form_Conf
   }
 
 
-  abstract public function getOrders();
+  public function getOrders() {
+    return [];
+  }
 }
\ No newline at end of file
diff --git a/public/admin/css/config_accueil.css b/public/admin/css/config_accueil.css
index 9332dd3a725..ca678d87ecf 100644
--- a/public/admin/css/config_accueil.css
+++ b/public/admin/css/config_accueil.css
@@ -165,3 +165,7 @@ ul.source_list {
 .profile_composition .container_list.deleted_widget {
     border:1px solid var(--error-background);
 }
+
+.profile_composition .container_list li:hover {
+    font-weight: bold;
+}
diff --git a/public/admin/skins/bokeh74/global.css b/public/admin/skins/bokeh74/global.css
index 1a049473b38..410e440dc55 100755
--- a/public/admin/skins/bokeh74/global.css
+++ b/public/admin/skins/bokeh74/global.css
@@ -1119,3 +1119,20 @@ table#album_item th, table#album_usage_report th {
 .test_my_opac li:hover {
     background-color: var(--line-highlight);
 }
+
+.profil_accueil .selected_items_widget {
+    position: fixed;
+    top: 125px;
+    bottom: unset;
+    right: 5%;
+    left: unset;
+    z-index: 101;
+}
+
+.profil_accueil .selected_items_widget > div {
+    background: var(--widget-background);
+}
+
+.profil_accueil .selected_items_widget.show ~ .profils.form {
+    margin-top: 80px;
+}
diff --git a/tests/scenarios/MultiSelection/MultiSelectionTest.php b/tests/scenarios/MultiSelection/MultiSelectionTest.php
index 453c6630a70..410dba2bbe2 100644
--- a/tests/scenarios/MultiSelection/MultiSelectionTest.php
+++ b/tests/scenarios/MultiSelection/MultiSelectionTest.php
@@ -499,7 +499,7 @@ class MultiSelectionArticlesPostDatasTest extends MultiSelectionArticlesPostTest
 
   /** @test */
   public function shouldNotifySucces() {
-    $this->assertFlashMessengerEquals([ ['notification' => ['message' => 'Les 2 articles sélectionnés ont bien été sauvegardés']]]);
+    $this->assertFlashMessengerEquals([ ['notification' => ['message' => 'Les 2 articles sélectionné(e)s ont bien été sauvegardé(e)s']]]);
   }
 
 
@@ -982,6 +982,6 @@ class MultiSelectionAlbumPostDatasTest extends MultiSelectionAlbumTestCase {
 
   /** @test */
   public function shouldNotifySuccess() {
-    $this->assertFlashMessengerEquals([ ['notification' => ['message' => 'Les 2 albums sélectionnés ont bien été sauvegardés']]]);
+    $this->assertFlashMessengerEquals([ ['notification' => ['message' => 'Les 2 albums sélectionné(e)s ont bien été sauvegardé(e)s']]]);
   }
 }
\ No newline at end of file
diff --git a/tests/scenarios/Templates/TemplatesWidgetsMultipleSelectionTest.php b/tests/scenarios/Templates/TemplatesWidgetsMultipleSelectionTest.php
index dbf095ceb1a..38a16cf4ec1 100644
--- a/tests/scenarios/Templates/TemplatesWidgetsMultipleSelectionTest.php
+++ b/tests/scenarios/Templates/TemplatesWidgetsMultipleSelectionTest.php
@@ -37,7 +37,6 @@ abstract class TemplatesWidgetsMultipleSelectionAdminTestCase extends Admin_Abst
                   Class_Profil::DIV_BANNIERE,
                   ['titre' => 'Réseau',
                    'rendering' => 'card-description',
-                   'libraries' => '1;2;3;4;5;6',
                    'layout' => 'multiple_carousel_plus',
                    'size' => 10]);
 
@@ -52,16 +51,19 @@ abstract class TemplatesWidgetsMultipleSelectionAdminTestCase extends Admin_Abst
                   Class_Profil::DIV_MAIN,
                   ['titre' => 'Nouveauté',
                    'rendering' => 'card-description',
-                   'libraries' => '1;2;3;4;5;6',
                    'layout' => 'multiple_carousel_plus',
                    'size' => 10])
 
       ->addWidget(Intonation_Library_Widget_Carousel_Article_Definition::CODE,
                   Class_Profil::DIV_MAIN,
-                  ['rendering' => 'card-description',
-                   'libraries' => '1;2;3;4;5;6',
+                  ['titre' => 'Agenda',
+                   'rendering' => 'card-description',
                    'layout' => 'multiple_carousel_plus',
-                   'size' => 10]);
+                   'size' => 10])
+
+      ->addWidget(Intonation_Library_Widget_Image_Definition::CODE,
+                  Class_Profil::DIV_MAIN,
+                  ['titre' => 'Logo']);
   }
 }
 
@@ -120,15 +122,22 @@ class TemplatesWidgetsMultipleSelectionProfilSessionSelectionTest extends Templa
 
 
 
-class TemplatesWidgetsMultipleSelectionProfilAccueilWithSelectedWidgets extends TemplatesWidgetsMultipleSelectionAdminTestCase {
+class TemplatesWidgetsMultipleSelectionProfilAccueilWithSelectedWidgetsTest extends TemplatesWidgetsMultipleSelectionAdminTestCase {
 
   public function setUp() {
     parent::setUp();
-    Zend_Registry::get('session')->selected_items = ['widget' => ['16-3', '13-1']];
+    Zend_Registry::get('session')->selected_items = ['widget' => ['16-2', '13-1']];
     $this->dispatch('admin/profil/accueil/id_profil/16');
   }
 
 
+  /** @test */
+  public function reseauTitleShouldBePresentInContainerListLi() {
+    $this->assertXPathContentContains('//ul[@class="container_list"]/li',
+                                      'Boite des bibliothèques : Réseau');
+  }
+
+
   /** @test */
   public function twoWidgetsSelectedMessageShouldBeDisplay() {
     $this->assertXpathContentContains('//div[@class="selected_items_widget show"]',
@@ -178,6 +187,12 @@ class TemplatesWidgetsMultipleSelectionProfilSessionEditSelectionTest extends Te
   public function shouldContainsHiddenMode() {
     $this->assertXPath('//form//select[contains(@id, "HiddenMode")]');
   }
+
+
+  /** @test */
+  public function shouldContainsLayout() {
+    $this->assertXPath('//form//select[contains(@id, "layout")]');
+  }
 }
 
 
@@ -188,6 +203,7 @@ class TemplatesWidgetsMultipleSelectionProfilSessionPostEditTest extends Templat
 
   public function setUp() {
     parent::setUp();
+    $_SERVER['HTTP_REFERER'] = 'admin/profil/accueil/id_profil/16';
     Zend_Registry::get('session')->selected_items = ['widget' => ['13-1', '16-3']];
     $this->postDispatch('/admin/profil/edit-multiple',
                         ['IntonationShowHeader' => 0,
@@ -195,14 +211,14 @@ class TemplatesWidgetsMultipleSelectionProfilSessionPostEditTest extends Templat
   }
 
   /** @test */
-  public function shouldRedirect() {
-    $this->assertRedirectTo('/');
+  public function shouldRedirectToReferer() {
+    $this->assertRedirectTo('/admin/profil/accueil/id_profil/16');
   }
 
 
   /** @test */
   public function shouldNotifySuccess() {
-    $this->assertFlashMessengerContentContains('Les 2 boites sélectionnés ont bien été sauvegardés');
+    $this->assertFlashMessengerContentContains('Les 2 boites sélectionné(e)s ont bien été sauvegardé(e)s');
   }
 
 
@@ -213,4 +229,32 @@ class TemplatesWidgetsMultipleSelectionProfilSessionPostEditTest extends Templat
                         ->setProfileId(13)
                         ->load()->gettitre());
   }
+
+
+  /** @test */
+  public function widgetLayoutShouldNotHaveBeenModified() {
+    $this->assertEquals('multiple_carousel_plus', (new Class_Systeme_Widget_Widget)
+                        ->setId(1)
+                        ->setProfileId(13)
+                        ->load()->getlayout());
+  }
 }
+
+
+
+
+
+class TemplatesWidgetsMultipleSelectionProfilSessionEditMixedSelectionTest extends TemplatesWidgetsMultipleSelectionAdminTestCase {
+
+
+  public function setUp() {
+    parent::setUp();
+    Zend_Registry::get('session')->selected_items = ['widget' => ['13-1', '16-3', '16-4']];
+    $this->dispatch('/admin/profil/edit-multiple');
+  }
+
+  /** @test */
+  public function shouldNotContainsLayout() {
+    $this->assertNotXPath('//form//select[contains(@id, "layout")]');
+  }
+}
\ No newline at end of file
-- 
GitLab