diff --git a/VERSIONS_HOTLINE/109494 b/VERSIONS_HOTLINE/109494
new file mode 100644
index 0000000000000000000000000000000000000000..2e5133c8f5e1cd3ff5a98404b9161c486b0c0222
--- /dev/null
+++ b/VERSIONS_HOTLINE/109494
@@ -0,0 +1 @@
+ - ticket #109494 : PNB Dilicom : Correction de la mise à jour erronée des compteur de prêts lorsque la commande a été annulée
\ No newline at end of file
diff --git a/VERSIONS_HOTLINE/114276 b/VERSIONS_HOTLINE/114276
new file mode 100644
index 0000000000000000000000000000000000000000..b5a961d30194f8598c3fa0549ae7134d8185c6e1
--- /dev/null
+++ b/VERSIONS_HOTLINE/114276
@@ -0,0 +1 @@
+ - ticket #114276 : Magasin de thèmes : correction de la prise en compte du critère de tri dans la boîte de recherche simple
\ No newline at end of file
diff --git a/VERSIONS_HOTLINE/115625 b/VERSIONS_HOTLINE/115625
new file mode 100644
index 0000000000000000000000000000000000000000..4b79e5cf6608a39e8542075965048a9bce7d0a04
--- /dev/null
+++ b/VERSIONS_HOTLINE/115625
@@ -0,0 +1 @@
+ - ticket #115625 : Moissonnage Openagenda MEL : Manque des champs
\ No newline at end of file
diff --git a/library/Class/Album/Item.php b/library/Class/Album/Item.php
index 4d3c4680ad18bdd094ce2e5638745e3a628b1bf6..a8df06267be322a0f1d28d303e3903ddea480224 100644
--- a/library/Class/Album/Item.php
+++ b/library/Class/Album/Item.php
@@ -112,6 +112,11 @@ class Class_Album_Item extends Storm_Model_Abstract {
   }
 
 
