<?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';

class NoticeAjaxControllerNonRegressionTest extends AbstractControllerTestCase {
	public function setUp() {
		parent::setUp();
		$this->fixture('Class_Notice',
									 ['id' => '197143']);
	}


	/** @test */
	function exemplairesWithoutIdNoticeShouldRenderEmptyHtml() {
		$this->dispatch('noticeAjax/exemplaires');
		$this->assertEmpty($this->_response->getBody(),$this->response->getBody());
	}


	/** @test */
	function detailShouldRenderAucuneNoticeTrouvee() {
		Class_Notice::newInstanceWithId(197143,
																		['titres' => 'IRM SOULEY',
																		 'auteurs' => 'MOI',
																		 'editeur' => 'CINE',
																		 'collection' => 'COLLEC BUNDLE',
																		 'matieres' => '  ETRANGE',
																		 'dewey' => '']);

		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Notice')
			->whenCalled('findAllBy')
			->with(['where' => "MATCH(titres,auteurs,editeur,collection,matieres,dewey) AGAINST('(IRM IRMS ) (SOULEY SOULEYS SOULAI) (MOI MOIS ) (CINE CINES SIN) (COLLEC COLLECS KOLEK) (BUNDLE BUNDLES BINDL) (ETRANGE ETRANGES ETRANJ)') AND id_notice != 197143",
							'limit' => 10])
			->answers([]);


		$this->dispatch('/opac/noticeajax/similaires?isbn=&onglet=set197143_onglet_0&page=0&id_notice=197143', true);
		$this->assertXPathContentContains('//td', 'Aucune information');
	}
}



class NoticeAjaxControllerNoticeWithGamUrlTestCase extends AbstractControllerTestCase {
	protected $_wesley;

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

		$this->_wesley = $this->fixture(
			'Class_Notice',
			['id' => 1,
			 'facettes' => 'A1',
			 'isbn' => '',
			 'ean' => '',
			 'type_doc' => 1,
			 'tome_alpha' => '',
			 'clef_alpha' => 'Wesley',
			 'unimarc' => "02502njm0 22007331  450 00100060000007100370000610000410004310100080008412700100009220000450010220000030014721000390015021500090018932700030019834500420020146400030024346400030024646400030024946400030025246400030025546400030025846400030026146400030026446400030026746400030027046400030027346400030027646400030027946400190028246400210030146400160032246400100033846400240034846400250037246400110039746400250040846400290043346400280046246400180049046400150050846400170052368600290054070000320056970000030060170100320060470200400063670200340067670200330071070200380074370200440078170200350082570200360086070200310089671100030092780100220093085601320095293301470108498401320123198500820136398500840144598500790152998500730160898500870168134793100a2784087bHIP-OSelect.com/Polydor  a20130311d2011    u  y0frey0103    ba0 aeng  a53:221 aThe Lost album featuring Watermelon man 1   cUniversal RecordsdRÂeedition 2011  a1 cd1   b0602527840871cdisque compactd7,48 E 1 1 1 1 1 1 1 1 1 1 1 1 1  tWatermelon man  tSweet loneliness  tSecret love  tSeulb  tYou've got a friend  tTransmograpification  tUse me  tGet on the good foot  tEverybody plays the fool  tAlone again (Naturally)  tBack stabbers  tJ.B. shout  tFunky & some  a1.382tJazz funky2PCDM4 1aWesleybFred40006trombone 1 1aThe JB's 40006ens. instr. 1aFarrellbJoe40006saxophone tÂenor 1aStammbMarvin4btr6trompette 1aBrownbCharlie40006guitare 1aCranshawbBob4MBS6basse guitare 1aBreckerbMichael40006saxophone tÂenor 1aBreckerbRandy4btr6trompette 1aCarterbRon4MBS6basse guitare 1aGaddbSteve4PDS6batterie02 0aFRbGAMc201303114 uhttp://www.gamannecy.com//upload/albums/201202/0602527840871_thumb.jpgzFred Wesley / Lost album featuring Watermelon man (The)  3http://www.gamannecy.com//upload/albums/201202/0602527840871_thumb.jpgahttp://www.gamannecy.com//upload/albums/201202/0602527840871_thumb.jpg  ahttp://www.gamannecy.com//upload/albums/201202/0602527840871_thumb.jpgbFred Wesley / Lost album featuring Watermelon man (The)  ahttp://www.gamannecy.com/polysson/201205/01-0602527840871.mp3bWatermelon man  ahttp://www.gamannecy.com/polysson/201205/02-0602527840871.mp3bSweet loneliness  ahttp://www.gamannecy.com/polysson/201205/03-0602527840871.mp3bSecret love  ahttp://www.gamannecy.com/polysson/201205/04-0602527840871.mp3bSeulb  ahttp://www.gamannecy.com/polysson/201205/05-0602527840871.mp3bYou've got a friend",
			 'annee' => '2000',
			 'url_vignette' => 'wesley_small.png',
			 'url_image' => 'wesley.png']);

		$mock_sql = Storm_Test_ObjectWrapper::on(Zend_Registry::get('sql'));
		Zend_Registry::set('sql', $mock_sql);

		$mock_sql
			->whenCalled('fetchOne')
			->with("select valeur from variables where clef='black_list_856'")
			->answers('electre');

		$this->fixture('Class_CosmoVar', ['id' => 'types_docs',
																			'liste' => "1:cd\r\n200:non identifié\r\n201:livres\r\n202:bd"]);
	}


	/** @test */
	public function withNoticeFoundResponseShouldContainsLienInternet() {
		$this->dispatch('/opac/noticeajax/detail/id_notice/1', true);
		$this->assertXPathContentContains('//a', 'http://www.gamannecy.com//upload/albums/201202/0602527840871_thumb.jpg', $this->_response->getBody());
	}
}




class NoticeAjaxControllerNoticeWithCustomLinks extends AbstractControllerTestCase {
	public function setUp() {
		parent::setUp();

		$this->fixture('Class_Notice',
									 ['id' => 999,
										'type_doc' => 1,
										'unimarc' => '02096nam0 22002651  450 0010008000000100034000080730018000421000041000602000038001012100035001392150042001742250011002163301160002274100037013876070043014246760007014677000032014748010038015068010028015449020019015729020010015919030006016019330103016079330120017100662324  a978-2-7491-4106-0d18,80 Ð   |a2-7491-4106-0  a20140623d2014    u  u0frey50      ba1 aLa TerreurfPatrick Wald Lasowski  aPariscCherche midi (Le)d2014  a345 p.cjaquette ill. en coul.d21 cm| aStyles  aMars 1793. Un homme s\'interroge. Malade, rongé par le cancer qu\'il soigne en mêlant grains d\'opium et verres de ratafia, le commissaire Grand-Jacques découvre les effets de la Terreur mise à l\'ordre du jour. Que veulent-ils ? Qu\'est-ce qui les fait danser, les Enragés, les Indulgents, les missionnaires, les juges et les jurés du Tribunal révolutionnaire et la meute des lécheurs de guillotine qui attend le passage des condamnés ? Est-ce une puissance de mort ou de vie ? Est-ce un charnier ou un berceau ? Et lui-même, Grand-Jacques, qui poursuit ses enquêtes ordinaires, assisté de ses deux lieutenants, Chêneville et Cloüet, qu\'attend-il des mois qui lui restent à vivre ? Du moins y a-t-il les moments partagés avec son ami mélomane, Bruiant Fauve-Roussel, et les rêves que suscite Adeline, la fille galante de la maison voisine, aux yeux charbonnés et aux lèvres gourmandes. Voilà pourtant qu\'une série de crimes d\'une extrême violence relance son désir de justice, au-delà de la pitié. Le vieux limier se met en quête. Parmi les victimes quotidiennes de la Terreur, ces prostituées assassinées sont des mortes de trop. 030527714tStylescLe Cherche midi  aFrancez1789-1799 (Révolution)xRoman  aRP 1aWald LasowskibPatrick4070 3aFrbLibrairie Dialoguesc20140623 2aFRbBDP Yonnec20141017  aRoman policier  aRoman  am  3http://www.pagedeslibraires.fr/livre-6236/la-terreur.htmlaVoir la chronique de Page des libraires  3http://www.lepoint.fr/livres/la-terreur-cinq-meurtres-de-trop-14-09-2014-1863005_37.phpaVoir la chronique du Point']);

		Class_Profil::getCurrentProfil()
			->setCfgModules(['recherche' => ['viewnotice1' => ['links_zones' => '933-3-a']]]);

		$this->fixture('Class_CosmoVar',
									 ['id' => 'types_docs',
										'liste' => "1:cd\r\n200:non identifié\r\n201:livres\r\n202:bd"]);

		$this->dispatch('/opac/noticeajax/detail/id_notice/999', true);
	}

