From 14e5376f1ad19ec5fbe2b848920bd962cdabb684 Mon Sep 17 00:00:00 2001
From: Ghislain Loas <gloas@afi-sa.fr>
Date: Wed, 5 Feb 2025 16:58:11 +0100
Subject: [PATCH] fix ajax_paginated_list not using loans

---
 VERSIONS_HOTLINE/213110                       |   1 +
 .../Helper/Template/RenderingHorizontal.php   |   3 +-
 .../View/Helper/Template/ReseauxSociaux.php   |   6 +-
 .../Helper/Template/SocialNetworksActions.php |   1 -
 .../Library/PaginatedCollectionHelper.php     |  24 +++-
 .../HistoryLoans.php                          |  29 ++++
 .../PaginatedCollectionHelper/Loans.php       |  29 ++++
 .../Intonation/Library/Selection.php          |   1 +
 .../templates/Intonation/Library/Settings.php |   1 +
 .../Library/View/Wrapper/RecordToSelect.php   |   4 +-
 .../View/Abonne/HistoryLoansList.php          |   3 +-
 .../Intonation/View/Abonne/LoansList.php      |   2 +-
 .../modules/AbstractControllerTestCase.php    |   7 +-
 tests/fixtures/KohaFixtures.php               |  44 ++++++
 .../Class/WebService/SIGB/Koha2405Test.php    |  24 ++--
 ...neReservationAjaxPaginatedDispatchTest.php | 111 ++++++++++++++
 .../Koha2405AbonneReservationsTest.php        | 136 ++++++++++++++++++
 .../TemplatesActivitiesDetailSessionTest.php  |   2 +-
 .../Templates/TemplatesArticlesTest.php       |   4 +-
 .../Templates/TemplatesRecordsTest.php        |  11 +-
 .../Templates/TemplatesSearchTest.php         |   4 +-
 21 files changed, 408 insertions(+), 39 deletions(-)
 create mode 100644 VERSIONS_HOTLINE/213110
 create mode 100644 library/templates/Intonation/Library/PaginatedCollectionHelper/HistoryLoans.php
 create mode 100644 library/templates/Intonation/Library/PaginatedCollectionHelper/Loans.php
 create mode 100644 tests/scenarios/Templates/Koha2405AbonneReservationAjaxPaginatedDispatchTest.php
 create mode 100644 tests/scenarios/Templates/Koha2405AbonneReservationsTest.php