+  public function getLoanMaxNumberOfUsers() {
+    return $this->getUsageConstraints()->getLoanMaxNumberOfUsers();
+  }
+
+
   public function setLoanMaxNumberOfUsers($max) {
     $this->getUsageConstraints()->setLoanMaxNumberOfUsers($max);
     return $this;
diff --git a/library/Class/ExternalAgenda/OpenAgenda.php b/library/Class/ExternalAgenda/OpenAgenda.php
index f5f3f7a2307438c90201b54543b3e62dfb997839..8f115612eb56ea3ad8fdd7b5c402c991042f859a 100644
--- a/library/Class/ExternalAgenda/OpenAgenda.php
+++ b/library/Class/ExternalAgenda/OpenAgenda.php
@@ -60,7 +60,10 @@ class Class_ExternalAgenda_OpenAgenda extends Class_ExternalAgenda_Provider {
     return $this->_external_agenda
       ->newEvent()
       ->setTitre($event->getString('title'))
-      ->setContenu($event->getImageTagWithCredits().$event->getHtml().$event->getInfosTag())
+      ->setContenu($event->getImageTagWithCredits()
+                   .$event->getHtml()
+                   .$event->getInfosTag()
+                   .$event->getInscriptionsTag())
       ->setIdOrigine($event->get('uid') . '_' . base64_encode($timing['start']))
       ->setDescription($event->getImageTag().'<p>'.$event->getString('description').'</p>')
       ->setTags(implode(';', $event->getKeywords()))
@@ -112,7 +115,41 @@ class Class_ExternalAgenda_OpenAgenda_Event {
     return '<p>' . $this->_('Infos pratiques :') . '</p><dl>' . $infos . '</dl>';
   }
 
-  protected function _addInfoElement($label, $description){
+
+  public function getInscriptionsTag() {
+    $contacts = [];
+
+    $type_mapping = [
+                     'email' => $this->_('Courriel'),
+                     'phone' => $this->_('Téléphone'),
+                     'lien' => $this->_('Site')
+    ];
+
+    foreach ($this->getArray('registration') as $registration){
+      $type = in_array($registration['type'], array_keys($type_mapping))
+        ? $registration['type']
+        : 'email';
+
+      if (!isset($registration['value'])
+          || !($registration['value']))
+          continue;
+
+      $contacts []= $this->_renderDtDd($type_mapping[$type],
+                                       $registration['value']);
+    }
+
+    if ($url = $this->getString('registrationUrl'))
+      $contacts []= $this->_renderDtDd($this->_('Lien'),
+                                       $url);
+
+    if (!$contacts)
+      return '';
+
+    return '<p>' . $this->_('Pour s\'inscrire :') . '</p><dl>' . implode('', $contacts) . '</dl>';
+  }
+
+
+  protected function _renderDtDd($label, $description){
     return '<dt>' . $label . '</dt>'
         . '<dd>' . $description . '</dd>';
   }
@@ -129,26 +166,24 @@ class Class_ExternalAgenda_OpenAgenda_Event {
 
   protected function _prepareConditionsString() {
     return ($conditions = $this->getString('conditions'))
-      ? $this->_addInfoElement(
-                               $this->_('Conditions'),
-                               $conditions)
-      : "";
+      ? $this->_renderDtDd(
+                           $this->_('Conditions'),
+                           $conditions)
+      : '';
   }
 
 
   protected function _prepareAgeString() {
     return ($this->_event['age'])
-      ? $this->_addInfoElement(
-                               $this->_('Âge'),
-                               $this->_('de %s à %s ans',
-                                        $this->_event['age']['min'],
-                                        $this->_event['age']['max']))
-      : "";
+      ? $this->_renderDtDd(
+                           $this->_('Âge'),
+                           $this->_('de %s à %s ans',
+                                    $this->_event['age']['min'],
+                                    $this->_event['age']['max']))
+      : '';
   }
 
 
-
-
   public function getString($name){
     if (!(isset($this->_event[$name]) && $this->_event[$name]))
       return '';
diff --git a/library/Class/WebService/BibNumerique/Dilicom/Hub.php b/library/Class/WebService/BibNumerique/Dilicom/Hub.php
index 2ee69d428033f04ddbe1a162276b42d4836f9d00..f0fccdcf8e4a4ed84abdc250df08fe8532ec5c96 100644
--- a/library/Class/WebService/BibNumerique/Dilicom/Hub.php
+++ b/library/Class/WebService/BibNumerique/Dilicom/Hub.php
@@ -479,14 +479,20 @@ class Class_WebService_BibNumerique_Dilicom_Hub extends Class_WebService_Abstrac
 
   protected function _updateItemStatus($item) {
     $content = $this->getLoanStatus($item);
+    if (!isset($content->loanResponseLine[0]))
+      return $this;
 
-    if (isset($content->loanResponseLine[0])) {
-      $simultaneous_users_remaining = $content->loanResponseLine[0]->nus1;
+    $status = $content->loanResponseLine[0];
+    if (!isset($status->nus1) || !isset($status->nta))
+      return $this;
 
-      $item->setLoanCount(max(0, $item->getUsageConstraints()->getLoanMaxNumberOfUsers() - $simultaneous_users_remaining));
-      $item->setQuantity($item->getUsageConstraints()->getLoanQuantity() - $content->loanResponseLine[0]->nta);
-      $item->save();
-    }
+    $simultaneous_users_remaining = $status->nus1;
+    $loans_remaining = $status->nta;
+
+    $item->setLoanCount(max(0, $item->getLoanMaxNumberOfUsers() - $simultaneous_users_remaining));
+    $item->setQuantity($item->getLoanQuantity() - $loans_remaining);
+
+    $item->save();
 
     return $this;
   }
diff --git a/library/templates/Intonation/Library/Widget/Search/View.php b/library/templates/Intonation/Library/Widget/Search/View.php
index 99effe30272fd3eb49220b0d5069dde54a5dc054..c2754d77a06f0be8328a362a5d0cc64b47f54872 100644
--- a/library/templates/Intonation/Library/Widget/Search/View.php
+++ b/library/templates/Intonation/Library/Widget/Search/View.php
@@ -201,8 +201,9 @@ abstract class IntonationSearchRenderAbstract {
 
     $form
       ->addElement('hidden',
-                   uniqid() . 'tri',
-                   ['value' => $this->_getOrder()])
+                   'tri',
+                   ['value' => $this->_getOrder(),
+                    'id' => uniqid() . 'tri'])
 
       ->addElement('search',
                    'expressionRecherche',
@@ -408,10 +409,9 @@ abstract class IntonationSearchRenderAbstract {
 
 
   protected function _getOrder() {
-    if ($user_order = (new Class_User_Settings($this->_user))->getSearchOrder())
-      return $user_order;
-
-    return $this->_settings->getTri();
+    return ($current_order = $this->_criteria->getParam('tri', null))
+      ? $current_order
+      : $this->_settings->getTri();
   }
 
 
diff --git a/tests/fixtures/DilicomFixtures.php b/tests/fixtures/DilicomFixtures.php
index 3e41a4ccbee309ea48a580327168fa4aac03e55e..ace18c53364d3d5f9b6651183fc2f71a29dffc5d 100644
--- a/tests/fixtures/DilicomFixtures.php
+++ b/tests/fixtures/DilicomFixtures.php
@@ -165,6 +165,16 @@ class DilicomFixtures {
   }
 
 
+  public static function getLoanStatusCancelledResponse($orderLineId) {
+    return '{
+      "date":"2020-09-10T15:51:53Z",
+      "loanResponseLine":[{"orderLineId":"' . $orderLineId . '",
+                           "returnStatus":"CANCELLED"}],
+      "returnStatus":"WARNING",
+      "returnMessage":["All order lines are returned with error"]}';
+  }
+
+
   public static function getEndedLoansResponse($lines=[]) {
     return '{
   "requestId":"aw01v2_000000041_201502261519",
@@ -176,6 +186,28 @@ class DilicomFixtures {
 
 
   public function albumTotemThora() {
+    $constraints = [$this->fixture('Class_Album_UsageConstraint',
+                                   ['id' => 1,
+                                    'album_id' => 3,
+                                    'usage_type' => Class_Album_UsageConstraint::LOAN_CONSTRAINT,
+                                    Class_Album_UsageConstraint::MAX_NB_OF_USERS => 50,
+                                    Class_Album_Usageconstraint::QUANTITY => 50]),
+
+                    $this->fixture('Class_Album_UsageConstraint',
+                                   ['id' => 2,
+                                    'album_id' => 3,
+                                    'usage_type' => Class_Album_UsageConstraint::AVAILABILITY_CONSTRAINT,
+                                    Class_Album_UsageConstraint::DURATION => '10000',
+                                    Class_Album_UsageConstraint::ORDER_DATE => '2015-04-01 00:00:00',
+                                    'order_line_id' => 'x321'])];
+
+    $item = $this->fixture('Class_Album_Item',
+                           ['id' => 1,
+                            'album_id' => 3,
+                            'loan_count' => 2,
+                            'quantity' => 4,
+                            'usage_constraints' => $constraints]);
+
     return $this->fixture('Class_Album',
                           ['id' => 3,
                            'titre' => 'Totem et Thora',
@@ -183,25 +215,7 @@ class DilicomFixtures {
                            'external_uri' => 'http://www.edenlivres.fr/p/23416',
                            'url_origine' => 'https://url_dilicom.org/ressource/id/1',
                            'type_doc_id' => Class_TypeDoc::DILICOM,
-                           'items' => [$this->fixture('Class_Album_Item',
-                                                      ['id' => 1,
-                                                       'album_id' => 3,
-                                                       'loan_count' => 2,
-                                                       'quantity' => 4,
-                                                       'usage_constraints' => [$this->fixture('Class_Album_UsageConstraint',
-                                                                                              ['id' => 1,
-                                                                                               'album_id' => 3,
-                                                                                               'usage_type' => Class_Album_UsageConstraint::LOAN_CONSTRAINT,
-                                                                                               Class_Album_UsageConstraint::MAX_NB_OF_USERS => 50,
-                                                                                               Class_Album_Usageconstraint::QUANTITY => 50]),
-
-                                                                               $this->fixture('Class_Album_UsageConstraint',
-                                                                                              ['id' => 2,
-                                                                                               'album_id' => 3,
-                                                                                               'usage_type' => Class_Album_UsageConstraint::AVAILABILITY_CONSTRAINT,
-                                                                                               Class_Album_UsageConstraint::DURATION => '10000',
-                                                                                               Class_Album_UsageConstraint::ORDER_DATE => '2015-04-01 00:00:00',
-                                                                                               'order_line_id' => 'x321'])]])]])
+                           'items' => [$item]])
                 ->addAuthor('Raphaël Draï');
   }
 }
\ No newline at end of file
diff --git a/tests/scenarios/ExternalAgendas/ExternalAgendasOpenAgendaTest.php b/tests/scenarios/ExternalAgendas/ExternalAgendasOpenAgendaTest.php
index 572c63b31f37ce4ec8e4cea0eca9585dfc870767..cc2d119d193b8fc5bb9b0b6406cec90a792808f9 100644
--- a/tests/scenarios/ExternalAgendas/ExternalAgendasOpenAgendaTest.php
+++ b/tests/scenarios/ExternalAgendas/ExternalAgendasOpenAgendaTest.php
@@ -207,7 +207,7 @@ class ExternalAgendasOpenAgendaAdminTest extends Admin_AbstractControllerTestCas
 
   /** @test */
   public function firstArticleImageShouldContainsHTMLAndImage() {
-    $this->assertEquals('<figure><img src="https://cibul.s3.amazonaws.com/9c3729cce33140c5a011056c8168ec5b.base.image.jpg" alt=""/><figcaption>Credits : moi</figcaption></figure><p>Voyons ça dans une session de coding dojo</p><p>Infos pratiques :</p><dl><dt>Conditions</dt><dd>être geek</dd><dt>Âge</dt><dd>de 6 à 99 ans</dd></dl>',
+    $this->assertEquals('<figure><img src="https://cibul.s3.amazonaws.com/9c3729cce33140c5a011056c8168ec5b.base.image.jpg" alt=""/><figcaption>Credits : moi</figcaption></figure><p>Voyons ça dans une session de coding dojo</p><p>Infos pratiques :</p><dl><dt>Conditions</dt><dd>être geek</dd><dt>Âge</dt><dd>de 6 à 99 ans</dd></dl><p>Pour s\'inscrire :</p><dl><dt>Courriel</dt><dd>llaffont@afi-sa.fr</dd><dt>Téléphone</dt><dd>0123456789</dd><dt>Site</dt><dd>https://www.website.org</dd><dt>Lien</dt><dd>https://registration.website.org/</dd></dl>',
                         Class_Article::find(1)->getContenu());
   }
 
diff --git a/tests/scenarios/ExternalAgendas/open-agenda-1.json b/tests/scenarios/ExternalAgendas/open-agenda-1.json
index 0a3068dea7612375a3e52a7eec40b92bbd893b43..e1d0fe0468f95aa312093e6a40a01d50ef128afd 100644
--- a/tests/scenarios/ExternalAgendas/open-agenda-1.json
+++ b/tests/scenarios/ExternalAgendas/open-agenda-1.json
@@ -51,7 +51,7 @@
       "conditions": {
         "fr": "être geek"
       },
-      "registrationUrl": "llaffont@afi-sa.fr",
+      "registrationUrl": "https://registration.website.org/",
       "locationName": "San pedro chez HDL",
       "locationUid": 91517332,
       "address": "San-Pédro",
@@ -115,6 +115,14 @@
           "value": "llaffont@afi-sa.fr",
           "type": "email",
           "prefix": "mailto:"
+        },
+        {
+          "value": "0123456789",
+          "type": "phone"
+        },
+        {
+          "value": "https://www.website.org",
+          "type": "lien"
         }
       ],
       "firstDate": "2019-11-25",
diff --git a/tests/scenarios/PnbDilicom/PnbDilicomTest.php b/tests/scenarios/PnbDilicom/PnbDilicomTest.php
index 20a9a6d1d2b51a847fb9130670544c865ef106e0..4f46447088ce73cc5dc3f9ea564b1eb4e2aecf02 100644
--- a/tests/scenarios/PnbDilicom/PnbDilicomTest.php
+++ b/tests/scenarios/PnbDilicom/PnbDilicomTest.php
@@ -1612,538 +1612,13 @@ class PnbDilicomViewHelperNoticeLoggedTest extends PnbDilicomViewHelperNoticeTes
 
 
 
-abstract class PnbDilicomViewHelperRenderAlbumTestCase extends ViewHelperTestCase {
-
-  protected $_storm_default_to_volatile = true,
-    $_helper,
-    $_html;
-
-  public function setUp() {
-    parent::setUp();
-
-    $view = new ZendAfi_Controller_Action_Helper_View();
-    $this->_helper = new ZendAfi_View_Helper_RenderAlbum();
-    $this->_helper->setView($view);
-
-    $this->book = (new DilicomFixtures())->albumTotemThora();
-    RessourcesNumeriquesFixtures::activateDilicom();
-
-    $this->_http = $this->mock();
-    Class_WebService_BibNumerique_Dilicom_Hub::setDefaultHttpClient($this->_http);
-
-    $this->_time_source = new TimeSourceForTest('2014-05-02 14:14:14');
-    Class_WebService_BibNumerique_Dilicom_Hub::setTimeSource($this->_time_source);
-    Class_Album_UsageConstraint::setTimeSource($this->_time_source);
-    Class_Hold_Pnb::setTimeSource($this->_time_source);
-
-    $this->_http
-      ->whenCalled('setAuth')
-      ->answers(null)
-
-      ->whenCalled('open_url')
-      ->answers(DilicomFixtures::getLoanStatusResponseAvailableUsersAndQuantityLeft(5, 24));
-
-  }
-
-
-  public function tearDown() {
-    ZendAfi_Auth::getInstance()->clearIdentity();
-    Class_WebService_BibNumerique_Dilicom_Hub::setTimeSource(null);
-    Class_Album_UsageConstraint::setTimeSource(null);
-    Class_Hold_Pnb::setTimeSource(null);
-    parent::tearDown();
-  }
-}
-
-
-
-
-class PnbDilicomViewHelperRenderAlbumPNBNotLoggedTest extends PnbDilicomViewHelperRenderAlbumTestCase {
-
-  public function setUp() {
-    parent::setUp();
-    ZendAfi_Auth::getInstance()->clearIdentity();
-    $this->_html = $this->_helper->renderAlbum($this->book);
-  }
-
-
-  /** @test */
-  public function htmlShouldNotContainsLinkToConsultBook() {
-    $this->assertXPathContentContains($this->_html,
-                                      '//a[contains(@href, "/bib-numerique/consult-book-ajax/id/3")]',
-                                      'Consulter le livre en ligne');
-  }
-}
-
-
-
-
-class PnbDilicomViewHelperRenderAlbumPNBLoggedButNotAuthorizeTest
-  extends PnbDilicomViewHelperRenderAlbumTestCase {
-
-  public function setUp() {
-    parent::setUp();
-    $this->logged_user = $this->fixture('Class_Users',
-                                        ['id' => 6,
-                                         'nom'=>'Pito',
-                                         'login'=>'Chat',
-                                         'password'=>'123456',
-                                         'id_site' => 1,
-                                         'idabon' => '12345']);
-
-    $this->logged_user->setUserGroups([]);
-    ZendAfi_Auth::getInstance()->logUser($this->logged_user);
-    $this->_html = $this->_helper->renderAlbum($this->book);
-  }
-
-
-  /** @test */
-  public function htmlShouldNotContainsLinkToConsultBook() {
-    $this->assertXPathContentContains($this->_html,
-                                      '//p',utf8_encode("Vous n'avez pas le droit d'accéder à la consultation en ligne."));
-  }
-}
-
-
-
-
-class PnbDilicomViewHelperRenderAlbumPNBTest extends PnbDilicomViewHelperRenderAlbumTestCase {
-
-  public function setUp() {
-    parent::setUp();
-
-    $this->fixture('Class_Bib', ['id' => 1,
-                                 'libelle' => 'Annecy',
-                                 'gln' => '333']);
-
-    $this->logged_user = $this->fixture('Class_Users',
-                                        ['id' => 6,
-                                         'nom'=>'Pito',
-                                         'login'=>'Chat',
-                                         'password'=>'123456',
-                                         'id_site' => 1,
-                                         'idabon' => '12345',
-                                         'user_groups' => [$this->fixture('Class_UserGroup',
-                                                                          ['id' => '20',
-                                                                           'libelle' => 'Multimedia',
-                                                                           'rights' => [Class_UserGroup::RIGHT_ACCES_PNB_DILICOM]])]]);
-
-    $this->logged_user->beAbonneSIGB()->assertSave();
-    ZendAfi_Auth::getInstance()->logUser($this->logged_user);
-
-    $this->fixture('Class_Loan_Pnb', ['id' => 1,
-                                      'record_origin_id' => 'Dilicom-88817216',
-                                      'user_id' => '6']);
-
-    Class_AdminVar::set('DILICOM_PNB_ENABLE_HOLDS', '1');
-    $this->_html = $this->_helper->renderAlbum($this->book);
-  }
-
-
-  public function tearDown() {
-    unset($_SERVER['HTTPS']);
-    parent::tearDown();
-  }
-
-
-  /** @test */
-  public function htmlShouldContainsIFrameOnEdenBook() {
-    $this->assertXPath($this->_html,
-                       '//iframe[@src="http://www.edenlivres.fr/p/23416"][@width="100%"][@height="600px"]',
-                       $this->_html);
-  }
-
-
-  /** @test */
-  public function htmlShouldContainsLinkToConsultBook() {
-    $this->assertXPathContentContains($this->_html,
-                                      '//a[contains(@href, "/bib-numerique/consult-book-ajax/id/3")]',
-                                      'Consulter le livre en ligne');
-  }
-
-
-  /** @test */
-  public function htmlShouldContainsLinkToLoanBook() {
-    $this->assertXPathContentContains($this->_html,
-                                      '//a[contains(@href, "/bib-numerique/loan-book-ajax/id/3")]',
-                                      'Emprunter le livre au format EPUB');
-  }
-
-
-  /** @test */
-  public function htmlShouldNotContainsHoldBookLink() {
-    $this->assertNotXPath($this->_html,
-                          '//a[contains(@href, "/hold-book")]');
-  }
-
-
-  /** @test */
-  public function htmlShouldNotContainsReservationImpossible() {
-    $this->assertNotXPathContentContains($this->_html,
-                                         '//span',
-                                         utf8_encode('Réservation impossible'),
-                                         $this->_html);
-  }
-
-
-  /** @test */
-  public function bibWithoutGlnShouldReturnErrorMessage() {
-    Class_Bib::find(1)->setGln('')->assertSave();
-    $this->_html = $this->_helper->renderAlbum($this->book);
-    $this->assertXPathContentContains($this->_html,
-                                      '//p', utf8_encode('Annecy n\'a pas accès à la consultation en ligne'));
-  }
-
-
-  /** @test */
-  public function userWithoutBibShouldReturnErrorMessage() {
-    $this->logged_user->setBib(null)->save();
-    $this->_html = $this->_helper->renderAlbum($this->book);
-    $this->assertXPathContentContains($this->_html,
-                                      '//p', utf8_encode('Vous devez être inscrit dans une bibliothèque pour accéder à la consultation en ligne'));
-
-  }
-
-  /** @test */
-  public function withHttpsPreviewSrcShouldBeHttps() {
-    $_SERVER['HTTPS'] = 'on';
-
-    $this->_html = $this->_helper->renderAlbum($this->book);
-    $this->assertXPath($this->_html,
-                       '//iframe[@src="https://www.edenlivres.fr/p/23416"][@width="100%"][@height="600px"]',
-                       $this->_html);
-  }
-}
-
-
-
-
-class PnbDilicomViewHelperRenderAlbumPNBLoggedButBlockedTest
-  extends PnbDilicomViewHelperRenderAlbumTestCase {
-
-  public function setUp() {
-    parent::setUp();
-
-    $this->fixture('Class_Bib', ['id' => 1,
-                                 'libelle' => 'Annecy',
-                                 'gln' => '333']);
-
-    $group = $this->fixture('Class_UserGroup',
-                            ['id' => '20',
-                             'libelle' => 'Dilicom',
-                             'group_type' => Class_UserGroup::TYPE_DYNAMIC,
-                             'filters'   => json_encode([
-                                                         'search_role_level' => ZendAfi_Acl_AdminControllerRoles::ABONNE_SIGB,
-                                                         'search_valid_subscription' => 1]),
-
-                             'rights' => [Class_UserGroup::RIGHT_ACCES_PNB_DILICOM]]);
-
-    $this->logged_user = $this
-      ->fixture('Class_Users',
-                ['id' => 6,
-                 'nom'=>'Pito',
-                 'login'=>'Chat',
-                 'password'=>'123456',
-                 'id_site' => 1,
-                 'int_bib' => $this->fixture('Class_IntBib',
-                                             ['id' => 1,
-                                              'comm_sigb' => Class_IntBib::COM_ORPHEE,
-                                              'comm_params' => ['url_serveur' => 'tests/fixtures/orphee.wsdl',
-                                                                'allow_hold_available_items' => true]]),
-                 'idabon' => '12345',
-                ]);
-
-    Class_WebService_SIGB_Orphee::setService($this->mock()
-                                             ->whenCalled('isConnected')->answers(true)
-                                             ->whenCalled('getEmprunteur')
-                                             ->answers(Class_WebService_SIGB_Emprunteur::nullInstance()->beBlocked())
-    );
-
-    $this->logged_user->beAbonneSIGB()->assertSave();
-    ZendAfi_Auth::getInstance()->logUser($this->logged_user);
-
-    $this->fixture('Class_Loan_Pnb', ['id' => 1,
-                                      'record_origin_id' => 'Dilicom-88817216',
-                                      'user_id' => '6']);
-
-
-    $this->_html = $this->_helper->renderAlbum($this->book);
-  }
-
-
-  public function tearDown() {
-    unset($_SERVER['HTTPS']);
-    Class_WebService_SIGB_Orphee::setService(null);
-
-    parent::tearDown();
-  }
-
-
-  /** @test */
-  public function htmlShouldContainsIFrameOnEdenBook() {
-    $this->assertXPath($this->_html,
-                       '//iframe[@src="http://www.edenlivres.fr/p/23416"][@width="100%"][@height="600px"]',
-                       $this->_html);
-  }
-
-
-  /** @test */
-  public function htmlShouldContainsNotAuthorizedMessage() {
-    $this->assertXPathContentContains($this->_html, '//div', 'Vous n\'avez pas le droit');
-  }
-}
-
-
-
-
-class PnbDilicomViewHelperRenderAlbumPNBGetLoanStatusTest extends PnbDilicomViewHelperRenderAlbumTestCase {
-
-  public function setUp() {
-    parent::setUp();
-    $this->fixture('Class_Bib', ['id' => 1,
-                                 'libelle' => 'Annecy',
-                                 'gln' => '333']);
-
-    $group =$this->fixture('Class_UserGroup',
-                           ['id' => '20',
-                            'libelle' => 'Multimedia',
-                            'rights' => [Class_UserGroup::RIGHT_ACCES_PNB_DILICOM]]);
-
-    $this->logged_user = $this->fixture('Class_Users',
-                                        ['id' => 6,
-                                         'nom'=>'Pito',
-                                         'login'=>'Chat',
-                                         'password'=>'123456',
-                                         'id_site' => 1,
-                                         'idabon' => '12345',
-                                         'user_groups' => [$group]]);
-
-    $this->logged_user->beAbonneSIGB()->assertSave();
-    ZendAfi_Auth::getInstance()->logUser($this->logged_user);
-
-
-    $this->other_user = $this->fixture('Class_Users',
-                                        ['id' => 7,
-                                         'nom'=>'Boum',
-                                         'login'=>'Baia',
-                                         'password'=>'9876',
-                                         'id_site' => 1,
-                                         'idabon' => '9876',
-                                         'user_groups' => [$group]]);
-
-    $this->other_user->beAbonneSIGB()->assertSave();
-  }
-
-
-  /** @test */
-  public function htmlShouldContainsRessourceNotAvailable() {
-    Class_Album_UsageConstraint::find(2)->setOrderDate('1900-05-02 14:14:14')->assertSave();
-    $this->_html = $this->_helper->renderAlbum($this->book);
-
-    $this->assertXPathContentContains($this->_html,
-                                      '//div//span[@class="error"]',
-                                      'La ressource n\'est plus disponible.');
-  }
-
-
-  /** @test */
-  public function htmlShouldContainsQuotaEmpty() {
-    $this->_http
-      ->whenCalled('open_url')
-      ->answers('');
-
-    Class_AdminVar::set('DILICOM_PNB_MAX_LOAN_PER_USER', 3);
-
-    foreach(range(1, 3) as $step)
-      $this->fixture('Class_Loan_Pnb',
-                     ['id' => $step,
-                      'user_id' => $this->logged_user->getId(),
-                      'record_origin_id' => $step,
-                      'expected_return_date' => '2022-06-01']);
-
-    $this->_html = $this->_helper->renderAlbum($this->book);
-
-    $this->assertXPathContentContains($this->_html,
-                                      '//div//span[@class="error"]',
-                                      'Emprunt impossible. Vous avez atteint votre quota de 3 emprunts');
-  }
-
-
-  /** @test */
-  public function withLoanCountTreeAndLoanCountLimitReachedHtmlShouldContainsNextAvailableLoanDate() {
-    Class_Album_UsageConstraint::find(1)->setMaxNumberOfUsers(5)->assertSave();
-    $this->_http
-      ->whenCalled('open_url')
-      ->answers(DilicomFixtures::getLoanStatusResponseAvailableUsersAndQuantityLeft(2, 24));
-    // ^ so current loan count = (5 max users - 2 loans available) = 3
-
-    Class_AdminVar::set('DILICOM_PNB_LOAN_COUNT_LIMIT', 1);
-    $this->fixture('Class_Loan_Pnb',
-                   ['id' => 1,
-                    'user_id' => $this->other_user->getId(),
-                    'record_origin_id' => 'Dilicom-88817216',
-                    'order_line_id' => 'x321',
-                    'expected_return_date' => '2022-06-01 20:10:00']);
-
-    $this->assertXPathContentContains($this->_helper->renderAlbum($this->book),
-                                      '//div//span[@class="error"]',
-                                      utf8_encode('Emprunt impossible. Le nombre d\'emprunts simultanés pour ce document est atteint. Le prochain emprunt sera possible le mercredi 01 juin à 20h10'));
-  }
-
-
-  /** @test */
-  public function withLoanCountOneAndOneActiveHoldsShouldContainsDocumentAlreadyHeld() {
-    Class_Album_UsageConstraint::find(1)->setMaxNumberOfUsers(5)->assertSave();
-    $this->_http
-      ->whenCalled('open_url')
-      ->answers(DilicomFixtures::getLoanStatusResponseAvailableUsersAndQuantityLeft(3, 24));
-    // ^ current loan count = (5 max users - 3 loans available) = 2
-
-    Class_AdminVar::set('DILICOM_PNB_LOAN_COUNT_LIMIT', 3);
-
-    $this->fixture('Class_Hold_Pnb',
-                   ['id' => 1,
-                    'user_id' => 876,
-                    'record_origin_id' => $this->book->getIdOrigine(),
-                    'hold_date' => '2014-04-25 14:14:14']);
-
-    $this->assertXPathContentContains($this->_helper->renderAlbum($this->book),
-                                      '//div//span[@class="error"]',
-                                      utf8_encode('Emprunt impossible. Ce document est déjà réservé'));
-  }
-
-
-  /** @test */
-  public function withLoanCountOneAndOneActiveHoldForCurrentUserShouldContainsLoanButton() {
-    Class_Album_UsageConstraint::find(1)->setMaxNumberOfUsers(5)->assertSave();
-    $this->_http
-      ->whenCalled('open_url')
-      ->answers(DilicomFixtures::getLoanStatusResponseAvailableUsersAndQuantityLeft(3, 24));
-    // ^ current loan count = (5 max users - 3 loans available) = 2
-
-    Class_AdminVar::set('DILICOM_PNB_LOAN_COUNT_LIMIT', 3);
-
-    $this->fixture('Class_Hold_Pnb',
-                   ['id' => 1,
-                    'user_id' => Class_Users::getIdentity()->getId(),
-                    'record_origin_id' => $this->book->getIdOrigine(),
-                    'hold_date' => '2014-04-25 14:14:14']);
-
-    $this->assertXPathContentContains($this->_helper->renderAlbum($this->book),
-                                      '//div//a',
-                                      utf8_encode('Emprunter le livre au format EPUB'));
-  }
-
-
-
-  /** @test */
-  public function withLoanCountOneAndOneExpiredHoldsShouldContainsLoanButton() {
-    Class_Album_UsageConstraint::find(1)->setMaxNumberOfUsers(5)->assertSave();
-    $this->_http
-      ->whenCalled('open_url')
-      ->answers(DilicomFixtures::getLoanStatusResponseAvailableUsersAndQuantityLeft(3, 24));
-    // ^ current loan count = (5 max users - 3 loans available) = 2
-
-    Class_AdminVar::set('DILICOM_PNB_LOAN_COUNT_LIMIT', 3);
-
-    $this->fixture('Class_Hold_Pnb',
-                   ['id' => 1,
-                    'user_id' => 876,
-                    'record_origin_id' => $this->book->getIdOrigine(),
-                    'hold_date' => '2014-04-25 14:14:14',
-                    'expiration_date' => '2014-04-26 14:14:14']);
-
-    $this->assertXPathContentContains($this->_helper->renderAlbum($this->book),
-                                      '//div//a',
-                                      utf8_encode('Emprunter le livre au format EPUB'));
-  }
-
-
-  /** @test */
-  public function withoutLoanAndThreeActiveHoldsAndAllocatedHolderShouldContainsLoanButton() {
-    Class_Album_UsageConstraint::find(1)->setMaxNumberOfUsers(1)->assertSave();
-    $this->_http
-      ->whenCalled('open_url')
-      ->answers(DilicomFixtures::getLoanStatusResponseAvailableUsersAndQuantityLeft(1, 1));
-
-    Class_AdminVar::set('DILICOM_PNB_LOAN_COUNT_LIMIT', 3);
-
-    $this->fixture('Class_Hold_Pnb',
-                   ['id' => 1,
-                    'user_id' => Class_Users::getIdentity()->getId(),
-                    'record_origin_id' => $this->book->getIdOrigine(),
-                    'hold_date' => '2014-04-25 14:14:14',
-                    'expiration_date' => '2014-05-05 23:59:59']);
-
-    $this->fixture('Class_Hold_Pnb',
-                   ['id' => 2,
-                    'user_id' => Class_Users::getIdentity()->getId() + 1,
-                    'record_origin_id' => $this->book->getIdOrigine(),
-                    'hold_date' => '2014-04-25 14:15:14']);
-
-    $this->fixture('Class_Hold_Pnb',
-                   ['id' => 3,
-                    'user_id' => Class_Users::getIdentity()->getId() + 2,
-                    'record_origin_id' => $this->book->getIdOrigine(),
-                    'hold_date' => '2014-04-25 14:16:14']);
-
-    $this->assertXPathContentContains($this->_helper->renderAlbum($this->book),
-                                      '//div//a',
-                                      utf8_encode('Emprunter le livre au format EPUB'));
-  }
-
-
-  /** @test */
-  public function withSimultaneousLoanLimitReachedButCurrentlyLoanedByCurrentUserHtmlShouldContainsButtonToLoadAgain() {
-    Class_Album_UsageConstraint::find(1)->setMaxNumberOfUsers(0)->assertSave();
-    Class_AdminVar::set('DILICOM_PNB_LOAN_COUNT_LIMIT',0);
-    $this->fixture('Class_Loan_Pnb',
-                   ['id' => 1,
-                    'user_id' => $this->logged_user->getId(),
-                    'record_origin_id' => 'Dilicom-88817216',
-                    'order_line_id' => 'x321',
-                    'expected_return_date' => '2025-06-01 20:10:00',
-                   'loan_link' => 'https://pnb-dilicom.centprod.com/v3//link/xxx.do']);
-
-    $this->_html = $this->_helper->renderAlbum($this->book);
-
-    $this->assertXPath($this->_html,
-                       '//a[contains(@href, "/bib-numerique/loan-book-ajax/id/3")]',
-                       $this->_html);
-  }
-
-
-  /** @test */
-  public function onUnknownReturnDateHtmlShouldNotContainsNextAvailableLoanDate() {
-    Class_Album_UsageConstraint::find(1)->setMaxNumberOfUsers(0)->assertSave();
-    Class_AdminVar::set('DILICOM_PNB_LOAN_COUNT_LIMIT',0);
-    $this->fixture('Class_Loan_Pnb',
-                   ['id' => 1,
-                    'user_id' => $this->logged_user->getId(),
-                    'record_origin_id' => 1,
-                    'order_line_id' => '???',
-                    'expected_return_date' => '2022-06-01 20:10:00']);
-
-    $this->_html = $this->_helper->renderAlbum($this->book);
-
-    $this->assertNotXPathContentContains($this->_html,
-                                         '//div//span[@class="error"]',
-                                         utf8_encode('Le prochain emprunt sera possible'));
-  }
-}
-
-
-
-
 class PnbDilicomBibNumeriqueControllerBlockedUserTest extends AbstractControllerTestCase {
-
   protected
     $_http,
     $_book,
     $_time_source,
     $_storm_default_to_volatile = true;
 
-
   public function setUp() {
     parent::setUp();
 
@@ -4736,5 +4211,4 @@ class PnbDilicomBatchProcessHoldsWithThreeLoansAndOnlyTwoHoldsAllocableTest exte
     $this->assertEquals('ridley@localhost.localdomain.com',
                         $this->_sent_mails[0]->getFrom());
   }
-
 }
diff --git a/tests/scenarios/PnbDilicom/PnbDilicomViewHelperTest.php b/tests/scenarios/PnbDilicom/PnbDilicomViewHelperTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c4ab89022664589f8dbaae23a95059bc23d07f47
--- /dev/null
+++ b/tests/scenarios/PnbDilicom/PnbDilicomViewHelperTest.php
@@ -0,0 +1,577 @@
+<?php
+/**
+ * Copyright (c) 2012-2020, 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
+ */
+
+require_once 'tests/fixtures/DilicomFixtures.php';
+
+abstract class PnbDilicomViewHelperRenderAlbumTestCase extends ViewHelperTestCase {
+
+  protected $_storm_default_to_volatile = true,
+    $_helper,
+    $_html;
+
+  public function setUp() {
+    parent::setUp();
+
+    $view = new ZendAfi_Controller_Action_Helper_View();
+    $this->_helper = new ZendAfi_View_Helper_RenderAlbum();
+    $this->_helper->setView($view);
+
+    $this->book = (new DilicomFixtures())->albumTotemThora();
+    RessourcesNumeriquesFixtures::activateDilicom();
+
+    $this->_http = $this->mock();
+    Class_WebService_BibNumerique_Dilicom_Hub::setDefaultHttpClient($this->_http);
+
+    $this->_time_source = new TimeSourceForTest('2014-05-02 14:14:14');
+    Class_WebService_BibNumerique_Dilicom_Hub::setTimeSource($this->_time_source);
+    Class_Album_UsageConstraint::setTimeSource($this->_time_source);
+    Class_Hold_Pnb::setTimeSource($this->_time_source);
+
+    $this->_http
+      ->whenCalled('setAuth')
+      ->answers(null)
+
+      ->whenCalled('open_url')
+      ->answers(DilicomFixtures::getLoanStatusResponseAvailableUsersAndQuantityLeft(5, 24));
+
+  }
+
+
+  public function tearDown() {
+    ZendAfi_Auth::getInstance()->clearIdentity();
+    Class_WebService_BibNumerique_Dilicom_Hub::setTimeSource(null);
+    Class_Album_UsageConstraint::setTimeSource(null);
+    Class_Hold_Pnb::setTimeSource(null);
+    parent::tearDown();
+  }
+}
+
+
+
+
+class PnbDilicomViewHelperRenderAlbumNotLoggedTest
+  extends PnbDilicomViewHelperRenderAlbumTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    ZendAfi_Auth::getInstance()->clearIdentity();
+    $this->_html = $this->_helper->renderAlbum($this->book);
+  }
+
+
+  /** @test */
+  public function htmlShouldNotContainsLinkToConsultBook() {
+    $this->assertXPathContentContains($this->_html,
+                                      '//a[contains(@href, "/bib-numerique/consult-book-ajax/id/3")]',
+                                      'Consulter le livre en ligne');
+  }
+}
+
+
+
+
+class PnbDilicomViewHelperRenderAlbumLoggedButNotAuthorizeTest
+  extends PnbDilicomViewHelperRenderAlbumTestCase {
+
+  public function setUp() {
+    parent::setUp();
+    $this->logged_user = $this->fixture('Class_Users',
+                                        ['id' => 6,
+                                         'nom'=>'Pito',
+                                         'login'=>'Chat',
+                                         'password'=>'123456',
+                                         'id_site' => 1,
+                                         'idabon' => '12345']);
+
+    $this->logged_user->setUserGroups([]);
+    ZendAfi_Auth::getInstance()->logUser($this->logged_user);
+    $this->_html = $this->_helper->renderAlbum($this->book);
+  }
+
+
+  /** @test */
+  public function htmlShouldNotContainsLinkToConsultBook() {
+    $this->assertXPathContentContains($this->_html,
+                                      '//p',utf8_encode("Vous n'avez pas le droit d'accéder à la consultation en ligne."));
+  }
+}
+
+
+
+
+class PnbDilicomViewHelperRenderAlbumLoggedAndAuthorizedTest
+  extends PnbDilicomViewHelperRenderAlbumTestCase {
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture('Class_Bib', ['id' => 1,
+                                 'libelle' => 'Annecy',
+                                 'gln' => '333']);
+
+    $this->logged_user = $this->fixture('Class_Users',
+                                        ['id' => 6,
+                                         'nom'=>'Pito',
+                                         'login'=>'Chat',
+                                         'password'=>'123456',
+                                         'id_site' => 1,
+                                         'idabon' => '12345',
+                                         'user_groups' => [$this->fixture('Class_UserGroup',
+                                                                          ['id' => '20',
+                                                                           'libelle' => 'Multimedia',
+                                                                           'rights' => [Class_UserGroup::RIGHT_ACCES_PNB_DILICOM]])]]);
+
+    $this->logged_user->beAbonneSIGB()->assertSave();
+    ZendAfi_Auth::getInstance()->logUser($this->logged_user);
+
+    $this->fixture('Class_Loan_Pnb', ['id' => 1,
+                                      'record_origin_id' => 'Dilicom-88817216',
+                                      'user_id' => '6']);
+
+    Class_AdminVar::set('DILICOM_PNB_ENABLE_HOLDS', '1');
+    $this->_html = $this->_helper->renderAlbum($this->book);
+  }
+
+
+  public function tearDown() {
+    unset($_SERVER['HTTPS']);
+    parent::tearDown();
+  }
+
+
+  /** @test */
+  public function htmlShouldContainsIFrameOnEdenBook() {
+    $this->assertXPath($this->_html,
+                       '//iframe[@src="http://www.edenlivres.fr/p/23416"][@width="100%"][@height="600px"]',
+                       $this->_html);
+  }
+
+
+  /** @test */
+  public function htmlShouldContainsLinkToConsultBook() {
+    $this->assertXPathContentContains($this->_html,
+                                      '//a[contains(@href, "/bib-numerique/consult-book-ajax/id/3")]',
+                                      'Consulter le livre en ligne');
+  }
+
+
+  /** @test */
+  public function htmlShouldContainsLinkToLoanBook() {
+    $this->assertXPathContentContains($this->_html,
+                                      '//a[contains(@href, "/bib-numerique/loan-book-ajax/id/3")]',
+                                      'Emprunter le livre au format EPUB');
+  }
+
+
+  /** @test */
+  public function htmlShouldNotContainsHoldBookLink() {
+    $this->assertNotXPath($this->_html,
+                          '//a[contains(@href, "/hold-book")]');
+  }
+
+
+  /** @test */
+  public function htmlShouldNotContainsReservationImpossible() {
+    $this->assertNotXPathContentContains($this->_html,
+                                         '//span',
+                                         utf8_encode('Réservation impossible'),
+                                         $this->_html);
+  }
+
+
+  /** @test */
+  public function bibWithoutGlnShouldReturnErrorMessage() {
+    Class_Bib::find(1)->setGln('')->assertSave();
+    $this->_html = $this->_helper->renderAlbum($this->book);
+    $this->assertXPathContentContains($this->_html,
+                                      '//p', utf8_encode('Annecy n\'a pas accès à la consultation en ligne'));
+  }
+
+
+  /** @test */
+  public function userWithoutBibShouldReturnErrorMessage() {
+    $this->logged_user->setBib(null)->save();
+    $this->_html = $this->_helper->renderAlbum($this->book);
+    $this->assertXPathContentContains($this->_html,
+                                      '//p', utf8_encode('Vous devez être inscrit dans une bibliothèque pour accéder à la consultation en ligne'));
+
+  }
+
+  /** @test */
+  public function withHttpsPreviewSrcShouldBeHttps() {
+    $_SERVER['HTTPS'] = 'on';
+
+    $this->_html = $this->_helper->renderAlbum($this->book);
+    $this->assertXPath($this->_html,
+                       '//iframe[@src="https://www.edenlivres.fr/p/23416"][@width="100%"][@height="600px"]',
+                       $this->_html);
+  }
+}
+
+
+
+
+class PnbDilicomViewHelperRenderAlbumLoggedButBlockedTest
+  extends PnbDilicomViewHelperRenderAlbumTestCase {
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture('Class_Bib', ['id' => 1,
+                                 'libelle' => 'Annecy',
+                                 'gln' => '333']);
+
+    $group = $this->fixture('Class_UserGroup',
+                            ['id' => '20',
+                             'libelle' => 'Dilicom',
+                             'group_type' => Class_UserGroup::TYPE_DYNAMIC,
+                             'filters'   => json_encode([
+                                                         'search_role_level' => ZendAfi_Acl_AdminControllerRoles::ABONNE_SIGB,
+                                                         'search_valid_subscription' => 1]),
+
+                             'rights' => [Class_UserGroup::RIGHT_ACCES_PNB_DILICOM]]);
+
+    $this->logged_user = $this
+      ->fixture('Class_Users',
+                ['id' => 6,
+                 'nom'=>'Pito',
+                 'login'=>'Chat',
+                 'password'=>'123456',
+                 'id_site' => 1,
+                 'int_bib' => $this->fixture('Class_IntBib',
+                                             ['id' => 1,
+                                              'comm_sigb' => Class_IntBib::COM_ORPHEE,
+                                              'comm_params' => ['url_serveur' => 'tests/fixtures/orphee.wsdl',
+                                                                'allow_hold_available_items' => true]]),
+                 'idabon' => '12345',
+                ]);
+
+    Class_WebService_SIGB_Orphee::setService($this->mock()
+                                             ->whenCalled('isConnected')->answers(true)
+                                             ->whenCalled('getEmprunteur')
+                                             ->answers(Class_WebService_SIGB_Emprunteur::nullInstance()->beBlocked())
+    );
+
+    $this->logged_user->beAbonneSIGB()->assertSave();
+    ZendAfi_Auth::getInstance()->logUser($this->logged_user);
+
+    $this->fixture('Class_Loan_Pnb', ['id' => 1,
+                                      'record_origin_id' => 'Dilicom-88817216',
+                                      'user_id' => '6']);
+
+
+    $this->_html = $this->_helper->renderAlbum($this->book);
+  }
+
+
+  public function tearDown() {
+    unset($_SERVER['HTTPS']);
+    Class_WebService_SIGB_Orphee::setService(null);
+
+    parent::tearDown();
+  }
+
+
+  /** @test */
+  public function htmlShouldContainsIFrameOnEdenBook() {
+    $this->assertXPath($this->_html,
+                       '//iframe[@src="http://www.edenlivres.fr/p/23416"][@width="100%"][@height="600px"]',
+                       $this->_html);
+  }
+
+
+  /** @test */
+  public function htmlShouldContainsNotAuthorizedMessage() {
+    $this->assertXPathContentContains($this->_html, '//div', 'Vous n\'avez pas le droit');
+  }
+}
+
+
+
+
+class PnbDilicomViewHelperRenderAlbumGetLoanStatusTest
+  extends PnbDilicomViewHelperRenderAlbumTestCase {
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture('Class_Bib', ['id' => 1,
+                                 'libelle' => 'Annecy',
+                                 'gln' => '333']);
+
+    $group =$this->fixture('Class_UserGroup',
+                           ['id' => '20',
+                            'libelle' => 'Multimedia',
+                            'rights' => [Class_UserGroup::RIGHT_ACCES_PNB_DILICOM]]);
+
+    $this->logged_user = $this->fixture('Class_Users',
+                                        ['id' => 6,
+                                         'nom'=>'Pito',
+                                         'login'=>'Chat',
+                                         'password'=>'123456',
+                                         'id_site' => 1,
+                                         'idabon' => '12345',
+                                         'user_groups' => [$group]]);
+
+    $this->logged_user->beAbonneSIGB()->assertSave();
+    ZendAfi_Auth::getInstance()->logUser($this->logged_user);
+
+
+    $this->other_user = $this->fixture('Class_Users',
+                                        ['id' => 7,
+                                         'nom'=>'Boum',
+                                         'login'=>'Baia',
+                                         'password'=>'9876',
+                                         'id_site' => 1,
+                                         'idabon' => '9876',
+                                         'user_groups' => [$group]]);
+
+    $this->other_user->beAbonneSIGB()->assertSave();
+  }
+
+
+  /** @test */
+  public function htmlShouldContainsRessourceNotAvailable() {
+    Class_Album_UsageConstraint::find(2)->setOrderDate('1900-05-02 14:14:14')->assertSave();
+    $this->_html = $this->_helper->renderAlbum($this->book);
+
+    $this->assertXPathContentContains($this->_html,
+                                      '//div//span[@class="error"]',
+                                      'La ressource n\'est plus disponible.');
+  }
+
+
+  /** @test */
+  public function htmlShouldContainsQuotaEmpty() {
+    $this->_http
+      ->whenCalled('open_url')
+      ->answers('');
+
+    Class_AdminVar::set('DILICOM_PNB_MAX_LOAN_PER_USER', 3);
+
+    foreach(range(1, 3) as $step)
+      $this->fixture('Class_Loan_Pnb',
+                     ['id' => $step,
+                      'user_id' => $this->logged_user->getId(),
+                      'record_origin_id' => $step,
+                      'expected_return_date' => '2022-06-01']);
+
+    $this->_html = $this->_helper->renderAlbum($this->book);
+
+    $this->assertXPathContentContains($this->_html,
+                                      '//div//span[@class="error"]',
+                                      'Emprunt impossible. Vous avez atteint votre quota de 3 emprunts');
+  }
+
+
+  /** @test */
+  public function withLoanCountTreeAndLoanCountLimitReachedHtmlShouldContainsNextAvailableLoanDate() {
+    Class_Album_UsageConstraint::find(1)->setMaxNumberOfUsers(5)->assertSave();
+    $this->_http
+      ->whenCalled('open_url')
+      ->answers(DilicomFixtures::getLoanStatusResponseAvailableUsersAndQuantityLeft(2, 24));
+    // ^ so current loan count = (5 max users - 2 loans available) = 3
+
+    Class_AdminVar::set('DILICOM_PNB_LOAN_COUNT_LIMIT', 1);
+    $this->fixture('Class_Loan_Pnb',
+                   ['id' => 1,
+                    'user_id' => $this->other_user->getId(),
+                    'record_origin_id' => 'Dilicom-88817216',
+                    'order_line_id' => 'x321',
+                    'expected_return_date' => '2022-06-01 20:10:00']);
+
+    $this->assertXPathContentContains($this->_helper->renderAlbum($this->book),
+                                      '//div//span[@class="error"]',
+                                      utf8_encode('Emprunt impossible. Le nombre d\'emprunts simultanés pour ce document est atteint. Le prochain emprunt sera possible le mercredi 01 juin à 20h10'));
+  }
+
+
+  /** @test */
+  public function withLoanCountOneAndOneActiveHoldsShouldContainsDocumentAlreadyHeld() {
+    Class_Album_UsageConstraint::find(1)->setMaxNumberOfUsers(5)->assertSave();
+    $this->_http
+      ->whenCalled('open_url')
+      ->answers(DilicomFixtures::getLoanStatusResponseAvailableUsersAndQuantityLeft(3, 24));
+    // ^ current loan count = (5 max users - 3 loans available) = 2
+
+    Class_AdminVar::set('DILICOM_PNB_LOAN_COUNT_LIMIT', 3);
+
+    $this->fixture('Class_Hold_Pnb',
+                   ['id' => 1,
+                    'user_id' => 876,
+                    'record_origin_id' => $this->book->getIdOrigine(),
+                    'hold_date' => '2014-04-25 14:14:14']);
+
+    $this->assertXPathContentContains($this->_helper->renderAlbum($this->book),
+                                      '//div//span[@class="error"]',
+                                      utf8_encode('Emprunt impossible. Ce document est déjà réservé'));
+  }
+
+
+  /** @test */
+  public function withLoanCountOneAndOneActiveHoldForCurrentUserShouldContainsLoanButton() {
+    Class_Album_UsageConstraint::find(1)->setMaxNumberOfUsers(5)->assertSave();
+    $this->_http
+      ->whenCalled('open_url')
+      ->answers(DilicomFixtures::getLoanStatusResponseAvailableUsersAndQuantityLeft(3, 24));
+    // ^ current loan count = (5 max users - 3 loans available) = 2
+
+    Class_AdminVar::set('DILICOM_PNB_LOAN_COUNT_LIMIT', 3);
+
+    $this->fixture('Class_Hold_Pnb',
+                   ['id' => 1,
+                    'user_id' => Class_Users::getIdentity()->getId(),
+                    'record_origin_id' => $this->book->getIdOrigine(),
+                    'hold_date' => '2014-04-25 14:14:14']);
+
+    $this->assertXPathContentContains($this->_helper->renderAlbum($this->book),
+                                      '//div//a',
+                                      utf8_encode('Emprunter le livre au format EPUB'));
+  }
+
+
+
+  /** @test */
+  public function withLoanCountOneAndOneExpiredHoldsShouldContainsLoanButton() {
+    Class_Album_UsageConstraint::find(1)->setMaxNumberOfUsers(5)->assertSave();
+    $this->_http
+      ->whenCalled('open_url')
+      ->answers(DilicomFixtures::getLoanStatusResponseAvailableUsersAndQuantityLeft(3, 24));
+    // ^ current loan count = (5 max users - 3 loans available) = 2
+
+    Class_AdminVar::set('DILICOM_PNB_LOAN_COUNT_LIMIT', 3);
+
+    $this->fixture('Class_Hold_Pnb',
+                   ['id' => 1,
+                    'user_id' => 876,
+                    'record_origin_id' => $this->book->getIdOrigine(),
+                    'hold_date' => '2014-04-25 14:14:14',
+                    'expiration_date' => '2014-04-26 14:14:14']);
+
+    $this->assertXPathContentContains($this->_helper->renderAlbum($this->book),
+                                      '//div//a',
+                                      utf8_encode('Emprunter le livre au format EPUB'));
+  }
+
+
+  /** @test */
+  public function withoutLoanAndThreeActiveHoldsAndAllocatedHolderShouldContainsLoanButton() {
+    Class_Album_UsageConstraint::find(1)->setMaxNumberOfUsers(1)->assertSave();
+    $this->_http
+      ->whenCalled('open_url')
+      ->answers(DilicomFixtures::getLoanStatusResponseAvailableUsersAndQuantityLeft(1, 1));
+
+    Class_AdminVar::set('DILICOM_PNB_LOAN_COUNT_LIMIT', 3);
+
+    $this->fixture('Class_Hold_Pnb',
+                   ['id' => 1,
+                    'user_id' => Class_Users::getIdentity()->getId(),
+                    'record_origin_id' => $this->book->getIdOrigine(),
+                    'hold_date' => '2014-04-25 14:14:14',
+                    'expiration_date' => '2014-05-05 23:59:59']);
+
+    $this->fixture('Class_Hold_Pnb',
+                   ['id' => 2,
+                    'user_id' => Class_Users::getIdentity()->getId() + 1,
+                    'record_origin_id' => $this->book->getIdOrigine(),
+                    'hold_date' => '2014-04-25 14:15:14']);
+
+    $this->fixture('Class_Hold_Pnb',
+                   ['id' => 3,
+                    'user_id' => Class_Users::getIdentity()->getId() + 2,
+                    'record_origin_id' => $this->book->getIdOrigine(),
+                    'hold_date' => '2014-04-25 14:16:14']);
+
+    $this->assertXPathContentContains($this->_helper->renderAlbum($this->book),
+                                      '//div//a',
+                                      utf8_encode('Emprunter le livre au format EPUB'));
+  }
+
+
+  /** @test */
+  public function withSimultaneousLoanLimitReachedButCurrentlyLoanedByCurrentUserHtmlShouldContainsButtonToLoadAgain() {
+    Class_Album_UsageConstraint::find(1)->setMaxNumberOfUsers(0)->assertSave();
+    Class_AdminVar::set('DILICOM_PNB_LOAN_COUNT_LIMIT',0);
+    $this->fixture('Class_Loan_Pnb',
+                   ['id' => 1,
+                    'user_id' => $this->logged_user->getId(),
+                    'record_origin_id' => 'Dilicom-88817216',
+                    'order_line_id' => 'x321',
+                    'expected_return_date' => '2025-06-01 20:10:00',
+                   'loan_link' => 'https://pnb-dilicom.centprod.com/v3//link/xxx.do']);
+
+    $this->_html = $this->_helper->renderAlbum($this->book);
+
+    $this->assertXPath($this->_html,
+                       '//a[contains(@href, "/bib-numerique/loan-book-ajax/id/3")]',
+                       $this->_html);
+  }
+
+
+  /** @test */
+  public function onUnknownReturnDateHtmlShouldNotContainsNextAvailableLoanDate() {
+    Class_Album_UsageConstraint::find(1)->setMaxNumberOfUsers(0)->assertSave();
+    Class_AdminVar::set('DILICOM_PNB_LOAN_COUNT_LIMIT',0);
+    $this->fixture('Class_Loan_Pnb',
+                   ['id' => 1,
+                    'user_id' => $this->logged_user->getId(),
+                    'record_origin_id' => 1,
+                    'order_line_id' => '???',
+                    'expected_return_date' => '2022-06-01 20:10:00']);
+
+    $this->_html = $this->_helper->renderAlbum($this->book);
+
+    $this->assertNotXPathContentContains($this->_html,
+                                         '//div//span[@class="error"]',
+                                         utf8_encode('Le prochain emprunt sera possible'));
+  }
+
+
+  /**
+   * @test
+   * @see http://forge.afi-sa.fr/issues/109494
+   */
+  public function withLoanStatusCancelledQuantityShouldNotBeUpdated() {
+    $item = Class_Album_Item::find(1);
+    $item
+      ->setLoanCount(0)
+      ->setQuantity(0)
+      ->assertSave();
+
+    $this->_http
+      ->whenCalled('open_url')
+      ->answers(DilicomFixtures::getLoanStatusCancelledResponse('x321'));
+
+    $this->_helper->renderAlbum($this->book);
+
+    $this->assertEquals(0, $item->getQuantity());
+    return $item;
+  }
+
+
+  /**
+   * @test
+   * @depends withLoanStatusCancelledQuantityShouldNotBeUpdated
+   */
+  public function withLoanStatusCancelledLoanCountShouldNotBeUpdated($item) {
+    $this->assertEquals(0, $item->getLoanCount());
+  }
+}
diff --git a/tests/scenarios/Templates/TemplatesSearchTest.php b/tests/scenarios/Templates/TemplatesSearchTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2580d03bb04eec820fd77da74ce53f95b72fbdab
--- /dev/null
+++ b/tests/scenarios/Templates/TemplatesSearchTest.php
@@ -0,0 +1,384 @@
+<?php
+/**
+ * Copyright (c) 2012-2020, 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
+ */
+
+require_once 'TemplatesTest.php';
+
+abstract class TemplatesSearchWithSortParameterInWidgetTesCase  extends Admin_AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->_buildTemplateProfil(['id' => 1,
+                                 'libelle' => 'My search page'])
+         ->setBoiteOfTypeInDivision(1,
+                                    Intonation_Library_Widget_Search_Definition::CODE,
+                                    ['tri' => Class_CriteresRecherche::SORT_NOVELTY_DESC,
+                                     'placeholder' => 'Pomme, poire'])
+         ->assertSave();
+  }
+}
+
+
+
+class TemplatesSearchWithSortParameterInWidgetFromIndexPageTest extends TemplatesSearchWithSortParameterInWidgetTesCase {
+  public function setUp() {
+    parent::setUp();
+    $this->dispatch('/');
+  }
+
+
+  /** @test */
+  public function pageShouldContainsSearchWidget() {
+    $this->assertXPath('//div[contains(@class, "boite rech_simple")]');
+  }
+
+
+  /** @test */
+  public function expressionRecherchePlaceHolderShouldBePommePoire() {
+    $this->assertXPath('//input[@name="expressionRecherche"][@placeholder="Pomme, poire"]');
+  }
+
+
+  /** @test */
+  public function formShouldContainsHiddenInputTriWithValueDateCreationAscAlphaTitreAsc() {
+    $this->assertXPath('//form//input[@type="hidden"][@name="tri"][@value="date_creation desc, alpha_titre asc"]');
+  }
+}
+
+
+
+
+class TemplatesSearchWithSortParameterInWidgetFromSearchPageWithTriParamTest extends TemplatesSearchWithSortParameterInWidgetTesCase {
+  public function setUp() {
+    parent::setUp();
+    $this->dispatch('/recherche/simple/expressionRecherche/poire/tri/alpha_auteur+desc');
+  }
+
+
+  /** @test */
+  public function formShouldContainsHiddenInputTriWithValueAlphaTitre() {
+    $this->assertXPath('//form//input[@type="hidden"][@name="tri"][@value="alpha_auteur desc"]');
+  }
+}
+
+
+
+
+class TemplatesDispatchIntonationSearchTest extends TemplatesIntonationTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $this->dispatch('/opac/recherche/simple/expressionRecherche/pomme/id_profil/72/multifacets/T1-Y1/facette/Y1/section/1', true);
+  }
+
+
+  /** @test */
+  public function searchResultShouldBeDisplay() {
+    $this->assertXPathContentContains('//h1', 'Résultats pour pomme');
+  }
+
+
+  public function adminNavShouldBePresent() {
+    $this->assertXPath('//div[contains(@class, "menu_admin")]');
+  }
+
+
+  /** @test */
+  public function footerShouldBePresent() {
+    $this->assertXPath('//body//footer');
+  }
+
+
+  /** @test */
+  public function breadcrumbShouldBePresent() {
+    $this->assertXPath('//ol[@class="breadcrumb"]');
+  }
+
+
+  /** @test */
+  public function navShouldBePresent() {
+    $this->assertXPath('//body//nav[contains(@class, "navbar")][@role="navigation"]');
+  }
+
+
+  /** @test */
+  public function widgetInMainSectionShouldNotBeVisible() {
+    $this->assertNotXPath('//main//section//div[contains(@class, "card widget")]');
+  }
+
+
+  /** @test */
+  public function currentProfilTemplateShouldBeIntonation() {
+    $this->assertEquals('INTONATION', Class_Profil::getCurrentProfil()->getTemplate());
+  }
+
+
+  /** @test */
+  public function linkToDeleteFacetShoulContainsMultifacetT3() {
+    $this->assertXPathContentContains('//div[@class="criteres_recherche"]//a[@href="/recherche/simple/expressionRecherche/pomme/multifacets/T1"]', 'Site:');
+  }
+}
+
+
+
+
+class TemplatesPostDispatchSearchWithCustomMultifactesTest extends AbstractControllerTestCase {
+  protected $_storm_default_to_volatile = true;
+
+  public function setUp() {
+    parent::setUp();
+    $this->postDispatch('/opac/recherche/simple/', ['custom_multifacets_annexe' => 'A1',
+                                                    'custom_multifacets_domains' => 'D1',
+                                                    'custom_multifacets_doctype' => ['T1','T2']]);
+  }
+
+  /** @test */
+  public function shouldRedirectToSimpleSearchWithMultifacets() {
+    $this->assertRedirectTo('/recherche/simple/multifacets/A1-D1-T1-T2');
+  }
+}
+
+
+
+
+class TemplatesSearchViewRecordTest extends TemplatesIntonationTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $conf = (new Class_Systeme_Widget_Action)
+      ->setId('recherche_viewnotice_1')
+      ->setProfileId(72)
+      ->load();
+
+    $conf
+      ->setNewDatas(['IntonationIcoAllRecordData' => 'https://ma.super-ico.afi-sa.fr',
+                     'IntonationLabelAllRecordData' => 'Tout savoir',
+                     'IntonationTitleAllRecordData' => 'Tout savoir sur la notice'])
+      ->updateProfile();
+
+    Class_Profil::clearCache();
+
+    $this->fixture('Class_CodifGenre',
+                   ['id' => 13,
+                    'libelle' => 'Roman']);
+
+    $this->fixture('Class_CodifMatiere',
+                   ['id' => 12,
+                    'libelle' => 'Horreur']);
+
+    $this->fixture('Class_Notice',
+                   ['id' => 456,
+                    'type_doc' => 1,
+                    'date_creation' => date('Y-m-d', Class_Notice::getTimeSource()->time()),
+                    'titre_principal' => 'Psycho',
+                    'clef_oeuvre' => 'PSYKO',
+                    'clef_alpha' => 'PSYKO',
+                    'facettes' => 'G13 M12']);
+
+    $this->fixture('Class_TypeDoc',
+                   ['id' => 1,
+                    'label' => 'book']);
+
+    $this->fixture('Class_AvisNotice',
+                   ['id' => 178,
+                    'entete' => "Lost héighway",
+                    'clef_oeuvre' => 'PSYKO',
+                    'avis' => 'Oh po po !',
+                    'note' => 5,
+                    'date_avis' => '2015-03-18 13:00:00',
+                    'statut' => 1,
+                    'abon_ou_bib' => 1,
+                    'id_notice' => 456,
+                    'source_author' => null]);
+
+    $this->dispatch('/opac/recherche/viewnotice/id/456/id_profil/72');
+  }
+
+
+  /** @test */
+  public function dispatchViewRecordShouldDisplayPsycho() {
+    $this->assertXPathContentContains('//h1', 'Psycho');
+  }
+
+
+  /** @test */
+  public function shouldBeANovelty() {
+    $this->assertXPathContentContains('//a[contains(@href, "/nouveaute/1")]', 'Nouveauté');
+  }
+
+
+  /** @test */
+  public function ratingShouldBeDisplayed() {
+    $this->assertXPathContentContains('//div', 'Lost héighway');
+  }
+
+
+  /** @test */
+  public function ratingDateForLostHeighwayShouldBe20150318() {
+    $this->assertXPathContentContains('//div', '18 mars 2015');
+  }
+
+
+  /** @test */
+  public function badgesShouldContainsOneBorrowerReview() {
+    $this->assertXPathContentContains('//span[contains(@class, "badge")]', '1 avis abonné');
+  }
+
+
+  /** @test */
+  public function badgesShouldContainsTopicRoman() {
+    $this->assertXPathContentContains('//a[contains(@class, "badge")][contains(@href, "/recherche/simple")][contains(@href, "code_rebond/G13")]', 'Roman');
+  }
+
+
+  /** @test */
+  public function textareaShouldHaveClassFormControl() {
+    $this->assertXPath('//textarea[contains(@class, "form-control")]');
+  }
+
+
+  /** @test */
+  public function recordNavShouldContainsHomeLinkActive() {
+    $this->assertXPathContentContains('//ul[contains(@class, "nav")]//li//a[contains(@class, "active")][contains(@href, "recherche/viewnotice")]//div', 'Tout savoir');
+  }
+
+
+  /** @test */
+  public function recordNavHomeLinkShouldContainsIcoMaSuperIcoAndToutSavoirSurLaNoticeTitle() {
+    $this->assertXPath('//ul[contains(@class, "nav")]//li//a[contains(@class, "active")][contains(@href, "recherche/viewnotice")][@title="Tout savoir sur la notice"]//img[@src= "https://ma.super-ico.afi-sa.fr"]');
+  }
+}
+
+
+
+
+class TemplatesSearchRecordsTest extends TemplatesIntonationTestCase {
+  public function setUp() {
+    parent::setUp();
+    $this->fixture('Class_Notice',
+                   ['id' => 456,
+                    'titre_principal' => 'Psycho',
+                    'clef_oeuvre' => 'PSYKO',
+                    'facettes' => 'G13 M12']);
+
+    $this->dispatch('/opac/recherche/psyko/id_profil/72');
+  }
+
+
+  /** @test */
+  public function shouldDisplayResultsForPsycho() {
+    $this->assertXPathContentContains('//h1', 'Résultats pour psyko');
+  }
+}
+
+
+
+
+class TemplatesDispatchIntonationSearchListFormatWallTest extends TemplatesIntonationTestCase {
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture('Class_CodifAuteur',
+                   ['id' => 43,
+                    'libelle' => 'Pomme d\'API']);
+
+    $records = [$this->fixture('Class_Notice',
+                               ['id' => 89]),
+                $this->fixture('Class_Notice',
+                               ['id' => 99])];
+
+    $result = $this->mock();
+
+    $result
+      ->whenCalled('setDuration')
+      ->answers($result)
+
+      ->whenCalled('setSettings')
+      ->answers($result)
+
+      ->whenCalled('getSettings')
+      ->answers(['facettes' => ''])
+
+      ->whenCalled('fetchFacetsAndTags')
+      ->answers(['facettes' => '',
+                 'suggests' => [['id' => 'M87',
+                                 'label' => 'Pomme (sujet)'],
+
+                                ['id' => 'A43',
+                                 'label' => 'Pomme d\'API (auteur)']]])
+
+      ->whenCalled('getRecordsCount')
+      ->answers(2)
+
+      ->whenCalled('isError')
+      ->answers(false)
+
+      ->whenCalled('getCriteresRecherche')
+      ->answers((new Intonation_Library_Search_Criteria)->setParams(['liste_format' => 4]))
+
+      ->whenCalled('fetchRecords')
+      ->answers($records);
+
+    $engine = $this->mock()
+
+                   ->whenCalled('lancerRecherche')
+                   ->answers($result);
+
+    Class_MoteurRecherche::setInstance($engine);
+
+    (new Class_User_Settings(Class_Users::getIdentity()))->setSearchOrder(Class_CriteresRecherche::SORT_AUTHOR_DESC)->save();
+
+    $this->dispatch('/opac/recherche/simple/expressionRecherche/pomme/id_profil/72/liste_format/4/titre/Les documents', true);
+  }
+
+
+  /** @test */
+  public function searchResultOrderShouldBeAuthorDESC() {
+    $this->assertXPath('//select/option[@selected="selected"][@value="alpha_auteur desc"]');
+  }
+
+
+  /** @test */
+  public function searchResultShouldBeDisplay() {
+    $this->assertXPathContentContains('//h1', 'les documents');
+  }
+
+
+  /** @test */
+  public function buttonMurShouldBeActive() {
+    $this->assertXpath('//div//a[contains(@class, "active")][contains(@href, "/liste_format/4")]');
+  }
+
+
+  /** @test */
+  public function suggestionsShouldBeDisplay() {
+    $this->assertXPathContentContains('//b', 'Suggestions');
+  }
+
+
+  /** @test */
+  public function masonryShouldBeLoaded() {
+    $this->assertXPath('//head/script[contains(@src, "/masonry.js")]');
+  }
+}
+
+?>
\ No newline at end of file
diff --git a/tests/scenarios/Templates/TemplatesTest.php b/tests/scenarios/Templates/TemplatesTest.php
index ab30bcb6819b49dce594dbc5423234dcb27febde..f73f4aeaf02c63aee06ad8c84fb418a6954211be 100644
--- a/tests/scenarios/Templates/TemplatesTest.php
+++ b/tests/scenarios/Templates/TemplatesTest.php
@@ -826,64 +826,6 @@ class TemplatesDispatchIntonationWithSectionSettingsTest extends TemplatesIntona
 
 
 