	/** @test */
	public function detailsShouldContainPrice() {
		$this->assertXPathContentContains('//dt[contains(@class, "prix")]/following-sibling::dd', '18,80');
	}

	/** @test */
	public function linkToPageDesLibrairesFrShouldBePresent() {
		$this->assertXPathContentContains('//a[contains(@href, "www.pagedeslibraires.fr/livre-6236/la-terreur.html")]',
																			'Voir la chronique de Page des libraires',
																			$this->_response->getBody());
	}


	/** @test */
	public function linkToLePointFrShouldBePresent() {
		$this->assertXPathContentContains('//a[contains(@href, "www.lepoint.fr/livres/la-terreur-cinq-meurtres-de-trop")]',
																			'Voir la chronique du Point',
																			$this->_response->getBody());
	}
}



abstract class NoticeAjaxControllerNoticeSouleymaneTestCase extends AbstractControllerTestCase {
	protected $_souleymane;

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

		Class_Profil::getCurrentProfil()
			->setCfgModules(['recherche' => ['resultatsimple' => ['liste_codes' => "TANECRG"]]]);

		$this->fixture('Class_CodifAuteur',
									 ['id' => 1,
										 'libelle' => 'Souleymane Cisse']);

		$this->_souleymane = Class_Notice::newInstanceWithId(1,
																												 ['facettes' => 'A1',
																													'isbn' => '',
																													'ean' => '',
																													'type_doc' => 1,
																													'tome_alpha' => '',
																													'clef_alpha' => 'SOULEYMANE',
																													'unimarc' => "01328ngm0 2200265   450 0010007000001000041000071010013000481020007000611150025000682000071000932100022001642150053001863000035002393000045002743300454003193450027007735100018008006060027008186060039008457000042008847020043009267020033009697020032010028010028010342247456  a20021213i20041975u  y0frey0103    ba0 abamjfre  aFR  ac086baz|zba    zz  c1 aLa jeune fillebDVDdDen MusofSouleymane Cisse, réal., scénario  cPathédcop. 2004  a1 DVD vidéo monoface zone 2 (1 h 26 min)ccoul.  aDate de sortie du film : 1975.  aFilm en bambara sous-titré en français  aSékou est renvoyé de l'usine parce qu'il a osé demander une augmentation. Chômeur, il sort avec Ténin, une jeune fille muette ; il ignore qu'elle est la fille de son ancien patron. Ténin, qui sera violée par Sékou lors d'une sortie entre jeunes, se retrouve enceinte et subit la colère de ses parents. Elle se trouve alors confrontée brutalement à la morale de sa famille et à la lâcheté de Sékou, qui refuse de reconnaiîre l'enfant.  b3388334509824d14.00 ?1 aDen Musozbam| 31070135aCinémayMali| 32243367aCinéma30076549yAfrique 131070144aCissébSouleymane43704690 132247457aCoulibalibDounamba Dani4590 132247458aDiabatebFanta4590 132247459aDiarrabOumou4590 0aFRbBNc20011120gAFNOR",
																													'annee' => '2000',
																													'url_vignette' => 'souleymane_small.png',
																													'url_image' => 'souleymane.png',
																													'titres' => 'IRM SOULEYMANE',
																													'collection' => 'HISTOIRE']);
	}
}




class NoticeAjaxControllerDetailActionTest extends NoticeAjaxControllerNoticeSouleymaneTestCase {
	/** @test */
	public function withNoticeFoundResponseShouldContainsTitleLaJeuneFille() {
		$this->dispatch('/opac/noticeajax/detail/id_notice/1', true);
		$this->assertXPathContentContains('//div', 'La jeune fille', $this->_response->getBody());
	}

	/** @test */
	public function withrNoticeNotFoundResponseShouldBeEmpty() {
		$this->dispatch('/opac/noticeajax/detail/id_notice/-1', true);
		$this->assertEmpty($this->_response->getBody());
	}
}




class NoticeAjaxControllerNoticeSimilairesSouleymaneTest extends NoticeAjaxControllerNoticeSouleymaneTestCase {
	public function setUp() {
		parent::setUp();

		Class_Notice::newInstanceWithId(18787,
																		['titres' => 'IRM SOULEY',
																		 'auteurs' => 'MOI',
																		 'editeur' => 'CINE',
																		 'collection' => 'COLLEC BUNDLE',
																		 'matieres' => '  ETRANGE',
																		 'dewey' => '']);

		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Notice')
			->whenCalled('findAllBy')
			->with(['where' => "MATCH(titres,auteurs,editeur,collection,matieres,dewey) AGAINST('(IRM IRMS ) (SOULEY SOULEYS SOULAI) (MOI MOIS ) (CINE CINES SIN) (COLLEC COLLECS KOLEK) (BUNDLE BUNDLES BINDL) (ETRANGE ETRANGES ETRANJ)') AND id_notice != 18787",
							'limit' => 10])
			->answers([$this->_souleymane]);

		$this->dispatch('/opac/noticeajax/similaires?isbn=&onglet=set197143_onglet_0&page=0&id_notice=18787', true);
	}


	/** @test */
	function aLinkShouldContainsAuteurSouleymaneCissé() {
		$this->assertXPathContentContains('//a', utf8_encode('Souleymane Cissé'));
	}


	/** @test */
	public function supportShouldBeDisplayed() {
		$this->assertContains("images/supports", $this->_response->getBody());
	}


	/** @test */
	public function dtForAnneeShouldBeVisible() {
		$this->assertXPathContentContains('//dl//dt', utf8_encode('Année'));
		$this->assertXPathContentContains('//dl//dd', '2000');
	}


	/** @test */
	public function dtForEditeurShouldBeVisible() {
		$this->assertXPathContentContains('//dl//dt', 'Editeur(s)');
		$this->assertXPathContentContains('//dl//dd', utf8_encode('Pathé'));
	}


	/** @test */
	public function dtForResumeShouldBeVisible() {
		$this->assertXPathContentContains('//dl//dt', utf8_encode('Résumé'));
		$this->assertXPathContentContains('//dl//dd', utf8_encode('Sékou est renvoyé'));
	}


	/** @test */
	public function dtForTitreShouldNotBeVisible() {
		$this->assertNotXPathContentContains('//dl//dt', 'La jeune fille');
	}


	/** @test */
	public function dtForAuteurShouldBeVisible() {
		$this->assertXPathContentContains('//dl//dt', 'Auteur');
		$this->assertXPath('//dl//dd//a[contains(@href, "code_rebond/A1")]');
	}
}




class NoticeAjaxControllerResNumeriquesTest extends AbstractControllerTestCase {

	public function setup() {
		parent::setup();
		$this->fixture('Class_Notice', ['id' => 123]);
		$this->fixture('Class_Exemplaire', ['id' => 34,
																				'id_origine' => 8,
																				'id_notice' => 123]);
	}


	/** @test */
	function bookletShouldBeLoadedWithAlbumTypeLivreNumerique() {
		$this->fixture('Class_Notice', ['id' => 123]);
		$album = $this->fixture('Class_Album', ['id' => 8,
																						'type_doc_id' => Class_TypeDoc::LIVRE_NUM]);

		$this->dispatch('noticeajax/resnumeriques?id_notice=123');

		$this->assertXPathContentContains('//script', '_load_in_scriptsRoot');
	}


	/** @test */
	function messageAucuneRessourceShouldBeDisplayedIfAlbumDoesNotExists() {
		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Exemplaire')
			->whenCalled('findFirstBy')
			->answers(null);

		$this->dispatch('noticeajax/resnumeriques?id_notice=124');

		$this->assertXPathContentContains('//p', 'Aucune ressource correspondante');
	}