diff --git a/VERSIONS_HOTLINE/213110 b/VERSIONS_HOTLINE/213110
new file mode 100644
index 00000000000..6a0744eff69
--- /dev/null
+++ b/VERSIONS_HOTLINE/213110
@@ -0,0 +1 @@
+ - correctif #213110 : Magasin de thèmes : correction de l'affichage des réservations paginée
\ No newline at end of file
diff --git a/library/ZendAfi/View/Helper/Template/RenderingHorizontal.php b/library/ZendAfi/View/Helper/Template/RenderingHorizontal.php
index cb2b3565868..0402e66bb4e 100644
--- a/library/ZendAfi/View/Helper/Template/RenderingHorizontal.php
+++ b/library/ZendAfi/View/Helper/Template/RenderingHorizontal.php
@@ -54,7 +54,8 @@ class ZendAfi_View_Helper_Template_RenderingHorizontal extends ZendAfi_View_Help
 
     return $this->_tag('div',
                        $this->view->grid($element->getAnchor()
-                                         . $this->view->div(['class' => $this->_img_class],
+                                         . $this->view->div(['class' => $this->_img_class,
+                                                             'aria-hidden' => 'true'],
                                                             $img)
 
                                          . $this->view->div(['class' => $this->_content_class],
diff --git a/library/ZendAfi/View/Helper/Template/ReseauxSociaux.php b/library/ZendAfi/View/Helper/Template/ReseauxSociaux.php
index 0b367e10d43..49efda2d25e 100644
--- a/library/ZendAfi/View/Helper/Template/ReseauxSociaux.php
+++ b/library/ZendAfi/View/Helper/Template/ReseauxSociaux.php
@@ -31,10 +31,8 @@ class ZendAfi_View_Helper_Template_ReseauxSociaux
                                   ->setText($clef)
                                   ->setUrl($url)
                                   ->setImage($this->view->templateIco($clef, 'utils'))
-                                  ->setTitle($this->_('Partager sur %s', $clef))
-                                  ->setScreenReaderText($this->_('Partager %s ',
-                                                           $url_table['titre']))
-                                  ->setClass('reseau-social-img py-1 my-1 d-block')
+                                  ->setScreenReaderText($this->_('Partager %s', $url_table['titre']))
+                                  ->setClass('reseau-social-img social_network_link')
                                   ->setAttrib('onclick', $script));
   }
 }
diff --git a/library/ZendAfi/View/Helper/Template/SocialNetworksActions.php b/library/ZendAfi/View/Helper/Template/SocialNetworksActions.php
index 2e09ae747f0..836441c7581 100644
--- a/library/ZendAfi/View/Helper/Template/SocialNetworksActions.php
+++ b/library/ZendAfi/View/Helper/Template/SocialNetworksActions.php
@@ -38,7 +38,6 @@ class ZendAfi_View_Helper_Template_SocialNetworksActions
     $this->_actions [] = (new Intonation_Library_Link)
       ->setImage($this->view->templateIco($clef, 'utils'))
       ->setText($clef)
-      ->setTitle($this->_('Partager sur %s',  $clef))
       ->setScreenReaderText($this->_('Partager %s ', $url_table['titre']))
       ->setUrl($url)
       ->setClass('share_record_on_' . $clef)
diff --git a/library/templates/Intonation/Library/PaginatedCollectionHelper.php b/library/templates/Intonation/Library/PaginatedCollectionHelper.php
index d129f4ca4f3..ddb934e4256 100644
--- a/library/templates/Intonation/Library/PaginatedCollectionHelper.php
+++ b/library/templates/Intonation/Library/PaginatedCollectionHelper.php
@@ -101,19 +101,33 @@ class Intonation_Library_PaginatedCollectionHelper
 
   protected function _initExternalAjaxHelper(): self
   {
-    if ( ! $user = Class_Users::getIdentity())
+    if ( ! $helper = $this->_externalAjaxHelperClassNameForUser())
       return $this;
 
-    if ( !$helper = (('' !== $this->_external_ajax_helper_classname)
-                     ? $this->_external_ajax_helper_classname
-                     : $user->getExternalAjaxLoansHelperClassname()))
-      return $this;
+    $this->setExternalAjaxHelperClassname($helper);
 
     $this->_external_ajax_helper = new $helper($this->_view);
     return $this;
   }
 
 
+  protected function _externalAjaxHelperClassNameForUser(): string
+  {
+    if ( $helper = $this->_external_ajax_helper_classname)
+      return $helper;
+
+    return ($user = Class_Users::getIdentity())
+      ? $this->_externalAjaxHelperClassNameWithUser($user)
+      : '';
+  }
+
+
+  protected function _externalAjaxHelperClassNameWithUser(Class_Users $user): string
+  {
+    return '';
+  }
+
+
   protected function _setParams(array $params): self
   {
     return $this
diff --git a/library/templates/Intonation/Library/PaginatedCollectionHelper/HistoryLoans.php b/library/templates/Intonation/Library/PaginatedCollectionHelper/HistoryLoans.php
new file mode 100644
index 00000000000..188700269de
--- /dev/null
+++ b/library/templates/Intonation/Library/PaginatedCollectionHelper/HistoryLoans.php
@@ -0,0 +1,29 @@
+<?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 Intonation_Library_PaginatedCollectionHelper_HistoryLoans extends Intonation_Library_PaginatedCollectionHelper
+{
+  protected function _externalAjaxHelperClassNameWithUser(Class_Users $user): string
+  {
+    return $user->getExternalAjaxHistoryLoansHelperClassname();
+  }
+}
diff --git a/library/templates/Intonation/Library/PaginatedCollectionHelper/Loans.php b/library/templates/Intonation/Library/PaginatedCollectionHelper/Loans.php
new file mode 100644
index 00000000000..b289d3475e9
--- /dev/null
+++ b/library/templates/Intonation/Library/PaginatedCollectionHelper/Loans.php
@@ -0,0 +1,29 @@
+<?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 Intonation_Library_PaginatedCollectionHelper_Loans extends Intonation_Library_PaginatedCollectionHelper
+{
+  protected function _externalAjaxHelperClassNameWithUser(Class_Users $user): string
+  {
+    return $user->getExternalAjaxLoansHelperClassname();
+  }
+}
diff --git a/library/templates/Intonation/Library/Selection.php b/library/templates/Intonation/Library/Selection.php
index 9e9b5a52254..f998e35cb18 100644
--- a/library/templates/Intonation/Library/Selection.php
+++ b/library/templates/Intonation/Library/Selection.php
@@ -101,6 +101,7 @@ class Intonation_Library_Selection {
                                                'library'))
       ->setClass($this->getClass())
       ->setTitle($this->_getTitleForContext(false))
+      ->setAriaLabel($this->_getTitleForContext())
       ->setScreenReaderText($this->_getTitleForContext())
       ->setPopup($popup);
   }
