From 889e2b71c0a9e12698e9687745b103a6db2bb8c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?ANDRE=20s=C3=A9bastien?= <sandre@afi-sa.fr>
Date: Wed, 27 Mar 2024 08:06:18 +0000
Subject: [PATCH] hotline : #193955 : dont use conf legacy in template

---
 VERSIONS_HOTLINE/193955                       |   1 +
 library/Class/Notice/Titles.php               |  61 ++-
 library/Class/PaginatedLoansExporter.php      |  40 +-
 .../Class/PaginatedLoansExporter/Barcodes.php |  19 +-
 library/Class/PaginatedLoansExporter/Csv.php  |   5 +-
 .../Class/PaginatedLoansExporter/Strategy.php |  18 +-
 .../Class/PaginatedLoansExporter/Unimarc.php  |  18 +-
 library/Class/Profil.php                      |  18 +-
 library/Class/Template.php                    |   2 +-
 library/storm                                 |   2 +-
 .../Intonation/Library/ProfilePatcher.php     |   3 +-
 .../snippets/text-mode/php-mode/class         |   6 +-
 .../snippets/text-mode/php-mode/teardown      |   3 +-
 .../Templates/TemplatesAbonnePretsTest.php    | 413 ++++++++++++------
 .../Templates/TemplatesSubTitlesTest.php      | 103 +++++
 15 files changed, 524 insertions(+), 188 deletions(-)
 create mode 100644 VERSIONS_HOTLINE/193955
 create mode 100644 tests/scenarios/Templates/TemplatesSubTitlesTest.php