	/** @test */
	function diaporamaShouldBeLoadedWithAlbumTypeDiaporama() {
		$album = $this->fixture('Class_Album', ['id' => 8,
																						'type_doc_id' => Class_TypeDoc::DIAPORAMA]);

		$this->dispatch('noticeajax/resnumeriques?id_notice=123', true);

		$this->assertXPath('//script[contains(@src, "jquery.cycle.all")]');
	}
}


class NoticeAjaxControllerBandeAnnonceTest extends AbstractControllerTestCase {

	/** @test */
	public function shouldContainsSourceTitle() {
		Class_WebService_AllServices::setHttpClient(
			Storm_Test_ObjectWrapper::mock()
			->whenCalled('open_url')
			->answers(json_encode(['source' => 'Testing', 'player' => 'toto'])));
		$this->dispatch('noticeajax/bandeannonce', true);
		$this->assertXPathContentContains('//h3', 'Source : Testing', $this->_response->getBody());
  }

}


abstract class NoticeAjaxControllerLastFmTestCase extends AbstractControllerTestCase {
	public function setUp() {
		parent::setUp();
		$this->lastfm = $this->mock();
		Class_WebService_Lastfm::setInstance($this->lastfm);

		$this->fixture('Class_Notice', ['id' => 777])
			->setAuteurPrincipal('Frodo')
			->setTypeDoc('3')
			->save();
	}


	public function tearDown() {
		Class_WebService_Lastfm::setInstance(null);
		parent::tearDown();
	}


	/** @test */
	public function shouldContainsTitle() {
		$this->assertXPath('//h3', $this->_response->getBody());
	}
}


class NoticeAjaxControllerPhotosTest extends NoticeAjaxControllerLastFmTestCase {
	public function setUp() {
		parent::setUp();
		$this->lastfm->whenCalled('getPhotos')->with('Frodo')->answers(['1.jpg']);
		$this->dispatch('noticeajax/photos/id_notice/777', true);
	}
}


class NoticeAjaxControllerBibliographiesTest extends NoticeAjaxControllerLastFmTestCase {
	public function setUp() {
		parent::setUp();
		$this->lastfm->whenCalled('getDiscographie')->with('Frodo')
			->answers([['vignette' => '', 'titre' => '']]);
		$this->dispatch('noticeajax/bibliographie?id_notice=777', true);
	}
}


class NoticeAjaxControllerInterviewsTest extends AbstractControllerTestCase {
	/** @test */
	public function shouldContainsTitle() {
		$this->fixture('Class_Notice', ['id' => 777])
			->setAuteurPrincipal('Frodo')
			->save();

		Class_WebService_AllServices::setHttpClient(
			Storm_Test_ObjectWrapper::mock()
			->whenCalled('open_url')->answers(json_encode(['source' => 'Testing',
																										 'videos' => [['titre' => '',
																											 'contenu' => '']]])));

		$this->dispatch('noticeajax/videos?id_notice=777', true);
		$this->assertXPath('//h3');
	}
}



/** @see http://forge.afi-sa.fr/issues/16741 */
class NoticeAjaxControllerResumeGamWidgetTest extends AbstractControllerTestCase {
	/** @test */
	public function shouldDisplayGamWidget() {
		$this->fixture('Class_Notice',
									 ['id' => 3800226,
										'unimarc' => file_get_contents(dirname(__FILE__)
																									 . '/sous_la_peau.uni')]);
		$this->dispatch('noticeajax/resume/id/3800226', true);
		$this->assertXPath('//iframe[contains(@src, "gamannecy.com")]');
	}
}



class NoticeAjaxControllerResumeAlbumTest extends AbstractControllerTestCase {
	protected $_notice;

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

		$this->_notice = Class_Notice::getLoader()
			->newInstanceWithId(123)
			->beLivreNumerique()
			->setExemplaires(array($exemplaire = Class_Exemplaire::getLoader()
														 ->newInstanceWithId(34)
														 ->setIdOrigine(2)));

		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Exemplaire')
			->whenCalled('findFirstBy')
			->with(['id_notice' => 123])
			->answers($exemplaire);

		Class_Album::getLoader()
			->newInstanceWithId(2)
			->setDescription('Lucky Luke est un grand cow-boy');
	}


	/** @test */
	public function contenuShouldContainsResume() {
		$this->dispatch('noticeajax/resume?id_notice=123');
		$this->assertXPathContentContains('//div', 'Lucky Luke est un grand cow-boy');
	}


	/** @test */
	public function withNoExemplairesShouldNotFail() {
		$this->_notice->setExemplaires(array());
		$this->dispatch('noticeajax/resume?id_notice=123');
	}


	/** @test */
	public function withNoAlbumFoundShouldNotFail() {
		array_first($this->_notice->getExemplaires())->setIdOrigine(999999999);
		$this->dispatch('noticeajax/resume?id_notice=123');
	}


  /** @test */
  public function shouldContainsSourceTitle() {
		$this->dispatch('noticeajax/resume?id_notice=123');
		$this->assertXPathContentContains('//h3', 'Source :');
  }
}



abstract class NoticeAjaxControllerExemplairesTestCase extends AbstractControllerTestCase {
	protected $_notice;

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

		ZendAfi_Auth::getInstance()->clearIdentity();

		$this->_notice = $this->fixture('Class_Notice', ['id' => 123,
																										 'clef_oeuvre' => 'AAA'])
													->beLivreNumerique()
													->setExemplaires([$this->fixture('Class_Exemplaire', ['id' =>999,
																																								'id_bib' => 99,
																																								'id_int_bib' => 4,
																																								'id_notice' => 123,

																																								'annexe' => 'MOUL',
																																								'section' => 'A9',
																																								'emplacement' => 'emplacement de test',
																																								'cote' => 'VOD-T-DLJ',
																																								'dispo' => 'Disponible',
																																								'date_retour' => 'En mai',
																																								'reservable' => true,
																																								'code_barres' => '7777734343488'])
																						]);

		$this->fixture('Class_Notice', ['id' => 125,
																		'clef_oeuvre' => 'AAA',
																		'exemplaires' => [$this->fixture('Class_Exemplaire', ['id' =>799,
																																													'id_bib' => 99,
																																													'cote' => 'VOD',
																																													'dispo' => 'Disponible'])]
																		]);


		Class_Profil::getCurrentProfil()->setCfgNotice([]);

		$mock_sql = Storm_Test_ObjectWrapper::on(Zend_Registry::get('sql'));
		Zend_Registry::set('sql', $mock_sql);

		$this->fixture('Class_IntBib', ['id' => 4,
																		'comm_sigb' => Class_IntBib::COM_NANOOK,
																		'comm_params' => serialize(['url_serveur' => ''])]);
		$this->fixture('Class_bib',
									 ['id' => 99,
									 ]);



	}
}



class NoticeAjaxControllerExemplairesSameWorkTest extends NoticeAjaxControllerExemplairesTestCase {
	public function setUp() {
		parent::setUp();

		$this->dispatch('noticeajax/exemplaires-same-work/id/123', true);
	}


	/** @test */
	public function shouldRenderNumber() {
		$this->assertXPathContentContains('//td', '1');
	}

/** @test */
	public function iconShouldBeLinkToAnotherNotice() {
		$this->assertXPath('//a[@href="/recherche/viewnotice/id/125"]//img[contains(@src,"loupe.gif")]'
											 ,$this->_response->getBody());

	}
}


class NoticeAjaxControllerExemplairesWithIdBibs extends NoticeAjaxControllerExemplairesTestCase {

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

		$this->_notice->addExemplaire(
																$this->fixture('Class_Exemplaire',
																							 ['id' =>777,
																								'id_bib' => 77,
																								'id_int_bib' => 0,
																								'id_notice' => 123,
																								'annexe' => 'MOUL',
																								'section' => 'A9',
																								'emplacement' => 'emplacement de test',
																								'cote' => 'VOD-T-II',
																								'dispo' => 'Disponible',
																								'date_retour' => 'En mai',
																								'reservable' => true,
																								'code_barres' => '7777734343488']));
		$this->_notice->save();
		Zend_Registry::get('session')->id_bibs=[77];
		$this->dispatch('noticeajax/exemplaires/id/123/id_notice/8', true);
	}

  /** @test */
	public function coteVODTIIShouldBeInExemplaire() {
		$this->assertXPathContentContains('//td[@class="cote"]','VOD-T-II');
	}

  /** @test */
	public function coteVODTShouldBeNotBeInExemplaire() {
		$this->assertNotXPathContentContains('//td[@class="cote"]','VOD-T-DLJ');
	}

}