diff --git a/library/templates/Intonation/Library/Settings.php b/library/templates/Intonation/Library/Settings.php
index ef6b54aaefe..de6fc2e9292 100644
--- a/library/templates/Intonation/Library/Settings.php
+++ b/library/templates/Intonation/Library/Settings.php
@@ -396,6 +396,7 @@ class Intonation_Library_Settings extends Intonation_System_Abstract {
                                                   'span class custom_field_actitivy_session' => 'badge-light',
                                                   'span class session_registration_warning' => 'badge-warning',
                                                   'span class session_registration_success' => 'badge-success',
+                                                  'a class social_network_link' => ' py-1 my-1 d-block',
                           ],
 
                           'icons_map_doc_types' => [],
diff --git a/library/templates/Intonation/Library/View/Wrapper/RecordToSelect.php b/library/templates/Intonation/Library/View/Wrapper/RecordToSelect.php
index f8c596d337f..96c89891267 100644
--- a/library/templates/Intonation/Library/View/Wrapper/RecordToSelect.php
+++ b/library/templates/Intonation/Library/View/Wrapper/RecordToSelect.php
@@ -56,9 +56,9 @@ class Intonation_Library_View_Wrapper_RecordToSelect
     $add = (new Intonation_Library_Link)
       ->setText($this->_('Ajouter'))
       ->setImage($in ? $this->getIco('check', 'utils') : $this->getIco('add', 'utils'))
-      ->setTitle($this->_('Ajouter à la sélection %s', $this->_selection->getLibelle()))
+      ->setTitle($this->_('Ajouter %s à la sélection %s', $this->getMainTitleAsText(), $this->_selection->getLibelle()))
       ->setScreenReaderText($this->_('le document %s à la sélection %s',
-                                     $this->getMainTitle(),
+                                     $this->getMainTitleAsText(),
                                      $this->_selection->getLibelle()))
       ->setClass('add_to_selection_link')
       ->setAttrib('id', $id)
