Skip to content
Snippets Groups Projects
RechercheControllerReservationTest.php 55.9 KiB
Newer Older
<?php
/**
 * Copyright (c) 2012-2014, Agence Française Informatique (AFI). All rights reserved.
 *
Laurent's avatar
Laurent committed
 * 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).
 *
Laurent's avatar
Laurent committed
 * 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
Laurent's avatar
Laurent committed
 * along with BOKEH; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA

abstract class RechercheControllerReservationTestCase
  extends AbstractControllerTestCase {

  protected $_json, $_xpath,
    $_storm_default_to_volatile = true;
Patrick Barroca's avatar
Patrick Barroca committed
  public function setUp() {
    parent::setUp();
    $this->fixture(Class_CodifAnnexe::class,
                   ['id' => 2,
                    'code' => '36',
                    'id_origine' => '36',
                    'libelle' => 'Annecy']);
    $this->fixture(Class_CodifAnnexe::class,
                   ['id' => 3,
                    'code' => '37',
                    'id_origine' => '37',
                    'libelle' => 'Cran']);
    $this->fixture(Class_Notice::class,
                   ['id' => 124,
                    'titre' => 'Aimer'
                   ]);

    $this->fixture(Class_IntBib::class,
                   ['id' => 12,
                    'sigb_comm' => Class_IntBib::COM_NANOOK,
                    'comm_params' => ['url_serveur' => 'http://valensol.net']]);

    $this->fixture(Class_Exemplaire::class,
                   ['id' => 13425,
                    'id_origine' => 12,
                    'id_int_bib' => 12,
                    'notice_id' => 124,
                    'code_barres' => '1242',
                   ]);

abstract class RechercheControllerReservationWithPickupChoiceTestCase
  extends RechercheControllerReservationTestCase {

  public function setUp() {
    parent::setUp();
    Class_CosmoVar::setValueOf('site_retrait_resa',
                               Class_CosmoVar::PICKUP_LOCATION_CHOICE);
  }
}



class RechercheControllerReservationPickupAjaxActionWithChosenPickupTest
  extends RechercheControllerReservationWithPickupChoiceTestCase {

  public function setUp() {
    parent::setUp();

    $this->dispatch('recherche/reservation-pickup-ajax?id_bib=2&id_origine=12&code_annexe=36&copy_id=13425',true);
Patrick Barroca's avatar
Patrick Barroca committed
    $this->_json = json_decode($this->_response->getBody());
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function shouldRenderAnnecyCheckedRadio() {
    $this->_xpath->assertXPath($this->_json->content,
                               '//input[@name="code_annexe"][@value="36"][@checked="checked"]',$this->_json->content);
Patrick Barroca's avatar
Patrick Barroca committed
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function shouldRenderCranRadio() {
    $this->_xpath->assertXPath($this->_json->content,
                               '//input[@name="code_annexe"][@value="37"]');
Patrick Barroca's avatar
Patrick Barroca committed
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function layoutShouldBeEmpty() {
    $this->_xpath->assertNotXPath($this->_json->content, '//div[@id="banniere"]');
  }
class RechercheControllerReservationPickupAjaxActionPostTest
  extends RechercheControllerReservationWithPickupChoiceTestCase {
  /** @test */
  public function responseShouldRedirectToReservationajaxAction() {
Ghislain Loas's avatar
Ghislain Loas committed
    $this->postDispatch('recherche/reservation-pickup-ajax',
                        ['id_bib' => 2,
                         'id_origine' => 12,
                         'copy_id' => 13425,
    $this->assertRedirectTo('/recherche/reservationajax/code_annexe/36');
  /** @test */
  public function withoutAvailablePickupLocationPostResponseShouldAnswerError() {
    Class_CodifAnnexe::deleteBy([]);
    $this->postDispatch('recherche/reservation-pickup-ajax',
                        ['id_bib' => 2,
                         'id_origine' => 12,
                         'copy_id' => 13425,
                         'code_annexe' => '36']);
    $json = json_decode($this->_response->getBody(), true);
    $this->assertContains('Aucun site de retrait disponible', $json['content']);
  }


  /** @test */
  public function withoutAvailablePickupLocationGETResponseShouldAnswerError() {
    Class_CodifAnnexe::deleteBy([]);
    $this->dispatch('recherche/reservation-pickup-ajax/id_bib/2/id_origine/12/copy_id/13425');
    $json = json_decode($this->_response->getBody(), true);
    $this->assertContains('Aucun site de retrait disponible', $json['content']);
  }


  /** @test */
  public function withPopupAndInspectorGadgetResponseShouldStillSendJSON() {
    Zend_Registry::get('session')->inspectorCalls = [serialize(new Class_InspectorGadget_ServiceCall('I', 'love', 'milk', 'coffee', '418'))];

    $this->postDispatch('recherche/reservation-pickup-ajax/render/popup/inspector_gadget/1',
                        ['id_bib' => 2,
                         'id_origine' => 12,
                         'copy_id' => 13425,
                         'code_annexe' => '36']);
    $this->assertNotNull($json = json_decode($this->_response->getBody(), true));
    $this->assertContains('<script>location.reload();</script>', $json['content']);
  }


Ghislain Loas's avatar
Ghislain Loas committed
  /** @test */
  public function responseShouldContainsJsonRedirectToReservationajaxAction() {
    $this->postDispatch('recherche/reservation-pickup-ajax/render/popup',
                        ['id_bib' => 2,
                         'id_origine' => 12,
                         'copy_id' => 13425,
Ghislain Loas's avatar
Ghislain Loas committed
    $json = json_decode($this->_response->getBody(), true);
    $this->assertContains('<script>location.reload();</script>', $json['content']);
class RechercheControllerReservationPickupAjaxActionTestWithChosenPickupDispatch
  extends RechercheControllerReservationWithPickupChoiceTestCase {
Patrick Barroca's avatar
Patrick Barroca committed
  public function setUp() {
    parent::setUp();
      ->fixture(Class_IntBib::class,
                ['id' => 1,
                 'comm_sigb' => Class_IntBib::COM_NANOOK,
                 'comm_params' => ['url_serveur' => 'http://bib.valensol.net']]);

    $this->jajm = $this
      ->fixture(Class_Users::class,
                ['id' => 1,
                 'login' => 'jajm',
                 'password' => 'secret',
                 'idabon' => '0000007',
    $this->nanook = (new Class_Testing_WebService_SIGB_Nanook_Service())
      ->whenCalled('reserverExemplaire')->answers(['erreur' => '', 'statut' => true])
      ->whenCalled('isConnected')->answers(true);
    Class_WebService_SIGB_Nanook::setService(['url_serveur' => 'http://bib.valensol.net',
                                              'id_bib' => 1,
                                              'type' => Class_IntBib::COM_NANOOK,],
                                             $this->nanook);
Patrick Barroca's avatar
Patrick Barroca committed
    ZendAfi_Auth::getInstance()->logUser($this->jajm);
    $this->fixture('Class_Exemplaire', ['id' => 12]);
    $mock_transport = new MockMailTransport();
    Zend_Mail::setDefaultTransport($mock_transport);

    $this->dispatch('recherche/reservationajax/id/11760/id_int_bib/23/id_bib/23/id_origine/594105/code_annexe/23/render/popup/copy_id/12', true);

    $this->_sent_mails = $mock_transport->getSentMails();
Patrick Barroca's avatar
Patrick Barroca committed
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function parameterCodeAnnexeShouldBeUsedForReservation() {
    $this->assertEquals('23',
                         $this->nanook->getAttributesForLastCallOn('reserverExemplaire')[2]);
Patrick Barroca's avatar
Patrick Barroca committed
  }


  /** @test */
  public function noEmailShouldHaveBeenSentWithDefaultConf() {
    $this->assertEmpty($this->_sent_mails);
  }
class RechercheControllerReservationPickupAjaxActionTestWithPatronLibraryPickup
  extends RechercheControllerReservationTestCase {
Patrick Barroca's avatar
Patrick Barroca committed
  public function setUp() {
    parent::setUp();
    $bib = $this
      ->fixture('Class_IntBib',
                ['id' => 12,
                 'comm_sigb' => Class_IntBib::COM_NANOOK,
                 'comm_params' => ['url_serveur' => 'http://bib.valensol.net']]);

Patrick Barroca's avatar
Patrick Barroca committed
    $this->jajm = $this->fixture('Class_Users',
                                 ['id' => 1,
                                  'login' => 'jajm',
                                  'password' => 'secret',
                                  'idabon' => '0000007',
    $this->nanook = (new Class_Testing_WebService_SIGB_Nanook_Service())
Patrick Barroca's avatar
Patrick Barroca committed
      ->whenCalled('isConnected')->answers(true)
      ->whenCalled('providesPickupLocations')->answers(false)
Patrick Barroca's avatar
Patrick Barroca committed
      ->whenCalled('getUserAnnexe')->answers('12');
    Class_WebService_SIGB_Nanook::setService(['url_serveur' => 'http://bib.valensol.net',
                                              'id_bib' => 12,
                                              'type' => Class_IntBib::COM_NANOOK,],
                                             $this->nanook);
Patrick Barroca's avatar
Patrick Barroca committed
    ZendAfi_Auth::getInstance()->logUser($this->jajm);
    Class_CosmoVar::setValueOf('site_retrait_resa',
                               Class_CosmoVar::PICKUP_LOCATION_PATRON);
    $this->fixture('Class_Exemplaire', ['id' => 12,
                                        'id_int_bib' => 12]);
    $this->dispatch('recherche/reservation-pickup-ajax?id_bib=2&id_origine=12&code_annexe=36&copy_id=12', true);
Patrick Barroca's avatar
Patrick Barroca committed
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function getUserAnnexeResultShouldBeUsedForReservation() {
    $this->assertEquals('12',
                        $this->nanook->getAttributesForLastCallOn('reserverExemplaire')[2]);
  }
class RechercheControllerReservationPickupAjaxActionTestWithItemLibraryPickup
  extends RechercheControllerReservationTestCase {
Patrick Barroca's avatar
Patrick Barroca committed
  public function setUp() {
    parent::setUp();
    $bib = $this->fixture(Class_IntBib::class,
                          ['id' => 1,
                           'comm_sigb' => Class_IntBib::COM_NANOOK,
                           'comm_params' => ['url_serveur' => 'http://bib.valensol.net']]);

    $this->jajm = $this->fixture(Class_Users::class,
Patrick Barroca's avatar
Patrick Barroca committed
                                 ['id' => 1,
                                  'login' => 'jajm',
                                  'password' => 'secret',
                                  'idabon' => '0000007',
    $this->nanook = (new Class_Testing_WebService_SIGB_Nanook_Service())
Patrick Barroca's avatar
Patrick Barroca committed
      ->whenCalled('isConnected')->answers(true)
      ->whenCalled('providesPickupLocations')->answers(false)
Laurent's avatar
Laurent committed
      ->whenCalled('reserverExemplaire')->answers(['statut' => true, 'erreur' => '']);
    Class_WebService_SIGB_Nanook::setService(['url_serveur' => 'http://bib.valensol.net',
                                              'id_bib' => 1,
                                              'type' => Class_IntBib::COM_NANOOK,],
                                             $this->nanook);
Patrick Barroca's avatar
Patrick Barroca committed
    ZendAfi_Auth::getInstance()->logUser($this->jajm);
    Class_CosmoVar::setValueOf('site_retrait_resa',
                               Class_CosmoVar::PICKUP_LOCATION_ITEM);
    $this->fixture(Class_Exemplaire::class,
                   ['id' => 12,
                    'id_int_bib' => 1,
    $this->dispatch('recherche/reservation-pickup-ajax?id_bib=2&id_origine=12&code_annexe=36&copy_id=12', true);
Patrick Barroca's avatar
Patrick Barroca committed
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function itemAnnexeShouldBeUsedForReservation() {
Patrick Barroca's avatar
Patrick Barroca committed
                        $this->nanook->getAttributesForLastCallOn('reserverExemplaire')[2]);
  }
class RechercheControllerReservationWithMailPostAction
  extends AbstractControllerTestCase {
  protected
    $_sent_mails,
    $_storm_default_to_volatile = true;
Patrick Barroca's avatar
Patrick Barroca committed
  public function setUp() {
    parent::setUp();
Patrick Barroca's avatar
Patrick Barroca committed
    $_SESSION["captcha_code"] = '1234';
Patrick Barroca's avatar
Patrick Barroca committed
    $mock_transport = new MockMailTransport();
    Zend_Mail::setDefaultTransport($mock_transport);
    $this->fixture('Class_Bib', ['id' => 4,
                                 'libelle' => 'Astrolabe',
                                 'mail' => 'zork@gloub.fr',]);

Patrick Barroca's avatar
Patrick Barroca committed
    $this->fixture('Class_Notice', ['id' => 4,
                                    'unimarc' => "01570nam0 2200325   450 0010007000000100033000070200017000400210027000571000041000841010008001251020007001331050018001401060006001582000106001642100075002702150044003452250023003893000125004123000020005373000137005573300265006943450018009594100051009775120027010286060033010556060060010886760012011487000045011608010039012052218529  a2-86642-370-4bbr.d8,95 EUR  aFRb00347575  aFRbDLE-20031204-51138  a20031107d2003    m  h0frey0103    ba| afre  aFR  ay   z   000y|  ar1 aCinema d'animationbTexte impriméedessin animé, marionnettes, images de synthèsefBernard Genin  a[Paris]c\"Cahiers du cinéma\"cSCEREN-CNDPdcop. 2003gimpr. en Italie  a95 p.cill., couv. ill. en coul.d19 cm2 aLes petits cahiers  aLa couv. porte en plus : \"du crayon à l'ordinateur, pour ou contre Disney, Europe-Japon : le dessin animé aujourd'hui\"  aBibliogr. p. 93  aSCEREN = Services, cultures, éditions, ressources pour l'éducation nationale. CNDP = Centre national de documentation pédagogique  aPrésente un historique du cinéma d'animation, un survol des différentes productions nationales à travers le monde (Etats-Unis, Japon, France, Canada), les techniques du volume animé, l'image de synthèse, mais aussi l'oeuvre de Disney et le film d'auteur.  b9782866423704 032525826tLes Petits cahiers (Paris)x1633-90531 aLe cinéma d'animation| 31053394aAnimation (cinéma)| 31031625aDessins animés32195497xHistoire et critique  a791.431 |32547161aGeninbBernardf1946-....4070 0aFRbBNFc20031107gAFNOR2intermrc"]);
    $this->postDispatch('/recherche/reservation/id_notice/4/id_bib/4/cote/XYZ',
                        ['user_name' => 'nanuk',
Patrick Barroca's avatar
Patrick Barroca committed
                         'demande' => 'je veux le livre',
                         'user_mail' => 'nanuk@gloub.com',
                         'code_saisi' => '1234']);
Patrick Barroca's avatar
Patrick Barroca committed
    $this->_sent_mails = $mock_transport->getSentMails();
    $this->first_mail = array_first($this->_sent_mails);
    $this->first_content = quoted_printable_decode($this->first_mail->getBodyText()->getContent());
Patrick Barroca's avatar
Patrick Barroca committed
    $this->last_mail = array_last($this->_sent_mails);
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function twoMailsShouldHaveBeenSent() {
    $this->assertEquals(2, count($this->_sent_mails));
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function firstMailFromShouldBeNanuk() {
    $this->assertEquals('nanuk@gloub.com',
                        $this->first_mail->getFrom());
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function firstMailSubjectShouldBeDemandeDeReservation() {
    $this->assertContains('Demande de réservation de document',
                          quoted_printable_decode($this->first_mail->getSubject()));
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function firstMailToShouldBeZork() {
    $this->assertContains('zork@gloub.fr',
                          $this->first_mail->getRecipients());
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function titleShouldBePresent() {
    $this->assertTrue(false !== strpos($this->first_content, 'Titre : Cinema d\'animation'));
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function authorShouldBePresent() {
    $this->assertTrue(false !== strpos($this->first_content, 'Auteur : Bernard Genin'),
                      $this->first_content);
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function secondMailFromShouldBeNobody() {
    $this->assertEquals('nobody@noreply.fr',
                        $this->last_mail->getFrom());
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function secondMailToShouldBeNanuk() {
    $this->assertContains('nanuk@gloub.com',
                          $this->last_mail->getRecipients());
  }
class RechercheControllerReservationWithWebServiceKohaTest
  extends AbstractControllerTestCase {
  protected $_storm_default_to_volatile = true;
Patrick Barroca's avatar
Patrick Barroca committed
  public function setUp() {
    parent::setUp();

    $webservice = 'http://bib.valensol.net';
    $bib = $this->fixture('Class_IntBib',
                          ['id' => 1,
                           'comm_sigb' => Class_IntBib::COM_KOHA_LEGACY,
                           'comm_params' => ['url_serveur' => $webservice]]);
Patrick Barroca's avatar
Patrick Barroca committed
    $this->jajm = $this->fixture('Class_Users',
                                 ['id' => 1,
                                  'login' => 'jajm',
                                  'password' => 'secret',
Patrick Barroca's avatar
Patrick Barroca committed

    ZendAfi_Auth::getInstance()->logUser($this->jajm);
    $this->koha = new Class_Testing_WebService_SIGB_KohaLegacy_Service();
    $this->koha->setServerRoot( $webservice);
    Class_WebService_SIGB_KohaLegacy::setService(['url_serveur' => $webservice,
                                            'type' => Class_IntBib::COM_KOHA_LEGACY],
                                           $this->koha);
Patrick Barroca's avatar
Patrick Barroca committed
  }


  protected function dispatchAndCheckContentEquals($expected) {
    $this->dispatch('/recherche/reservationajax/id_bib/1/copy_id/456/code_annexe/VS',
Patrick Barroca's avatar
Patrick Barroca committed
                    true);
    $this->json = json_decode($this->_response->getBody());
    $this->assertEquals($expected, $this->json->content);
  /** @test */
  public function reservationAjaxWithItemRequiringCalendarHoldShouldRedirectToReservationCalendarAjax() {
    $this->fixture(Class_CodifAnnexe::class,
                   ['id' => 123,
                    'code' => 'VS',
                    'libelle' => 'ValStar',
                    'id_int_bib' => 1,
                    'id_origine' => 'VS']);

    $item = $this->fixture(Class_Exemplaire::class,
                           ['id' => 456,
                            'code_barres' => 123,
                            'id_int_bib' => 1,
                            'notice' => $this->fixture(Class_Notice::class,
                                                       ['id' => 8890,
                                                        'titre_principal' => 'Elementaire mon cher polar',
                                                        'auteur_principal' => 'Conan Doyle'])]);

    $item->setSigbExemplaire((Class_WebService_SIGB_Koha_Exemplaire::newInstance())
                             ->doRequiresCalendarHold()
                             ->setId(2)
                             ->beReservable())->save();
    $this->jajm->setIdabon(395749);

    $this->koha
      ->whenCalledDo('reserverExemplaire', [], function()
                 return $this->_error('error');
               });

    $this->dispatch('/recherche/reservationajax/id_bib/1/copy_id/456/code_annexe/VS');

    $this->assertRedirectTo('/recherche/reservation-calendar-ajax/id_bib/1/copy_id/456/code_annexe/VS');
  }


Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function withMatchingHoldMessageShouldContainsPickupLocation() {
    $item = $this->fixture(Class_Exemplaire::class,
                           ['id' => 456,
                            'code_barres' => 123,
                            'id_int_bib' => 1]);

    $response = $this->_prepareEmprunteurHolding($item, 'Valensole');
    $expected_message = 'Votre réservation est enregistrée.<br>Nous vous informerons quand le document sera disponible pour être retiré à : Valensole';
    $this->_dispatchWithEmprunteurAndAssertContentEquals($response,
                                                         $expected_message);
Patrick Barroca's avatar
Patrick Barroca committed
  }


  /** @test */
  public function withMatchingHoldAndRecordWithBRInTitleMessageShouldContainsPickupLocationAndRecordTitleAuthor() {
    $exemplaire = $this->fixture(Class_Exemplaire::class,
Patrick Barroca's avatar
Patrick Barroca committed
                                 ['id' => 456,
                                  'code_barres' => 123,
                                  'id_int_bib' => 1,
                                  'notice' => $this->fixture(Class_Notice::class,
Patrick Barroca's avatar
Patrick Barroca committed
                                                             ['id' => 8890,
                                                              'titre_principal' => 'Albator <br /> Arcadia',
Patrick Barroca's avatar
Patrick Barroca committed
                                                              'auteur_principal' => 'Matsumoto'])]);
    $this->_dispatchWithEmprunteurAndAssertContentEquals(
      $this->_prepareEmprunteurHolding($exemplaire, 'Valensole'),
      'Votre réservation est enregistrée.<br>Nous vous informerons quand le document \'Albator  Arcadia / Matsumoto\' sera disponible pour être retiré à : Valensole');
  /** @test */
  public function withMatchingHoldAndRecordWithoutAuthorMessageShouldContainsPickupLocationAndRecordTitleOnly() {
    $exemplaire = $this->fixture('Class_Exemplaire',
                                 ['id' => 456,
                                  'code_barres' => 123,
                                  'id_int_bib' => 1,
                                  'notice' => $this->fixture('Class_Notice',
                                                             ['id' => 8890,
                                                              'titre_principal' => 'Arcadia'])]);
    $this->_dispatchWithEmprunteurAndAssertContentEquals(
      $this->_prepareEmprunteurHolding($exemplaire, 'Valensole'),
      'Votre réservation est enregistrée.<br>Nous vous informerons quand le document \'Arcadia\' sera disponible pour être retiré à : Valensole');
  }


Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function withoutMatchingHoldMessageShouldContainsDocumentNotFound() {
Patrick Barroca's avatar
Patrick Barroca committed
    $this->_dispatchWithEmprunteurAndAssertContentEquals(
      $this->_prepareEmprunteurHolding(null, 'Valensole'),
      'Document introuvable');
Patrick Barroca's avatar
Patrick Barroca committed
  }


  /** @test */
  public function withMatchingHoldAndNoPickupLocationShouldNotContainsPickupLocation() {
    $this->_dispatchWithEmprunteurAndAssertContentEquals(
      $this->_prepareEmprunteurHolding($this->fixture('Class_Exemplaire', ['id' => 456]),
                                       null),
      'Votre réservation est enregistrée.<br>Nous vous informerons quand le document sera disponible');
  }


  protected function _prepareEmprunteurHolding($item, $pickup_label) {
    $this->jajm->setIdabon(395749);

    $exemplaire = (new Class_WebService_SIGB_Exemplaire(2))
      ->setExemplaireOPAC($item);
    $hold = new Class_WebService_SIGB_Reservation(2, $exemplaire);
    $hold->setPickupLocationLabel($pickup_label)
         ->setCodeBarre(123);
Patrick Barroca's avatar
Patrick Barroca committed

    $emprunteur_jajm = Class_WebService_SIGB_Emprunteur::newInstance(2, 'jajm');
    $emprunteur_jajm->reservationsAdd($hold);
    return $emprunteur_jajm;
  }


  protected function _dispatchWithEmprunteurAndAssertContentEquals($emprunteur, $content) {
    $this->koha
      ->whenCalledDefaultAnswers('reserverExemplaire', ['statut' => true,
                                                        'erreur' => '',
                                                        'popup' => false])
      ->whenCalledDefaultAnswers('getEmprunteur',$emprunteur);
Patrick Barroca's avatar
Patrick Barroca committed

    $this->dispatchAndCheckContentEquals($content);
  }


  /** @test */
  public function popupResultContentWithWebServiceErrorShouldContainsErreurDeCommunication() {
    $this->jajm->setIdabon(395749);

    $this->_prepareEmprunteurHolding($this->fixture('Class_Exemplaire', ['id' => 456]),
                                     'Valensole');
    $this->koha->whenCalled('isConnected')->answers(false);
Patrick Barroca's avatar
Patrick Barroca committed

    $this->dispatchAndCheckContentEquals("Une erreur de communication avec le serveur a fait échouer la requête. Merci de signaler ce problème à la bibliothèque.");
  }


  /** @test */
  public function withoutIdAbonpopupResultContentShouldContainsVousDevezVousConnecterSousVotreNumeroDeCarte() {
    $this->_prepareEmprunteurHolding($this->fixture('Class_Exemplaire', ['id' => 456]),
                                     'Valensole');
    $this->jajm->setIdabon(null)->save();
Patrick Barroca's avatar
Patrick Barroca committed
    $this->dispatchAndCheckContentEquals("Vous devez vous connecter sous votre numéro de carte pour effectuer une réservation.");
  }
class RechercheControllerReservationSerialWithWebServiceKohaTest
  extends AbstractControllerTestCase {
  protected $_storm_default_to_volatile = true;
  protected $_exemplaire;

  public function setUp() {
    parent::setUp();

    $webservice = 'http://bib.valensol.net';
    $bib = $this->fixture('Class_IntBib',
                          ['id' => 1,
                           'comm_sigb' => Class_IntBib::COM_KOHA_LEGACY,
                           'comm_params' => ['url_serveur' => $webservice]]);

    $data_profile = $this->fixture('Class_IntProfilDonnees',
                   ['id' => 433,
                    'id_article_periodique' => Class_IntProfilDonnees::SERIAL_FORMAT_KOHA]
    );

    $this->_exemplaire = $this->fixture('Class_Exemplaire',
                                 ['id' => 203609,
                                  'code_barres' => 1644067,
                                  'id_int_bib' => 1,
                                  'id_origine' => '259517-123',
                                  'data_profile' => $data_profile,
                                  'notice' => $this->fixture('Class_Notice',
                                                             ['id' => 205227,
                                                              'titre_principal' => 'Animan 210',
                                                              'type_doc' => Class_TypeDoc::PERIODIQUE
                                                             ])]);

    $this->jajm = $this->fixture('Class_Users',
                                 ['id' => 1,
                                  'login' => 'jajm',
                                  'password' => 'secret',
                                  'int_bib' => $bib,
                                 ]);

    Class_AdminVar::set('KOHA_MULTI_SITES','1');

    ZendAfi_Auth::getInstance()->logUser($this->jajm);
    $this->koha = new Class_Testing_WebService_SIGB_Koha_Service();
      ->whenCalledDefaultAnswers('getServerRoot', $webservice);
    Class_WebService_SIGB_KohaLegacy::setService(['url_serveur' => $webservice,
                                                  'id_bib' => 1,
                                                  'type' => Class_IntBib::COM_KOHA_LEGACY],
                                                 $this->koha);
  }


  protected function dispatchAndCheckContentEquals($expected) {
    $this->dispatch('/recherche/reservationajax/id/205227-123/id_notice/205227-210/id_bib/1/copy_id/203609/code_annexe/VS',
                    true);
    $this->json = json_decode($this->_response->getBody());
    $this->assertEquals($expected, $this->json->content);
  }


  /** @test */
  public function functionGetBibNumberFromIdOrigineShouldReturn259517() {
    $this->assertEquals('259517', $this->_exemplaire->getBibNumberFromIdOrigine());
  }


  /** @test */
  public function withMatchingHoldAndRecordSerialMessageShouldContainsPickupLocationAndRecordTitle() {
    $response = $this->_prepareEmprunteurHolding($this->_exemplaire, 'Valensole');
    $expected_message = 'Votre réservation est enregistrée.<br>Nous vous informerons quand le document \'Animan 210\' sera disponible pour être retiré à : Valensole';
    $this->_dispatchWithEmprunteurAndAssertContentEquals($response,
                                                         $expected_message);
  }


  protected function _prepareEmprunteurHolding($item, $pickup_label) {
    $this->jajm->setIdabon(395749);

    $exemplaire = (new Class_WebService_SIGB_Exemplaire(203609))
      ->setExemplaireOPAC($item);
    $hold = new Class_WebService_SIGB_Reservation(2, $exemplaire);
    $hold->setPickupLocationLabel($pickup_label)
         ->setCodeBarre(1644067);

    $emprunteur_jajm = Class_WebService_SIGB_Emprunteur::newInstance(2, 'jajm');
    $emprunteur_jajm->reservationsAdd($hold);
    $emprunteur_jajm->save();
    return $emprunteur_jajm;
  }


  protected function _dispatchWithEmprunteurAndAssertContentEquals($emprunteur, $content) {
    $this->koha
      ->whenCalledDefaultAnswers('reserverExemplaire',['statut' => true,
                                                  'popup' => false])
      ->whenCalledDefaultAnswers('getEmprunteur', $emprunteur);

class RechercheControllerReservationCalendarAjaxTest extends AbstractControllerTestCase {
  protected
    $_storm_default_to_volatile = true,
    $_json,
    $_xpath;

  public function setUp() {
    parent::setUp();

    $item = $this->fixture('Class_Exemplaire',
                           ['id' => 456,
                            'id_origine' => 1,
                            'annexe' => 'VS']);

    $comm_sigb = (new Class_Testing_WebService_SIGB_Koha_Service())
      ->whenCalledAnswers('holdsForItem',
                         [$item],
                         ['statut' => true,
                          'holds' => [(new Class_WebService_SIGB_Koha_Reservation(3,$item))
                                      ->setReserveDate('2020-01-15')
                                      ->setExpirationDate('2020-06-16'),
                                      (new Class_WebService_SIGB_Koha_Reservation(2,$item))
                                      ->setReserveDate('2019-07-26')
                                      ->setExpirationDate('2019-12-31')]]);

    Class_CommSigb::setInstance($comm_sigb);

    $this->dispatch('/recherche/reservation-calendar-ajax/id_bib/1/copy_id/456/code_annexe/VS',true);
    $this->_json = json_decode($this->_response->getBody());
    $this->_xpath = new Storm_Test_XPath();
  }


  /** @test */
  public function popupHoldsListShouldContainsDu26JuilletAu31Decembre() {
    $this->_xpath->assertXPathContentContains($this->_json->content,
                                              '//ul/li[1]',
                                              utf8_encode('Du 26 juillet 2019 au 31 décembre 2019'));
  }


  /** @test */
  public function popupHoldsListShouldContainsDu15JanvierAu16Juin() {
    $this->_xpath->assertXPathContentContains($this->_json->content,
                                              '//ul/li[2]',
                                              utf8_encode('Du 15 janvier 2020 au 16 juin 2020'));
  }


  /** @test */
  public function formActionShouldBeRechercheReservationCalendarAjax() {
    $this->_xpath->assertXPath($this->_json->content,
                               '//form[@action="/recherche/reservation-calendar-ajax/id_bib/1/copy_id/456/code_annexe/VS"]');
  }


  /** @test */
  public function formCancelButtonShouldCloseDialog() {
    $this->_xpath->assertXPath($this->_json->content,
                               '//button[@value="Annuler"][contains(@onclick, "opacDialogClose()")]');
  }


  /** @test */
  public function formShouldContainsSubmit() {
    $this->_xpath->assertXPath($this->_json->content,
                               '//input[@type="submit"][@value="Valider"]');
  }


  /** @test */
  public function responseShouldContainsInputDatePickerForResevationDate() {
    $this->_xpath->assertXPath($this->_json->content,
                               '//input[@name="reservedate"]');
  }


  /** @test */
  public function responseShouldContainsInputDatePickerForExpirationDate() {
    $this->_xpath->assertXPath($this->_json->content,
                               '//input[@name="expirationdate"]');
  }
}




class RechercheControllerReservationCalendarPostTest extends AbstractControllerTestCase {
  protected
    $_storm_default_to_volatile = true,
    $_comm_sigb;

  public function setUp() {
    parent::setUp();
    $int_bib = $this
      ->fixture('Class_IntBib',
                ['id' => 1,
                 'comm_sigb' => Class_IntBib::COM_KOHA_LEGACY,
                 'use_card_number' => 12345,
                 'comm_params' => ['bundled_holds_minimal_duration' => 29,
                                   'url_serveur' => 'http://bib.valensol.net/cgi-bin/koha/ilsdi.pl']]);

    $item = $this->fixture('Class_Exemplaire',
                           ['id' => 456,
                            'code_barres' => 123,
                            'id_int_bib' => 1,
                            'notice' => $this->fixture('Class_Notice',
                                                       ['id' => 8890,
                                                        'titre_principal' => 'Elementaire mon cher polar',
                                                        'auteur_principal' => 'Conan Doyle'])]);

    $this->_comm_sigb = (new Class_Testing_CommSigb())
      ->whenCalledAnswers('holdsForItem',[$item],['statut' => true,
                                                  'holds' => []]);


    Class_CommSigb::setInstance($this->_comm_sigb);
  }


  /** @test */
  public function withReserveDateAndExpirationDateShouldNotifyHoldSuccess() {
    $this->_comm_sigb
      ->whenCalledAnswers('ficheAbonne', [Class_Users::getIdentity()],null)

      ->whenCalledDo('holdCalendar',  [456,'VS','2020-01-19','2020-05-25'],fn() => []);

    $this->postDispatch('/recherche/reservation-calendar-ajax/id_bib/1/copy_id/456/code_annexe/VS',
                        ['reservedate' => '19/01/2020' ,
                         'expirationdate' => '25/05/2020']);

    $this->json = json_decode($this->_response->getBody());
    $this->assertContains('Votre réservation est enregistrée',
                          $this->json->content);
  }


  /** @test */
  public function withInvalidReserveDateShouldDisplayErrorReserveDateInvalide() {
    Class_Users::getIdentity()->setIdIntBib(1)->save();
    $this->postDispatch('/recherche/reservation-calendar-ajax/id_bib/1/copy_id/456/code_annexe/VS',
                        ['reservedate' => 'pouet' ,
                         'expirationdate' => '25/05/2020']);

    $this->json = json_decode($this->_response->getBody());
    $xpath = new Storm_Test_XPath();

    $xpath->assertXPathContentContains($this->json->content,
                                       '//ul[@class="errors"]/li',
                                       '\'pouet\' ne correspond pas au format de date attendu',
                                       $this->json->content);
  }


  /** @test */
  public function withDurationInferiorToMinimunShouldDisplayErrorDurationTooSmall() {
    // $this->_comm_sigb->whenCalledDo('holdCalendar',
    //                                      [456,'VS','2020-05-10','2020-05-25'],
    //                                 fn()=> $this->addError(');
    Class_Users::getIdentity()->setIdIntBib(1)->save();
    $this->postDispatch('/recherche/reservation-calendar-ajax/id_bib/1/copy_id/456/code_annexe/VS',
                        ['reservedate' => '10/05/2020' ,
                         'expirationdate' => '25/05/2020']);

    $this->json = json_decode($this->_response->getBody());
    $xpath = new Storm_Test_XPath();

    $xpath->assertXPathContentContains($this->json->content,
                                       '//ul[@class="errors"]',
                                       'Durée minimale requise: 29 jours');

    $xpath->assertXPath($this->json->content,
                        '//input[@name="reservedate"][@value="10/05/2020"]',
                        $this->json->content);
  }
}




class RechercheControllerReservationWithMailFormTest
  extends AbstractControllerTestCase {

  protected $_storm_default_to_volatile = true;
Patrick Barroca's avatar
Patrick Barroca committed
  public function setUp() {
    parent::setUp();
    $this->fixture('Class_Bib', ['id' => 88,
                                 'libelle' => 'My Library',
                                 'mail' => 'my@library.com']);

    $this->fixture('Class_Notice',
                   ['id' => 550171,
                    'type_doc' => 1,
                    'titre_principal' => 'Test record',
                    'auteur_principal' => 'Test author',
                    'editeur' => 'Test editor',
                   ]);

Patrick Barroca's avatar
Patrick Barroca committed
    $this->dispatch('/recherche/reservation/id/550171/id_int_bib/88/id_bib/88/id_notice/550171/cote/P+TRA', true);
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function bibNameShouldBePresentInForm() {
    $this->assertXPath('//input[@type="text"][@disabled][@name="bib_name"][@value="My Library"]');
Patrick Barroca's avatar
Patrick Barroca committed
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function shouldContainsUserName() {
    $this->assertXPath('//input[@type="text"][@name="user_name"]');
Patrick Barroca's avatar
Patrick Barroca committed
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function shouldContainsMessage() {
    $this->assertXPath('//textarea[@name="demande"]');
  }


  /** @test */
  public function shouldContainsUserMail() {
    $this->assertXPath('//input[@type="email"][@name="user_mail"]');
Patrick Barroca's avatar
Patrick Barroca committed
  }
Patrick Barroca's avatar
Patrick Barroca committed
  /** @test */
  public function shouldContainsCaptcha() {
    $this->assertXPath('//input[@type="text"][@name="code_saisi"]');
Patrick Barroca's avatar
Patrick Barroca committed
  }
abstract class RechercheControllerReservationWithMailFormPostTestCase
  extends AbstractControllerTestCase {
  protected
    $_storm_default_to_volatile = true,
    $_mail_transport;

  public function setUp() {
    parent::setUp();

    $this->fixture('Class_Bib', ['id' => 88,
                                 'libelle' => 'My Library',
                                 'mail' => 'my@library.com']);

    $unimarc = (new Class_NoticeUnimarc_Fluent)
      ->zoneWithContent('001', '')
      ->zoneWithChildren('200', [ 'a' => 'Test record'], ' 0')
      ->zoneWithChildren('214', [ 'c' => 'Test editor'], ' 0')
      ->render();

    $this->fixture(Class_Notice::class,
                   ['id' => 550171,
                    'type_doc' => 1,
                    'auteur_principal' => 'Test author',
                    'unimarc' => $unimarc,
                   ]);

    $_SESSION['captcha_code'] = 'e2df0';