class NoticeAjaxControllerExemplairesTest extends NoticeAjaxControllerExemplairesTestCase {
	public function setUp() {
		parent::setUp();

		$this->dispatch('noticeajax/exemplaires/id/123/id_notice/8', true);
	}


	/** @test */
	public function shouldRenderNumber() {
		$this->assertXPathContentContains('//td', '1');
	}


	/** @test */
	public function shouldRenderCote() {
		$this->assertXPathContentContains('//td', 'VOD-T-DLJ');
	}

	/** @test */
	public function shouldHaveClassDisponble() {
		$this->assertXPath('//td[@class="dispo disponible"]');
	}


	/** @test */
	public function fonctionsAdminShouldNotBeVisible() {
		$this->assertNotXPath('//a[contains(@href, "/admin/modulesnotice/exemplaires")]', $this->_response->getBody());
	}

	/** @test */
	public function fonctionsAdminShouldBeVisibleIfCurrentUserIsAdmin() {
		$this->bootstrap();
		ZendAfi_Auth::getInstance()->logUser(Class_Users::newInstanceWithId(5)->beAdminPortail());
		$this->dispatch('noticeajax/exemplaires?id_notice=123');
		$this->assertXPath('//a[@data-popup="true"][@href="/admin/modulesnotice/exemplaires/config/admin/id_profil/2"]', $this->_response->getBody());
	}


	/** @test */
	public function fonctionsAdminShouldBeVisibleIfCurrentUserHasRightConfigurerBoites() {
		ZendAfi_Auth::getInstance()->logUser($user = Class_Users::newInstanceWithId(5)
																				 ->beModoBib()
																				 ->setUserGroups([Class_UserGroup::newInstanceWithId(2)
																													->addRightConfigFront()]));
		$this->dispatch('noticeajax/exemplaires?id_notice=123', true);
		$this->assertXPath('//a[@data-popup="true"][@href="/admin/modulesnotice/exemplaires/config/admin/id_profil/2"]', $this->_response->getBody());
	}
}



class NoticeAjaxControllerBabelthequeTest extends AbstractControllerTestCase {
	public function setUp() {
		parent::setUp();

		Class_Notice::getLoader()
			->newInstanceWithId(157675)
			->setIsbn('978-2-226-21993-0');

		Class_AdminVar::getLoader()
			->newInstanceWithId('BABELTHEQUE_JS')
			->setValeur('http://www.babeltheque.com/bw_85.js');

		$this->dispatch('/opac/noticeajax/babeltheque?id_notice=N157675', true);
	}


	/** @test */
	public function responseShouldContainsBabelthequeScript() {
		$this->assertXPath('//script[@src="http://www.babeltheque.com/bw_85.js"]');
	}


	/** @test */
	public function pageShouldContainsInputHiddenWithIsbn() {
		$this->assertXPath('//input[@type="hidden"][@id="BW_id_isbn"][@value="978-2-226-21993-0"]');
	}


	/** @test */
	public function pageShouldContainsNotes() {
		$this->assertXPath('//div[@id="BW_notes"]');
	}


	/** @test */
	public function pageShouldContainsCritiques() {
		$this->assertXPath('//div[@id="BW_critiques"]');
	}
}




class NoticeAjaxControllerBabelthequeWithoutOptionTest extends AbstractControllerTestCase {
	public function setUp() {
		parent::setUp();

		Class_AdminVar::getLoader()
			->newInstanceWithId('BABELTHEQUE_JS')
			->setValeur('');

		$this->dispatch('/opac/noticeajax/babeltheque?id_notice=N157675', true);
	}


	/** @test */
	public function responseShouldBeEmpty() {
		$this->assertEquals('', $this->_response->getBody());
	}
}



class NoticeAjaxControllerFrbrNotFoundTest extends AbstractControllerTestCase {
	public function setUp() {
		parent::setUp();

		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Notice')
				->whenCalled('find')
				->with(777)
				->answers(null);

		$this->dispatch('/opac/noticeajax/frbr?id_notice=777', true);
	}


	/** @test */
	public function actionShouldBeFrbr() {
		$this->assertAction('frbr');
	}


	/** @test */
	public function responseShouldContainAucunLien() {
		$this->assertTrue(false !== strpos($this->_response->getBody(), 'Aucun lien'));
	}
}


abstract class NoticeAjaxControllerFrbrWithLinksTestCase extends AbstractControllerTestCase {
	private $_lesGrandsTextes;
	private $_moiCEstQuoi;

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

		$leCombat = 'LECOMBATDESJUGES--BILLYY--ZARAFAFILMSDISTRIB-2006-4';
		$this->_lesGrandsTextes = 'LESGRANDSTEXTESDEDROITINTERNATIONALPUBLIC--DUPUYP--DALLOZ-2010-1';
		$this->_moiCEstQuoi = 'MOICESTQUOI--BRENIFIERO--NATHANJEUNESSE-2004-1';

		$type = Class_FRBR_LinkType::newInstanceWithId(1)
				->setLibelle('Suite')
				->setFromSource('a pour suite')
				->setFromTarget('est une suite de');

		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_FRBR_Link')
				->whenCalled('getLinksForSource')
				->with($leCombat)
				->answers([Class_FRBR_Link::newInstanceWithId(1)
						       ->setType($type)
						       ->setSource($this->_getUrlForKey($leCombat))
						       ->setSourceType(Class_FRBR_Link::TYPE_NOTICE)
						       ->setTarget($this->_getUrlForKey($this->_lesGrandsTextes))
						       ->setTargetType(Class_FRBR_Link::TYPE_NOTICE)])

				->whenCalled('getLinksForTarget')
				->with($leCombat)
				->answers([Class_FRBR_Link::newInstanceWithId(2)
						       ->setType($type)
						       ->setSource($this->_getUrlForKey($this->_moiCEstQuoi))
						       ->setSourceType(Class_FRBR_Link::TYPE_NOTICE)
						       ->setTarget($this->_getUrlForKey($leCombat))
						       ->setTargetType(Class_FRBR_Link::TYPE_NOTICE)]);


		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Notice')
				->whenCalled('getNoticeByClefAlpha')
				->with($this->_lesGrandsTextes)
				->answers(Class_Notice::newInstanceWithId(888)
					        ->setTitrePrincipal('Les grands textes de droit')
					        ->setClefAlpha($this->_lesGrandsTextes)
									->setUrlVignette('NO')
									->setUrlImage('NO')
									->setTypeDoc(2))

				->whenCalled('getNoticeByClefAlpha')
				->with($this->_moiCEstQuoi)
				->answers(Class_Notice::newInstanceWithId(999)
									->setTypeDoc(2)
					        ->setTitrePrincipal('Moi, c\'est quoi ?')
					        ->setClefAlpha($this->_moiCEstQuoi)
									->setUrlVignette('moi_c_est_quoi.jpg')
									->setUrlImage('moi_c_est_quoi.jpg'))

				->whenCalled('find')
				->with(777)
				->answers(Class_Notice::newInstanceWithId(777, ['clef_alpha' => $leCombat,
																												'url_vignette' => '',
																												'url_image' => '']));
	}


	protected function _getUrlForKey($key) {
		return 'http://localhost' . BASE_URL . '/recherche/viewnotice/clef/' . $key
				. '?id_profil=1&type_doc=1';
	}


	/** @test */
	public function linkTypeAPourSuiteShouldBePresent() {
		$this->assertXPathContentContains('//div', 'a pour suite');
	}


	/** @test */
	public function lesGrandsTextesShouldBePresent() {
		$this->assertXPathContentContains('//a', 'Les grands textes de droit',$this->_response->getBody());
	}


	/** @test */
	public function linkToTargetShouldBePresent() {
		$this->assertXPath('//div[contains(@onclick, "/viewnotice/clef/' . $this->_lesGrandsTextes . '")]');
	}


	/** @test */
	public function linkTypeEstSuiteShouldBePresent() {
		$this->assertXPathContentContains('//div', 'est une suite de', $this->_response->getBody());
	}


	/** @test */
	public function moiCEstQuoiShouldBePresent() {
		$this->assertXPathContentContains('//a', 'Moi, c\'est quoi',$this->_response->getBody());
	}


	/** @test */
	public function linkToSourceShouldBePresent() {
		$this->assertXPath('//a[contains(@href, "/viewnotice/clef/' . $this->_moiCEstQuoi . '")]',$this->_response->getBody());
	}

	/** @test */
	public function vignetteForMoiCestQuoiShouldMoiCestQuoiDotJpg() {
		$this->assertXPath('//img[contains(@src, "moi_c_est_quoi.jpg")]');
	}


	/** @test */
	public function vignetteForGrandsTextesShouldBeGenerated() {
		$this->assertXPath('//div[@class="nothumbnail type_doc_2"]');
	}
}