diff --git a/library/templates/Intonation/View/Abonne/HistoryLoansList.php b/library/templates/Intonation/View/Abonne/HistoryLoansList.php
index f73419e8b6e..53ebba58161 100644
--- a/library/templates/Intonation/View/Abonne/HistoryLoansList.php
+++ b/library/templates/Intonation/View/Abonne/HistoryLoansList.php
@@ -33,8 +33,7 @@ class Intonation_View_Abonne_HistoryLoansList extends Intonation_View_Abonne_Loa
   {
     if ($this->_config->useIlsForPagination())
     {
-      $helper = (new Intonation_Library_PaginatedCollectionHelper($collection))
-        ->setExternalAjaxHelperClassname(Class_Users::getIdentity()->getExternalAjaxHistoryLoansHelperClassname())
+      $helper = (new Intonation_Library_PaginatedCollectionHelper_HistoryLoans($collection))
         ->warmUp($this->view, $this->_config->getParams());
 
       return $this->view->paginatedCollection($helper);
diff --git a/library/templates/Intonation/View/Abonne/LoansList.php b/library/templates/Intonation/View/Abonne/LoansList.php
index 210d7d9d6d1..bef2094a0d9 100644
--- a/library/templates/Intonation/View/Abonne/LoansList.php
+++ b/library/templates/Intonation/View/Abonne/LoansList.php
@@ -60,7 +60,7 @@ class Intonation_View_Abonne_LoansList extends ZendAfi_View_Helper_BaseHelper {
                                      $count_total,
                                      $this->_config->getCurrentPage());
 
-    $helper = (new Intonation_Library_PaginatedCollectionHelper($collection))
+    $helper = (new Intonation_Library_PaginatedCollectionHelper_Loans($collection))
       ->warmUp($this->view, $this->_config->getParams())
       ->setSortOptions($this->_config->getSortOptions());
 
diff --git a/tests/application/modules/AbstractControllerTestCase.php b/tests/application/modules/AbstractControllerTestCase.php
index f3882c40179..617e2b04579 100644
--- a/tests/application/modules/AbstractControllerTestCase.php
+++ b/tests/application/modules/AbstractControllerTestCase.php
@@ -608,10 +608,13 @@ abstract class AbstractControllerTestCase extends Zend_Test_PHPUnit_ControllerTe
 
     foreach ($this->queryXPath('//a[@title]') as $element) {
       $title = '';
-      if ($attr = $element->getAttribute('title'))
-        $title = $attr;
+
       if ($attr = $element->textContent)
         $title = $attr;
+
+      if ($attr = $element->getAttribute('title'))
+        $title = $attr;
+
       if ($attr = $element->getAttribute('aria-label'))
         $title = $attr;
 
diff --git a/tests/fixtures/KohaFixtures.php b/tests/fixtures/KohaFixtures.php
index 742fbb1b1d1..0f43a1ffa9c 100644
--- a/tests/fixtures/KohaFixtures.php
+++ b/tests/fixtures/KohaFixtures.php
@@ -4178,6 +4178,50 @@ class KohaFixtures {
           }
 
 
+  public static function xmlGetPatronInfoJamesBondWithMoreHolds() {
+    $hold_string = '';
+    for ($i=0; $i<30; $i++)
+      $hold_string .= '<hold>
+                <expirationdate>2019-12-31</expirationdate>
+                <reservedate>2019-07-26</reservedate>
+                <biblionumber>'. $i .'</biblionumber>
+                <title>Élémentaire mon cher polar '.$i .'</title>
+                <item>
+                  <itemnumber>11219'. $i.'</itemnumber>
+                  <withdrawn>0</withdrawn>
+                  <biblionumber>96629</biblionumber>
+                  <barcode>MALLE00010</barcode>
+                  <title>Élémentaire mon cher polar '. $i. '</title>
+                  <notforloan>0</notforloan>
+                  <itemtype>MAL_EXPO</itemtype>
+                  <homebranch>BDY</homebranch>
+                  <holdingbranch>BDY</holdingbranch>
+                  <itype>PRET_MALLE</itype>
+                  <biblioitemnumber>966'. $i.'</biblioitemnumber>
+                </item>
+                <branchname>BDP</branchname>
+                <reserve_id>11'. $i .'</reserve_id>
+                <itemnumber>11219'. $i .'</itemnumber>
+                <status>NEW</status>
+                <priority>1</priority>
+             </hold>';
+
+
+    return '<?xml version="1.0" encoding="UTF-8" ?>
+        <GetPatronInfo>
+          <borrowernumber>007</borrowernumber>
+          <cardnumber>007</cardnumber>
+          <itype>I_WILL_CRASH_YOU</itype>
+<holds>'
+      . $hold_string
+. '</holds>
+          <loans>
+          </loans>
+       </GetPatronInfo>'
+          ;
+          }
+
+
   public static function xmlGetRecordsElementaireMonCherPolar () {
     return
           '<?xml version="1.0" encoding="ISO-8859-1" ?>
diff --git a/tests/library/Class/WebService/SIGB/Koha2405Test.php b/tests/library/Class/WebService/SIGB/Koha2405Test.php
index 7951158f2fb..0c44688aa4a 100644
--- a/tests/library/Class/WebService/SIGB/Koha2405Test.php
+++ b/tests/library/Class/WebService/SIGB/Koha2405Test.php
@@ -21,7 +21,7 @@
 
 require_once 'tests/fixtures/Koha2405Fixtures.php';
 
-abstract class Koha2405TestCase extends AbstractControllerTestCase
+abstract class Koha2405VersionTestCase extends AbstractControllerTestCase
 {
 
   public function setUp(): void
@@ -120,7 +120,7 @@ abstract class Koha2405TestCase extends AbstractControllerTestCase
 
 
 
-class Koha2405LoanPageTest extends Koha2405TestCase
+class Koha2405LoanPageTest extends Koha2405VersionTestCase
 {
 
   public function setUp(): void
@@ -154,7 +154,7 @@ class Koha2405LoanPageTest extends Koha2405TestCase
 
 
 
-class Koha2405AjaxLoansDispatchTest extends Koha2405TestCase
+class Koha2405AjaxLoansDispatchTest extends Koha2405VersionTestCase
 {
 
   public function setUp(): void
@@ -210,7 +210,7 @@ class Koha2405AjaxLoansDispatchTest extends Koha2405TestCase
     if (version_compare(PHP_VERSION, '8.0.0') < 0)
       return $this->assertTrue(true);
 
-    $this->assertXPathContentContains('//script', '$("#exportable-button-unimarc_1eb34a59cfe030c0e709e41080dcfa85").export_button()', $this->_response->getBody());
+    $this->assertXPathContentContains('//script', '$("#exportable-button-unimarc_1eb34a59cfe030c0e709e41080dcfa85").export_button()');
   }
 
 
@@ -326,7 +326,7 @@ class Koha2405AjaxLoansDispatchTest extends Koha2405TestCase
 
 
 
-class Koha2405AjaxPaginatedSize3DispatchTest extends Koha2405TestCase
+class Koha2405AjaxPaginatedSize3DispatchTest extends Koha2405VersionTestCase
 {
 
   public function setUp(): void
@@ -401,7 +401,7 @@ class Koha2405AjaxPaginatedSize3DispatchTest extends Koha2405TestCase
 
 
 
-class Koha2405AjaxLoansPage3Test extends Koha2405TestCase
+class Koha2405AjaxLoansPage3Test extends Koha2405VersionTestCase
 {
 
   public function setUp(): void
@@ -462,7 +462,7 @@ class Koha2405AjaxLoansPage3Test extends Koha2405TestCase
 
 
 
-class Koha2405IndexAjaxPaginatedListLateLoansFilterDispatchTest extends Koha2405TestCase
+class Koha2405IndexAjaxPaginatedListLateLoansFilterDispatchTest extends Koha2405VersionTestCase
 {
 
   public function setUp(): void
@@ -520,7 +520,7 @@ class Koha2405IndexAjaxPaginatedListLateLoansFilterDispatchTest extends Koha2405
 
 
 
-class Koha2405AjaxLoansByIssueDateTest extends Koha2405TestCase
+class Koha2405AjaxLoansByIssueDateTest extends Koha2405VersionTestCase
 {
 
   public function setUp(): void
@@ -589,7 +589,7 @@ class Koha2405AjaxLoansByIssueDateTest extends Koha2405TestCase
 
 
 
-class Koha2405AjaxLoansByDueDateTest extends Koha2405TestCase
+class Koha2405AjaxLoansByDueDateTest extends Koha2405VersionTestCase
 {
 
   public function setUp(): void
@@ -657,7 +657,7 @@ class Koha2405AjaxLoansByDueDateTest extends Koha2405TestCase
 
 
 
-class Koha2405AjaxLoansByOnHoldTest extends Koha2405TestCase
+class Koha2405AjaxLoansByOnHoldTest extends Koha2405VersionTestCase
 {
 
   public function setUp(): void
@@ -710,7 +710,7 @@ class Koha2405AjaxLoansByOnHoldTest extends Koha2405TestCase
 
 
 
-class Koha2405AjaxLoansHistoryTest extends Koha2405TestCase
+class Koha2405AjaxLoansHistoryTest extends Koha2405VersionTestCase
 {
 
   public function setUp(): void
@@ -773,7 +773,7 @@ class Koha2405AjaxLoansHistoryTest extends Koha2405TestCase
 
 
 
-class Koha2405AjaxLoansEmptyWithFilterTest extends Koha2405TestCase
+class Koha2405AjaxLoansEmptyWithFilterTest extends Koha2405VersionTestCase
 {
 
   public function setUp(): void
diff --git a/tests/scenarios/Templates/Koha2405AbonneReservationAjaxPaginatedDispatchTest.php b/tests/scenarios/Templates/Koha2405AbonneReservationAjaxPaginatedDispatchTest.php
new file mode 100644
index 00000000000..e2f45bc6791
--- /dev/null
+++ b/tests/scenarios/Templates/Koha2405AbonneReservationAjaxPaginatedDispatchTest.php
@@ -0,0 +1,111 @@
+<?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
+ */
+
+
+require_once 'tests/fixtures/Koha2405Fixtures.php';
+
+
+class Koha2405AbonneReservationAjaxPaginatedDispatchTest
+  extends AbstractControllerTestCase
+{
+
+  public function setUp() : void
+  {
+    parent::setUp();
+
+    $this->_buildIntonation();
+
+    $this->fixture(Class_IntBib::class,
+                   ['id' => 21,
+                    'comm_sigb' => Class_IntBib::COM_KOHA2405,
+                    'id_bib' => 16,
+                    'comm_params' => serialize(['url_serveur' => 'https://koha-community/ilsdi.pl',
+                                                'api_user' => 'koha_admin',
+                                                'api_pass' => 'k0h@_P455'])]);
+
+    $user =
+      $this->fixture(Class_Users::class,
+                     ['id' => 34,
+                      'login' => 'dupont',
+                      'password' => 'arcadia',
+                      'role_level' => ZendAfi_Acl_AdminControllerRoles::ABONNE_SIGB,
+                      'nom' => 'Super bien',
+                      'prenom' => 'Olivier',
+                      'mail' => 'old@mail.org',
+                      'id_sigb' => '96138',
+                      'idabon' => '11111111',
+                      'id_site' => 21,
+                      'id_int_bib' => 21]);
+
+    ZendAfi_Auth::getInstance()->logUser($user);
+
+    Storm_Cache::beVolatile();
+
+    Class_HttpClientFactory::forTest();
+
+    Class_HttpClientFactory::getInstance()
+      ->getLastHttpClient()
+      ->addRequestWithResponse('https://koha-community:443/ilsdi.pl?service=GetPatronInfo'
+                               . '&patron_id=96138&show_contact=1&show_loans=0&show_holds=1',
+                               KohaFixtures::xmlGetPatronInfoJamesBondWithMoreHolds())
+
+      ->addRequestWithResponse('https://koha-community:443/ilsdi.pl/patrons/007/checkouts?_page=1&_per_page=1&_order_by=checkout_date',
+                               Koha2405Fixtures::jsonLoansPage1(),
+                               ['user' => 'koha_admin', 'password' => 'k0h@_P455'],
+                               ['X-total-count' => 5])
+
+      ->addRequestWithResponse('https://koha-community:443/ilsdi.pl/patrons/007/checkouts?_page=1&_per_page=20&_order_by=checkout_date',
+                               Koha2405Fixtures::jsonLoansPage2(),
+                               ['user' => 'koha_admin', 'password' => 'k0h@_P455'],
+                               ['X-total-count' => 5]);
+
+    $view_renderer = new ZendAfi_Controller_Action_Helper_ViewRenderer;
+    $view_renderer->preDispatch();
+
+    $view_renderer->view->abonne_HoldsBoard($user);
+
+    $this->dispatch('/opac/index/ajax-paginated-list/id/85a7b6df7957594b8f8964cd06e62ee8/size/2/page/2');
+  }
+
+
+  /** @test */
+  public function pageShouldContainsIntonationLibraryViewWrapperHolds()
+  {
+    $this->assertXPathCount('//div[contains(@class,"title_Intonation_Library_View_Wrapper_Hold")]',
+                            2);
+  }
+
+
+  /** @test */
+  public function reservationResponseTitleShouldDisplayHoldsWithTitleElementaireMonCherPolar()
+  {
+    $this->assertXPathContentContains('(//div[contains(@class,"card_title_Intonation_Library_View_Wrapper_Hold")])[1]//div[@class="document_title"]',
+                                      'mentaire mon cher polar 2');
+  }
+
+
+  /** @test */
+  public function reservationResponseTitleShouldDisplayHoldsWithTitleMentaireMonCherPolar3()
+  {
+    $this->assertXPathContentContains('(//div[contains(@class,"card_title_Intonation_Library_View_Wrapper_Hold")])[2]//div[@class="document_title"]',
+                                      'mentaire mon cher polar 3');
+  }
+}
diff --git a/tests/scenarios/Templates/Koha2405AbonneReservationsTest.php b/tests/scenarios/Templates/Koha2405AbonneReservationsTest.php
new file mode 100644
index 00000000000..41a0ecd0aff
--- /dev/null
+++ b/tests/scenarios/Templates/Koha2405AbonneReservationsTest.php
@@ -0,0 +1,136 @@
+<?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
+ */
+
+
+require_once 'tests/fixtures/Koha2405Fixtures.php';
+
+
+class Koha2405AbonneReservationsDispatchTest
+  extends AbstractControllerTestCase
+{
+
+  public function setUp() : void
+  {
+    parent::setUp();
+
+    $this->_buildIntonation();
+
+    $this->fixture(Class_IntBib::class,
+                   ['id' => 21,
+                    'comm_sigb' => Class_IntBib::COM_KOHA2405,
+                    'id_bib' => 16,
+                    'comm_params' => serialize(['url_serveur' => 'https://koha-community/ilsdi.pl',
+                                                'api_user' => 'koha_admin',
+                                                'api_pass' => 'k0h@_P455'])]);
+
+    $user =
+      $this->fixture(Class_Users::class,
+                     ['id' => 34,
+                      'login' => 'dupont',
+                      'password' => 'arcadia',
+                      'role_level' => ZendAfi_Acl_AdminControllerRoles::ABONNE_SIGB,
+                      'nom' => 'Super bien',
+                      'prenom' => 'Olivier',
+                      'mail' => 'old@mail.org',
+                      'id_sigb' => '96138',
+                      'idabon' => '11111111',
+                      'id_site' => 21,
+                      'id_int_bib' => 21]);
+
+    ZendAfi_Auth::getInstance()->logUser($user);
+
+    Storm_Cache::beVolatile();
+
+    Class_HttpClientFactory::forTest();
+
+    Class_HttpClientFactory::getInstance()
+      ->getLastHttpClient()
+      ->addRequestWithResponse('https://koha-community:443/ilsdi.pl?service=GetPatronInfo'
+                               . '&patron_id=96138&show_contact=1&show_loans=0&show_holds=1',
+                               KohaFixtures::xmlGetPatronInfoJamesBondWithMoreHolds())
+
+      ->addRequestWithResponse('https://koha-community:443/ilsdi.pl/patrons/007/checkouts?_page=1&_per_page=1&_order_by=checkout_date',
+                               Koha2405Fixtures::jsonLoansPage1(),
+                               ['user' => 'koha_admin', 'password' => 'k0h@_P455'],
+                               ['X-total-count' => 5])
+
+      ->addRequestWithResponse('https://koha-community:443/ilsdi.pl/patrons/007/checkouts?_page=1&_per_page=20&_order_by=checkout_date',
+                               Koha2405Fixtures::jsonLoansPage1(),
+                               ['user' => 'koha_admin', 'password' => 'k0h@_P455'],
+                               ['X-total-count' => 5]);
+
+    $this->dispatch('/abonne/reservations');
+  }
+
+
+  /** @test */
+  public function shouldDisplayTenHolds()
+  {
+    $this->assertXPathCount('//div[contains(@class,"title_Intonation_Library_View_Wrapper_Hold")]',
+                            10);
+  }
+
+
+  /** @test */
+  public function numberOfHoldsShouldBe30()
+  {
+    $this->assertXPathContentContains('//div//span[@class="truncate_list_size_number"]', '30');
+  }
+
+
+  /** @test */
+  public function monCherPolarOneShouldBePresent()
+  {
+    $this->assertXPathContentContains('(//div[@class="card-title card_title card_title_Intonation_Library_View_Wrapper_Hold"])//div[@class="document_title"]',
+                                      'Élémentaire mon cher polar 1');
+  }
+
+
+
+    /** @test */
+  public function monCherPolarNineShouldBePresent()
+  {
+    $this->assertXPathContentContains('(//div[@class="card-title card_title card_title_Intonation_Library_View_Wrapper_Hold"])//div[@class="document_title"]',
+                                      'Élémentaire mon cher polar 9');
+  }
+
+
+    /** @test */
+  public function allHttpCallsShouldHaveBeenCalled() {
+    Class_HttpClientFactory::getInstance()
+      ->getLastHttpClient()
+      ->checkCalls($this);
+  }
+
+
+  /** @test */
+  public function reservationsPageShouldBeHTML5Valid()
+  {
+    $this->assertHTML5();
+  }
+
+
+  /** @test */
+  public function reservationsPageShouldBeAccessible()
+  {
+    $this->assertAccessible();
+  }
+}
diff --git a/tests/scenarios/Templates/TemplatesActivitiesDetailSessionTest.php b/tests/scenarios/Templates/TemplatesActivitiesDetailSessionTest.php
index 25148d0a292..a771c853439 100644
--- a/tests/scenarios/Templates/TemplatesActivitiesDetailSessionTest.php
+++ b/tests/scenarios/Templates/TemplatesActivitiesDetailSessionTest.php
@@ -79,7 +79,7 @@ class TemplatesActivitiesDetailSessionTest extends AbstractControllerTestCase
 
 
   /** @test */
-  public function pageShouldBeAccessible()
+  public function pageDetailSessionShouldBeAccessible()
   {
     $this->assertAccessible();
   }
diff --git a/tests/scenarios/Templates/TemplatesArticlesTest.php b/tests/scenarios/Templates/TemplatesArticlesTest.php
index bf09339323d..c647e075e87 100644
--- a/tests/scenarios/Templates/TemplatesArticlesTest.php
+++ b/tests/scenarios/Templates/TemplatesArticlesTest.php
@@ -250,8 +250,8 @@ class TemplatesArticlesWidgetTest extends TemplatesArticlesWidgetTestCase {
 
 
   /** @test */
-  public function pageShouldBeAccessible() {
-    $this->assertAccessible(true , $this->_response->getBody());
+  public function pageArticleShouldBeAccessible() {
+    $this->assertAccessible();
   }
 
 
diff --git a/tests/scenarios/Templates/TemplatesRecordsTest.php b/tests/scenarios/Templates/TemplatesRecordsTest.php
index 7e9228b7f8c..47966a0aea0 100644
--- a/tests/scenarios/Templates/TemplatesRecordsTest.php
+++ b/tests/scenarios/Templates/TemplatesRecordsTest.php
@@ -40,8 +40,11 @@ class TemplatesRecordsWidgetTest extends AbstractControllerTestCase
       $this->fixture(Class_Notice::class,
                      ['id' => $i,
                       'type_doc' => Class_TypeDoc::LIVRE,
-                      'titre_principal' => 'Thérapie de groupe ' . $i,
-                      'resume' => 'Une bonne BD de Manu']);
+                      'resume' => 'Une bonne BD de Manu',
+                      'unimarc' => (new Class_NoticeUnimarc_Fluent)
+                      ->zoneWithContent('001', '78978979'.$i)
+                      ->zoneWithChildren('200', ['a' => 'Thérapie de groupe ' . $i])->render()
+]);
 
     Storm_Cache::beVolatile();
     Class_AdminVar::set('CACHE_ACTIF', 1);
@@ -78,9 +81,9 @@ class TemplatesRecordsWidgetTest extends AbstractControllerTestCase
 
 
   /** @test */
-  public function pageShouldBeAccessible()
+  public function pageHomeShouldBeAccessible()
   {
-    $this->assertAccessible(true, $this->_response->getBody());
+    $this->assertAccessible();
   }
 }
 
diff --git a/tests/scenarios/Templates/TemplatesSearchTest.php b/tests/scenarios/Templates/TemplatesSearchTest.php
index 12d6dbc4608..3055fd99009 100644
--- a/tests/scenarios/Templates/TemplatesSearchTest.php
+++ b/tests/scenarios/Templates/TemplatesSearchTest.php
@@ -511,7 +511,7 @@ class TemplatesSearchViewRecordTest extends TemplatesIntonationTestCase {
 
   /** @test */
   public function linkShareOnFacebookShouldHaveClassReseauSocialImg() {
-    $this->assertXPath('//div/a[@class="card-link reseau-social-img py-1 my-1 d-block"]');
+    $this->assertXPath('//div/a[@class="card-link reseau-social-img social_network_link py-1 my-1 d-block"]');
   }
 }
 
@@ -1169,7 +1169,7 @@ class TemplatesSearchDispatchWithNouveauteNowParamTest extends AbstractControlle
 
 
   /** @test */
-  public function pageShouldBeHtml5Valid() {
+  public function searchPageShouldBeHtml5Valid() {
     $this->assertHTML5();
   }
 }
-- 
GitLab