diff --git a/VERSIONS_HOTLINE/193955 b/VERSIONS_HOTLINE/193955
new file mode 100644
index 00000000000..3d36a63dbb5
--- /dev/null
+++ b/VERSIONS_HOTLINE/193955
@@ -0,0 +1 @@
+ - correctif #193955 : Magasin de thème : Notice, ne plus afficher des titres de périodique en double.
\ No newline at end of file
diff --git a/library/Class/Notice/Titles.php b/library/Class/Notice/Titles.php
index 536b427392e..12132b613c9 100644
--- a/library/Class/Notice/Titles.php
+++ b/library/Class/Notice/Titles.php
@@ -27,7 +27,8 @@ class Class_Notice_Titles {
     MAIN_TITLE = '200a',
     OTHER_TITLE = '200e',
     SET_TITLE = '461t',
-    PIECE_TITLE = '463t';
+    PIECE_TITLE = '463t',
+    SEPARATOR_ZONE = '$';
 
   protected Class_NoticeUnimarc $_unimarc;
 
@@ -63,53 +64,61 @@ class Class_Notice_Titles {
   }
 
 
-  public function getAllTitlesAsArray(string $main_title = '') : array {
+  public function getAllTitlesAsArray(string $main_title = ''): array
+  {
     $record_title = $main_title
       ? $this->_filter($main_title)
       : $this->_getFirstSubfield(static::MAIN_TITLE);
 
     $titles_as_array = [];
 
-    foreach($this->_unimarc->get_subfield(461, 't', 'v') as $title_volume)
+    foreach ($this->_unimarc->get_subfield(461, 't', 'v') as $title_volume)
       $titles_as_array = $this->_add461TextTo($this->_filter($title_volume['t']),
                                               $this->_filter($title_volume['v']),
                                               $record_title,
                                               $titles_as_array);
 
     if ( ! isset($titles_as_array[static::MAIN_TITLE]))
-      $titles_as_array[static::MAIN_TITLE] = $record_title;
+      $titles_as_array [static::MAIN_TITLE] = $record_title;
 
     return array_filter($titles_as_array);
   }
 
 
-  protected function _add461TextTo(string $title, string $volume, string $record_title, array $titles) : array {
+  protected function _add461TextTo(string $title,
+                                   string $volume,
+                                   string $record_title,
+                                   array $titles): array
+  {
     if ( ! $title && ! $volume)
       return $titles;
 
     $key = static::SET_TITLE . ' ' . static::SET_TITLE . '_' . (count($titles) + 1);
 
-    if ( $title && $volume && $title !== $record_title) {
+    if ($title && $volume && $title !== $record_title) {
       $titles [$key] = $this->_('%s n° %s', $title, $volume);
+
       return $titles;
     }
 
-    if ( $title && ! $volume && $title !== $record_title ) {
+    if ($title && ! $volume && $title !== $record_title ) {
       $titles [$key] = $title;
+
       return $titles;
     }
 
-    if ( $volume )
+    if ($volume)
       $titles [static::MAIN_TITLE] = $this->_('%s n° %s', $record_title, $volume);
 
     return $titles;
   }
 
 
-  public function getAllTitlesAndSubtitlesAsArray() : array {
+  public function getAllTitlesAndSubtitlesAsArray(): array
+  {
     $titles = $this->getAllTitlesAsArray();
 
-    if ( $subtitles = $this->getSubtitlesAsArray())
+    if ($subtitles = $this->_subtitlesAsArray($titles))
       $subtitles = array_map(fn($subtitle) => ': ' . $subtitle,
                              $subtitles);
 
@@ -117,18 +126,42 @@ class Class_Notice_Titles {
   }
 
 
-  public function getSubtitlesAsArray() : array {
+  protected function _subtitlesAsArray(array $main_titles = []): array
+  {
+    $zones_title = $this->_zonesTitle($main_titles);
+
     $subtitles = [];
-    foreach(Class_Profil::getCurrentProfil()->getZonesTitre() as $zone)
+    foreach ($zones_title as $zone)
       if ($subtitle = $this->_getFirstSubfield($zone))
         $subtitles [$zone] = $subtitle;
 
-    return $subtitles;
+    return array_filter($subtitles);
+  }
+
+
+  protected function _zonesTitle(array $main_titles): array
+  {
+    $zones_title = Class_Profil::getCurrentProfil()->getZonesTitre();
+
+    if ( ! $main_titles)
+      return $zones_title;
+
+    $main_keys = array_filter(array_map(fn($key) => explode(' ', (string) $key)[0] ?? '',
+                                        array_keys($main_titles)));
+
+    return (new Storm_Collection($zones_title))
+      ->reject(function($zone) use ($main_keys)
+      {
+        $key = str_replace(static::SEPARATOR_ZONE, '', (string) $zone);
+
+        return $key && in_array($key, $main_keys);
+      })
+      ->getArrayCopy();
   }
 
 
   public function getSubtitle() : string {
-    return implode(' : ', $this->getSubtitlesAsArray());
+    return implode(' : ', $this->_subtitlesAsArray());
   }
 
 
diff --git a/library/Class/PaginatedLoansExporter.php b/library/Class/PaginatedLoansExporter.php
index 25b375f2615..13e736af8dc 100644
--- a/library/Class/PaginatedLoansExporter.php
+++ b/library/Class/PaginatedLoansExporter.php
@@ -20,9 +20,9 @@
  */
 
 
-class Class_PaginatedLoansExporter {
-  use Trait_StormFileSystem;
-  use Trait_Translator;
+class Class_PaginatedLoansExporter
+{
+  use Trait_StormFileSystem, Trait_Translator;
 
   protected static int $_page_size = 200;
   protected array $_params;
@@ -34,7 +34,6 @@ class Class_PaginatedLoansExporter {
   protected int $_completed_loans;
   protected Class_PaginatedLoansExporter_Strategy $_strategy;
 
-
   public function __construct(Class_PaginatedLoansExporter_Strategy $strategy) {
     $this->_strategy = $strategy;
   }
@@ -59,7 +58,8 @@ class Class_PaginatedLoansExporter {
   }
 
 
-  protected function _pageDataContent(){
+  protected function _pageDataContent(): self
+  {
     $loans = $this->_user->getIlsLoans($this->_params)->getArrayCopy();
     $this->_total_loans = $this->_user->getIlsLoansCount($this->_params);
     $this->_data_page = array_filter(array_map($this->_strategy->processData(),
@@ -70,24 +70,29 @@ class Class_PaginatedLoansExporter {
     $this->_processBegin();
 
     if ($this->_data_page)
-      $this->getFileSystem()
-           ->fileAppendContents($this->getFilename(),
-                                implode("",$this->_data_page));
+      static::getFileSystem()
+        ->fileAppendContents($this->getFilename(),
+                             implode('', $this->_data_page));
 
     $this->_completed_loans =
-      static::$_page_size * ($this->_params['page'] - 1 ) + $this->_current_loans;
+      static::$_page_size * ($this->_params['page'] - 1) + $this->_current_loans;
+
     return $this;
   }
 
 
-  protected function _processBegin() :self{
-    if (!isset($this->_params['page']) || !($this->_params['page'] ==1))
+  protected function _processBegin(): self
+  {
+    if ( ! isset($this->_params['page']) || ! ($this->_params['page'] == 1))
       return $this;
-    if ($this->getFileSystem()
+
+    if (static::getFileSystem()
         ->fileExists($this->getFilename()))
-      $this->getFileSystem()->delete($this->getFilename());
+      static::getFileSystem()->delete($this->getFilename());
+
     if ($header = $this->_strategy->getHeader())
       array_unshift($this->_data_page, $header);
+
     return $this;
   }
 
@@ -125,10 +130,11 @@ class Class_PaginatedLoansExporter {
   }
 
 
-  public function getFileContent() : string {
-    $content = $this->getFileSystem()
-                    ->fileGetContents($this->getFilename()) ?? '';
-    $this->getFileSystem()->delete($this->getFilename());
+  public function getFileContent(): string
+  {
+    $content = static::getFileSystem()
+      ->fileGetContents($this->getFilename()) ?? '';
+    static::getFileSystem()->delete($this->getFilename());
 
     return $content;
   }
diff --git a/library/Class/PaginatedLoansExporter/Barcodes.php b/library/Class/PaginatedLoansExporter/Barcodes.php
index c53fba34d83..edd15bc9f2a 100644
--- a/library/Class/PaginatedLoansExporter/Barcodes.php
+++ b/library/Class/PaginatedLoansExporter/Barcodes.php
@@ -20,30 +20,37 @@
  */
 
 
-class Class_PaginatedLoansExporter_Barcodes extends Class_PaginatedLoansExporter_Strategy {
+class Class_PaginatedLoansExporter_Barcodes extends Class_PaginatedLoansExporter_Strategy
+{
   use Trait_Translator;
 
   protected $_action = 'paginated-barcodes-export';
 
-  public function processData() :closure {
+  public function processData(): Closure
+  {
     return fn($element) => $element->getCodeBarre(). "\n" ;
   }
 
 
-  public function getHeader() :string {
+  public function getHeader(): string
+  {
     return $this->_('Code-barre') . "\n" ;
   }
 
 
-  public function generateFilename() :string {
+  public function generateFilename(): string
+  {
     return sprintf("prets_codes_barres_%s_%s%s",
                    Class_Users::getIdentity()->getId(),
-                   (new Class_TimeSource)->dateYmd(),
+                   static::getCurrentDate(),
                    '.csv');
   }
 
 
-  public function renderFinish(ZendAfi_Controller_Action_Helper $helper, string $content, string $filename) :self {
+  public function renderFinish(ZendAfi_Controller_Action_Helper $helper,
+                               string $content,
+                               string $filename): self
+  {
     $helper
       ->csv($filename,
             $content);
diff --git a/library/Class/PaginatedLoansExporter/Csv.php b/library/Class/PaginatedLoansExporter/Csv.php
index 9508ce37ff6..f104c3def6e 100644
--- a/library/Class/PaginatedLoansExporter/Csv.php
+++ b/library/Class/PaginatedLoansExporter/Csv.php
@@ -60,10 +60,11 @@ class Class_PaginatedLoansExporter_Csv extends Class_PaginatedLoansExporter_Stra
   }
 
 
-  public function generateFilename() :string {
+  public function generateFilename(): string
+  {
     return sprintf("prets_csv_%s_%s%s",
                    Class_Users::getIdentity()->getId(),
-                   (new Class_TimeSource)->dateYmd(),
+                   static::getCurrentDate(),
                    '.csv');
   }
 
diff --git a/library/Class/PaginatedLoansExporter/Strategy.php b/library/Class/PaginatedLoansExporter/Strategy.php
index a7e8fd871e5..1ea90d202c4 100644
--- a/library/Class/PaginatedLoansExporter/Strategy.php
+++ b/library/Class/PaginatedLoansExporter/Strategy.php
@@ -20,23 +20,29 @@
  */
 
 
-abstract class Class_PaginatedLoansExporter_Strategy {
+abstract class Class_PaginatedLoansExporter_Strategy
+{
+  use Trait_TimeSource;
 
-  abstract public function processData() :closure;
+  abstract public function processData(): Closure;
 
-  abstract public function generateFilename() :string;
+  abstract public function generateFilename(): string;
 
-  public function getUrl(int $page = 0) :string {
+  public function getUrl(int $page = 0): string
+  {
     return Class_Url::relative(array_filter(['controller' => 'abonne',
                                              'action' => $this->_action,
                                              'page' => $page]));
   }
 
 
-  public function getHeader() :string {
+  public function getHeader(): string
+  {
     return '';
   }
 
 
-  abstract public function renderFinish(ZendAfi_Controller_Action_Helper $helper, string $content, string $filename) :self;
+  abstract public function renderFinish(ZendAfi_Controller_Action_Helper $helper,
+                                        string $content,
+                                        string $filename): self;
 }
diff --git a/library/Class/PaginatedLoansExporter/Unimarc.php b/library/Class/PaginatedLoansExporter/Unimarc.php
index 8c1d8025390..4e2d1add4e1 100644
--- a/library/Class/PaginatedLoansExporter/Unimarc.php
+++ b/library/Class/PaginatedLoansExporter/Unimarc.php
@@ -24,8 +24,9 @@ class Class_PaginatedLoansExporter_Unimarc extends Class_PaginatedLoansExporter_
 
   protected $_action = 'paginated-loan-export';
 
-  public function processData() :closure {
-    return function($element){
+  public function processData(): Closure
+  {
+    return function($element) {
       return ($exemplaire = $element->getExemplaireOPAC())
         ? $exemplaire->toUnimarcIso2709()
         : '';
@@ -33,19 +34,22 @@ class Class_PaginatedLoansExporter_Unimarc extends Class_PaginatedLoansExporter_
   }
 
 
-  public function generateFilename() :string {
+  public function generateFilename(): string
+  {
     return sprintf("fichier_prets_%s_%s%s",
                    Class_Users::getIdentity()->getId(),
-                   (new Class_TimeSource)->dateYmd(),
+                   static::getCurrentDate(),
                    '.mrc');
   }
 
 
-  public function renderFinish(ZendAfi_Controller_Action_Helper $helper, string $content, string $filename) :self {
+  public function renderFinish(ZendAfi_Controller_Action_Helper $helper,
+                               string $content,
+                               string $filename): self
+  {
     $helper->viewRenderer->setNoRender();
     $helper
-      ->binaryDownload($content,
-                       $filename);
+      ->binaryDownload($content, $filename);
 
     return $this;
   }
diff --git a/library/Class/Profil.php b/library/Class/Profil.php
index f10a9dcce47..fce7d1ffb9f 100644
--- a/library/Class/Profil.php
+++ b/library/Class/Profil.php
@@ -2326,18 +2326,30 @@ class Class_Profil extends Storm_Model_Abstract {
   }
 
 
-  /** @return array la liste des zones titre a afficher dans le resultat de recherche */
-  public function getZonesTitre() : array {
+  public function getZonesTitre(): array
+  {
     $cfg = $this->getCfgModulesAsArray();
 
     $zones = isset($cfg['recherche']['resultatsimple']['zones_titre'])
       ? $cfg['recherche']['resultatsimple']['zones_titre']
-      : (new Class_Systeme_ModulesAppli())->getValeursParDefaut('recherche', 'resultat')['zones_titre'];
+      : (new Class_Systeme_ModulesAppli)
+          ->getValeursParDefaut('recherche', 'resultat')['zones_titre'];
 
     return explode(';', $zones);
   }
 
 
+  public function resetZonesTitle(): self
+  {
+    $cfg_modules = $this->getCfgModulesAsArray();
+    unset($cfg_modules['recherche']['resultatsimple']['zones_titre']);
+
+    $this->setCfgModules($cfg_modules);
+
+    return $this;
+  }
+
+
   public function getSearchResultSettings() : array {
     return $this->getConfigurationOf('recherche', 'resultat' , 'simple');
   }
diff --git a/library/Class/Template.php b/library/Class/Template.php
index f949d65a6e3..e34a2b06012 100644
--- a/library/Class/Template.php
+++ b/library/Class/Template.php
@@ -181,7 +181,7 @@ class Class_Template {
 
 
   public function tryOn($profile) {
-    if(!$profile)
+    if ( ! $profile)
       return null;
 
     $try_profile = $this->_findOrCreateTryProfileFrom($profile);
diff --git a/library/storm b/library/storm
index 471d1fa9475..b7678208d14 160000
--- a/library/storm
+++ b/library/storm
@@ -1 +1 @@
-Subproject commit 471d1fa9475497f7933ea41654f672630a93cab1
+Subproject commit b7678208d14f8387fbaae564c34e01514a41d32e
diff --git a/library/templates/Intonation/Library/ProfilePatcher.php b/library/templates/Intonation/Library/ProfilePatcher.php
index f9f49b450ed..b549be23487 100644
--- a/library/templates/Intonation/Library/ProfilePatcher.php
+++ b/library/templates/Intonation/Library/ProfilePatcher.php
@@ -244,6 +244,7 @@ class Intonation_Library_ProfilePatcher extends Class_Template_ProfilePatcher
     }
 
     $this->_profile
+      ->resetZonesTitle()
       ->setCfgSiteParam('skin', '')
       ->setCfgSiteParam('browser', 'opac')
       ->setCfgSiteParam('parent_id', 'null')
@@ -613,4 +614,4 @@ class Intonation_Library_ProfilePatcher extends Class_Template_ProfilePatcher
   public function getDefaultWidgetConfiguration(array $params) : array {
     return [$this->_template->withNameSpace('styles_pack') => $this->_men_in_black->getId()];
   }
-}
\ No newline at end of file
+}
diff --git a/scripts/emacs/yasnippet/snippets/text-mode/php-mode/class b/scripts/emacs/yasnippet/snippets/text-mode/php-mode/class
index ffe5331b204..24e46a8076e 100644
--- a/scripts/emacs/yasnippet/snippets/text-mode/php-mode/class
+++ b/scripts/emacs/yasnippet/snippets/text-mode/php-mode/class
@@ -23,8 +23,6 @@
  */
 
 
-class ${class_name} {
-   public function ${function_name}() {
-      $0
-   }
+class ${class_name}
+{
 }
diff --git a/scripts/emacs/yasnippet/snippets/text-mode/php-mode/teardown b/scripts/emacs/yasnippet/snippets/text-mode/php-mode/teardown
index 577d1da6a99..bf6810b65a8 100644
--- a/scripts/emacs/yasnippet/snippets/text-mode/php-mode/teardown
+++ b/scripts/emacs/yasnippet/snippets/text-mode/php-mode/teardown
@@ -1,7 +1,8 @@
 #contributor : Ghislain Loas <gloas@afi-sa.fr>
 #name : funct ...(...)
 # --
-public function tearDown() {
+public function tearDown()
+{
   $0
   parent::tearDown();
 }
\ No newline at end of file
diff --git a/tests/scenarios/Templates/TemplatesAbonnePretsTest.php b/tests/scenarios/Templates/TemplatesAbonnePretsTest.php
index b1155a75383..233d82d2e53 100644
--- a/tests/scenarios/Templates/TemplatesAbonnePretsTest.php
+++ b/tests/scenarios/Templates/TemplatesAbonnePretsTest.php
@@ -23,43 +23,57 @@ include_once('Class/WebService/SIGB/Orphee/Service.php');
 include_once('Class/WebService/SIGB/Orphee/SessionStrategy.php');
 include_once('library/Class/WebService/SIGB/OrpheeFixtures.php');
 
+abstract class TemplatesAbonnePretsAjaxLoansPaginatedTestCase extends AbstractControllerTestCase
+{
 
-abstract class TemplatesAbonnePretsAjaxLoansPaginatedTestCase extends AbstractControllerTestCase {
-
+  protected Storm_FileSystem_Volatile $_file_system;
   protected
     $_search_client,
     $_orphee,
     $_orphee_allow_hold_avail,
     $_henry_dupont;
 
-
-  public function setUp(){
+  public function setUp()
+  {
     parent::setUp();
 
     Class_AdminVar::set('ACTIVATE_AUTH_LOG', true);
 
+    Class_PaginatedLoansExporter_Strategy::setTimeSource(new TimeSourceForTest('2024-03-01 01:00:00'));
+
+    $this->_file_system = (new Storm_FileSystem_Volatile)
+      ->mkdir(PATH_TEMP);
+
+    Class_PaginatedLoansExporter::setFileSystem($this->_file_system);
+
     $this->_search_client = Storm_Test_ObjectWrapper::mock();
 
     $this->_search_client
+
       ->whenCalled('__getLastRequest')
       ->answers('last request')
+
       ->whenCalled('__getLastResponse')
       ->answers('last response')
+
       ->whenCalled('__getLastResponseHeaders')
       ->answers('last response  headers')
+
       ->whenCalled('__getLastRequestHeaders')
       ->answers('last response')
+
       ->whenCalled('hasFunction')
       ->answers(false)
+
       ->whenCalled('GetId')
-      ->with(new GetId())
+      ->with(new GetId)
       ->answers(GetIdResponse::withIdResult('1234'))
 
       ->whenCalled('__setCookie')
       ->answers(null)
 
       ->whenCalled('EndSession')
-      ->answers(new EndSessionResponse());
+      ->answers(new EndSessionResponse);
 
     $this->_beforeOrpheeServiceCreate();
 
@@ -91,14 +105,36 @@ abstract class TemplatesAbonnePretsAjaxLoansPaginatedTestCase extends AbstractCo
                                                           'type' => Class_IntBib::COM_ORPHEE]),
                                              $this->_orphee);
 
-    $this->_buildTemplateProfil(['id'=>72]);
+    $this->_buildTemplateProfil(['id' => 72]);
 
     ZendAfi_Auth::getInstance()->logUser($this->_henry_dupont);
   }
 
 
-  public function _beforeOrpheeServiceCreate(){
+  public function tearDown()
+  {
+    Class_PaginatedLoansExporter::setFileSystem(null);
+    Class_PaginatedLoansExporter_Strategy::setTimeSource(null);
+    parent::tearDown();
+  }
+
+
+  protected function _fileContentFor(string $name, string $extension = '.csv'): string
+  {
+    return $this->_file_system->fileGetContents($this->_fullFileNameWithRoot($name, $extension));
+  }
+
+
+  protected function _fullFileNameWithRoot(string $name, string $extension = '.csv'): string
+  {
+    return PATH_TEMP . $name . '_2024-03-01' . $extension;
+  }
+
+
+  public function _beforeOrpheeServiceCreate()
+  {
     $this->_search_client
+
       ->whenCalled('hasFunction')
       ->with('GetToken')
       ->answers(true)
@@ -142,62 +178,74 @@ abstract class TemplatesAbonnePretsAjaxLoansPaginatedTestCase extends AbstractCo
 
 
 
-class TemplatesAbonnePretsAjaxLoansWithPagesAllTest extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase {
-  public function setUp() {
+class TemplatesAbonnePretsAjaxLoansWithPagesAllTest
+  extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase
+{
+
+  public function setUp()
+  {
     parent::setUp();
+
     $this->dispatch('opac/abonne/ajax-loans/id_profil/72/pages/all');
   }
 
 
   /** @test */
-  public function pageShouldContains11loans() {
-    $this->assertXPathCount('//div[contains(@class, "list-group-item")]',11, $this->_response->getBody());
+  public function pageShouldContains11loans()
+  {
+    $this->assertXPathCount('//div[contains(@class, "list-group-item")]', 11);
   }
 }
 
 
 
 
-class TemplatesAbonnePretsIndexTest extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase {
-  public function setUp() {
+class TemplatesAbonnePretsIndexTest extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase
+{
+
+  public function setUp()
+  {
     parent::setUp();
+
     Class_Profil::find(72)
       ->setCfgMenus(['H' => ['libelle' => 'Principal',
                              'picto' => 'main.png',
                              'menus' => []]])
-      ->setCfgAccueil( ['modules' =>
-                     ['10' => ['division' => 2,
-                              'type_module' => 'LOGIN',
-                              'preferences' => ['IntonationFormStyle' => 0]]]])
-
-
+      ->setCfgAccueil(['modules' =>
+                       ['10' => ['division' => 2,
+                                 'type_module' => 'LOGIN',
+                                 'preferences' => ['IntonationFormStyle' => 0]]]])
       ->save();
 
-    ZendAfi_Auth::getInstance()->logUser( $this->_henry_dupont);
+    ZendAfi_Auth::getInstance()->logUser($this->_henry_dupont);
     $this->dispatch('opac/index/index/id_profil/72');
   }
 
 
   /** @test */
-  public function boitedefaultLoginShouldContainsLinkPretsEnCours() {
+  public function boitedefaultLoginShouldContainsLinkPretsEnCours()
+  {
     $this->assertXPathContentContains('//div[@class="default_login"]//a[contains(@class,"account-loans")][@href="/abonne/prets"]',"Voir les prêts en cours");
   }
 
 
   /** @test */
-  public function boitedefaultLoginShouldContainsLinkPretsEnRetard() {
+  public function boitedefaultLoginShouldContainsLinkPretsEnRetard()
+  {
     $this->assertXPathContentContains('//div[@class="default_login"]//a[contains(@class,"account-loans")][@href="/abonne/prets/filter/late"]',"Voir les prêts en retard");
   }
 
 
   /** @test */
-  public function boitedefaultLoginShouldContainsLinkPretsReserves() {
+  public function boitedefaultLoginShouldContainsLinkPretsReserves()
+  {
     $this->assertXPathContentContains('//div[@class="default_login"]//a[contains(@class,"account-loans")][@href="/abonne/prets/filter/to_be_returned"]',"Voir les prêts réservés par d'autres");
   }
 
 
   /** @test */
-  public function boitedefaultLoginShouldContainsLinkResrvations() {
+  public function boitedefaultLoginShouldContainsLinkResrvations()
+  {
     $this->assertXPathContentContains('//div[@class="default_login"]//a[contains(@class,"account-booking")][@href="/abonne/reservations"]',"Voir les réservations");
   }
 }
@@ -205,45 +253,55 @@ class TemplatesAbonnePretsIndexTest extends TemplatesAbonnePretsAjaxLoansPaginat
 
 
 
-class TemplatesAbonnePretsAjaxLoansWithPage1LoansPerPage2Test extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase {
-  public function setUp() {
+class TemplatesAbonnePretsAjaxLoansWithPage1LoansPerPage2Test
+  extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase
+{
+
+  public function setUp()
+  {
     parent::setUp();
 
-    $this->postDispatch('opac/abonne/ajax-loans/id_profil/72/page/1', ['size'=>2]);
+    $this->postDispatch('opac/abonne/ajax-loans/id_profil/72/page/1', ['size' => 2]);
   }
 
 
   /** @test */
-  public function pageShouldContains2loans() {
-    $this->assertXPathCount('//div[contains(@class, "list-group-item")]',2, $this->_response->getBody());
+  public function pageShouldContains2loans()
+  {
+    $this->assertXPathCount('//div[contains(@class, "list-group-item")]', 2);
   }
 
 
   /** @test */
-  public function listSizeNumberShouldBe17810() {
+  public function listSizeNumberShouldBe17810()
+  {
     $this->assertXPathContentContains('//span[contains(@class,"truncate_list_size_number")]','17810');
   }
 
 
   /** @test */
-  public function currentPageCountShouldBeOne() {
-    $this->assertXPathContentContains('//span[@class="btn btn-sm"]','Page 1 / 8905');
+  public function currentPageCountShouldBeOne()
+  {
+    $this->assertXPathContentContains('//span[@class="btn btn-sm"]', 'Page 1 / 8905');
   }
 
 
   /** @test */
-  public function urlNextPageShouldContainsAjaxLoansPage2() {
+  public function urlNextPageShouldContainsAjaxLoansPage2()
+  {
     $this->assertXPath('//a[contains(@class,"next_ajax_anchor")][@href="/abonne/ajax-loans/id_profil/72/page/2"][@title="page suivante"]' );
   }
 
 
   /** @test */
-  public function formShouldDisplayOnlyFourSortOptions() {
+  public function formShouldDisplayOnlyFourSortOptions()
+  {
     $this->assertXPathCount('//select[contains(@name,"order")]//option', 4);
   }
 
 
-  public function supportedSortOptions(){
+  public function supportedSortOptions()
+  {
     return [['4_1', 'Date de prêt croissant'],
             ['4_2', 'Date de prêt décroissant'],
             ['7_1', 'Date de retour croissant'],
@@ -255,61 +313,71 @@ class TemplatesAbonnePretsAjaxLoansWithPage1LoansPerPage2Test extends TemplatesA
    * @test
    * @dataProvider supportedSortOptions
    */
-  public function formShouldDisplaySortOptions(string $sortvalue, string $sortlabel) {
+  public function formShouldDisplaySortOptions(string $sortvalue, string $sortlabel)
+  {
     $this->assertXPathContentContains('//select[contains(@name,"order")]//option[@value="'.$sortvalue.'"]', $sortlabel);
   }
 
 
   /** @test */
-  public function formShouldNotDisplayFilterOptions() {
+  public function formShouldNotDisplayFilterOptions()
+  {
     $this->assertNotXPath('//input[contains(@name,"input_")]');
   }
 
 
   /** @test */
-  public function formShouldDisplaySelectFilterOptions() {
+  public function formShouldDisplaySelectFilterOptions()
+  {
     $this->assertXPathContentContains('//select[@name="filter"]', 'Prêts en retard');
   }
 
 
   /** @test */
-  public function formShouldDisplayInputIssueStart() {
+  public function formShouldDisplayInputIssueStart()
+  {
     $this->assertXPath('//input[@name="date_from"]');
   }
 
 
   /** @test */
-  public function formShouldDisplayInputIssueEnd() {
+  public function formShouldDisplayInputIssueEnd()
+  {
     $this->assertXPath('//input[@name="date_to"]');
   }
 
 
   /** @test */
-  public function formShouldDisplayButtonOk() {
+  public function formShouldDisplayButtonOk()
+  {
     $this->assertXPath('//input[@type="submit"][@value="Ok"]');
   }
 
 
   /** @test */
-  public function linkExportMarcShouldBeDisplayed() {
+  public function linkExportMarcShouldBeDisplayed()
+  {
     $this->assertXPathContentContains('//a[contains(@class,"loans_export_marc")][contains(@href,"#")]', 'Export Unimarc');
   }
 
 
   /** @test */
-  public function linkExportBarcodesShouldBeDisplayed() {
+  public function linkExportBarcodesShouldBeDisplayed()
+  {
     $this->assertXPathContentContains('//a[contains(@class,"loans_export_barcodes")][contains(@href,"#")]', 'Export codes barres');
   }
 
 
   /** @test */
-  public function linkExportCsvShouldBeDisplayed() {
+  public function linkExportCsvShouldBeDisplayed()
+  {
     $this->assertXPathContentContains('//a[contains(@class,"loans_export_csv")][contains(@href,"#")]', 'Export Csv');
   }
 
 
   /** @test */
-  public function historicalLoansListShouldNotBeDisplayed() {
+  public function historicalLoansListShouldNotBeDisplayed()
+  {
     $this->assertNotXPath('//div[@name="historical_loans_list"]');
   }
 }
@@ -317,16 +385,22 @@ class TemplatesAbonnePretsAjaxLoansWithPage1LoansPerPage2Test extends TemplatesA
 
 
 
-class TemplatesAbonnePretsAjaxLoansWithPage2LoansPerPage2Test extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase {
-  public function setUp() {
+class TemplatesAbonnePretsAjaxLoansWithPage2LoansPerPage2Test
+  extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase
+{
+
+  public function setUp()
+  {
     parent::setUp();
 
-    $this->postDispatch('opac/abonne/ajax-loans/id_profil/72/page/2', ['size'=> 2 ]);
+    $this->postDispatch('opac/abonne/ajax-loans/id_profil/72/page/2', ['size' => 2]);
   }
 
 
-  public function _beforeOrpheeServiceCreate(){
+  public function _beforeOrpheeServiceCreate()
+  {
     parent::_beforeOrpheeServiceCreate();
+
     $this->_search_client
       ->whenCalled('setTri')
       ->with(SetTri::withTypeTriAndOrdre(SetTri::SORT_TITLE, SetTri::ORDER_ASC))
@@ -335,19 +409,22 @@ class TemplatesAbonnePretsAjaxLoansWithPage2LoansPerPage2Test extends TemplatesA
 
 
   /** @test */
-  public function page2ShouldContains2loans() {
-    $this->assertXPathCount('//div[contains(@class, "list-group-item")]',2);
+  public function page2ShouldContains2loans()
+  {
+    $this->assertXPathCount('//div[contains(@class, "list-group-item")]', 2);
   }
 
 
   /** @test */
-  public function page2ShouldContainsTitleZoeJuju() {
+  public function page2ShouldContainsTitleZoeJuju()
+  {
     $this->assertXPathContentContains('//div[@class="document_title"]',' + Juju');
   }
 
 
   /** @test */
-  public function currentPageCountShouldBeTwo() {
+  public function currentPageCountShouldBeTwo()
+  {
     $this->assertXPathContentContains('//span[@class="btn btn-sm"]','Page 2 / 8905');
   }
 }
@@ -355,17 +432,24 @@ class TemplatesAbonnePretsAjaxLoansWithPage2LoansPerPage2Test extends TemplatesA
 
 
 
-class TemplatesAbonnePretsAjaxLoansWithPage1OrderTest extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase {
-  public function setUp() {
+class TemplatesAbonnePretsAjaxLoansWithPage1OrderTest
+  extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase
+{
+
+  public function setUp()
+  {
     parent::setUp();
+
     $this->postDispatch('opac/abonne/ajax-loans/id_profil/72/page/1',
-                        ['order' =>'4_1',
-                         'size' =>2]);
+                        ['order' => '4_1',
+                         'size' => 2]);
   }
 
 
-  public function _beforeOrpheeServiceCreate(){
+  public function _beforeOrpheeServiceCreate()
+  {
     parent::_beforeOrpheeServiceCreate();
+
     $this->_search_client
       ->whenCalled('setTri')
       ->with(SetTri::withTypeTriAndOrdre(SetTri::SORT_ISSUE, SetTri::ORDER_ASC))
@@ -374,13 +458,15 @@ class TemplatesAbonnePretsAjaxLoansWithPage1OrderTest extends TemplatesAbonnePre
 
 
   /** @test */
-  public function pageShouldContains2loans() {
-    $this->assertXPathCount('//div[contains(@class, "list-group-item")]',2);
+  public function pageShouldContains2loans()
+  {
+    $this->assertXPathCount('//div[contains(@class, "list-group-item")]', 2);
   }
 
 
   /** @test */
-  public function urlNextPageShouldContainsOrder() {
+  public function urlNextPageShouldContainsOrder()
+  {
     $this->assertXPath('//a[contains(@class,"next_ajax_anchor")][@href="/abonne/ajax-loans/id_profil/72/page/2"][@title="page suivante"]' );
   }
 }
@@ -388,17 +474,24 @@ class TemplatesAbonnePretsAjaxLoansWithPage1OrderTest extends TemplatesAbonnePre
 
 
 
-class TemplatesAbonnePretsAjaxLoansWithPage1LateFilterTest extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase {
-  public function setUp() {
+class TemplatesAbonnePretsAjaxLoansWithPage1LateFilterTest
+  extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase
+{
+
+  public function setUp()
+  {
     parent::setUp();
+
     $this->postDispatch('opac/abonne/ajax-loans/id_profil/72/page/1',
-                        ['filter' =>'late',
+                        ['filter' => 'late',
                          'size' => 2]);
   }
 
 
-  public function _beforeOrpheeServiceCreate(){
+  public function _beforeOrpheeServiceCreate()
+  {
     parent::_beforeOrpheeServiceCreate();
+
     $this->_search_client
       ->whenCalled('SetCritPrets')
       ->with(setCritPrets::withCodeAndVal(1, setCritPrets::LATE_ISSUES))
@@ -407,13 +500,15 @@ class TemplatesAbonnePretsAjaxLoansWithPage1LateFilterTest extends TemplatesAbon
 
 
   /** @test */
-  public function pageShouldContains2loans() {
-    $this->assertXPathCount('//div[contains(@class, "list-group-item")]',2);
+  public function pageShouldContains2loans()
+  {
+    $this->assertXPathCount('//div[contains(@class, "list-group-item")]', 2);
   }
 
 
   /** @test */
-  public function urlNextPageShouldContainsOrder() {
+  public function urlNextPageShouldContainsOrder()
+  {
     $this->assertXPath('//a[contains(@class,"next_ajax_anchor")][@href="/abonne/ajax-loans/id_profil/72/page/2"][@title="page suivante"]' );
   }
 }
@@ -421,26 +516,36 @@ class TemplatesAbonnePretsAjaxLoansWithPage1LateFilterTest extends TemplatesAbon
 
 
 
-class TemplatesAbonnePretsAjaxLoansWithFilterIssueDateDateFromTest extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase {
-  public function setUp() {
+class TemplatesAbonnePretsAjaxLoansWithFilterIssueDateDateFromTest
+  extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase
+{
+
+  public function setUp()
+  {
     parent::setUp();
+
     $this->postDispatch('opac/abonne/ajax-loans/id_profil/72/page/1',
-                        ['filter' =>'issue_date',
+                        ['filter' => 'issue_date',
                          'date_from' => '01/01/2013',
                          'date_to' => '21/08/2015',
                          'size' => 2]);
   }
 
 
-  public function _beforeOrpheeServiceCreate(){
+  public function _beforeOrpheeServiceCreate()
+  {
     parent::_beforeOrpheeServiceCreate();
+
     $this->_search_client
+
       ->whenCalled('SetCritPrets')
       ->with(SetCritPrets::withCodeAndVal(1,SetCritPrets::FILTER_DATE))
       ->answers(true)
+
       ->whenCalled('SetCritPrets')
       ->with(SetCritPrets::withCodeAndVal(14, '01012013'))
       ->answers(true)
+
       ->whenCalled('SetCritPrets')
       ->with(SetCritPrets::withCodeAndVal(15, '21082015'))
       ->answers(true);
@@ -448,13 +553,15 @@ class TemplatesAbonnePretsAjaxLoansWithFilterIssueDateDateFromTest extends Templ
 
 
   /** @test */
-  public function pageShouldContains2loans() {
-    $this->assertXPathCount('//div[contains(@class, "list-group-item")]',2);
+  public function pageShouldContains2loans()
+  {
+    $this->assertXPathCount('//div[contains(@class, "list-group-item")]', 2);
   }
 
 
   /** @test */
-  public function urlNextPageShouldContainsOrder() {
+  public function urlNextPageShouldContainsOrder()
+  {
     $this->assertXPath('//a[contains(@class,"next_ajax_anchor")][@href="/abonne/ajax-loans/id_profil/72/page/2"][@title="page suivante"]' );
   }
 }
@@ -462,34 +569,47 @@ class TemplatesAbonnePretsAjaxLoansWithFilterIssueDateDateFromTest extends Templ
 
 
 
-class TemplatesAbonnePretsAjaxLoansWithUserNonDepotPageOneTest extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase {
-  public function setUp() {
+class TemplatesAbonnePretsAjaxLoansWithUserNonDepotPageOneTest
+  extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase
+{
+
+  public function setUp()
+  {
     parent::setUp();
 
-    $this->postDispatch('opac/abonne/ajax-loans/id_profil/72/page/1', ['size'=>2]);
+    $this->postDispatch('opac/abonne/ajax-loans/id_profil/72/page/1', ['size' => 2]);
   }
 
-  public function _beforeOrpheeServiceCreate(){
+
+  public function _beforeOrpheeServiceCreate()
+  {
     $this->_search_client
+
       ->whenCalled('hasFunction')
       ->with('GetToken')
       ->answers(true)
 
       ->whenCalled('GetToken')
       ->answers(new GetTokenResponse(OrpheeFixtures::TokenResult()))
+
       ->whenCalled('GetInfoUser')
       ->answers(OrpheeFixtures::xmlGetAdhHenryDupont())
-      ->whenCalled('hasFunction')->with('GetAdh')->answers(true)
+
+      ->whenCalled('hasFunction')
+      ->with('GetAdh')
+      ->answers(true)
 
       ->whenCalled('GetAdh')
       ->answers(Storm_Test_ObjectWrapper::mock()
                 ->whenCalled('getXml')
                 ->answers(OrpheeFixtures::xmlGetAdhHenryDupont()))
+
       ->whenCalled('GetLstPret')
       ->with(GetLstPret::withAdhAndCountPerPage('3062803' ,-1))
       ->answers(Storm_Test_ObjectWrapper::mock()
                 ->whenCalled('getXml')
                 ->answers(OrpheeFixtures::xmlGetLstPretsNewOrpheeVersion()))
+
       ->whenCalled('setTri')
       ->with(SetTri::withTypeTriAndOrdre(SetTri::SORT_ISSUE, SetTri::ORDER_DESC))
       ->answers(true);
@@ -497,19 +617,22 @@ class TemplatesAbonnePretsAjaxLoansWithUserNonDepotPageOneTest extends Templates
 
 
   /** @test */
-  public function linkExportMarcShouldNotBeDisplayed() {
+  public function linkExportMarcShouldNotBeDisplayed()
+  {
     $this->assertNotXPath('//a[contains(@class,"loans-export-marc")][contains(@href,"abonne/paginated-loan-export/pages/all")]');
   }
 
 
   /** @test */
-  public function linkExportBarcodesShouldNotBeDisplayed() {
+  public function linkExportBarcodesShouldNotBeDisplayed()
+  {
     $this->assertNotXPath('//a[contains(@class,"loans-export-barcodes")][contains(@href,"abonne/paginated-barcodes-export/pages/all")]');
   }
 
 
   /** @test */
-  public function oneToolLinkShouldBeDisplayed() {
+  public function oneToolLinkShouldBeDisplayed()
+  {
     $this->assertXPathCount('//div[contains(@class,"collection_actions")]//div[contains(@class,"collection_action")]//a', 1);
   }
 }
@@ -517,10 +640,14 @@ class TemplatesAbonnePretsAjaxLoansWithUserNonDepotPageOneTest extends Templates
 
 
 
-class TemplatesAbonnePretsBarcodesExportTest extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase {
+class TemplatesAbonnePretsBarcodesExportTest
+  extends TemplatesAbonnePretsAjaxLoansPaginatedTestCase
+{
 
-  public function setUp() {
+  public function setUp()
+  {
     parent::setUp();
+
     $this->fixture(Class_CodifSection::class,
                    ['id' => 'JEU',
                     'libelle' => 'Jeunesse']);
@@ -531,25 +658,23 @@ class TemplatesAbonnePretsBarcodesExportTest extends TemplatesAbonnePretsAjaxLoa
                     'regles' => '995$w']);
 
     $exemplaire = $this->fixture(Class_Exemplaire::class,
-                   ['id' => 42,
-                    'id_origine' =>198431,
-                    'id_int_bib' => 34,
-                    'code_barres' =>'1984310054',
-                    'section' => 'JEU',
-                    'cote' => 'VAM MdC',
-                    'emplacement' => 'MED',
-                    'notice' => $this->fixture(Class_Notice::class,
-                                               [
-                                                'id' => 22,
-                                                'type_doc' => Class_TypeDoc::LIVRE,
-                                                'unimarc' => (new Class_NoticeUnimarc_Fluent())
-                                                ->zoneWithChildren('200', ['a' => 'Les Vampires de Manhattan',
-                                                                           'f' => 'Melanie de la Cruz',
-                                                                           'h' => 't. 1'])
-                                                ->render()
-
-                                               ])
-                   ]);
+                                 ['id' => 42,
+                                  'id_origine' => 198431,
+                                  'id_int_bib' => 34,
+                                  'code_barres' => '1984310054',
+                                  'section' => 'JEU',
+                                  'cote' => 'VAM MdC',
+                                  'emplacement' => 'MED',
+                                  'notice' => $this->fixture(Class_Notice::class,
+                                                             ['id' => 22,
+                                                              'type_doc' => Class_TypeDoc::LIVRE,
+                                                              'unimarc' => (new Class_NoticeUnimarc_Fluent)
+                                                              ->zoneWithChildren('200', ['a' => 'Les Vampires de Manhattan',
+                                                                                         'f' => 'Melanie de la Cruz',
+                                                                                         'h' => 't. 1'])
+                                                              ->render()
+                                                             ])
+                                 ]);
 
     $comm_params = ['url_serveur' => 'tests/fixtures/orphee.wsdl',
                     'allow_hold_available_items' => true,
@@ -564,40 +689,51 @@ class TemplatesAbonnePretsBarcodesExportTest extends TemplatesAbonnePretsAjaxLoa
   }
 
 
-  public function _beforeOrpheeServiceCreate(){
+  public function _beforeOrpheeServiceCreate()
+  {
     $this->_search_client
+
       ->whenCalled('hasFunction')
       ->with('GetToken')
       ->answers(true)
 
       ->whenCalled('GetToken')
       ->answers(new GetTokenResponse(OrpheeFixtures::TokenResult()))
+
       ->whenCalled('GetInfoUser')
       ->answers(OrpheeFixtures::xmlGetAdhFoix())
-      ->whenCalled('hasFunction')->with('GetAdh')->answers(true)
+
+      ->whenCalled('hasFunction')
+      ->with('GetAdh')
+      ->answers(true)
 
       ->whenCalled('GetAdh')
       ->answers(Storm_Test_ObjectWrapper::mock()
                 ->whenCalled('getXml')
                 ->answers(OrpheeFixtures::xmlGetAdhFoix()))
+
       ->whenCalled('GetLstPret')
-      ->with(GetLstPret::withAdhAndCountPerPage('1301500012' ,2))
+      ->with(GetLstPret::withAdhAndCountPerPage('1301500012', 2))
       ->answers(Storm_Test_ObjectWrapper::mock()
                 ->whenCalled('getXml')
                 ->answers(OrpheeFixtures::getLstPret5()))
+
       ->whenCalled('GetNextPret')
       ->answers(Storm_Test_ObjectWrapper::mock()
                 ->whenCalled('getXml')
                 ->answers(OrpheeFixtures::getNextPret5()))
+
       ->whenCalled('SetCritPrets')
       ->with(setCritPrets::withCodeAndVal(1, setCritPrets::TO_BE_RETURNED))
       ->answers(true)
+
       ->whenCalled('setTri')
       ->answers(true);
   }
 
 
-  public function getPage() :array {
+  public function getPage(): array
+  {
     return [['/abonne/paginated-barcodes-export', 1],
             ['/abonne/paginated-barcodes-export', 2],
             ['/abonne/paginated-loan-export', 1],
@@ -608,34 +744,52 @@ class TemplatesAbonnePretsBarcodesExportTest extends TemplatesAbonnePretsAjaxLoa
   }
 
 
-
-  /** @test
-   *  @dataProvider getPage
+  /**
+   * @test
+   * @dataProvider getPage
    */
-  public function pageShouldContainsdivExportAjaxWithDataExportAndDataExportEnd($url, $page_number) {
-    $this->postDispatch( $url.'/page/'. $page_number,
-                         ['filter' => 'to_be_returned',
-                          'order' => '4_1']);
+  public function pageShouldContainsdivExportAjaxWithDataExportAndDataExportEnd(string $url,
+                                                                                int $page_number)
+  {
+    $this->postDispatch($url . '/page/' . $page_number,
+                        ['filter' => 'to_be_returned',
+                         'order' => '4_1']);
 
-    $this->assertXPath('//div[@class="export_ajax"][@data-export="'. $url .'/page/'. ($page_number + 1) .'"][@data-export-end="'. $url .'"]');
+    $this->assertXPath('//div[@class="export_ajax"][@data-export="'
+                       . $url . '/page/' . ($page_number + 1)
+                       . '"][@data-export-end="' . $url . '"]');
   }
 
 
   /** @test */
-  public function barcodesExportShouldRenderBarcodeFile() {
-    $this->dispatch('/abonne/paginated-barcodes-export');
+  public function barcodesExportShouldRenderBarcodeFile()
+  {
+    $this->postDispatch('/abonne/paginated-barcodes-export/page/1',
+                        ['filter' => 'to_be_returned',
+                         'order' => '4_1']);
+    $this->postDispatch('/abonne/paginated-barcodes-export/page/2',
+                        ['filter' => 'to_be_returned',
+                         'order' => '4_1']);
+
     $this->assertEquals('Code-barre
 1984310054
 3923910054
 5878240054
 3906500054
-', $this->_response->getBody());
+', $this->_fileContentFor('prets_codes_barres_2'));
   }
 
 
   /** @test */
-  public function csvExportShouldRenderCsvFile() {
-    $this->dispatch('/abonne/paginated-csv-export');
+  public function csvExportShouldRenderCsvFile()
+  {
+    $this->postDispatch('/abonne/paginated-csv-export/page/1',
+                        ['filter' => 'to_be_returned',
+                         'order' => '4_1']);
+    $this->postDispatch('/abonne/paginated-csv-export/page/2',
+                        ['filter' => 'to_be_returned',
+                         'order' => '4_1']);
+
     $template = <<<TEMPLATE_RECORD
 "Titre","Auteur","Code-barre","Cote","Support","Section","Emplacement","Date Prêt","Date Retour"
 "Les Vampires de Manhattan : t. 1","Melanie de la Cruz","1984310054","VAM MdC","Livres","JEU Jeunesse","MED Médiathèque","07/01/2015",""
@@ -645,13 +799,22 @@ class TemplatesAbonnePretsBarcodesExportTest extends TemplatesAbonnePretsAjaxLoa
 
 TEMPLATE_RECORD;
 
-    $this->assertEquals($template, $this->_response->getBody());
+    $this->assertEquals($template, $this->_fileContentFor('prets_csv_2'));
   }
 
 
   /** @test */
-  public function loanExportShouldRenderUnimarcFile() {
+  public function loanExportShouldRenderUnimarcFile()
+  {
+    $this->postDispatch('/abonne/paginated-loan-export/page/1',
+                        ['filter' => 'to_be_returned',
+                         'order' => '4_1']);
+    $this->postDispatch('/abonne/paginated-loan-export/page/2',
+                        ['filter' => 'to_be_returned',
+                         'order' => '4_1']);
+
     $this->dispatch('/abonne/paginated-loan-export');
-    $this->assertEquals(109, strlen($this->_response->getBody()));
+    $this->assertEquals(109,
+                        strlen($this->_fileContentFor('fichier_prets_2', '.mrc')));
   }
 }
diff --git a/tests/scenarios/Templates/TemplatesSubTitlesTest.php b/tests/scenarios/Templates/TemplatesSubTitlesTest.php
new file mode 100644
index 00000000000..4ac0735ce63
--- /dev/null
+++ b/tests/scenarios/Templates/TemplatesSubTitlesTest.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Copyright (c) 2012-2024, Agence Française Informatique (AFI). All rights reserved.
+ *
+ * BOKEH is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
+ * the Free Software Foundation.
+ *
+ * There are special exceptions to the terms and conditions of the AGPL as it
+ * is applied to this software (see README file).
+ *
+ * BOKEH is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * along with BOKEH; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
+ */
+
+
+class TemplatesSubTitlesDisplayTest extends AbstractControllerTestCase
+{
+
+  public function setUp()
+  {
+    parent::setUp();
+
+    $profile = $this->_buildTemplateProfil(['id' => 72]);
+
+    (new Class_Profil_Preferences)
+      ->setModulePref($profile,
+                      new Class_Profil_ModuleDefinition('recherche',
+                                                        'resultatsimple'),
+                      ['zones_titre' => '200$e;200$h;200$i;461$t']);
+
+    $unimarc = (new Class_NoticeUnimarc_Fluent)
+      ->zoneWithContent('001', '12345')
+      ->zoneWithChildren('461', ['t' => 'Sept soeurs',
+                                 'v' => '1'])
+      ->zoneWithChildren('700', ['a' => 'JM', 'b' => 'Big']);
+
+    $this->fixture(Class_Notice::class,
+                   ['id' => 125441,
+                    'clef_alpha' => 'MAIA--RILEYL-1-LGF-2023-1',
+                    'titres' => 'SEPT SOEURS',
+                    'unimarc' => $unimarc->render(),
+                    'type' => 1]);
+
+    $this->dispatch('/opac/recherche/viewnotice/clef/MAIA--RILEYL-1-LGF-2023-1/id/125441/tri/%2A/expressionRecherche/sept+soeurs');
+  }
+
+
+  /** @test */
+  public function title_461t_ShouldExistWithValueSeptSoeurs1()
+  {
+    $this->assertXPath('//div[@class="card-title"]/span[@class="461t 461t_1"][text()="Sept soeurs n° 1"]');
+  }
+
+
+  /** @test */
+  public function configurationSubtitleShouldNotExistInTemplateMode()
+  {
+    $this->assertNotXPath('//span[@class="461$t"]');
+  }
+}
+
+
+
+
+class TemplatesSubTitlesTryOnTest extends AbstractControllerTestCase
+{
+
+  protected int $_herisson_id;
+
+  public function setUp()
+  {
+    parent::setUp();
+
+    Class_Systeme_ModulesAccueil::reset();
+    Class_AdminVar::set('TEMPLATING', 1);
+
+    $profile = $this->_buildTemplateProfil(['id' => 23,
+                                            'template' => 'HISTORIC']);
+
+    (new Class_Profil_Preferences)
+      ->setModulePref($profile,
+                      new Class_Profil_ModuleDefinition('recherche',
+                                                        'resultatsimple'),
+                      ['zones_titre' => '200$e;200$h;200$i;461$t;330$a']);
+
+    $this->_herisson_id = (new Herisson_Template)->tryOn($profile);
+  }
+
+
+  /** @test */
+  public function zonesTitreShouldHaveBeenReset()
+  {
+    $this->assertEquals(['200$e', '200$h', '200$i'],
+                        Class_Profil::find($this->_herisson_id)->getZonesTitre());
+  }
+}
-- 
GitLab