An error occurred while loading the file. Please try again.
-
efalcy authorede7d6b006
RechercheControllerReservationTest.php 52.34 KiB
<?php
/**
* Copyright (c) 2012-2014, 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
*/
abstract class RechercheControllerReservationTestCase
extends AbstractControllerTestCase {
protected $_json, $_xpath,
$_storm_default_to_volatile = true;
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->_xpath = new Storm_Test_XPath();
}
}
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',true);
$this->_json = json_decode($this->_response->getBody());
}
/** @test */
public function shouldRenderAnnecyCheckedRadio() {
$this->_xpath->assertXPath($this->_json->content,
'//input[@name="code_annexe"][@value="36"][@checked="checked"]',$this->_json->content);
}
/** @test */
public function shouldRenderCranRadio() {
$this->_xpath->assertXPath($this->_json->content,
'//input[@name="code_annexe"][@value="37"]');
}
/** @test */
public function layoutShouldBeEmpty() {
$this->_xpath->assertNotXPath($this->_json->content, '//div[@id="banniere"]');
}
}
class RechercheControllerReservationPickupAjaxActionPostTest
extends RechercheControllerReservationWithPickupChoiceTestCase {
/** @test */
public function responseShouldRedirectToReservationajaxAction() {
$this->postDispatch('recherche/reservation-pickup-ajax',
['id_bib' => 2,
'id_origine' => 12,
'code_annexe' => '36']);
$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,
'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');
$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,
'code_annexe' => '36']);
$this->assertNotNull($json = json_decode($this->_response->getBody(), true));
$this->assertContains('<script>location.reload();</script>', $json['content']);
}
/** @test */
public function responseShouldContainsJsonRedirectToReservationajaxAction() {
$this->postDispatch('recherche/reservation-pickup-ajax/render/popup',
['id_bib' => 2,
'id_origine' => 12,
'code_annexe' => '36']);
$json = json_decode($this->_response->getBody(), true);
$this->assertContains('<script>location.reload();</script>', $json['content']);
}
}
class RechercheControllerReservationPickupAjaxActionTestWithChosenPickupDispatch
extends RechercheControllerReservationWithPickupChoiceTestCase {
protected $_sent_mails;
public function setUp() {
parent::setUp();
$bib = $this
->fixture('Class_IntBib',
['id' => 1,
'comm_sigb' => Class_IntBib::COM_NANOOK,
'comm_params' => ['url_serveur' => 'http://bib.valensol.net']]);
$this->jajm = $this
->fixture('Class_Users',
['id' => 1,
'login' => 'jajm',
'password' => 'secret',
'idabon' => '0000007',
'int_bib' => $bib,
]);
$this->nanook = Storm_Test_ObjectWrapper::mock()
->whenCalled('isConnected')->answers(true)
->whenCalled('reserverExemplaire')->answers(['erreur' => '', 'statut' => true]);
Class_WebService_SIGB_Nanook::setService(['url_serveur' => 'http://bib.valensol.net',
'id_bib' => 1,
'type' => Class_IntBib::COM_NANOOK,],
$this->nanook);
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();
}
/** @test */
public function parameterCodeAnnexeShouldBeUsedForReservation() {
$this->assertEquals('23',
$this->nanook->getAttributesForLastCallOn('reserverExemplaire')[2]);
}
/** @test */
public function noEmailShouldHaveBeenSentWithDefaultConf() {
$this->assertEmpty($this->_sent_mails);
}
}
class RechercheControllerReservationPickupAjaxActionTestWithPatronLibraryPickup
extends RechercheControllerReservationTestCase {
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']]);
$this->jajm = $this->fixture('Class_Users',
['id' => 1,
'login' => 'jajm',
'password' => 'secret',
'idabon' => '0000007',
'int_bib' => $bib]);
$this->nanook = Storm_Test_ObjectWrapper::mock()
->whenCalled('isConnected')->answers(true)
->whenCalled('reserverExemplaire')->answers(['erreur' => '', 'statut' => true])
->whenCalled('providesPickupLocations')->answers(false)
->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);
ZendAfi_Auth::getInstance()->logUser($this->jajm);
Class_CosmoVar::setValueOf('site_retrait_resa',
Class_CosmoVar::PICKUP_LOCATION_PATRON);
$this->fixture('Class_Exemplaire', ['id' => 12]);
$this->dispatch('recherche/reservation-pickup-ajax?id_bib=2&id_origine=12&code_annexe=36©_id=12', true);
}
/** @test */
public function getUserAnnexeResultShouldBeUsedForReservation() {
$this->assertEquals('12',
$this->nanook->getAttributesForLastCallOn('reserverExemplaire')[2]);
}
}
class RechercheControllerReservationPickupAjaxActionTestWithItemLibraryPickup
extends RechercheControllerReservationTestCase {
public function setUp() {
parent::setUp();
$bib = $this->fixture('Class_IntBib',
['id' => 1,
'comm_sigb' => Class_IntBib::COM_NANOOK,
'comm_params' => ['url_serveur' => 'http://bib.valensol.net']]);
$this->jajm = $this->fixture('Class_Users',
['id' => 1,
'login' => 'jajm',
'password' => 'secret',
'idabon' => '0000007',
'int_bib' => $bib
]);
$this->nanook = Storm_Test_ObjectWrapper::mock()
->whenCalled('isConnected')->answers(true)
->whenCalled('providesPickupLocations')->answers(false)
->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);
ZendAfi_Auth::getInstance()->logUser($this->jajm);
Class_CosmoVar::setValueOf('site_retrait_resa',
Class_CosmoVar::PICKUP_LOCATION_ITEM);
$this->fixture('Class_Exemplaire', ['id' => 12]);
$this->dispatch('recherche/reservation-pickup-ajax?id_bib=2&id_origine=12&code_annexe=36©_id=12', true);
}
/** @test */
public function itemAnnexeShouldBeUsedForReservation() {
$this->assertEquals('36',
$this->nanook->getAttributesForLastCallOn('reserverExemplaire')[2]);
}
}
class RechercheControllerReservationWithMailPostAction
extends AbstractControllerTestCase {
protected
$_sent_mails,
$_storm_default_to_volatile = true;
public function setUp() {
parent::setUp();
$_SESSION["captcha_code"] = '1234';
$mock_transport = new MockMailTransport();
Zend_Mail::setDefaultTransport($mock_transport);
$this->fixture('Class_Bib', ['id' => 4,
'libelle' => 'Astrolabe',
'mail' => 'zork@gloub.fr',]);
$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',
'demande' => 'je veux le livre',
'user_mail' => 'nanuk@gloub.com',
'code_saisi' => '1234']);
$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());
$this->last_mail = array_last($this->_sent_mails);
}
/** @test */
public function twoMailsShouldHaveBeenSent() {
$this->assertEquals(2, count($this->_sent_mails));
}
/** @test */
public function firstMailFromShouldBeNanuk() {
$this->assertEquals('nanuk@gloub.com',
$this->first_mail->getFrom());
}
/** @test */
public function firstMailSubjectShouldBeDemandeDeReservation() {
$this->assertContains('Demande de réservation de document',
quoted_printable_decode($this->first_mail->getSubject()));
}
/** @test */
public function firstMailToShouldBeZork() {
$this->assertContains('zork@gloub.fr',
$this->first_mail->getRecipients());
}
/** @test */
public function titleShouldBePresent() {
$this->assertTrue(false !== strpos($this->first_content, 'Titre : Cinema d\'animation'));
}
/** @test */
public function authorShouldBePresent() {
$this->assertTrue(false !== strpos($this->first_content, 'Auteur : Bernard Genin'),
$this->first_content);
}
/** @test */
public function secondMailFromShouldBeNobody() {
$this->assertEquals('nobody@noreply.fr',
$this->last_mail->getFrom());
}
/** @test */
public function secondMailToShouldBeNanuk() {
$this->assertContains('nanuk@gloub.com',
$this->last_mail->getRecipients());
}
}
class RechercheControllerReservationWithWebServiceKohaTest
extends AbstractControllerTestCase {
protected $_storm_default_to_volatile = true;
public function setUp() {
parent::setUp();
$webservice = 'http://bib.valensol.net';
$bib = $this->fixture('Class_IntBib',
['id' => 1,
'comm_sigb' => Class_IntBib::COM_KOHA,
'comm_params' => ['url_serveur' => $webservice]]);
$this->jajm = $this->fixture('Class_Users',
['id' => 1,
'login' => 'jajm',
'password' => 'secret',
'int_bib' => $bib,
]);
ZendAfi_Auth::getInstance()->logUser($this->jajm);
$this->koha = Storm_Test_ObjectWrapper::mock();
$this->koha
->whenCalled('getServerRoot')
->answers($webservice);
Class_WebService_SIGB_Koha::setService(['url_serveur' => $webservice,
'id_bib' => 1,
'type' => Class_IntBib::COM_KOHA],
$this->koha);
}
protected function dispatchAndCheckContentEquals($expected) {
$this->dispatch('/recherche/reservationajax/id_bib/1/copy_id/456/code_annexe/VS',
true);
$this->json = json_decode($this->_response->getBody());
$this->assertEquals($expected, $this->json->content);
}
/** @test */
public function reservationAjaxWithItemRequiringCalendarHoldShouldRedirectToReservationCalendarAjax() {
$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->jajm->setIdabon(395749);
$this->koha
->whenCalled('isConnected')
->answers(true)
->whenCalled('reserverExemplaire')
->willDo(function()
{
throw new Class_WebService_SIGB_RequiresCalendarHoldException();
});
$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');
}
/** @test */
public function withMatchingHoldMessageShouldContainsPickupLocation() {
$item = $this->fixture('Class_Exemplaire',
['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);
}
/** @test */
public function withMatchingHoldAndRecordWithBRInTitleMessageShouldContainsPickupLocationAndRecordTitleAuthor() {
$exemplaire = $this->fixture('Class_Exemplaire',
['id' => 456,
'code_barres' => 123,
'id_int_bib' => 1,
'notice' => $this->fixture('Class_Notice',
['id' => 8890,
'titre_principal' => 'Albator <br /> Arcadia',
'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');
}
/** @test */
public function withoutMatchingHoldMessageShouldContainsDocumentNotFound() {
$this->_dispatchWithEmprunteurAndAssertContentEquals(
$this->_prepareEmprunteurHolding(null, 'Valensole'),
'Document introuvable');
}
/** @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);
$emprunteur_jajm = Class_WebService_SIGB_Emprunteur::newInstance(2, 'jajm');
$emprunteur_jajm->reservationsAdd($hold);
return $emprunteur_jajm;
}
protected function _dispatchWithEmprunteurAndAssertContentEquals($emprunteur, $content) {
$this->koha
->whenCalled('isConnected')->answers(true)
->whenCalled('reserverExemplaire')->answers(['statut' => true,
'erreur' => '',
'popup' => false])
->whenCalled('getEmprunteur')->answers($emprunteur);
$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);
$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->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,
'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 = Storm_Test_ObjectWrapper::mock();
$this->koha
->whenCalled('getServerRoot')
->answers($webservice);
Class_WebService_SIGB_Koha::setService(['url_serveur' => $webservice,
'id_bib' => 1,
'type' => Class_IntBib::COM_KOHA],
$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);
return $emprunteur_jajm;
}
protected function _dispatchWithEmprunteurAndAssertContentEquals($emprunteur, $content) {
$this->koha
->whenCalled('isConnected')->answers(true)
->whenCalled('reserverExemplaire')->answers(['statut' => true,
'erreur' => '',
'popup' => false])
->whenCalled('getEmprunteur')->answers($emprunteur);
$this->dispatchAndCheckContentEquals($content);
}
}
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 = $this->mock()
->whenCalled('holdsForItem')
->with($item)
->answers(['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();
$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 = $this->mock()
->whenCalled('holdsForItem')
->with($item)
->answers(['statut' => true,
'holds' => []])
->beStrict();
Class_CommSigb::setInstance($this->_comm_sigb);
}
/** @test */
public function withReserveDateAndExpirationDateShouldNotifyHoldSuccess() {
$this->_comm_sigb
->whenCalled('ficheAbonne')
->with(Class_Users::getIdentity())
->answers(null)
->whenCalled('reserverExemplaire')
->with(1,456,'VS','2020-01-19','2020-05-25')
->answers(['statut' => true, 'erreur' => '']);
$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() {
$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->whenCalled('reserverExemplaire')
->with(1,456,'VS','2020-05-10','2020-05-25')
->answers(['statut' => false,
'erreur' => 'Durée minimale requise: 30 jours']);
$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: 30 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;
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',
]);
$this->dispatch('/recherche/reservation/id/550171/id_int_bib/88/id_bib/88/id_notice/550171/cote/P+TRA', true);
}
/** @test */
public function bibNameShouldBePresentInForm() {
$this->assertXPath('//input[@type="text"][@disabled][@name="bib_name"][@value="My Library"]');
}
/** @test */
public function shouldContainsUserName() {
$this->assertXPath('//input[@type="text"][@name="user_name"]');
}
/** @test */
public function shouldContainsMessage() {
$this->assertXPath('//textarea[@name="demande"]');
}
/** @test */
public function shouldContainsUserMail() {
$this->assertXPath('//input[@type="email"][@name="user_mail"]');
}
/** @test */
public function shouldContainsCaptcha() {
$this->assertXPath('//input[@type="text"][@name="code_saisi"]');
}
}
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',
['id' => 550171,
'type_doc' => 1,
'auteur_principal' => 'Test author',
'unimarc' => $unimarc,
]);
$_SESSION['captcha_code'] = 'e2df0';
Zend_Mail::setDefaultTransport($this->_mail_transport = new MockMailTransport());
}
protected function postDatas($datas) {
$this->postDispatch('/recherche/reservation/id/550171/id_int_bib/88/id_bib/88/id_notice/550171/cote/P+TRA',
$datas);
}
protected function assertElementError($path, $message) {
$this->assertXPathContentContains($path . '/following-sibling::ul[@class="errors"]/li', $message);
}
}
class RechercheControllerReservationWithMailFormInvalidPostTest
extends RechercheControllerReservationWithMailFormPostTestCase{
/** @test */
public function withEmptyPostAllFieldsShouldBeRequired() {
$this->postDatas([]);
foreach([
['//input[@name="user_name"]', 'Une valeur est requise'],
['//textarea[@name="demande"]', 'Une valeur est requise'],
['//input[@name="user_mail"]', 'Une valeur est requise'],
['//input[@name="code_saisi"]', 'Une valeur est requise'],
] as $case) {
list($path, $message) = $case;
$this->assertElementError($path, $message);
}
}
/** @test */
public function withBadMailShouldDisplayInvalidMail() {
$this->postDatas(['user_mail' => 'bad mail address']);
$this->assertElementError('//input[@name="user_mail"]', 'n\'est pas un email valide');
}
/** @test */
public function withBadCaptchaShouldDisplayInvalidCaptchaHaveEmptyValue() {
$this->postDatas(['code_saisi' => 'bad captcha code']);
$this->assertElementError('//input[@name="code_saisi"][@value=""]',
'Le code anti-spam est incorrect');
}
}
class RechercheControllerReservationWithMailFormValidPostTest
extends RechercheControllerReservationWithMailFormPostTestCase{
protected $_mails;
public function setUp() {
parent::setUp();
Class_AdminVar::set('TEXTE_MAIL_RESA', 'Thanks for your hold');
$this->postDatas(['user_name' => 'Testing user',
'demande' => 'testing demande',
'user_mail' => 'test@server.com',
'code_saisi' => 'e2df0']);
$this->_mails = $this->_mail_transport->getSentMails();
}
protected function assertMailBodyContains($needle, $mail) {
$this->assertContains($needle, quoted_printable_decode($mail->getBodyText(true)));
}
/** @test */
public function validFormShouldSendTwoMails() {
$this->assertCount(2, $this->_mails);
}
/** @test */
public function mailsShouldHaveHoldQuerySubject() {
foreach($this->_mails as $mail)
$this->assertContains('Demande de réservation de document',
quoted_printable_decode($mail->getSubject()));
}
/** @test */
public function firstMailRecipientShouldBeLibrary() {
$this->assertContains('my@library.com', $this->_mails[0]->getRecipients());
}
/** @test */
public function firstMailFromShouldBeUser() {
$this->assertEquals('test@server.com', $this->_mails[0]->getFrom());
}
/** @test */
public function firstMailBodyShouldContainsUserName() {
$this->assertMailBodyContains('Testing user', $this->_mails[0]);
}
/** @test */
public function firstMailBodyShouldContainsRecordInfo() {
foreach(['Test record', 'P TRA', 'Test author', 'Test editor'] as $info)
$this->assertMailBodyContains($info, $this->_mails[0]);
}
/** @test */
public function firstMailBodyShouldUserMessage() {
$this->assertMailBodyContains('testing demande', $this->_mails[0]);
}
/** @test */
public function secondMailRecipientShouldBeUser() {
$this->assertContains('test@server.com', $this->_mails[1]->getRecipients());
}
/** @test */
public function secondMailFromShouldBeNobody() {
$this->assertEquals('nobody@noreply.fr', $this->_mails[1]->getFrom());
}
/** @test */
public function secondMailBodyShouldContainsTexteMailResa() {
$this->assertMailBodyContains('Thanks for your hold', $this->_mails[1]);
}
/** @test */
public function shouldRedirectToRecordView() {
$this->assertRedirectTo('/opac/recherche/viewnotice/id/550171?type_doc=1');
}
}
abstract class RechercheControllerReservationPickupAjaxWithNanookPickupLocationsTestCase
extends RechercheControllerReservationTestCase{
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']]);
$this->jajm = $this->fixture('Class_Users',
['id' => 1,
'login' => 'jajm',
'password' => 'secret',
'idabon' => '0000007',
'int_bib' => $bib]);
$this->nanook = $this->mock()
->whenCalled('isConnected')->answers(true)
->whenCalled('providesPickupLocations')->answers(true)
->whenCalled('pickupLocationsFor')
->answers(['36' => 'Annecy',
'37' => 'Cran',
'45' => 'Istres',
'99' => 'Lunel <strong>(Disponible)</strong>']);
Class_WebService_SIGB_Nanook::setService(['url_serveur' => 'http://bib.valensol.net',
'id_bib' => 12,
'type' => Class_IntBib::COM_NANOOK,],
$this->nanook);
ZendAfi_Auth::getInstance()->logUser($this->jajm);
$this->fixture('Class_Exemplaire', ['id' => 12]);
}
public function choices() {
return [[36], [37], [45]];
}
/**
* @test
* @dataProvider choices
*/
public function choiceShouldBePresent($location_id) {
$this->_xpath
->assertXPath($this->_json->content,
'//input[@type="radio"][@value="' . $location_id . '"]');
}
}
class RechercheControllerReservationPickupAjaxNanookPickupLocationsPrecheckPatronTest
extends RechercheControllerReservationPickupAjaxWithNanookPickupLocationsTestCase {
public function setUp() {
parent::setUp();
$this->nanook->whenCalled('getUserAnnexe')->answers('45');
$this->dispatch('recherche/reservation-pickup-ajax?id_bib=2&id_origine=12&code_annexe=37©_id=12', true);
$this->_json = json_decode($this->_response->getBody());
}
/** @test */
public function istresShouldBeChecked() {
$this->_xpath
->assertXPath($this->_json->content, '//input[@type="radio"][@value="45"][@checked]');
}
}
class RechercheControllerReservationPickupAjaxNanookPickupLocationsPrecheckRequestedTest
extends RechercheControllerReservationPickupAjaxWithNanookPickupLocationsTestCase {
public function setUp() {
parent::setUp();
$this->nanook->whenCalled('getUserAnnexe')->answers('66');
$this->dispatch('recherche/reservation-pickup-ajax?id_bib=2&id_origine=12&code_annexe=37©_id=12', true);
$this->_json = json_decode($this->_response->getBody());
}
/** @test */
public function cranShouldBeChecked() {
$this->_xpath
->assertXPath($this->_json->content, '//input[@type="radio"][@value="37"][@checked]');
}
}
class RechercheControllerReservationPickupAjaxNanookPickupLocationsNoPrecheckTest
extends RechercheControllerReservationPickupAjaxWithNanookPickupLocationsTestCase {
public function setUp() {
parent::setUp();
$this->nanook->whenCalled('getUserAnnexe')->answers('66');
$this->dispatch('recherche/reservation-pickup-ajax?id_bib=2&id_origine=12&code_annexe=77©_id=12', true);
$this->_json = json_decode($this->_response->getBody());
}
/**
* @test
* @see https://forge.afi-sa.net/issues/128814
*/
public function noSiteShouldBePreChecked() {
$this->_xpath
->assertNotXPath($this->_json->content, '//input[@type="radio"][@checked]');
}
}
class RechercheControllerReservationPickupAjaxNanookPickupLocationsStrongInLabel
extends RechercheControllerReservationPickupAjaxWithNanookPickupLocationsTestCase {
public function setUp() {
parent::setUp();
$this->nanook->whenCalled('getUserAnnexe')->answers('66');
$this->dispatch('recherche/reservation-pickup-ajax?id_bib=2&id_origine=12&code_annexe=99©_id=12', true);
$this->_json = json_decode($this->_response->getBody());
}
/**
@see https://forge.afi-sa.net/issues/94332
@test
*/
public function LunelShouldContainStrong() {
$this->_xpath
->assertXPath($this->_json->content, '//strong',$this->_json->content);
}
}
class RechercheControllerReservationPickupAjaxAndNotifyByMailEnabledTest
extends RechercheControllerReservationWithPickupChoiceTestCase {
protected $_sent_mails = [];
public function setUp() {
parent::setUp();
Class_Profil::getCurrentProfil()->setMailSite('admin@example.com');
$int_bib = $this
->fixture('Class_IntBib',
['id' => 1,
'comm_sigb' => Class_IntBib::COM_KOHA,
'use_card_number' => 12345,
'comm_params' => ['url_serveur' => 'http://bib.valensol.net/cgi-bin/koha/ilsdi.pl']]);
$bib = $this->fixture('Class_Bib',
['id' => 1,
'notify_on_new_resa' => 1,
'mail'=>'adminpukapuka@example.com',
'int_bib' => $int_bib]);
$this->fixture(Class_CodifAnnexe::class,
['id' => 34,
'libelle'=>'BDM',
'id_origine' => 23]);
$this->jajm = $this
->fixture('Class_Users',
['id' => 1,
'login' => 'jajm',
'password' => 'secret',
'nom' => 'Monsieur',
'prenom' => 'Julian',
'idabon' => '00004',
'int_bib' => $int_bib,
'id_sigb' =>'0000007',
'bib' => $bib
]);
$this->mock = Storm_Test_ObjectWrapper::mock()
->whenCalled('isConnected')->answers(true)
->whenCalled('open_url')
->with('http://bib.valensol.net/cgi-bin/koha/ilsdi.pl?service=HoldTitle&patron_id=0000007&bib_id=13&request_location=127.0.0.1&pickup_location=23')
->answers('<HoldTitle>
<title>Mireille l\'abeille</title>
<pickup_location>Bibliothèque Départementale de la Meuse</pickup_location>
</HoldTitle>')
->whenCalled('reserverExemplaire')->answers(['statut'=>true,'erreur'=>'']);
Class_WebService_SIGB_Koha::setService(['url_serveur' => 'http://bib.valensol.net/cgi-bin/koha/ilsdi.pl',
'id_bib' => 1,
'type' => Class_IntBib::COM_KOHA,],
$this->mock);
ZendAfi_Auth::getInstance()->logUser($this->jajm);
$this->fixture('Class_Exemplaire', ['id' => 12,
'id_origine' =>13,
'code_barres' =>12341,
'notice'=> $this->fixture('Class_Notice',
['id'=>54,
'titre_principal' => "Mireille l'Abeille",
'type_doc' => Class_TypeDoc::LIVRE])
]);
$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();
}
/** @test */
public function parameterCodeAnnexeShouldBeUsedForReservation() {
$this->assertEquals('23',
$this->mock->getAttributesForLastCallOn('reserverExemplaire')[2]);
}
/** @test */
public function mailShouldHaveBeenSent() {
$this->assertEquals(1, count($this->_sent_mails));
}
/** @test */
public function mailSubjectShouldContainsJulianMonsieurSurExemplaire12341() {
$this->assertContains("Julian Monsieur ? =?utf-8?Q?sur l'exemplaire 12341",
quoted_printable_decode(current($this->_sent_mails)->getSubject()));
}
/** @test */
public function mailToShouldBeAdminPukaPukaAtExampleDotCom() {
$this->assertContains("adminpukapuka@example.com",current($this->_sent_mails)->getRecipients()[0]);
}
/** @test */
public function mailFromShouldBeMailAdminAtExampleDotCom() {
$this->assertContains("admin@example.com",current($this->_sent_mails)->getFrom());
}
public function expectedData() {
return [['Titre : Mireille l\'Abeille'],
['Annexe de retrait : BDM'],
['Julian Monsieur 00004'],
['Code Barre : 12341'],
['Type de Document : Livres'],
];
}
/**
* @test
* @dataProvider expectedData
*/
public function mailBodyShouldContainsContent($content) {
$this->assertContains($content,quoted_printable_decode(current($this->_sent_mails)->getBodyHtml(true)));
}
}
require_once 'tests/fixtures/KohaFixtures.php';
class RechercheControllerReservationWithWebServiceKohaAndItypesTest
extends AbstractControllerTestCase {
protected $_xpath;
public function setUp() {
parent::setUp();
Class_WebService_SIGB_AbstractRESTService::shouldThrowError(true);
$koha_service_params = ['url_serveur' => 'http://bib.valensol.net',
'grouped_holds_itypes' => " PRET_MALLE
OUT
PRET_GLACIERE
PRET_VALISE",
'bundled_holds_minimal_duration' => 30,
'bundled_holds_maximal_duration' => 60,
'id_bib' => 1,
'type' => 5];
$bib = $this->fixture('Class_IntBib',
['id' => 1,
'comm_sigb' => Class_IntBib::COM_KOHA,
'comm_params' => $koha_service_params]);
$http_client = $this
->mock()
->whenCalled('open_url')
->with('http://bib.valensol.net?service=GetRecords&id=678')
->answers(KohaFixtures::getRecordsWithGroupHoldsItypes())
->beStrict();
Class_WebService_SIGB_Koha::getService($koha_service_params)
->setWebClient($http_client);
$record =
$this->fixture(Class_Notice::class,
['id' => 8890,
'titre_principal' => 'Elementaire mon cher polar',
'auteur_principal' => 'Conan Doyle']);
$this->fixture(Class_Exemplaire::class,
['id' => 456,
'id_origine' => 678,
'code_barres' => 5360246264,
'id_int_bib' => 1,
'notice' => $record]);
$this->fixture(Class_CodifAnnexe::class,
['id' => 3,
'code' => 'VS',
'id_origine' => 'VS',
'libelle' => 'Cran',
'no_pickup' => '0']);
$this->fixture(Class_CodifAnnexe::class,
['id' => 4,
'code' => 'AN',
'id_origine' => 'AN',
'libelle' => 'Annecy',
'no_pickup' => '0']);
Class_CosmoVar::setValueOf('site_retrait_resa', 1);
$user = $this->fixture('Class_Users',
['id' => 1,
'login' => 'jajm',
'password' => 'secret',
'int_bib' => $bib,
'id_site' => 3,
'idabon' => '395749'
]);
$this->_xpath = new Storm_Test_XPath();
ZendAfi_Auth::getInstance()->logUser($user);
}
/** @test */
public function reservationShouldSelectUserAnnexeByDefault() {
$emprunteur = new Class_WebService_SIGB_Emprunteur('395749', 'jajm');
$emprunteur->setLibraryCode('VS');
Class_CommSigb::setInstance($this->mock()
->whenCalled('ficheAbonne')
->answers(['fiche' => $emprunteur]));
$this->dispatch('/recherche/reservation-pickup-ajax/id_bib/1/copy_id/456/code_annexe/AN');
$json = json_decode($this->_response->getBody());
$this->_xpath
->assertXPath($json->content, '//input[@type="radio"][@name="code_annexe"][ @value="VS"][ @checked="checked"]', $json->content);
}
/** @test */
public function reservationAjaxWithItemRequiringCalendarHoldShouldRedirectToReservationCalendarAjaxWithoutException() {
$this->postDispatch('/recherche/reservation-pickup-ajax/id_bib/1/copy_id/456/code_annexe/VS',
['code_annexe' => 'VS']);
$this->assertRedirectTo('/recherche/reservationajax/id_bib/1/copy_id/456/code_annexe/VS');
}
/** @test */
public function dispatchReservationajaxShouldRenderCalendar() {
$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');
}
}