-class TemplatesDispatchIntonationSearchTest extends TemplatesIntonationTestCase {
-  public function setUp() {
-    parent::setUp();
-
-    $this->dispatch('/opac/recherche/simple/expressionRecherche/pomme/id_profil/72/multifacets/T1-Y1/facette/Y1/section/1', true);
-  }
-
-
-  /** @test */
-  public function searchResultShouldBeDisplay() {
-    $this->assertXPathContentContains('//h1', 'Résultats pour pomme');
-  }
-
-
-  public function adminNavShouldBePresent() {
-    $this->assertXPath('//div[contains(@class, "menu_admin")]');
-  }
-
-
-  /** @test */
-  public function footerShouldBePresent() {
-    $this->assertXPath('//body//footer');
-  }
-
-
-  /** @test */
-  public function breadcrumbShouldBePresent() {
-    $this->assertXPath('//ol[@class="breadcrumb"]');
-  }
-
-
-  /** @test */
-  public function navShouldBePresent() {
-    $this->assertXPath('//body//nav[contains(@class, "navbar")][@role="navigation"]');
-  }
-
-
-  /** @test */
-  public function widgetInMainSectionShouldNotBeVisible() {
-    $this->assertNotXPath('//main//section//div[contains(@class, "card widget")]');
-  }
-
-
-  /** @test */
-  public function currentProfilTemplateShouldBeIntonation() {
-    $this->assertEquals('INTONATION', Class_Profil::getCurrentProfil()->getTemplate());
-  }
-
-
-  /** @test */
-  public function linkToDeleteFacetShoulContainsMultifacetT3() {
-    $this->assertXPathContentContains('//div[@class="criteres_recherche"]//a[@href="/recherche/simple/expressionRecherche/pomme/multifacets/T1"]', 'Site:');
-  }
-}
-
-
-
-
 class TemplatesEditTest extends TemplatesEnabledTestCase {
   protected $_storm_default_to_volatile = true;
 
@@ -1323,134 +1265,6 @@ class TemplatesILSBorrowerLoggedTest extends TemplatesIntonationTestCase {
 
 
 
-class TemplatesPostDispatchSearchWithCustomMultifactesTest extends AbstractControllerTestCase {
-  protected $_storm_default_to_volatile = true;
-
-  public function setUp() {
-    parent::setUp();
-    $this->postDispatch('/opac/recherche/simple/', ['custom_multifacets_annexe' => 'A1',
-                                                    'custom_multifacets_domains' => 'D1',
-                                                    'custom_multifacets_doctype' => ['T1','T2']]);
-  }
-
-  /** @test */
-  public function shouldRedirectToSimpleSearchWithMultifacets() {
-    $this->assertRedirectTo('/recherche/simple/multifacets/A1-D1-T1-T2');
-  }
-}
-
-
-
-
-class TemplatesViewRecordTest extends TemplatesIntonationTestCase {
-  public function setUp() {
-    parent::setUp();
-
-    $conf = (new Class_Systeme_Widget_Action)
-      ->setId('recherche_viewnotice_1')
-      ->setProfileId(72)
-      ->load();
-
-    $conf
-      ->setNewDatas(['IntonationIcoAllRecordData' => 'https://ma.super-ico.afi-sa.fr',
-                     'IntonationLabelAllRecordData' => 'Tout savoir',
-                     'IntonationTitleAllRecordData' => 'Tout savoir sur la notice'])
-      ->updateProfile();
-
-    Class_Profil::clearCache();
-
-    $this->fixture('Class_CodifGenre',
-                   ['id' => 13,
-                    'libelle' => 'Roman']);
-
-    $this->fixture('Class_CodifMatiere',
-                   ['id' => 12,
-                    'libelle' => 'Horreur']);
-
-    $this->fixture('Class_Notice',
-                   ['id' => 456,
-                    'type_doc' => 1,
-                    'date_creation' => date('Y-m-d', Class_Notice::getTimeSource()->time()),
-                    'titre_principal' => 'Psycho',
-                    'clef_oeuvre' => 'PSYKO',
-                    'clef_alpha' => 'PSYKO',
-                    'facettes' => 'G13 M12']);
-
-    $this->fixture('Class_TypeDoc',
-                   ['id' => 1,
-                    'label' => 'book']);
-
-    $this->fixture('Class_AvisNotice',
-                   ['id' => 178,
-                    'entete' => "Lost héighway",
-                    'clef_oeuvre' => 'PSYKO',
-                    'avis' => 'Oh po po !',
-                    'note' => 5,
-                    'date_avis' => '2015-03-18 13:00:00',
-                    'statut' => 1,
-                    'abon_ou_bib' => 1,
-                    'id_notice' => 456,
-                    'source_author' => null]);
-
-    $this->dispatch('/opac/recherche/viewnotice/id/456/id_profil/72');
-  }
-
-
-  /** @test */
-  public function dispatchViewRecordShouldDisplayPsycho() {
-    $this->assertXPathContentContains('//h1', 'Psycho');
-  }
-
-
-  /** @test */
-  public function shouldBeANovelty() {
-    $this->assertXPathContentContains('//a[contains(@href, "/nouveaute/1")]', 'Nouveauté');
-  }
-
-
-  /** @test */
-  public function ratingShouldBeDisplayed() {
-    $this->assertXPathContentContains('//div', 'Lost héighway');
-  }
-
-
-  /** @test */
-  public function ratingDateForLostHeighwayShouldBe20150318() {
-    $this->assertXPathContentContains('//div', '18 mars 2015');
-  }
-
-
-  /** @test */
-  public function badgesShouldContainsOneBorrowerReview() {
-    $this->assertXPathContentContains('//span[contains(@class, "badge")]', '1 avis abonné');
-  }
-
-
-  /** @test */
-  public function badgesShouldContainsTopicRoman() {
-    $this->assertXPathContentContains('//a[contains(@class, "badge")][contains(@href, "/recherche/simple")][contains(@href, "code_rebond/G13")]', 'Roman');
-  }
-
-
-  /** @test */
-  public function textareaShouldHaveClassFormControl() {
-    $this->assertXPath('//textarea[contains(@class, "form-control")]');
-  }
-
-
-  /** @test */
-  public function recordNavShouldContainsHomeLinkActive() {
-    $this->assertXPathContentContains('//ul[contains(@class, "nav")]//li//a[contains(@class, "active")][contains(@href, "recherche/viewnotice")]//div', 'Tout savoir');
-  }
-
-
-  /** @test */
-  public function recordNavHomeLinkShouldContainsIcoMaSuperIcoAndToutSavoirSurLaNoticeTitle() {
-    $this->assertXPath('//ul[contains(@class, "nav")]//li//a[contains(@class, "active")][contains(@href, "recherche/viewnotice")][@title="Tout savoir sur la notice"]//img[@src= "https://ma.super-ico.afi-sa.fr"]');
-  }
-}
-
-
 
 class TemplatesDispatchNoticeAjaxResourcesTest extends TemplatesIntonationTestCase {
   /** @test */
@@ -1877,28 +1691,6 @@ class TemplatesDispatchNoticeajaxAuthorActionTest extends TemplatesIntonationTes
 
 
 
-class TemplatesSearchRecordsTest extends TemplatesIntonationTestCase {
-  public function setUp() {
-    parent::setUp();
-    $this->fixture('Class_Notice',
-                   ['id' => 456,
-                    'titre_principal' => 'Psycho',
-                    'clef_oeuvre' => 'PSYKO',
-                    'facettes' => 'G13 M12']);
-
-    $this->dispatch('/opac/recherche/psyko/id_profil/72');
-  }
-
-
-  /** @test */
-  public function shouldDisplayResultsForPsycho() {
-    $this->assertXPathContentContains('//h1', 'Résultats pour psyko');
-  }
-}
-
-
-
-
 class TemplatesNoticeajaxMediaDispatchTest extends TemplatesIntonationTestCase {
   public function setUp() {
     parent::setUp();
@@ -1938,97 +1730,6 @@ class TemplatesNoticeajaxMediaDispatchTest extends TemplatesIntonationTestCase {
 
 
 
-class TemplatesDispatchIntonationSearchListFormatWallTest extends TemplatesIntonationTestCase {
-  public function setUp() {
-    parent::setUp();
-
-    $this->fixture('Class_CodifAuteur',
-                   ['id' => 43,
-                    'libelle' => 'Pomme d\'API']);
-
-    $records = [$this->fixture('Class_Notice',
-                               ['id' => 89]),
-                $this->fixture('Class_Notice',
-                               ['id' => 99])];
-
-    $result = $this->mock();
-
-    $result
-      ->whenCalled('setDuration')
-      ->answers($result)
-
-      ->whenCalled('setSettings')
-      ->answers($result)
-
-      ->whenCalled('getSettings')
-      ->answers(['facettes' => ''])
-
-      ->whenCalled('fetchFacetsAndTags')
-      ->answers(['facettes' => '',
-                 'suggests' => [['id' => 'M87',
-                                 'label' => 'Pomme (sujet)'],
-
-                                ['id' => 'A43',
-                                 'label' => 'Pomme d\'API (auteur)']]])
-
-      ->whenCalled('getRecordsCount')
-      ->answers(2)
-
-      ->whenCalled('isError')
-      ->answers(false)
-
-      ->whenCalled('getCriteresRecherche')
-      ->answers((new Intonation_Library_Search_Criteria)->setParams(['liste_format' => 4]))
-
-      ->whenCalled('fetchRecords')
-      ->answers($records);
-
-    $engine = $this->mock()
-
-                   ->whenCalled('lancerRecherche')
-                   ->answers($result);
-
-    Class_MoteurRecherche::setInstance($engine);
-
-    (new Class_User_Settings(Class_Users::getIdentity()))->setSearchOrder(Class_CriteresRecherche::SORT_AUTHOR_DESC)->save();
-
-    $this->dispatch('/opac/recherche/simple/expressionRecherche/pomme/id_profil/72/liste_format/4/titre/Les documents', true);
-  }
-
-
-  /** @test */
-  public function searchResultOrderShouldBeAuthorDESC() {
-    $this->assertXPath('//select/option[@selected="selected"][@value="alpha_auteur desc"]');
-  }
-
-
-  /** @test */
-  public function searchResultShouldBeDisplay() {
-    $this->assertXPathContentContains('//h1', 'les documents');
-  }
-
-
-  /** @test */
-  public function buttonMurShouldBeActive() {
-    $this->assertXpath('//div//a[contains(@class, "active")][contains(@href, "/liste_format/4")]');
-  }
-
-
-  /** @test */
-  public function suggestionsShouldBeDisplay() {
-    $this->assertXPathContentContains('//b', 'Suggestions');
-  }
-
-
-  /** @test */
-  public function masonryShouldBeLoaded() {
-    $this->assertXPath('//head/script[contains(@src, "/masonry.js")]');
-  }
-}
-
-
-
-
 abstract class TemplatesIntonationAccountTestCase extends TemplatesIntonationTestCase {
   protected $_mock_emprunts, $_emprunteur;
 
@@ -3342,9 +3043,8 @@ class TemplatesDispatchEditAllActionsTest extends TemplatesIntonationTestCase {
 
 
 
-class TemplatesSearchInSessionTest extends TemplatesIntonationTestCase {
-
 
+class TemplatesSearchInSessionTest extends TemplatesIntonationTestCase {
   public function setUp() {
     parent::setUp();
     Zend_Registry::get('session')->last_search = ['expressionRecherche' => 'trolls de troy'];