class NoticeAjaxControllerFrbrWithLinksTest extends NoticeAjaxControllerFrbrWithLinksTestCase {
	public function setUp() {
		parent::setUp();
		$this->dispatch('/opac/noticeajax/frbr?id_notice=777', true);
	}
}



class NoticeAjaxControllerFrbrWithLinksAndNInIdTest extends NoticeAjaxControllerFrbrWithLinksTestCase {
	public function setUp() {
		parent::setUp();
		$this->dispatch('/opac/noticeajax/frbr?id_notice=N777', true);
	}
}




class NoticeAjaxControllerNoticeActionTest extends AbstractControllerTestCase {
	public function setUp() {
		parent::setUp();
		$this->notice = Class_Notice::getLoader()->findFirstBy([]);
		$this->notice->setTitrePrincipal('Bending new corners');
		$this->dispatch('/opac/noticeajax/notice?id_notice=N'.$this->notice->getId(), true);
	}


	/** @test */
	public function pageShouldContainsTitreNotice() {
		$this->assertXPathContentContains('//h1', 'Bending new corners');
	}

	/** @test */
	public function shouldContainsTitle() {
		$this->assertXPath('//div[contains(@class, "notice_bloc_titre") and h2]');
	}
}




class NoticeAjaxControllerVideoMorceauTest extends AbstractControllerTestCase {
	public function setUp() {
		parent::setUp();
		$this->dispatch('/opac/noticeajax/videomorceau?auteur=The%20Beatles&titre=Come%20together&width=300', true);
	}


	/**
	 * @group integration
	 * @test
	 */
	public function responseShouldContainsPlayer() {
		$this->assertXPath('//param[@name="movie"][@value="http://youtube.googleapis.com/v/axb2sHpGwHQ&source=uds&autoplay=1"]');
	}


	/**
	 * @group integration
	 * @test
	 */
	public function playerShouldHaveWidth300() {
		$this->assertXPath('//object[@width="300"]', $this->_response->getBody());
	}
}




class NoticeAjaxControllerResumeNoticeTest extends AbstractControllerTestCase {
	/** @test */
	public function withResumeNoticeShouldRenderHistoireDeLHomme() {
		Class_Notice::newInstanceWithId(123,
																		['titre_principal' => 'Tarzan',
																		 'resume' => 'L \'histoire de l\'homme qui habite dans la jungle.']);

		$this->dispatch('/noticeajax/resumenotice?id_notice=123',true);
		$this->assertXPathContentContains('//body', 'homme qui habite dans la jungle');
	}



	/** @test */
	public function withoutResumeNoticeShouldRenderAucunResume() {
		Class_Notice::newInstanceWithId(123,
																		['titre_principal' => 'Tarzan']);

		$this->dispatch('/noticeajax/resumenotice?id_notice=123', true);
		$this->assertXPathContentContains('//body', utf8_encode('Aucun résumé'));
	}
}






class NoticeAjaxControllerDVDSeriesTest extends AbstractControllerTestCase {
	/** @test */
	public function withSeriesNoticeShouldOzSeason3() {
		$oz_season1=Class_Notice::newInstanceWithId(234,
																		['titre_principal' => 'Oz Season 1',
																		 'clef_chapeau' => 'OZ',
																		 'tome_alpha' => '4',
																		 'type_doc' => Class_TypeDoc::DVD,
																		 'resume' => 'Serie TV']);

		$oz_season1->set_subfield('461','t', 'OZ');
		$oz_season3 = Class_Notice::newInstanceWithId(2345,
																		['titre_principal' => 'Oz saison 3',

																		 'clef_chapeau' => 'OZ',
																		 'type_doc' => Class_TypeDoc::DVD,
																		 'tome_alpha' => '3',
																		 'url_vignette' => '',
																		 'url_image' => '',
																		 'resume' => 'Serie TV']);
		$oz_season3->set_subfield('461','t', 'OZ');
		$oz_season2 = Class_Notice::newInstanceWithId(23456,
																		['titre_principal' => 'Oz saison 2',
																		 'clef_chapeau' => 'OZ',
																		 'tome_alpha' => '3',
																		 'url_vignette' => '',
																		 'url_image' => '',
																		 'type_doc' => Class_TypeDoc::DVD,
																		 'resume' => 'Serie TV']);
		$oz_season2->set_subfield('461','t', 'OZ');
		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Notice')
			->whenCalled('findAllBy')
			->with(['clef_chapeau' => 'OZ',
							'order' => 'tome_alpha desc'])
			->answers([$oz_season2, $oz_season3]);


		$this->dispatch('/noticeajax/series?id_notice=234',true);
		$this->assertXPathContentContains('//div', utf8_encode('Voir tous les épisodes d\'OZ'),$this->_response->getBody());
	}
}




class NoticeAjaxControllerPeriodiqueSerieTest extends AbstractControllerTestCase {
	/** @test */
	public function withPeriodiqueNoticeShouldDisplayTousLesNumerosDeFakir() {
		Class_Notice::newInstanceWithId(234,
																		['unimarc' => '00170nas0 2200085   450 0010008000001000018000082000030000262100009000564610019000653059603  a|||||||||2012  aFakirh58iDécembre 2012  d2012 032979322tFakir',
																		 'titre_principal' => 'Fakir 58',
																		 'clef_chapeau' => 'FAKIR',
																		 'tome_alpha' => '58',
																		 'type_doc' => Class_TypeDoc::PERIODIQUE,
																		 'resume' => 'Fakir hebdo']);


		$fakir57= Class_Notice::newInstanceWithId(2345,
																		['titre_principal' => 'Fakir 57 septembre-novembre 2012',
																		 'unimarc' => '00179nas0 2200085   450 0010008000001000018000082000039000262100009000654610019000743037025  a|||||||||2012  aFakirh57iSeptembre-Novembre 2012  d2012 032979322tFakir',
																		 'clef_chapeau' => 'FAKIR',
																		 'type_doc' => Class_TypeDoc::PERIODIQUE,
																		 'tome_alpha' => '57',
																		 'url_vignette' => '',
																		 'url_image' => '',
																		 'resume' => 'Fakir hebdo']);
		$fakir56 = Class_Notice::newInstanceWithId(23456,
																		['titre_principal' => 'juillet Fakir 56',
																		 'unimarc' => '00168nas0 2200085   450 0010008000001000018000082000028000262100009000544610019000633025081  a|||||||||2012  aFakirh56iJuillet 2012  d2012 032979322tFakir',
																		 'clef_chapeau' => 'FAKIR',
																		 'tome_alpha' => '56',
																		 'url_vignette' => '',
																		 'url_image' => '',
																		 'type_doc' => Class_TypeDoc::PERIODIQUE,
																		 'resume' => 'Fakir hebdo']);

		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Notice')
			->whenCalled('findAllBy')
			->with(['clef_chapeau' => 'FAKIR',
							'order' => 'tome_alpha desc'])
			->answers([$fakir56, $fakir57]);


		$this->dispatch('/noticeajax/series/id_notice/234',true);
		$this->assertXPathContentContains('//a[contains(@href,"/recherche/simple/serie/FAKIR/tri/date_creation+desc")]', utf8_encode('Voir tous les numéros de Fakir'),$this->_response->getBody());
	}
}





