<?php /** * Copyright (c) 2012, 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 'AbstractControllerTestCase.php'; require_once 'tests/fixtures/DilicomFixtures.php'; abstract class AbstractAbonneControllerPretsTestCase extends AbstractControllerTestCase { protected $_old_zend_cache, $_http, $_time_source, $_storm_default_to_volatile = true; protected function _loginHook($account) { $account->ROLE = "abonne_sigb"; $account->ROLE_LEVEL = 2; $account->ID_USER = '123456'; $account->PSEUDO = "Florence"; $this->account = $account; } public function setUp() { parent::setUp(); $this->florence = $this->fixture('Class_Users', ['id' => '123456', 'login' => 'flo', 'password' => 'flo']); $this->zend_cache = Storm_Test_ObjectWrapper::mock(); Storm_Cache::setDefaultZendCache($this->zend_cache); $this->zend_cache ->whenCalled('save') ->answers(true) ->whenCalled('remove') ->answers(true); $this->fixture('Class_AdminVar', ['id' => 'DILICOM_PNB_GLN_COLLECTIVITE', 'valeur' => 'test-gln']); $this->fixture('Class_AdminVar', ['id' => 'DILICOM_PNB_PWD_COLLECTIVITE', 'valeur' => 'test-gln-pass']); $this->fixture('Class_AdminVar', ['id' => 'DILICOM_PNB_GLN_CONTRACTOR', 'valeur' => '777']); $this->_http = $this->mock() ->whenCalled('setAuth') ->with('test-gln', 'test-gln-pass') ->answers(null) ->whenCalled('open_url') ->with('/v2/pnb-numerique/json/getEndedLoans?glnContractor=777&loanId[0]=5') ->answers(DilicomFixtures::getEndedLoansResponse()) ; Class_WebService_BibNumerique_Dilicom_Hub::setDefaultHttpClient($this->_http); $this->_time_source = $this->mock() ->whenCalled('dateFormat') ->with('Y-m-d H:i:s') ->answers('2015-09-30 16:51:09') ->beStrict(); Class_WebService_BibNumerique_Dilicom_Hub::setTimeSource($this->_time_source); Class_Loan_Pnb::setTimeSource($this->_time_source); } public function tearDown() { Class_WebService_BibNumerique_Dilicom_Hub::setDefaultHttpClient(null); Class_WebService_BibNumerique_Dilicom_Hub::setTimeSource(null); Class_Loan_Pnb::setTimeSource(null); parent::tearDown(); } public function assertUserRemovedFromEmprunteurCache($user) { $user_key = md5(serialize(['local', Class_WebService_SIGB_EmprunteurCache::newInstance()->keyFor($user)])); $this->assertTrue($this->zend_cache ->methodHasBeenCalledWithParams('remove', array($user_key))); } } abstract class AbonneControllerPretsListThreePretsTestCase extends AbstractAbonneControllerPretsTestCase { public function setUp() { parent::setUp(); $potter = new Class_WebService_SIGB_Emprunt('12', new Class_WebService_SIGB_Exemplaire(123)); $potter->getExemplaire()->setTitre('Potter'); $potter->parseExtraAttributes(['Dateretourprevue' => '29/10/2022', 'Section' => 'Espace jeunesse', 'Auteur' => 'JK Rowling', 'Bibliotheque' => 'Astrolabe', 'N° de notice' => '1234', 'Type' => 'P1']); $this->fixture('Class_Exemplaire', ['id' => 967, 'id_origine' => 1234, 'zone995' => serialize([['clef' => 'a', 'valeur' => 'PotterItem']]), 'notice' => $this->fixture('Class_Notice', ['id' => 889, 'titre_principal' => 'Potter', 'unimarc' => '00577nam0 2200181 450 001001500000010001800015100004100033101000800074200010700082210003000189215001100219461002000230606002900250676000800279700004500287801005600332940000700388frOr1314913787 a9781408812792 a20140320 0103 aEng1 aHarry Potter and the deathly hallowsdHarry Potter et les reliques de la mortfJoanne Kathleen Rowling aLondrescBloomsburyd2010 a831 p. 1tHarry Potterv7 aAnglais (langue)2Rameau a420 1aRowlingbJoanne Kathleenf1965-....4070 aFRbBibliothèque de l\'agglomération de Saint-Omer apm'])]); $alice = new Class_WebService_SIGB_Emprunt('13', new Class_WebService_SIGB_Exemplaire(456)); $alice->getExemplaire()->setTitre('Alice'); $alice->parseExtraAttributes(['Dateretourprevue' => '21/10/2010', 'Section' => 'Espace jeunesse', 'Auteur' => 'Lewis Caroll', 'Bibliotheque' => 'Almont', 'N° de notice' => '5678']); $this->fixture('Class_Exemplaire', ['id' => 918, 'id_origine' => 5678, 'zone995' => serialize([['clef' => 'a', 'valeur' => 'AliceItem']]), 'notice' => $this->fixture('Class_Notice', ['id' => 827, 'titre_principal' => 'Alice', 'unimarc' => '01175cam0 22002771 450 001001500000010003700015100004100052101000800093102000700101105001800108106000600126200009300132210002400225211001300249215006400262300002400326307002900350330027300379345001800652461005600670700001800726701003000744801003300774856008300807940000700890frOr0354235228 a978-2-35592-635-8bbr.d7,65 EUR a20140225d2014 | |0fre|0103||||ba afre aFR a 0||y| ar1 aAlice au royaume de TrèfleeCheshire cat Waltzh5fQuinRosegdessin Mamenosuke Fujimaru aPariscKi-oond2014 1a20140227 a1 vol. (164 p.)cillustrations en noir et blancd18 x 13 cm aTraduit du japonais aSens de lecture japonais aPerdue dans la forêt aux portes, Alice tombe nez à nez avec Ace. Devenue malgré elle la confidente du chevalier, elle ne sait comment repousser ses avances. Lorsque le chat du Cheshire, qui a assisté à la scène, intervient, la rencontre tourne à l\'affrontement. b9782355926358 1tAlice au royaume de Trèfle : Cheshire cat Waltzv5 1aQuinRose4070 1aFujimarubMamenosuke4440 aFRbElectrec20140225gAFNOR uhttp://www.electre.com//GetBlob.ashx?Ean=9782355926358,0-1913692&Size=Original aLR'])]); $emprunteur = new Class_WebService_SIGB_Emprunteur('1234', 'Florence'); $emprunteur->empruntsAddAll([$potter, $alice]); $this->fixture('Class_Loan_Pnb', ['id' => 5, 'user_id' => $this->florence->getId(), 'ongoing' => true, 'expected_return_date' => '2022-05-02T18:14:14+02:00', 'album' => $this->fixture('Class_Album', ['id' => 4, 'notice_id' => 5, 'id_origine' => 'Dilicom-88817216', 'titre' => 'Pinocchio'])->addAuthor('Collodi') ]); $this->florence ->setFicheSigb(['type_comm' => 2, //OPSYS 'fiche' => $emprunteur, 'message' => '', 'erreur' => '', 'nom_aff' => 'FloFlo']) ->setPseudo('FloFlo'); } } class AbonneControllerPretsExportThreePretsTest extends AbonneControllerPretsListThreePretsTestCase { protected $_storm_default_to_volatile = true, $_dl_file, $unimarc = '01201nam0 22002891 450 001001500000010003700015100004100052101000800093102000700101105001800108106000600126200009300132210002400225211001300249215006400262300002400326307002900350330027300379345001800652461005600670700001800726701003000744801003300774856008300807940000700890995001400897frOr0354235228 a978-2-35592-635-8bbr.d7,65 EUR a20140225d2014 | |0fre|0103||||ba afre aFR a 0||y| ar1 aAlice au royaume de Tr�efleeCheshire cat Waltzh5fQuinRosegdessin Mamenosuke Fujimaru aPariscKi-oond2014 1a20140227 a1 vol. (164 p.)cillustrations en noir et blancd18 x 13 cm aTraduit du japonais aSens de lecture japonais aPerdue dans la for�et aux portes, Alice tombe nez �a nez avec Ace. Devenue malgr�e elle la confidente du chevalier, elle ne sait comment repousser ses avances. Lorsque le chat du Cheshire, qui a assist�e �a la sc�ene, intervient, la rencontre tourne �a l\'affrontement. b9782355926358 1tAlice au royaume de Tr�efle : Cheshire cat Waltzv5 1aQuinRose4070 1aFujimarubMamenosuke4440 aFRbElectrec20140225gAFNOR uhttp://www.electre.com//GetBlob.ashx?Ean=9782355926358,0-1913692&Size=Original aLR 1aAliceItem00604nam0 22001931 450 001001500000010001800015100004100033101000800074200010700082210003000189215001100219461002000230606002900250676000800279700004500287801005600332940000700388995001500395frOr1314913787 a9781408812792 a20140320 0103 aEng1 aHarry Potter and the deathly hallowsdHarry Potter et les reliques de la mortfJoanne Kathleen Rowling aLondrescBloomsburyd2010 a831 p. 1tHarry Potterv7 aAnglais (langue)2Rameau a420 1aRowlingbJoanne Kathleenf1965-....4070 aFRbBiblioth�eque de l\'agglom�eration de Saint-Omer apm 1aPotterItem'; public function setUp() { parent::setUp(); $this->dispatch('/opac/abonne/loan-export', true); $this->_dl_file = tempnam('/tmp', 'UNIMARC'); file_put_contents($this->_dl_file, $this->_response->getBody()); } /** @test */ public function controllerAndActionShouldBeAbonnePrets() { $this->assertController('abonne'); $this->assertAction('loan-export'); } /** @test */ public function responseBodyShouldBeAttachment() { $this->assertHeaderContains('Content-Disposition', 'attachment'); } /** @test */ public function responseFileNameShouldContainsPrets() { $this->assertHeaderContains('Content-Disposition', 'filename="prets_'); $this->assertHeaderContains('Content-Type', 'name="prets_'); } /** @test */ public function bodyShouldContainsUnimarcs() { $this->assertSame($this->unimarc, $this->_response->getBody()); } /** @test */ public function dlFileShouldContainsUnimarc() { $this->assertEquals($this->unimarc, file_get_contents($this->_dl_file)); } } class AbonneControllerPretsListThreePretsTest extends AbonneControllerPretsListThreePretsTestCase { public function setUp() { parent::setUp(); $this->dispatch('/opac/abonne/prets', true); } /** @test */ public function returnToMyHomeShouldBePresent() { $this->assertXPathContentContains('//a[contains(@href, "/abonne/fiche")]', utf8_encode('Retour � mon compte')); } /** @test */ public function controllerAndActionShouldBeAbonnePrets() { $this->assertController('abonne'); $this->assertAction('prets'); } /** @test */ public function cacheShouldHaveBeenCleared() { $this->assertUserRemovedFromEmprunteurCache($this->florence); } /** @test */ public function userNameShouldBePresent() { $this->assertQueryContentContains('div.abonneTitre', 'FloFlo'); } /** @test */ public function loanExportLinkShouldBePresent() { $this->assertXPathContentContains('//a[contains(@href, "/abonne/loan-export")]', 'Export unimarc', $this->_response->getBody()); } /** @test */ public function tableShouldHaveClassTableSorter() { $this->assertXPath('//table[@class="tablesorter loans"]', $this->_response->getBody()); } /** @test */ public function tableSorterShouldBeLoaded() { $this->assertXPath('//script[contains(@src, "tablesorter.min")]'); $this->assertXPath('//link[contains(@href, "tablesorter/css/theme.default.css")]'); $this->assertXPathContentContains('//script', '$(".tablesorter").tablesorter()'); } /** @test */ public function aliceLoanShouldBePresent() { $this->assertXPathContentContains("//tbody/tr[1][@class=\"pret_en_retard\"]//td//a[contains(@href, '/recherche/viewnotice/id/827/retour_abonne/prets')]", 'Alice'); } /** @test */ public function aliceLibraryShouldBeAlmont() { $this->assertXPathContentContains("//tbody/tr[1]//td", 'Almont'); } /** @test */ public function aliceAuthorShouldBeLewisCaroll() { $this->assertXPathContentContains("//tbody/tr[1]//td", 'Lewis Caroll'); } /** @test */ public function aliceDueDateShouldBeTwentyOneOctober() { $this->assertXPathContentContains("//tbody/tr[1]//td", '21/10/2010'); } /** @test */ public function aliceLoanShouldHaveExtendLink() { $this->assertXPathContentContains("//tbody/tr[1]//td//a[@href='/abonne/prolongerPret/id_pret/13'][@data-popup='true']", 'Prolonger'); } /** @test */ public function potterLoanShouldBePresent() { $this->assertXPathContentContains("//tbody/tr[2]//td", 'Potter', $this->_response->getBody()); } /** @test */ public function potterLibraryShouldBeAstrolab() { $this->assertXPathContentContains("//tbody/tr[2]//td", 'Astrolabe'); } /** @test */ public function potterAuthorShouldBeJKRolling() { $this->assertXPathContentContains("//tbody/tr[2]//td", 'JK Rowling'); } /** @test */ public function potterDueDateShouldBeTwentyNineOctober2022() { $this->assertXPathContentContains("//tbody/tr[2][not(@class)]//td", '29/10/2022'); } /** @test */ public function potterLoanShouldHaveExtendLink() { $this->assertXPathContentContains("//tbody/tr[2]//td//a[@href='/abonne/prolongerPret/id_pret/12'][@data-popup='true']", 'Prolonger'); } /** @test **/ public function colonneInformationShouldBeDisplay(){ $this->assertXPathContentContains('//thead//th','Informations'); } /** @test **/ public function colonneInformationShouldContainsP1(){ $this->assertXPathContentContains('//tbody//td','P1', $this->_response->getBody()); } /** @test */ public function pnbH2TitleShouldBePresent() { $this->assertXpathContentContains('//h2', utf8_encode('Pr�ts num�riques en cours'), $this->_response->getBody()); } /** @test */ public function pinocchioPnbLoanShouldBePresent() { $this->assertXPathContentContains('//tbody//a[contains(@href, "viewnotice/id/5")]', 'Pinocchio'); } /** @test */ public function pinocchioPnbLoanReturnDateShouldBeAsExpected() { $this->assertXPathContentContains('//tbody//td[@class="date_retour"]', '2022-05-02T18:14:14+02:00'); } } class AbonneControllerPretsListThreePretsPnbEarlyReturnTest extends AbonneControllerPretsListThreePretsTestCase { public function setUp() { parent::setUp(); $this->_http ->whenCalled('open_url') ->with('/v2/pnb-numerique/json/getEndedLoans?glnContractor=777&loanId[0]=5') ->answers(DilicomFixtures::getEndedLoansResponse(['{"loanId":"5","returnDate":"2015-09-18T14:30:00+02:00"}'])) ->beStrict(); $this->dispatch('/opac/abonne/prets', true); } /** @test */ public function pnbTitleShouldNotBePresent() { $this->assertNotXpathContentContains('//h2', utf8_encode('Pr�ts num�riques en cours')); } /** @test */ public function pnbLoanReturnDateShouldBeUpdated() { $this->assertEquals('2015-09-18T14:30:00+02:00', Class_Loan_Pnb::find(5)->getExpectedReturnDate()); } } class AbonneControllerPretsListReservationTest extends AbstractAbonneControllerPretsTestCase { public function setUp() { parent::setUp(); Class_Exemplaire::beVolatile(); $potter = (new Class_WebService_SIGB_Reservation('12', (new Class_WebService_SIGB_Exemplaire(123))->setTitre('Potter'))) ->parseExtraAttributes(['Etat' => 'Réservation émise', 'Rang' => '2', 'Bibliotheque' => 'Tombouctou', 'N° de notice' => 564]); // This item has no library: non-regression test. $dobby = (new Class_WebService_SIGB_Reservation('13', (new Class_WebService_SIGB_Exemplaire(124))->setTitre('Dobby'))) ->parseExtraAttributes(['Etat' => 'Réservation émise', 'Rang' => '2', 'N° de notice' => 565]); $this->fixture('Class_Notice', ['id' => 820, 'titre_principal' => 'Potter']); $this->fixture('Class_Notice', ['id' => 824, 'titre_principal' => 'Dobby']); $this->fixture('Class_Exemplaire', ['id' => 120, 'id_origine' => 564, 'id_notice' => 820]); $this->fixture('Class_Exemplaire', ['id' => 130, 'id_origine' => 565, 'id_notice' => '824', 'zone995' => '']); $this->florence ->setPseudo('FloFlo') ->setFicheSigb(['type_comm' => Class_IntBib::COM_OPSYS, 'fiche' => (new Class_WebService_SIGB_Emprunteur('1234', 'Florence')) ->reservationsAddAll([$potter, $dobby]), 'message' => '', 'erreur' => '']); $this->dispatch('/opac/abonne/reservations'); } /** @test */ public function controllerShouldBeAbonne() { $this->assertController('abonne'); } /** @test */ public function cacheShouldHaveBeenCleared() { $this->assertUserRemovedFromEmprunteurCache($this->florence); } /** @test */ public function actionShouldBeReservations() { $this->assertAction('reservations'); } /** @test */ public function nomShouldBeFloFlo() { $this->assertQueryContentContains('div.abonneTitre', 'FloFlo'); } /** @test */ public function tableShouldHaveClassTableSorter() { $this->assertXPath('//table[@class="tablesorter"]'); } /** @test */ public function tableSorterShouldBeLoaded() { $this->assertXPath('//script[contains(@src, "tablesorter.min")]'); } /** @test */ public function titreShouldBePotterAndLinkToNotice() { $this->assertXPathContentContains('//tbody/tr[1]//td//a[contains(@href, "recherche/viewnotice/id/820/retour_abonne/reservations")]', 'Potter', $this->_response->getBody()); } /** @test */ public function etatShouldBeReservationEmise() { $this->assertXPathContentContains('//tbody/tr[1]//td', 'Réservation émise'); } /** @test */ public function rangShouldBeTwo() { $this->assertXPathContentContains('//tbody/tr[1]//td', '2'); } /** @test */ public function linkToDeleteShouldBeAsExpected() { $this->assertXPath("//tbody/tr[1]//td//a[@href='/abonne/reservations/id_delete/12']"); } /** @test */ public function bibliothequeShouldBeTombouctou() { $this->assertXPathContentContains('//tbody/tr[1]//td', 'Tombouctou', $this->_response->getBody()); } /** @test */ public function secondReservationTitleShouldBeDobby() { $this->assertXPathContentContains('//tbody/tr[2]//td//a', 'Dobby', $this->_response->getBody()); } } abstract class AbonneControllerPretsRenewThreePretsTestCase extends AbonneControllerPretsListThreePretsTestCase { public function setUp() { parent::setUp(); Class_CommSigb::setInstance($this->getSigbMock()); $this->dispatch('/opac/abonne/prolongerPret/render/popup', true); $this->json = json_decode($this->_response->getBody()); } protected function getSigbMock() { return $this->mock(); } public function tearDown() { Class_CommSigb::setInstance(null); parent::tearDown(); } /** @test */ public function responseShouldBeJson() { $this->assertNotNull($this->json); } /** @test */ public function popupShouldBeModal() { $this->assertEquals('true', $this->json->show_modal); } /** @test */ public function popupShouldBeContered() { $this->assertEquals('center center', $this->json->position->my); $this->assertEquals('center center', $this->json->position->at); } } class AbonneControllerPretsRenewErrorThreePretsTest extends AbonneControllerPretsRenewThreePretsTestCase { protected function getSigbMock() { return $this->mock() ->whenCalled('prolongerPret') ->answers(['statut' => 0, 'erreur' => '<strong>Patron not found</strong>']); } /** @test */ public function popupTitleShouldBeErreur() { $this->assertEquals('Erreur', $this->json->title); } /** @test */ public function popupContentShouldContainsPatronNotFound() { $this->assertEquals('<strong>Patron not found</strong>', $this->json->content); } } class AbonneControllerPretsRenewSuccessThreePretsTest extends AbonneControllerPretsRenewThreePretsTestCase { protected function getSigbMock() { return $this->mock() ->whenCalled('prolongerPret') ->answers(['statut' => 1]); } /** @test */ public function popupTitleShouldBeErreur() { $this->assertEquals(utf8_encode('Pr�t prolong�'), $this->json->title); } /** @test */ public function popupContentShouldContainsPatronNotFound() { $this->assertEquals(utf8_encode('Votre pr�t a bien �t� prolong�.'), $this->json->content); } } /** @see http://forge.afi-sa.fr/issues/31316 */ class AbonneControllerPretsPeriodicalTitleTest extends AbstractAbonneControllerPretsTestCase { protected $_sigb; public function setUp() { parent::setUp(); $this->zend_cache->whenCalled('test')->answers(false); $identity = Class_Users::getIdentity(); $patron = new Class_WebService_SIGB_Emprunteur($identity->getId(), 'FloFlo'); $item = (new Class_WebService_SIGB_Exemplaire(12387)) ->setTitre('Avril-mai-juin 2013') ->setDateRetour('30-12-2015') ->setNoNotice(13340) ->setBibliotheque('Espace Culturel Fran�ois-Mitterrand'); $loan = new Class_WebService_SIGB_Emprunt(12387, $item); $patron->empruntsAdd($loan); Class_CommSigb::setInstance($this->mock() ->whenCalled('ficheAbonne') ->answers(['fiche' => $patron])); $record = $this->fixture('Class_Notice', ['id' => 889, 'unimarc' => file_get_contents(__DIR__.'/petites_mains.mrc')]); $z995 = [['clef' => 'a', 'valeur' => 'Espace Culturel'], ['clef' => 'f', 'valeur' => '0720028863'], ['clef' => 'k', 'valeur' => 'J-REV 10-N�90']]; $this->fixture('Class_Exemplaire', ['id' => 967, 'id_origine' => 13340, 'zone995' => serialize($z995), 'notice' => $record]); $identity->setIdabon('007'); $this->dispatch('/opac/abonne/prets', true); } public function tearDown() { Class_CommSigb::setInstance(null); parent::tearDown(); } /** @test */ public function titleShouldBePetitesMains90() { $this->assertXPathContentContains('//a', utf8_encode('Petites mains n� 90')); } }