abstract class NoticeAjaxMemeAuteurTest extends AbstractControllerTestCase {
	/** @test */
	public function withAuteurNoticeShouldOzSeason3() {
		Class_Notice::newInstanceWithId(234,
																		['titre_principal' => 'Eloge de la fuite',
																		 'alpha_auteur' => 'HENRI LABORIT',
																		 'resume' => '']);


		Class_Notice::newInstanceWithId(234,
																		['titre_principal' => 'La nouvelle grille',
																		 'alpha_auteur' => 'HENRI LABORIT',
																		 'resume' => '']);

/*		Storm_Test_ObjectWrapper::onLoaderOfModel('Class_Notice')
			->whenCalled('findAllBy')
			->with(['clef_chapeau' => 'OZ',
							'order' => 'tome_alpha'])
			->answers([$oz_season2, $oz_season3]);
*/

		$this->dispatch('/noticeajax/auteur?id_notice=234',true);
		$this->assertXPathContentContains('//body', 'nouvelle grille',$this->_response->getBody());
	}



	/** @test */
	public function withoutSeriesNoticeShouldRenderAucuneSerie() {
		$this->fixture('Class_Notice', ['id'=>123,
																		'titre_principal' => 'Tarzan']);

		$this->dispatch('/noticeajax/series?id_notice=123', true);
		$this->assertXPathContentContains('//body', utf8_encode('Aucune information'),$this->_response->getBody());
	}
}


class NoticeAjaxControllerDisponibiliteNoticeTest extends AbstractControllerTestCase {
	protected
		$_notice,
		$_exemplaire,
		$_sigb_exemplaire;

	public function setUp() {
		parent::setUp();
		$this->_sigb_exemplaire = Storm_Test_ObjectWrapper::mock();


		$this->_exemplaire = $this->fixture('Class_Exemplaire',
																				['id' => 34,
																				 'id_bib' => 456,
																				 'id_int_bib' => 456,
																				 'id_origine' => 12,
																				 'id_notice' => 123,
																				 'code_barres' => '12256663233656',
																				 'is_available' => false,
																				 'cote' => 'DDD',
																				 'dispo' => 'Disponible',
																				 'sigb_exemplaire' => $this->_sigb_exemplaire
																				]);

		$this->_notice = $this->fixture('Class_Notice', ['id'=>123,
																										 'titre_principal' => 'Tarzan',
																										 'exemplaires' => [$this->_exemplaire]]);
	}


	private function assertDispoNoticeHtmlContains($available) {
		$this->dispatch('/noticeajax/dispo-notice?id_notice=123',true);
		$this->assertXPathContentContains('//body', $available, $this->_response->getBody());
	}


	/** @test */
	public function withoutExemplaireShouldNotBeAvailable () {
		$this->_notice->setExemplaires([])
									->save();
		$this->assertDispoNoticeHtmlContains('false');
	}

	/** @test */
	public function withNonAvailableExemplaireShouldNotBeAvailable() {
		$this->_sigb_exemplaire->whenCalled('isDisponible')
													 ->answers(false);
		$this->assertDispoNoticeHtmlContains('false');
	}

  /** @test */
	public function withAvailableExemplaireShouldBeAvailable() {
		$this->_sigb_exemplaire->whenCalled('isDisponible')
													 ->answers(true);
		$this->assertDispoNoticeHtmlContains('true');
	}


  /** @test */
	public function assertNoticeShouldBeUpdatedWithAvailabilityTrue() {
		$this->_sigb_exemplaire->whenCalled('isDisponible')
													 ->answers(true);

		$this->dispatch('/noticeajax/exemplaires/id/123',true);
		Class_Exemplaire::clearCache();
		Class_Notice::clearCache();

		$this->assertTrue(Class_Exemplaire::find(34)->getIsAvailable());
		return $this->_notice;
	}

	/**
	 * @test
	 * @depends assertNoticeShouldBeUpdatedWithAvailabilityTrue
	 */
	public function noticeShouldContainsFacetV456($notice) {
		$this->assertContains('V456', $notice->getFacettes());
	}


  /** @test */
	public function assertNoticeShouldBeUpdatedWithAvailabilityFalse() {
		$this->_notice->setFacettes('V456')->save();
		$this->_exemplaire->setIsAvailable(true)->save();

		$this->_sigb_exemplaire->whenCalled('isDisponible')
													 ->answers(false);

		$this->dispatch('/noticeajax/exemplaires/id/123',true);
		Class_Exemplaire::clearCache();
		Class_Notice::clearCache();

		$this->assertFalse(Class_Exemplaire::find(34)->getIsAvailable());
		return $this->_notice;
	}


	/**
	 * @test
	 * @depends assertNoticeShouldBeUpdatedWithAvailabilityFalse
	 */
	public function noticeShouldNotContainsFacetV456($notice) {
		$this->assertNotContains('V456', $notice->getFacettes());
	}
}




abstract class NoticeAjaxControllerNoticeWithAvisTestCase extends AbstractControllerTestCase {
	public function setup() {
		parent::setup();

		Class_AdminVar::newInstanceWithId('AVIS_BIB_SEULEMENT')->setValeur(0);

		$avis_de_paul = Class_AvisNotice::newInstanceWithId(23,['entete'=>'Tres Bien',
																														'note'=>'4',
																														'user'=>Class_Users::newInstanceWithId(15,['login'=>'polo'])->beAbonneSIGB(),
																														'avis'=>'de la balle',
																														'date_avis'=>'15/03/2013',
																														'clef_oeuvre'=>'potter',
																														'abon_ou_bib'=>'0'])
			->setModerationOk();

		$avis_de_francois = Class_AvisNotice::newInstanceWithId(24,['entete'=>'Cool',
																																'note'=>'4',
																																'user'=>Class_Users::newInstanceWithId(15,['login'=>'francois'])->beAdminPortail(),
																																'avis'=>'tres bien',
																																'date_avis'=>'16/02/2013',
																																'clef_oeuvre'=>'potter',
																																'abon_ou_bib'=>'1'])
			->setModerationOk();

		Class_Notice::newInstanceWithId(34,['titre_principal'=>'Potter',
																				'clef_oeuvre'=>'potter',
																				'avis' => [$avis_de_paul, $avis_de_francois]]);

	}
}



class NoticeAjaxControllerNoticeWithAvisEditLinkNotLoggedTest extends NoticeAjaxControllerNoticeWithAvisTestCase {
	/**
	 * parent::_login setup an admin account by default -> do not log at all in this test
	 */
	protected function _login() {}


	/** @test */
	public function editLinkShouldNotBePresent() {
		$this->dispatch('/opac/noticeajax/avis/id_notice/34/page/0/onglet/bloc', true);
		$this->assertNotXPath('//a[contains(@href, "abonne/editavisnotice")]');
	}
}



class NoticeAjaxControllerNoticeWithAvisEditLinkGuestLoggedTest extends NoticeAjaxControllerNoticeWithAvisTestCase {
	protected function _loginHook($account) {
		$account->ROLE_LEVEL = ZendAfi_Acl_AdminControllerRoles::INVITE;
		$account->ROLE = 'invite';

	}

	/** @test */
	public function editLinkShouldNotBePresent() {
		$this->dispatch('/opac/noticeajax/avis/id_notice/34/page/0/onglet/bloc', true);
		$this->assertNotXPath('//a[contains(@href, "abonne/editavisnotice")]');
	}
}



class NoticeAjaxControllerNoticeWithAvisEditLinkModoLoggedTest extends NoticeAjaxControllerNoticeWithAvisTestCase {
	protected function _loginHook($account) {
		$account->ROLE_LEVEL = ZendAfi_Acl_AdminControllerRoles::MODO_BIB;
		$account->ROLE = 'modo_bib';
	}

	public function setUp() {
		parent::setUp();
		$this->dispatch('/opac/noticeajax/avis/id_notice/34/page/0/onglet/bloc', true);
	}


	/** @test */
	public function editLinkShouldBePresent() {
		$this->assertXPath('//a[contains(@href, "abonne/editavisnotice")]');
	}


	/** @test */
	public function editLinkShouldBePopup() {
		$this->assertXPath('//a[contains(@href, "abonne/editavisnotice")][@data-popup="true"]');
	}


	/** @test */
	public function deleteLinkShouldBePresent() {
		$this->assertXPath('//a[contains(@href, "abonne/delavisnotice")]');
	}
}



class NoticeAjaxControllerAvisNoticeNotFoundTest extends AbstractControllerTestCase {
	public function setUp() {
		parent::setUp();
		$this->dispatch('/opac/noticeajax/avis/id_notice/-1', true);
	}


	/** @test */
	public function responseShouldBeEmpty() {
		$this->assertEmpty($this->_response->getBody());
	}
}




class NoticeAjaxControllerNoticeWithAvisAvisAbonneTest extends NoticeAjaxControllerNoticeWithAvisTestCase {
	public function setUp() {
		parent::setUp();
		$this->dispatch('/opac/noticeajax/avis-abonne/id_notice/34', true);
	}


	/** @test */
	public function answerShouldContainsAvisDePaul() {
		$this->assertXPathContentContains('//body', 'Tres Bien');
		$this->assertXPath('//img[contains(@class, "note-4")]');
		$this->assertXPathContentContains('//body', '15 mars 2013');
		$this->assertXPathContentContains('//body', 'de la balle');
	}


	/** @test */
	public function answerShouldNotContainsAvisDeFrancois() {
		$this->assertNotXPathContentContains('//body', 'Cool');
	}
}




class NoticeAjaxControllerNoticeWithAvisAvisTest extends NoticeAjaxControllerNoticeWithAvisTestCase {
	public function setUp() {
		parent::setUp();

		$user = $this->fixture('Class_Users',
													 ['id' => 1,
														'login' => 'pom',
														'password' => '123',
														]);
		$user->setRoleLevel(ZendAfi_Acl_AdminControllerRoles::ADMIN_PORTAIL)->save();

		ZendAfi_Auth::getInstance()->logUser($user);

		Class_AdminVar::newInstanceWithId('AVIS_BIB_SEULEMENT')->setValeur(0);

		$this->dispatch('/opac/noticeajax/avis/id_notice/34/page/0/onglet/bloc', true);
	}



	/** @test */
	public function linkAddAvisShouldBePopup() {
		$this->assertXPathContentContains('//a[contains(@href, "/noticeajax/add-avis/id_notice/34")][@data-popup="true"]',
																			'Donnez ou modifiez votre avis', $this->_response->getBody());
	}
}


abstract class NoticeAjaxControllerCvsSearchtest extends AbstractControllerTestCase {
	public function setup() {
		parent::setup();
		RessourcesNumeriquesFixtures::activateCVS();

		$polo= $this->fixture('Class_Users', ['id' => 15,
																					'login' => 'polo',
																					'password' => '456',
																					'pseudo' => 'polo'])
			->beAbonneSIGB();

		ZendAfi_Auth::getInstance()->logUser($polo);
	}
}

class NoticeAjaxControllerCvsSearchWithNoRecordTest extends NoticeAjaxControllerCvsSearchtest {
	public function setUp() {
		parent::setUp();

		$mock_cvs = Storm_Test_ObjectWrapper::mock();

		Storm_Test_ObjectWrapper::mock()
 			->whenCalled('forUser')
			->answers($this->mock_cvs);
		$mock_cvs
			->whenCalled('searchNotices')
			->answers([]);

		Class_Profil::getCurrentProfil()->setCfgModules(['recherche' =>	['resultat' => []]]);
		$this->dispatch('/opac/noticeajax/cvs-search/expressionRecherche/Cuisson/page/2', true);
	}


	/** @test */
	public function resultShouldReturnEmptyMessage() {
		$this->assertXPathContentContains('//div[@id="cvs_result"]/span','Aucun document trouv',$this->_response->getBody());
	}
}



class NoticeAjaxControllerCvsWithRecordsSearchTest extends NoticeAjaxControllerCvsSearchtest {
	protected $_cvs;
	protected $_http_client;

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

		Class_Profil::getCurrentProfil()
			->setCfgModules(['recherche' =>
											 ['resultatsimple' => [	'cvs_display_position' => '1',
																							'liste_format' => 3,
																							'cvs_nb_result' => 2]]]);

		RessourcesNumeriquesFixtures::activateCVS();

		$record = $this->fixture('Class_Notice',['id'=> 10,
																						 'titre_principal' => 'Le photographe',
																						 'auteur_principal' => 'Guibert']);
		$this->_cvs = Class_CVSLink::forUser($record);
		$this->_http_client = Storm_Test_ObjectWrapper::mock();

		Class_CVSLink::setTimeSource((new TimeSourceForTest)->setTime(1369640315));
		Class_CVSLink::setDefaultHttpClient($this->_http_client);
		Class_Xml::setDefaultHttpClient($this->_http_client);
		RessourcesNumeriquesFixtures::activateCVS();

		$this->_http_client
			->whenCalled('postData')
			->answers($this->_returnedXML())
			;

		$this->dispatch('/opac/noticeajax/cvs-search/expressionRecherche/Cuisson/page/1', true);
	}


	protected function _returnedXML() {
		$xml = file_get_contents(realpath(dirname(__FILE__)). '/../../../../fixtures/cvs_search_ecole.xml');
		return $xml;
	}


	/** @test */
	public function simpleContentShouldContainsCVSDiv() {
		$this->assertXPath('//div[@id="cvs_result"]//div[@class="cvs_record_list"]', $this->_response->getBody());
	}


	/** @test **/
	public function resultFormatShouldBeVignetteMode() {
		$this->assertXPath('//div[@class="liste_vignettes"]');
	}


	/** @test **/
	public function cvsSearchRequestShouldHaveNbParPage2() {
		$xml= base64_decode(strtr($this->_http_client->getAttributesForLastCallOn('postData')[1]['xml'], '-_', '+/'));
		$xpath = new Storm_Test_XPathXML();
		$xpath->assertXPath($xml,'//nombre_par_page[contains(text(),2)]');
	}
}





class NoticeAjaxControllerErrorTagsTest extends AbstractControllerTestCase {
	public function setUp() {
		parent::setUp();
		$this->dispatch('/noticeajax/tags/id/-1', true);
	}


	/** @test */
	public function responseShouldNotThrowError() {
		$this->assertXPathContentContains('//a', 'Proposer des tags pour cette notice');
	}
}



abstract class NoticeAjaxControllerBiographieTestCase extends AbstractControllerTestCase {
	public function setUp() {
		parent::setUp();

		Class_Notice::newInstanceWithId(23, ['auteur_principal' => 'J.K Rowling',
																				 'clef_oeuvre' => 'HARRY_POTTER']);

		Class_CosmoVar::newInstanceWithId('url_services', ['valeur' => 'http://cache.org']);

		$admin = Class_Users::newInstanceWithId(15,['login'=>'admin'])->beAdminPortail();
		Zend_Auth::getInstance()->logUser($admin);
	}
}




class NoticeAjaxControllerBiographieTest extends NoticeAjaxControllerBiographieTestCase {
	public function setUp() {
		parent::setUp();

		Class_WebService_AllServices::setHttpClient($http_client = Storm_Test_ObjectWrapper::mock()
																								->whenCalled('open_url')
																								->with('http://cache.org'
																											 .'?auteur='.urlencode('J.K Rowling')
																											 .'&clef_oeuvre=HARRY_POTTER'
																											 .'&src='.Class_WebService_AllServices::createSecurityKey()
																											 .'&action=8')

																								->answers(json_encode(['statut_recherche' => '0',
																																			 'source' => 'Wikipedia',
																																			 'vignette' => 'rowling.jpg',
																																			 'image' => 'rowling_big.jpg',
																																			 'biographie' => [
																																				 ['texte' => 'Auteur de H.Potter']
																																				 ]
																																				])));
		$this->dispatch('/opac/noticeajax/biographie/id_notice/23', true);
	}


	/** @test */
	public function htmlShouldContainsTDWithAuteurDeHarryPotter() {
		$this->assertXPathContentContains('//td', 'Auteur de H.Potter', $this->_response->getBody());
	}


	/** @test */
	public function imgShouldContainsRowlingDotJpg() {
		$this->assertXPath('//img[@src="rowling.jpg"]');
	}


	/** @test */
	public function anchorShouldContainsRowlingBigDotJpg() {
		$this->assertXPath('//a[@href="rowling_big.jpg"]');
	}


	/** @test */
	public function linkModifierLaBiographieShouldBeVisible() {
		$this->assertXPathContentContains('//a', 'Modifier la biographie');
	}

	/** @test */
	public function shouldContainTitle() {
		$this->assertXPath('//h3');
	}

	/** @test */
	public function tdShouldContainTitle() {
		$this->assertXPath('//td[contains(@class, "notice_info_titre") and h3]');
	}

	/** @test */
	public function asAbonneLienModifierShouldNotBeVisible() {
		$this->bootstrap();

		$abon = Class_Users::newInstanceWithId(15,['login'=>'abon'])->beAbonneSIGB();
		Zend_Auth::getInstance()->logUser($abon);

		$this->dispatch('/opac/noticeajax/biographie/id_notice/23', true);
		$this->assertNotXPathContentContains('//a', 'Modifier la biographie');
	}
}




class NoticeAjaxControllerBiographieNonTrouveeTest extends NoticeAjaxControllerBiographieTestCase {
	public function setUp() {
		parent::setUp();

		Class_WebService_AllServices::setHttpClient($http_client = Storm_Test_ObjectWrapper::mock()
																								->whenCalled('open_url')
																								->answers(json_encode(['statut_recherche' => '0',
																																			 'source' => '',
																																			 'vignette' => '',
																																			 'image' => '',
																																			 'biographie' => ''
																																				])));
		$this->dispatch('/opac/noticeajax/biographie/id_notice/23', true);
	}


	/** @test */
	public function answerShouldDisplayAucuneInformationTrouvee() {
		$this->assertXPathContentContains('//td', 'Aucune information');
	}
}




abstract class NoticeAjaxControllerLocalisationTestCase extends AbstractControllerTestCase {
	protected $_json;


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

		Class_Exemplaire::beVolatile();
		$file_system = Storm_Test_ObjectWrapper::mock()
			->whenCalled('unlink')
			->answers(true)
			->whenCalled('file_exists')
			->answers(true)
			->whenCalled('getimagesize')
			->answers(['480','360',2,'width="480" height="600"'])
			->whenCalled('rename')
			->answers(true)
			->whenCalled('getcwd')
			->answers('path');
		Class_Localisation::beVolatile();
		Class_Plan::beVolatile();
		Class_Localisation::setFileSystem($file_system);
		Class_Plan::setFileSystem($file_system);
		$this->fixture('Class_Notice',
									 ['id' => 1,
										'titre' => 'An Error occurd',
										'type_doc' => '1']);

		$this->fixture('Class_Localisation',
									 ['id' => '1',
										'id_bib' => '1',
										'libelle' => 'First Floor',
										'id_plan' => 1,
										'genre' => 'Doc']);

		$this->fixture('Class_bib',
									 ['id' => 1,
									 ]);

		$this->fixture('Class_Plan',
									 ['id' => 1,
										'image' => 'plan_bib_level_1.png']);


	}

}



class NoticeAjaxControllerNoLocalisationTest extends NoticeAjaxControllerLocalisationTestCase {
	public function setUp() {
		parent::setUp();
		$this->dispatch('noticeajax/localisation/id_bib/1', true);
	}

	/** @test */
	public function errorMessageShouldBeAsExpected() {
		$this->assertEquals('{"erreur":"Aucune donn\u00e9e de localisation trouv\u00e9e pour cet exemplaire"}', $this->_response->getBody());
	}
}



class NoticeAjaxControllerNoLocaltionForExemplaireTest extends NoticeAjaxControllerLocalisationTestCase {
	public function setUp() {
		parent::setUp();

		Class_Localisation::deleteBy([]);

		$this->fixture('Class_Exemplaire',
									 ['id' => 1,
										'id_bib' => 1,
										'code_barres' => 123456,
										'cote' => 123,
										'genre' => '',
										'id_notice' => '1',
										'section' => '',
										'emplacement' => '']);
		$this->dispatch('noticeajax/localisation/id_bib/1/cote/123', true);
	}


	/** @test */
	public function noLocalisationDataShouldBeReturn() {
		$this->assertEquals('{"erreur":"Aucune donn\u00e9e de localisation trouv\u00e9e pour cet exemplaire"}', $this->_response->getBody());
	}
}




class NoticeAjaxControllerWithLocalisationTest extends NoticeAjaxControllerLocalisationTestCase {
	public function setUp() {
		parent::setUp();

		$this->fixture('Class_Exemplaire',
									 ['id' => 1,
										'id_bib' => 1,
										'code_barres' => 123456,
										'cote' => 123,
										'genre' => 'Doc',
										'id_notice' => '1',
										'section' => '',
										'emplacement' => '']);


		$this->dispatch('noticeajax/localisation/id_bib/1/cote/123', true);
		$this->_json = json_decode($this->_response->getBody());
	}


	/** @test */
	public function urlShoudlBeAsExpected() {

		$this->assertContains('/userfiles/photobib/plans/bib_0_plan_1.png', $this->_json->url);
	}


	/** @test */
	public function locationTitleShouldBeFirstFloor() {
		$this->assertEquals('First Floor', $this->_json->libelle);
	}
}




class NoticeAjaxControllerWithMultipleSelectorLocalisationTest extends NoticeAjaxControllerLocalisationTestCase {
	public function setUp() {
		parent::setUp();

		$this->fixture('Class_Exemplaire',
									 ['id' => 5,
										'id_bib' => 1,
										'code_barres' => '',
										'cote' => 123789,
										'genre' => 'Doc',
										'emplacement' => '7',
										'id_notice' => 1,
										'section' => '']);

		$this->fixture('Class_Localisation',
									 ['id' => 2,
										'id_bib' => 1,
										'libelle' => 'Second floor',
										'id_plan' => '1',
										'genre' => 'Doc',
										'emplacement' => '7']);



		$this->dispatch('noticeajax/localisation/id_bib/1/cote/123789', true);
		$this->_json = json_decode($this->_response->getBody());
	}


	/** @test */
	public function locationTitleShouldBeSecondFloor() {
		$this->assertEquals('Second floor', $this->_json->libelle);
	}
}



class NoticeAjaxControllerLocalisationWithCoteTest extends  NoticeAjaxControllerLocalisationTestCase {
	public function setUp() {
		parent::setUp();
		$this->fixture('Class_Exemplaire',
									 ['id' => 5,
										'id_bib' => 1,
										'code_barres' => '123456',
										'cote' => '995 E',
										'genre' => 'Doc',
										'emplacement' => '7',
										'id_notice' => 1,
										'section' => '']);

		Class_Localisation::find(1)
			->setLibelle('Last floor')
			->setGenre('')
			->setCoteDebut('995 A')
			->setCoteFin('999 Z')
			->save();

		$this->dispatch('noticeajax/localisation/id_bib/1/code_barres/123456', true);
		$this->_json = json_decode($this->_response->getBody());
	}


	/** @test */
	public function locationTitleWithStartCoteShouldBeLastFloor() {
		$this->assertEquals('Last floor', $this->_json->libelle);
	}
}





class NoticeAjaxControllerLocalisationWithStartedCoteTest extends  NoticeAjaxControllerLocalisationTestCase {
	public function setUp() {
		parent::setUp();
		$this->fixture('Class_Exemplaire',
									 ['id' => 5,
										'id_bib' => 1,
										'code_barres' => '123456',
										'cote' => '995 E',
										'genre' => 'Doc',
										'emplacement' => '7',
										'id_notice' => 1,
										'section' => '']);

		Class_Localisation::find(1)
			->setLibelle('Last floor')
			->setGenre('')
			->setCoteDebut('995 A')
			->setCoteFin('999 Z')
			->save();

		$this->dispatch('noticeajax/localisation/id_bib/1/code_barres/123456', true);
		$this->_json = json_decode($this->_response->getBody());
	}


	/** @test */
	public function locationTitleShouldBeLastFloor() {
		$this->assertEquals('Last floor', $this->_json->libelle);
	}
}




class NoticeAjaxControllerLocalisationWithEndCoteTest extends  NoticeAjaxControllerLocalisationTestCase {
	public function setUp() {
		parent::setUp();
		$this->fixture('Class_Exemplaire',
									 ['id' => 5,
										'id_bib' => 1,
										'code_barres' => '123456',
										'cote' => '995 E',
										'genre' => 'Doc',
										'emplacement' => '7',
										'id_notice' => 1,
										'section' => '']);

		Class_Localisation::find(1)
			->setLibelle('Last floor')
			->setGenre('')
			->setCoteFin('999 Z')
			->save();

		$this->dispatch('noticeajax/localisation/id_bib/1/code_barres/123456', true);
		$this->_json = json_decode($this->_response->getBody());
	}


	/** @test */
	public function locationTitleWithEndCoteShouldBeLastFloor() {
		$this->assertEquals('Last floor', $this->_json->libelle);
	}
}
?>